下面我以 WM_COMMAND为例分析消息的分流
1. 我们知道,每个消息都有 wParam 和 lParam,如WM_COMMAND,wParam包含两个不同的值,其中:
wParam:低字节是控件的id,高字节是通知码 notifyCode
lParam: 强制转换为按钮或控件的句柄值 hWndCtl
2. HAND_MSG宏定义,第五版是chHANDLE_DLGMSG (windowsx.h)
// The normal HANDLE_MSG macro in WindowsX.h does not work properly for dialog
// boxes because DlgProc returns 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))))
#define HANDLE_MSG(hwnd,message,fn) \
case (message): \
Return HANDLE_##message((hwnd),(wParam),(lParam),(fn))
3. 如遇到 WM_COMMAND,则语句扩展成
case (WM_COMMAND):
return (SetDlgMsgResult(hWnd, uMsg, \
HANDLE_WM_COMMAND((hWnd), (wParam), (lParam), (Dlg_OnCommand))
4. 这里,你可以看一下HAND_WM_COMMAND宏的扩展 (windowsx.h)
#define HANDLE_WM_COMMAND(hwnd,wParam,lParam,fn) \
((fn) ((hwnd),(int)(LOWORD(wParam)),(HWND)(lParam),
(UINT)HIWORD(wParam)),0L)
5. 应用窗口的回调函数定义
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);
}
return(FALSE);
}
6. 应用窗口的回调函数实现
void Dlg_OnCommand(HWND hWnd, int id, HWND hWndCtl, UINT codeNotify)
{
switch (id)
{
case IDCANCEL:
EndDialog(hWnd, id);
break;
case IDC_BTN_STOP:
{
// StopProcessing can't be called from the UI thread
// or a deadlock will occur: SendMessage() is used
// to fill up the listboxes
// --> Another thread is required
DWORD dwThreadID;
CloseHandle(chBEGINTHREADEX(NULL, 0, StoppingThread, NULL, 0, &dwThreadID));
// This button can't be pushed twice,这个控件的句柄
Button_Enable(hWndCtl, FALSE);
}
break;
}
}