MFC教程(4)-- 消息映射的实现(2)
2010-03-25 20:33:48 来源:WEB开发网(2)CWnd的OnCommand函数
BOOL CWnd::OnCommand(WPARAM wParam, LPARAM lParam)
它按一定的顺序处理命令或者通知消息,如果发送成功,返回TRUE,否则,FALSE。处理顺序如下:
如果是命令消息,则调用OnCmdMsg(nID, CN_UPDATE_COMMAND_UI, &state, NULL)测试nID命令是否已经被禁止,如果这样,返回FALSE;否则,调用OnCmdMsg进行命令发送。关于CN_UPDATE_COMMAND_UI通知消息,见后面用户界面状态的更新处理。
如果是控制通知消息,则先用ReflectLastMsg反射通知消息到子窗口。如果子窗口处理了该消息,则返回TRUE;否则,调用OnCmdMsg进行命令发送。关于通知消息的反射见后面4.4.4.3节。OnCommand给OnCmdMsg传递四个参数:nID,即命令消息ID;nCode,如果是通知消息则为通知代码,如果是命令消息则为NC_COMMAND(即0);其余两个参数为空。
(3)CFrameWnd的OnCmdMsg函数
BOOL CFrameWnd::OnCmdMsg(UINT nID, int nCode, void* pExtra,
AFX_CMDHANDLERINFO* pHandlerInfo)
参数1是命令ID;如果是通知消息(WM_COMMAND或者WM_NOTIFY),则参数2表示通知代码,如果是命令消息,参数2是0;如果是WM_NOTIFY,参数3包含了一些额外的信息;参数4在正常消息处理中应该是空。
在这个例子里,参数1是命令ID,参数2为0,参数3空。
OnCmdMsg是虚拟函数,CFrameWnd覆盖了该函数,当前对象(this所指)是MFC单文档的边框窗口对象。故CFrameWnd的OnCmdMsg被调用。CFrameWnd::OnCmdMsg在MFC消息发送中占有非常重要的地位,MFC对该函数的缺省实现确定了MFC的标准命令发送路径:
送给活动(Active)视处理,调用活动视的OnCmdMsg。由于当前对象是MFC视对象,所以,OnCmdMsg将搜索CTview及其基类的消息映射数组,试图得到相应的处理函数。
如果视对象自己不处理,则视得到和它关联的文档,调用关联文档的OnCmdMsg。由于当前对象是MFC视对象,所以,OnCmdMsg将搜索CTdoc及其基类的消息映射数组,试图得到相应的处理函数。
如果文档对象不处理,则它得到管理文档的文档模板对象,调用文档模板的OnCmdMsg。由于当前对象是MFC文档模板对象,所以,OnCmdMsg将搜索文档模板类及其基类的消息映射数组,试图得到相应的处理函数。
如果文档模板不处理,则把没有处理的信息逐级返回:文档模板告诉文档对象,文档对象告诉视对象,视对象告诉边框窗口对象。最后,边框窗口得知,视、文档、文档模板都没有处理消息。
CFrameWnd的OnCmdMsg继续调用CWnd::OnCmdMsg(斜体表示有类属限制)来处理消息。由于CWnd没有覆盖OnCmdMsg,故实际上调用了函数CCmdTarget::OnCmdMsg。由于当前对象是MFC边框窗口对象,所以OnCmdMsg函数将搜索CMainFrame类及其所有基类的消息映射数组,试图得到相应的处理函数。CWnd没有实现OnCmdMsg却指定要执行其OnCmdMsg函数,可能是为了以后MFC给CWnd实现了OnCmdMsg之后其他代码不用改变。
这一步是边框窗口自己尝试处理消息。
如果边框窗口对象不处理,则送给应用程序对象处理。调用CTApp的OnCmdMsg,由于实际上CTApp及其基类CWinApp没有覆盖OnCmdMsg,故实际上调用了函数CCmdTarget::OnCmdMsg。由于当前对象是MFC应用程序对象,所以OnCmdMsg函数将搜索CTApp类及其所有基类的的消息映射入口数组,试图得到相应的处理函数
如果应用程序对象不处理,则返回FALSE,表明没有命令目标处理当前的命令消息。这样,函数逐级别返回,OnCmdMsg告诉OnCommand消息没有被处理,OnCommand告诉OnWndMsg消息没有被处理,OnWndMsg告诉WindowProc消息没有被处理,于是WindowProc调用DefWindowProc进行缺省处理。
本例子在第六步中,应用程序对ID_APP_ABOUT消息作了处理。它找到处理函数CTApp::OnAbout,使用DispatchCmdMsg派发消息给该函数处理。
如果是MDI边框窗口,标准发送路径还有一个环节,该环节和第二、三、四步所涉及的OnCmdMsg函数,将在下两节再次具体分析。
命令消息的派发和消息的多次处理
更多精彩
赞助商链接