在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表明已经处理