消息分流器

通常的窗口过程是通过一个switch语句来实现的,这个事情很烦,有没有更简便的方法呢?有,那就是消息分流器,利用消息分流器,我们可以把switch语句分成更小的函数,每一个消息都对应一个小函数,这样做的好处就是对消息更容易管理。

之所以被称为消息分流器,就是因为它可以对任何消息进行分流。下面我们做一个函数就很清楚了:

[cpp]  view plain copy
  1. void MsgCracker(HWND hWnd,int id,HWND hWndCtl,UINT codeNotify)  
  2. {  
  3.       switch(id)  
  4.       {  
  5.      case ID_A:  
  6.                   if(codeNotify==EN_CHANGE)...  
  7.                   break;  
  8.      case ID_B:  
  9.                   if(codeNotify==BN_CLICKED)...  
  10.                   break;  
  11.              ....  
  12.        }  
  13. }  

[cpp]  view plain copy
  1. LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)  
  2. {  
  3.        switch(message)  
  4.       {  
  5.              HANDLE_MSG(hWnd,WM_COMMAND,MsgCracker);  
  6.              HANDLE_MSG(hWnd,WM_DESTROY,MsgCracker);  
  7.            default:  
  8.                     return DefWindowProc(hWnd, message, wParam, lParam);  
  9.    }  
  10.   return 0;  
  11. }  

在WindowsX.h中定义了如下的HANDLE_MSG宏:

#define HANDLE_MSG(hwnd,msg,fn) \

switch(msg): return HANDLE_##msg((hwnd),(wParam),(lParam),(fn));

实际上,HANDLE_WM_XXXX都是宏,例如:HANDLE_MSG(hWnd,WM_COMMAND,MsgCracker);

将被转换成如下定义:

#define HANDLE_WM_COMMAND(hwnd,wParam,lParam,fn)\ 

((fn)((hwnd),(int)(LOWORD(wParam)),(HWND)(lParam),(UINT)HIWORD(wParam)),0L);

好了,事情到了这一步,应该一切都明朗了。

不过,我们发现在windowsx.h里面还有一个宏:FORWARD_WM_XXXX,我们还是那WM_COMMAND为例,进行分析:

#define FORWARD_WM_COMMAND(hwnd, id, hwndCtl, codeNotify, fn) \

(void)(fn)((hwnd), WM_COMMAND, MAKEWPARAM((UINT)(id),(UINT)(codeNotify)), (LPARAM)(HWND)(hwndCtl))

所以实际上,FORWARD_WM_XXXX将消息参数进行了重新构造,生成了wParam && lParam,然后调用了我们定义的函数。


在《Windows核心编程》一书中,大牛Jeffrey自己定义了一个宏,使SetDlgMsgResult宏的使用更加方便:
#define chHANDLE_DLGMSG(hwnd, message, fn)
case (message): return (SetDlgMsgResult(hwnd, uMsg,
HANDLE_##message((hwnd), (wParam), (lParam), (fn))))
可见这个宏只是简单的对SetDlgMsgRseult宏进行了封装。
这样,我们最终的代码可以写成:
[cpp]  view plain copy
  1. LRESULT CALLBACK Dlg_Proc (HWND hwnd, UINT msg,WPARAM wParam, LPARAM lParam)  
  2. {  
  3. switch(msg)  
  4. {  
  5. chHANDLE_DLGMSG(hwnd, WM_INITDIALOG, Cls_OnInitDialog); // 使用大牛的chHANDLE_DLGMSG宏  
  6. chHANDLE_DLGMSG(hwnd, WM_COMMAND, Cls_OnCommand);  
  7. }  
  8. return false;  
  9. }  


下面把原来程序整个框架列出来:
[cpp]  view plain copy
  1. LRESULT CALLBACK Dlg_Proc(HWND hwnd, UNIT umsg, WPARAM wparam, LPARAM lparam)  
  2. {  
  3. switch(msg)  
  4. {  
  5. case WM_COMMAND: // 每个case都被一个message cracker代替,这里使用大牛同志的  
  6. // do something; // chHANDLE_DLGMSG宏;这个宏负责对消息筛选,处理并返回相应的值  
  7. return true;  
  8. case WM_INITDIALOG:  
  9. // do something;  
  10. return xxxx;  
  11. }  
  12. return false// 如果消息不在我们的DlgProc过程中被处理,则告诉调用这个DlgProc的消息,  
  13. //告诉系统的对话框管理器,这个消息我们不处理,交给你了  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值