class="p0" style="margin-top: 0pt; margin-bottom: 0pt;">MFC消息发送和处理的本质也如Windows消息。但是,所有MFC窗口都使用同一窗口过程,程序员不必去设计和实现自己的窗口过程,而是通过MFC提供的一套消息映射机制来处理消息。
?
Tips:MFC在创建窗口之前,创建了一个WH_CBT类型的钩子。这样,创建窗口时所有的消息都会被钩子过程函数_AfxCbtFilterHook捕获。若是希望的HOOK,则先把MFC窗口对象和刚刚创建的Windows窗口对象捆绑在一起,建立他们的映射。这样AfxWndProc就成为CWnd或其派生类的窗口过程。不论是队列消息,还是非队列消息,都送到AfxWndProc窗口过程来处理。
?
消息映射
所谓消息映射,就是让程序员指定某个MFC类处理某个消息。下面会进行一番详述。
消息映射的声明
其实质是给所在的类添加几个静态成员变量和静态或虚拟函数,当然它们是与消息映射相关的变量和函数。
成员变量:_messageEntries和messageMap
_messageEntries[]是一个AFX_MSGMAP_ENTRY类型的数组变量,用来容纳类的消息映射条目。
其中每条映射包括两部分,消息ID和消息对应的执行函数。
messageMaps?是一个AFX_MSGMAP类型的静态成员变量,它是一个包含了消息映射信息的变量。通过messageMap可以得到类的消息映射数组_messageEntries和函数_GetBaseMessageMap(用来得到基类消息映射的函数)的地址。
消息映射的实现
其实质是初始化声明中定义的静态成员函数_messageEntries和messageMap。实现所所声明的静态或虚拟函数GetMessageMap、_GetBaseMessageMap。这样,在进入WinMain函数之前,每个可以响应消息的MFC类都生成了一个消息映射表,程序运行时通过查询表判断是否需要相应某条消息。
下面以一张图为例:
MFC主要处理三类消息:
1.Windows消息,前缀以”WM_”打头,WM_COMMAND例外,Windows消息直接送给
对应MFC窗口过程处理,窗口过程调用对应的消息处理函数。
Windows消息送给AfxWndProc窗口过程之后,AfxWndProc得到HWND窗口对应的MFC窗口对象。然后,搜索该MFC窗口对象和其基类的消息映射数组。判定它们是否处理当前消息。如果是,则调用对应的消息处理函数,否则,进行缺省处理。
2.控制通知消息,是控制子窗口送给父窗口的WM_COMMAND通知消息。
命令消息和控制消息都是有窗口过程给OnCommand处理。OnCommand通过wParam和lParam参数区分是命令消息或通知消息,然后送给OnCmdMsg处理。WM_NOTIFY消息是WIN32中用来传递信息复杂的通知消息。在分析CWnd::OnWndMsg函数时,当消息是WM_NOTIFY,它把消息传递给OnNotify虚拟函数处理。
3.命令消息,这是来自菜单、工具条按钮、工具条等用户接口对象的消息,属于应用程序自己定义的消息。MFC框架把命令按一定的路径分发给多种类型的对象处理,如文档、窗口、应用程序等对象。能处理消息映射的类必须从CCmdTarget类派生。
在SDI或MDI应用程序中,命令消息由用户界面对象产生,主边框窗口使用标准MFC窗口过程处理命令消息并传递给MFC主边框窗口对象开始命令消息的分发。MFC边框窗口类CFrameWnd提供了消息分发的能力。