window核心编程笔记 No.1

news/2024/7/20 16:08:52 标签: 内存管理, c/c++

 

jeffrey大牛写的 《windows via c/c++》

正如书中序言所说,charles petzold的《programing windows》面向用户编程,而这本书面向系统编程

系统编程,大概就是进程/线程调度,内存管理,当然还有windows的DLL相关的技术。

翻了一下第一章基础知识部分,错误处理,着重介绍了 win的一个API  GetLastError

简单的分析一下第一章例子的源代码作为笔记:

 

首先使用了大量的宏定义,写在CmnHdr.h头文件当中

 

int WINAPI _tWinMain(HINSTANCE hinstExe, HINSTANCE, PTSTR pszCmdLine, int) {

   //查找窗口是否已经创建,类名为32770,窗口名为Error Show
   HWND hwnd = FindWindow(TEXT("#32770"), TEXT("Error Show"));
   
   //如果已经创建了该窗口,发送ESM_POKECODEANDLOOKUP消息给该窗口
  //lparam为控制台输入的字符串转换为整数
   if (IsWindow(hwnd)) {
      // An instance is already running, activate it and send it the new #
      SendMessage(hwnd, ESM_POKECODEANDLOOKUP, _ttoi(pszCmdLine), 0);
   }

   //如果没有创建,创建窗口,以IDD_ERRORSHOW资源位模板
   else {
      DialogBoxParam(hinstExe, MAKEINTRESOURCE(IDD_ERRORSHOW), 
         NULL, Dlg_Proc, _ttoi(pszCmdLine));
   }
   return(0);
}
DialogBoxParam函数功能:该函数根据对话框模板资源创建一个模态的对话框。在显示对话框之前,函数将一个应用程序定义的值传到对话框过程中 WM_INITDIALOG
消息的 lParam 参数,应用程序可用此值来初始化对话框。
函数原型:int DialogBoxParam(HINSTANCE hInstance,LPCTSTR IpTemplateName,HWND hWndParent, DLGPROC IPDialogFunc,LPARAM dwlnitParam);
 
INT_PTR WINAPI Dlg_Proc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {

   switch (uMsg) {
      //使用自定义宏和事件处理函数处理对应的消息
      chHANDLE_DLGMSG(hwnd, WM_INITDIALOG, Dlg_OnInitDialog);
      chHANDLE_DLGMSG(hwnd, WM_COMMAND,    Dlg_OnCommand);

   //对于消息ESM_POKECODEANDLOOKUP的响应,将编辑框中的错误代码编码
  //设置为传入的整数,并且发送按钮按下的消息,查找消息对应的错误代码
   case ESM_POKECODEANDLOOKUP:
      SetDlgItemInt(hwnd, IDC_ERRORCODE, (UINT) wParam, FALSE);
      FORWARD_WM_COMMAND(hwnd, IDOK, GetDlgItem(hwnd, IDOK), BN_CLICKED, 
         PostMessage);
      SetForegroundWindow(hwnd);
      break;
   }

   return(FALSE);
}

 

创建Dialog的时候首先处理的就是WM_INITDIALOG消息

BOOL Dlg_OnInitDialog(HWND hwnd, HWND hwndFocus, LPARAM lParam) {

   //使用自定义宏更换图标
   chSETDLGICONS(hwnd, IDI_ERRORSHOW);

   // Don't accept error codes more than 5 digits long
   Edit_LimitText(GetDlgItem(hwnd, IDC_ERRORCODE), 5);

   // Look up the command-line passed error number
   SendMessage(hwnd, ESM_POKECODEANDLOOKUP, lParam, 0);
   return(TRUE);
}


其它的WM_COMMAND类型的消息的处理函数

void Dlg_OnCommand(HWND hwnd, int id, HWND hwndCtl, UINT codeNotify) {

   switch (id) {

   case IDCANCEL:
      EndDialog(hwnd, id);
      break;

   //on top复选框选中的消息响应
   case IDC_ALWAYSONTOP:
      SetWindowPos(hwnd, IsDlgButtonChecked(hwnd, IDC_ALWAYSONTOP) 
         ? HWND_TOPMOST : HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
      break;

   //编辑框变化以后的响应,如果为空,不启用查询按钮
   case IDC_ERRORCODE: 
      EnableWindow(GetDlgItem(hwnd, IDOK), Edit_GetTextLength(hwndCtl) > 0);
      break;

   case IDOK:
      // Get the error code
      DWORD dwError = GetDlgItemInt(hwnd, IDC_ERRORCODE, NULL, FALSE);

      HLOCAL hlocal = NULL;   // Buffer that gets the error message string

      //核心部分,申请内存以存储查询到的错误代码文本
      // Get the error code's textual description
      BOOL fOk = FormatMessage(
         FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER, 
         NULL, dwError, MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), 
         (PTSTR) &hlocal, 0, NULL);

      if (!fOk) {
         // Is it a network-related error? 如果和网络相关,查询相关的DLL是 
       // 否有相应的文本
         HMODULE hDll = LoadLibraryEx(TEXT("netmsg.dll"), NULL, 
            DONT_RESOLVE_DLL_REFERENCES);

         if (hDll != NULL) {
            FormatMessage(
               FORMAT_MESSAGE_FROM_HMODULE | FORMAT_MESSAGE_FROM_SYSTEM,
               hDll, dwError, MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US),
               (PTSTR) &hlocal, 0, NULL);
            FreeLibrary(hDll);
         }
      }

      if (hlocal != NULL) {
         SetDlgItemText(hwnd, IDC_ERRORTEXT, (PCTSTR) LocalLock(hlocal));
         LocalFree(hlocal);
      } else {
         SetDlgItemText(hwnd, IDC_ERRORTEXT, TEXT("Error number not found."));
      }
      break;
   }
}

 

// The normal HANDLE_MSG macro in WindowsX.h does not work properly for dialog
// boxes because DlgProc return a BOOL instead of an LRESULT (like
// WndProcs). This chHANDLE_DLGMSG macro corrects the problem:
#define chHANDLE_DLGMSG(hwnd, message, fn)                 \
   case (message): return (SetDlgMsgResult(hwnd, uMsg,     \
      HANDLE_##message((hwnd), (wParam), (lParam), (fn))))

这个消息处理宏相对而言比较复杂,大体意思WindowsX.h提供的HANDLE_MSG宏不会返回TRUE或者FALSE来通知对话框过程

有没有对于消息进行处理,自定义宏能够对消息的处理进行返回。适合在对话框中调用

 

转载于:https://www.cnblogs.com/rayforsure/p/3415024.html


http://www.niftyadmin.cn/n/1070336.html

相关文章

ARTS-17--图数据结构的认识

概述: 左耳朵耗子专栏《左耳听风》 用户自发每周完成一个ARTS: 1.Algorithm:每周至少做一个 leetcode 的算法题 2.Review:阅读并点评至少一篇英文技术文章 3.Tip:学习至少一个技术技巧 4.Share:分享一篇…

华为交换机以及基本配置

目录 前言 目录 一、交换机的概述 1、交换机的作用 2、交换机原理 二、交换机的配置 1、基础命令 2、查看mac地址表 总结 前言 交换机”是一个舶来词,源自英文“Switch”,原意是“开关”,我国技术界在引入这个词汇时,翻…

IsPostBack--Asp.net

.net程序员首先需要了解什么是IsPostBack.msdn上边有IsPostBack的定义:获取一个值,该值指示该页是否正为响应客户端回发而加载,或者它是否正被首次加载和访问。如果是为响应客户端回发而加载该页,则为true;否则为 fals…

教你怎么样设计一块好的PCB板精华教程

大家都知道理做PCB板就是把设计好的原理图变成一块实实在在的PCB电路板,请别小看这一过程,有很多原理上行得通的东西在工程中却难以实现,或是别人能实现的东西另一些人却实现不了,因此说做一块PCB板不难,但要做好一块PCB板却不是一件容易的事情。微电子领域的两大难点在于高频信…

ARTS-21 深夜打卡记录

Algorithm 不知不觉已经过去了二十周了,也就是140天,在过去的5个月左右的时间里面,大概刷了几十道算法题目,所以这周打算重新回顾一下以前的刷题记录。 主要的算法题目还是在围绕,数组,链表,树…

VLAN技术和配置

前言 一、VLAN技术 1、VLAN的概念 2、VLAN的作用 3、VLAN的优势 二、VLAN各项的配置 1、access 的配置 2、trunk 的配置 3、单臂路由的技术 总结 前言 一个数据帧或包被传输到本地网段(由广播域定义)上的每个节点就是广播;由于网络拓扑的设计和连接问题&a…

CListView使用示例

1 void CListViewDemoView::OnInitialUpdate()2 {3 CListView::OnInitialUpdate();4 5 CListCtrl& m_list GetListCtrl();//得到内置的listctrl引用6 LONG lStyle; 7 lStyle GetWindowLong(m_list.m_hWnd, GWL_STYLE);//获取当前窗口风格8 lStyle &a…

动态生成元素动作绑定,jquery 1.9如何实现

问: 1.7后增加了 live()1.9后被移除了 网上说可以用 on() 代替 可以实际在动态生成元素上绑定动作,没效果,求解绝方法(用低版本的jQuery这种方法,求别说。。) 答: 之前有老兄回答过类似这个问题…