最近一直在看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 = ;
  24. wndclass.cbWndExtra = ;
  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 ;
  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, , ))
  44. {
  45. TranslateMessage(&msg);
  46. DispatchMessage(&msg);
  47. }
  48. return msg.wParam;
  49. }
  50.  
  51. void FillListBox(HWND hwndList)
  52. {
  53. int iLength;
  54. TCHAR * pVarBlock, *pVarBeg, *pVarEnd, *pVarName;
  55. pVarBlock = GetEnvironmentStrings(); //Get pointer to environment block
  56.  
  57. while (*pVarBlock)
  58. {
  59. if (*pVarBlock != '=') //Skip variable names begining with '='
  60. {
  61. pVarBeg = pVarBlock; //Beging of variable name
  62. while (*(pVarBlock++) != '='); //Scan until '='
  63. pVarEnd = pVarBlock - ; //Points to '=' sign
  64. iLength = pVarEnd - pVarBeg; //Length of variable name
  65.  
  66. //Allocate memory for the variable name and terminating
  67. //zero.Copy the variable name and append a zero
  68. pVarName = calloc(iLength + , sizeof(TCHAR));
  69. CopyMemory(pVarName, pVarBeg, iLength * sizeof(TCHAR));
  70. pVarName[iLength] = '\0';
  71.  
  72. //Put the variable name int the list box and free memory
  73. SendMessage(hwndList, LB_ADDSTRING, , (LPARAM)pVarName);
  74. free(pVarName);
  75. }
  76. while (*pVarBlock++ != '\0'); //Scna until terminating zero
  77.  
  78. }
  79. FreeEnvironmentStrings(pVarBlock);
  80. int code;
  81. code = GetLastError();
  82. }
  83.  
  84. LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
  85. {
  86. static HWND hwndList, hwndText;
  87. int iIndex, iLength, cxChar, cyChar;
  88. TCHAR * pVarName, *pVarValue;
  89.  
  90. switch (message)
  91. {
  92. case WM_CREATE:
  93. cxChar = LOWORD(GetDialogBaseUnits());
  94. cyChar = HIWORD(GetDialogBaseUnits());
  95.  
  96. //Create listbox and static text windows
  97. hwndList = CreateWindow(TEXT("listbox"), NULL, WS_CHILD | WS_VISIBLE | LBS_STANDARD,
  98. cxChar, cyChar * , cxChar * + GetSystemMetrics(SM_CXVSCROLL), cyChar * , hwnd,
  99. (HMENU)ID_LIST, (HINSTANCE)GetWindowLong(hwnd, GWL_HINSTANCE), NULL);
  100. hwndText = CreateWindow(TEXT("static"), NULL, WS_CHILD | WS_VISIBLE | SS_LEFT, cxChar, cyChar,
  101. GetSystemMetrics(SM_CXSCREEN), cyChar, hwnd, (HMENU)ID_TEXT,
  102. (HINSTANCE)GetWindowLong(hwnd, GWL_HINSTANCE), NULL);
  103. FillListBox(hwndList);
  104. return ;
  105.  
  106. case WM_SETFOCUS:
  107. SetFocus(hwndList);
  108. return ;
  109.  
  110. case WM_COMMAND:
  111. if (LOWORD(wParam) == ID_LIST&&HIWORD(wParam) == LBN_SELCHANGE)
  112. {
  113. //Get current selectiong
  114. iIndex = SendMessage(hwndList, LB_GETCURSEL, , );
  115. iLength = SendMessage(hwndList, LB_GETTEXTLEN, iIndex, ) + ;
  116. pVarName = calloc(iLength, sizeof(TCHAR));
  117. SendMessage(hwndList, LB_GETTEXT, iIndex, (LPARAM)pVarName);
  118.  
  119. //Get environment string
  120. iLength = GetEnvironmentVariable(pVarName, NULL, );
  121. pVarValue = calloc(iLength, sizeof(TCHAR));
  122. GetEnvironmentVariable(pVarName, pVarValue, iLength);
  123.  
  124. //Show it in window
  125. SetWindowText(hwndText, pVarValue);
  126. free(pVarName);
  127. free(pVarValue);
  128. }
  129. return ;
  130.  
  131. case WM_DESTROY:
  132. PostQuitMessage();
  133. return ;
  134. }
  135. return DefWindowProc(hwnd, message, wParam, lParam);
  136. }

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

提示如图:

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

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

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

  1. Windows程序设计(第五版)学习:第三章 窗口与消息

        第三章 窗口与消息 1,windows窗口过程:应用程序所创建的每一个窗口都有一个与之关联的窗口过程,用于处理传递给窗口的消息. 2,窗口依据窗口类来创建.窗口类标识了用于处理传递给窗口的消息 ...

  2. Windows程序设计(第五版)学习:第一章 起步

    第一章 起步 1,windows主要的三个动态库: kernel32.dll负责操作系统的传统工作,包括内存管理.文件输入以及任务管理等. user32.dll负责用户界面的操作,即所有窗口的管理 g ...

  3. Windows程序设计(第五版)学习:第二章 Unicode简介

    第二章 Unicode简介 1,Windows通过双字节技术DBCS解决这个问题,代码页定义不同的字符集,称为ANSI字符集,比如日文为CP932,韩文为CP949,繁体中文为CP950,简体中文为C ...

  4. Windows程序设计(第五版)学习:第四章 文本输出

    第四章 文本输出 1,客户区:整个应用程序窗口中没有被标题栏.边框.菜单栏.工具栏.状态栏和滚动条占用的区域.简而言之,客户区就是窗口中程序可以在上面绘制并向用户传达可视化信息的区域.   2,大多数 ...

  5. 《Windows程序设计第5版》学习进度备忘

    书签:另外跳过的内容有待跟进 __________________学习资源: <Windows程序设计第5版珍藏版> __________________知识基础支持: _________ ...

  6. 用MyEclipse2016 CI版创建一个SpringBoot程序

    之前先要在Eclipse里安装STS,步骤如下: 1.点击菜单Help->Install from Catalog 2.在弹出的对话框中点击Popular选项卡,在STS旁边点Install按钮 ...

  7. C#只能运行一个实例程序的方法

    互斥进程(程序), 简单点说,就是在系统中只能有该程序的一个实例运行. 现在很多软件都有这功能,如Maxthon 可以设置为"只允许打开一个窗体",还有Bitcomet等. 我也是 ...

  8. [MFC.Windows程序设计(第2版) 第一章

    1,windows编程模型如下图: 2, windows的消息有成百上千种,以下列举10个: 3,消息处理函数的四个参数:窗口句柄(表示消息属于哪个窗口,32值.该窗口句柄引用一个数据结构,数据结构存 ...

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

    5.1 GDI的结构 图形设备接口(GDI:Graphics Device Interface)是Windows的子系统,它负责在视讯显示器和打印机上显示图形. 5.2 设备环境 5.2.1 获取设备 ...

随机推荐

  1. 2015-2016 ACM-ICPC Nordic Collegiate Programming Contest ---E题Entertainment Box(有点变化的贪心)

    提交链接 http://codeforces.com/gym/100781/submit Description: Ada, Bertrand and Charles often argue over ...

  2. 修改thinkphp路由模式,去掉Home

    第一步:入口文件增加 define('BIND_MODULE', 'Home'); 第二步:修改config文件,我这里路由模式设置为2 效果展示:

  3. PHP内核探索之变量(3)- hash table

    在PHP中,除了zval, 另一个比较重要的数据结构非hash table莫属,例如我们最常见的数组,在底层便是hash table.除了数组,在线程安全(TSRM).GC.资源管理.Global变量 ...

  4. 高效 Java Web 应用开发框架 JessMA v3.2.2 正式发布

    JessMA(原名:Portal-Basic)是由 JessMA Open Source 开发的一套高效 Java Full-Stack Web 应用开发框架,内置可扩展的 MVC Web 基础架构和 ...

  5. mysql出错:Access denied for user 'root'@'localhost' (using password: YES)

    网站链接mysql数据库的时候,连接不上,并报出错误:Access denied for user 'root'@'localhost' (using password:YES) 这是个相当恼火的问题 ...

  6. Quartz.NET开源作业调度框架系列(一):快速入门step by step

    Quartz.NET是一个被广泛使用的开源作业调度框架 , 由于是用C#语言创建,可方便的用于winform和asp.net应用程序中.Quartz.NET提供了巨大的灵活性但又兼具简单性.开发人员可 ...

  7. 从0开始学angularjs-笔记01

    一.angularjs简介 AngularJS 是一个为动态WEB应用设计的结构框架.它能让你使用HTML作为模板语言,通过扩展HTML的语法,让你能更清楚.简洁地构建你的应用组件.它的创新点在于,利 ...

  8. window7安装git详解

    1.Git详细介绍 一.Git的诞生 Linus虽然创建了Linux,但Linux的壮大是靠全世界热心的志愿者参与的,这么多人在世界各地为Linux编写代码,那Linux的代码是如何管理的呢? 事实是 ...

  9. LigerUI一个前台框架增、删、改asp.net代码的实现

    先上代码:前台代码 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://w ...

  10. iOS:JSON格式字符串转字典,字典转JSON格式字符串

    在iOS开发中,和服务器交互中,经常用到字典和JSON格式字符串相互转换. 代码如下: 1.JSON格式字符串转字典 + (NSDictionary *)dictionaryWithJsonStrin ...