对与这一部分如果有不理解,请先学习设计模式中的观察者模式与命令模式(手动微笑)
对于一个Windows程序,在进行完基本的初始化工作之后,则就将开始进行最最重要也是难以理解的部分:消息循环与消息映射
最简单的消息循环不过如下:
while (GetMessage(&msg, ...)) {
TranslateMessage(&msg); //转换键盘消息
DispatchMessage(&msg); //分发消息
}首先,第一步TranslateMessage(&msg)则是为了将键盘消息转化,而第2句DispatchMessage(&msg)则会将消息分发给窗口函数去处理,消息产生之时操作系统会根据当初状态,为其
标明所属窗口,而窗口所属的窗口类一开始产生指出就已经明白地标识了窗口函数,所以消息就这样被分发到了指定的窗口之中,对于这一部分其实如果有写过MVC或者
其它相关的观察者模式的例子应该会很好理解这一部分。
这里顺便值得一提的是MFC中的窗口函数,对于MFC的窗口函数,其函数的形式总是保持如下形式:
LRESULR CALLBACK WndProc(HWND hWnd,
UINT message,
WPARAM wParam,
LPARAM lParam)无论什么消息,被发送给窗口函数之后都将会被处理,而处理的方法就是最简单的 switch/case 组合中的default: 处必须调用DefWindowProc ,这个是Windows内部默认的消息处理函数。
最后为了将消息的具体行为与窗口方法的逻辑分离开来,使用了一点命令模式:分离了具体行为与个体之间的耦合,这里的说法可能有一点不准确
实现方式如下:
struct MSGMAP_ENTRY {
UINT nMessahe;
LONG(*pfn)(HWND , UINT,WPARAM,LPARAM); //窗口函数的指针
};以此结构体便可以设计如下的消息列表和命令列表
<pre name="code" class="cpp">struct MSGMAP_ENTRY _messageEntries[] =
{
WM_CREATE ,OnCreate ,
WM_PAINT , OnPaint ,
WM_SIZE , OnSize ,
WM_COMMAND , OnCommand ,
WM_SETFOCUS , OnSetFocus ,
WM_CLOSE , OnClose ,
WM_DESTROY , OnDestroy ,
}struct MSGMAP_ENTRY _commandEntries[] =
{
IDM_ABOUT , OnAbort ,
IDM_FILEOPEN , OnFileOpen ,
IDM_SAVEAS , OnSaveAs ,
}这样一来窗口函数和命令处理函数将永远都不在需要改变,每当有新的消息,只需要在_messageEntries[] 和 _commandEntries[] 俩个数组加上新元素,并单独攥写新消息的处
理例程即可,这是一次几乎完美的解耦合
这也是MFC的Message Map 的雏形,实际的将会更加复杂。如果大家看完还有迷惑的话,就请重新读一遍本文的第一句话(手动微笑)
本文深入探讨MFC中的消息机制,从消息循环到消息映射,结合设计模式如观察者模式和命令模式进行解释。讲解了MFC窗口函数的一般形式,并介绍了如何通过命令模式降低窗口方法与具体行为的耦合。
6494

被折叠的 条评论
为什么被折叠?



