window核心编程笔记 No.1
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来通知对话框过程
有没有对于消息进行处理,自定义宏能够对消息的处理进行返回。适合在对话框中调用