关于《Windows程序设计(第五版)》中一个实例程序的疑问

最近一直在看Charlse Petzold的《Windows程序设计》,作为一个新得不能再新的新手,只能先照着书的抄抄源码了,之前的例子一直都很正常,但昨天遇到一个很诡异的BUG。

先看实例源码吧:

  1 /*-----------------------------------------------------------------
  2         ENVIRON.C -- Environment List Box
  3         (c) Charles Petzold,1998
  4         Copy by XXXX,2015/1/26
  5 ------------------------------------------------------------------*/
  6
  7 #include <windows.h>
  8
  9 #define ID_LIST 1
 10 #define ID_TEXT 2
 11
 12 LRESULT CALLBACK WndProc(HWND hwnd, UINT, WPARAM, LPARAM);
 13
 14 int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
 15 {
 16     static TCHAR szAppName[] = TEXT("Environ");
 17     HWND hwnd;
 18     MSG msg;
 19     WNDCLASS wndclass;
 20
 21     wndclass.style = CS_VREDRAW | CS_HREDRAW;
 22     wndclass.lpfnWndProc = WndProc;
 23     wndclass.cbClsExtra = 0;
 24     wndclass.cbWndExtra = 0;
 25     wndclass.hInstance = hInstance;
 26     wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
 27     wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
 28     wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
 29     wndclass.lpszMenuName = NULL;
 30     wndclass.lpszClassName = szAppName;
 31
 32     if (!RegisterClass(&wndclass))
 33     {
 34         MessageBox(NULL, TEXT("This program requires Windows NT!"), szAppName, MB_ICONERROR);
 35         return 0;
 36     }
 37
 38     hwnd = CreateWindow(szAppName, TEXT("Environment List Box"), WS_OVERLAPPEDWINDOW,
 39         CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL);
 40     ShowWindow(hwnd, iCmdShow);
 41     UpdateWindow(hwnd);
 42
 43     while (GetMessage(&msg, NULL, 0, 0))
 44     {
 45         TranslateMessage(&msg);
 46         DispatchMessage(&msg);
 47     }
 48     return msg.wParam;
 49 }
 50
 51
 52 void FillListBox(HWND hwndList)
 53 {
 54     int iLength;
 55     TCHAR * pVarBlock, *pVarBeg, *pVarEnd, *pVarName;
 56     pVarBlock = GetEnvironmentStrings();    //Get pointer to environment block
 57
 58     while (*pVarBlock)
 59     {
 60         if (*pVarBlock != ‘=‘)    //Skip variable names begining with ‘=‘
 61         {
 62             pVarBeg = pVarBlock;    //Beging of variable name
 63             while (*(pVarBlock++) != ‘=‘);    //Scan until ‘=‘
 64             pVarEnd = pVarBlock - 1;    //Points to ‘=‘ sign
 65             iLength = pVarEnd - pVarBeg;    //Length of variable name
 66
 67             //Allocate memory for the variable name and terminating
 68             //zero.Copy the variable name and append a zero
 69             pVarName = calloc(iLength + 1, sizeof(TCHAR));
 70             CopyMemory(pVarName, pVarBeg, iLength * sizeof(TCHAR));
 71             pVarName[iLength] = ‘\0‘;
 72
 73             //Put the variable name int the list box and free memory
 74             SendMessage(hwndList, LB_ADDSTRING, 0, (LPARAM)pVarName);
 75             free(pVarName);
 76         }
 77         while (*pVarBlock++ != ‘\0‘);    //Scna until terminating zero
 78
 79     }
 80     FreeEnvironmentStrings(pVarBlock);
 81     int code;
 82     code = GetLastError();
 83 }
 84
 85
 86 LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
 87 {
 88     static HWND hwndList, hwndText;
 89     int iIndex, iLength, cxChar, cyChar;
 90     TCHAR * pVarName, *pVarValue;
 91
 92     switch (message)
 93     {
 94     case WM_CREATE:
 95         cxChar = LOWORD(GetDialogBaseUnits());
 96         cyChar = HIWORD(GetDialogBaseUnits());
 97
 98         //Create listbox and static text windows
 99         hwndList = CreateWindow(TEXT("listbox"), NULL, WS_CHILD | WS_VISIBLE | LBS_STANDARD,
100             cxChar, cyChar * 3, cxChar * 16 + GetSystemMetrics(SM_CXVSCROLL), cyChar * 5, hwnd,
101             (HMENU)ID_LIST, (HINSTANCE)GetWindowLong(hwnd, GWL_HINSTANCE), NULL);
102         hwndText = CreateWindow(TEXT("static"), NULL, WS_CHILD | WS_VISIBLE | SS_LEFT, cxChar, cyChar,
103             GetSystemMetrics(SM_CXSCREEN), cyChar, hwnd, (HMENU)ID_TEXT,
104             (HINSTANCE)GetWindowLong(hwnd, GWL_HINSTANCE), NULL);
105         FillListBox(hwndList);
106         return 0;
107
108
109     case WM_SETFOCUS:
110         SetFocus(hwndList);
111         return 0;
112
113
114     case WM_COMMAND:
115         if (LOWORD(wParam) == ID_LIST&&HIWORD(wParam) == LBN_SELCHANGE)
116         {
117             //Get current selectiong
118             iIndex = SendMessage(hwndList, LB_GETCURSEL, 0, 0);
119             iLength = SendMessage(hwndList, LB_GETTEXTLEN, iIndex, 0) + 1;
120             pVarName = calloc(iLength, sizeof(TCHAR));
121             SendMessage(hwndList, LB_GETTEXT, iIndex, (LPARAM)pVarName);
122
123             //Get environment string
124             iLength = GetEnvironmentVariable(pVarName, NULL, 0);
125             pVarValue = calloc(iLength, sizeof(TCHAR));
126             GetEnvironmentVariable(pVarName, pVarValue, iLength);
127
128             //Show it in window
129             SetWindowText(hwndText, pVarValue);
130             free(pVarName);
131             free(pVarValue);
132         }
133         return 0;
134
135
136     case WM_DESTROY:
137         PostQuitMessage(0);
138         return 0;
139     }
140     return DefWindowProc(hwnd, message, wParam, lParam);
141 }

编译什么的都没有错误提示,但是在本地调试时提示触发一个断点,但是我确定我没有下过断点!!!

提示如图:

选择“继续”后会又提示一个中断,提示堆被损坏

作为一个小彩笔,真心弄不懂,求教大牛!!!

时间: 2024-12-21 01:20:06

关于《Windows程序设计(第五版)》中一个实例程序的疑问的相关文章

android中一个应用程序启动另外一个应用程序,并传递数据。

一.android一个应用程序启动了另外一个应用程序时候有2中方法. 第一种是知道了调用的app的具体action,category(一般前两个值是默认的即下面方法里的).包名和类名 public void start(View v) { Intent intent2 = new Intent("android.intent.action.MAIN"); intent2.addCategory("android.intent.category.LAUNCHER");

《Windows程序设计 第5版》第3章 窗口与消息 笔记

广告先: LibUIDK界面库:制作QQ.360界面时,你能找到的最强大的界面库.基于DirectHWND技术! 3.1 窗口的创建 一个简单的win32程序如下(假设工程名为"HelloWin32",下面的代码是使用vc6.0创建一个名为HelloWin32的"Win32 Application",并且选择"A typical "Hello World" application"后创建的代码精简后得到): // HelloW

Windows程序设计--(五)绘图基础

5.1 GDI的结构 图形设备接口(GDI:Graphics Device Interface)是Windows的子系统,它负责在视讯显示器和打印机上显示图形. 5.2 设备环境 5.2.1 获取设备环境句柄 最常用的取得并释放设备内容句柄的方法是,在处理WM_PAINT消息时,使用BeginPaint和EndPaint呼叫: hdc = BeginPaint (hwnd, &ps) ; 其它行程序 EndPaint (hwnd, &ps) ; Windows程序还可以在处理非WM_PAI

Oracle PL/SQL程序设计 第五版 上册 第三章 语言基础

最近看了很多东西,也练习了一些,我发现这东西好像有点进入瓶颈的感觉,这个瓶颈,我觉得是因为时间太短, 练习的还不够多,并且有很多东西都是随意带过弄的.并且最近在学习Python,有些东西还有点混淆了,我决定从新 来一遍这本书,把每一个例子都进行一个学习. PL/SQL块有匿名的,也有命名的,其实命名就是那些过程.函数.包.触发器.对象类型这些.书中第一个例子是这样的. insert.sql CREATE OR REPLACE PROCEDURE get_happy(emp_id_in IN NU

BOOL运算符号(从C#入门经典第五版中摘录)

只总结自己觉得难的哈: (1) var1=!var2;    //(非) (2) var1=var2&var3;    //(与) (3)var1=var2|var3;    //(或) (4)var1=var2^var3;   //(取异或) “ ”或“与”异或“的区别就是....var2和var3中有且仅有一个是true,var1的值就是true. & 和|运算符也有两个类似的运算符,称为条件布尔运算符(见表4.3). 这些运算符的结果与&和|完全相同,但得到结果的方式有一个重

Oracle PL/SQL程序设计 第五版 上册 第五章 用循环进行迭代处理

先是那个最简单的LOOP循环 loop.sql CREATE OR REPLACE PROCEDURE loop_demo     AUTHID CURRENT_USER IS     l_date DATE; BEGIN     l_date := SYSDATE;     LOOP         EXIT WHEN l_date > SYSDATE + 10;         l_date := l_date + 1;         DBMS_OUTPUT.PUT_LINE(l_date

Oracle PL/SQL程序设计 第五版 上册 第四章 条件和顺序控制

这一章的练习使用,那个scott下的emp表进行. 先使用IF / END IF; if.sql CREATE OR REPLACE PROCEDURE get_sal(emp_no_in IN NUMBER)     AUTHID CURRENT_USER IS     l_sal NUMBER; BEGIN     SELECT sal INTO l_sal     FROM emp     WHERE empno = emp_no_in;     IF l_sal > 2000     T

Oracle PL/SQL程序设计 第五版 上册 第八章 字符串

第七章 东西也挺杂的,看了不太清楚.虽然看完了,但是觉得没有获得太多东西,还得回去看. 看到了这个CHR函数, 原来就是把数字转成ASCII码,比如CHR(10)就是回车. BEGIN     DBMS_OUTPUT.PUT_LINE('gogo' || CHR(10) || 'tot'); END; / 这里使用||来连接字符,也可以使用CONCAT来连接.不过CONCAT只有两个参数,也就是连接两个字符串.

Oracle PL/SQL程序设计 第五版 上册 第十章 日期

DATE:  到秒 TIMESTAMP:  到十亿分之一秒 这两个一样,但是精度不同,. CURRENT_DATE  会话的时区  返回DATE CURRENT_TIMESTAMP   会话的时区,返回TIMESTAMP WITH TIME ZONE LOCALTIMESTAMP  会话时区   返回TIMESTAMP SYSDATE  服务器时区,返回DATE SYSTIMESTAMP  服务器时区,返回TIMESTAMP WITH TIME ZONE