在Jeffrey的Error Show程序作者自定義了一段宏
#define chHANDLE_DLGMSG(hWnd, message, fn) \
case (message): return (SetDlgMsgResult(hWnd, uMsg, \
HANDLE_##message((hWnd), (wParam), (lParam), (fn))))
HANDLE_##message((hWnd), (wParam), (lParam), (fn))是借用了windows.h里面的
#define HANDLE_MSG(hwnd, message, fn)
case (message): return HANDLE_##message((hwnd), (wParam), (lParam), (fn))
如果message是WM_CREAT的話,這個應該是
HANDLE_WM_CREATE((hwnd), (wParam), (lParam), (Cls_OnCreate))
#define HANDLE_WM_CREATE(hwnd, wParam, lParam, fn) \
((fn)((hwnd), (LPCREATESTRUCT)(lParam)) ? 0L : (LRESULT)-1L)
那么宏展開為:return Cls_OnCreate(hwnd, (LPCREATESTRUCT)(lParam) )? 0L : (LRESULT)-1L;
但是在對話框消息處理中,對話框過程函數應該在處理了消息的情況下返回TRUE,如果沒有處理,則返回FALSE。如果對話框過程返回了FALSE,那么對話框管理器為這條消息準備默認的對話操作。如果對話框處理了一個需要特定返回值的消息,則對話框的返回值應該被設置為調用SetWindowLong后的返回值,這些特殊消息有:
? WM_CHARTOITEM
? WM_COMPAREITEM
? WM_CTLCOLORBTN
? WM_CTLCOLORDLG
? WM_CTLCOLOREDIT
? WM_CTLCOLORLISTBOX
? WM_CTLCOLORSCROLLBAR
? WM_CTLCOLORSTATIC
? WM_INITDIALOG
? WM_QUERYDRAGICON
? WM_VKEYTOITEM
所以在處理WM_INITDIALOG 時,我們不能單純的調用消息分流器.
而在處理WM_COMMAND中,從windowsx.h可以看到:
/* void Cls_OnCommand(HWND hwnd, int id, HWND hwndCtl, UINT codeNotify) */
#define HANDLE_WM_COMMAND(hwnd, wParam, lParam, fn) \
((fn)((hwnd), (int)(LOWORD(wParam)), (HWND)(lParam), (UINT)HIWORD(wParam)), 0L)
void Cls_OnCommand(HWND hwnd, int id, HWND hwndCtl, UINT codeNotify)
Cls_OnCommand由于是個void型的函數,是沒有返回值的,因此windows默認這種消息處理過程必須返回一個0值,而返回0值不就表示我們的消息過程不處理這個消息,這是矛盾的,如果直接使用HANDLE_WM_COMMAND(hwnd, wParam, lParam, Dlg_OnCommand) ;按鈕會沒有反應,關閉也不行/所以可以使用使用下面的宏解決
#define SetDlgMsgResult(hwnd, msg, result) (( \
(msg) == WM_CTLCOLORMSGBOX || \
(msg) == WM_CTLCOLOREDIT || \
(msg) == WM_CTLCOLORLISTBOX || \
(msg) == WM_CTLCOLORBTN || \
(msg) == WM_CTLCOLORDLG || \
(msg) == WM_CTLCOLORSCROLLBAR || \
(msg) == WM_CTLCOLORSTATIC || \
(msg) == WM_COMPAREITEM || \
(msg) == WM_VKEYTOITEM || \
(msg) == WM_CHARTOITEM || \
(msg) == WM_QUERYDRAGICON || \
(msg) == WM_INITDIALOG \
) ? (BOOL)(result) : (SetWindowLong((hwnd), DWL_MSGRESULT, (LPARAM)(LRESULT)(result)), TRUE))
#define chHANDLE_DLGMSG(hWnd, message, fn) \
case (message): return (SetDlgMsgResult(hWnd, uMsg, \
HANDLE_##message((hWnd), (wParam), (lParam), (fn))))
從這兩個宏可以得到,如果是特殊消息的話那么返回默認0,并設置說明消息處理,如果WM_COMMAND的話,那么返回SetWindowLong((hwnd), DWL_MSGRESULT, (LPARAM)(LRESULT)(result)), TRUE),一般為TRUE表明已經處理