MFC教程(4)-- 消息映射的实现(2)
2010-03-25 20:33:48 来源:WEB开发网一些消息处理类的OnCommand的实现
除了虚拟函数OnCmdMsg,还有一个虚拟函数OnCommand在命令消息的发送中占有重要地位。在处理命令或者通知消息时,OnCommand被MFC窗口过程调用,然后它调用OnCmdMsg按一定路径传送消息。除了CWnd类和一些OLE相关类外,MFC里主要还有MDI边框窗口实现了OnCommand。
BOOL CMDIFrameWnd::OnCommand(WPARAM wParam, LPARAM lParam)
第一,如果存在活动的文档边框窗口,则使用AfxCallWndProc调用它的窗口过程,把消息送给文档边框窗口来处理。这将导致文档边框窗口的OnCmdMsg作如下的处理:
活动视处理消息→与视关联的文档处理消息→本文档边框窗口处理消息→应用程序对象处理消息→文档边框窗口缺省处理
任何一个环节如果处理消息,则不再向下发送消息,处理终止。如果消息仍然没有被处理,就只有交给主边框窗口了。
第二,第一步没有处理命令,继续调用CFrameWnd::OnCommand,将导致CMDIFrameWnd的OnCmdMsg被调用。从前面的分析知道,将再次把消息送给MDI边框窗口的活动文档边框窗口,第一步的过程除了文档边框窗口缺省处理外都将被重复。具体的处理过程见前文的CMDIFrameWnd::OnCmdMsg函数。
对于MDI消息,如果主边框窗口还不处理的话,交给CMDIFrameWnd的DefWindowProc作缺省处理。
消息没有处理,返回FALSE。
上述分析综合了OnCommand和OnCmdMsg的处理,它们是在MFC内部MDI边框窗口处理命令消息的完整的流程和标准的步骤。整个处理过程再次表明了边框窗口在处理命令消息时的中心作用。从程序员的角度来看,可以认为整个标准处理路径如下:
活动视处理消息→与视关联的文档处理消息→本文档边框窗口处理消息→应用程序对象处理消息→文档边框窗口缺省处理→MDI边框窗口处理消息→MDI边框窗口缺省处理
任何一个环节如果处理消息,不再向下发送消息,急处理终止。
对控制通知消息的接收和处理
WM_COMMAND控制通知消息的处理
WM_COMMAND控制通知消息的处理和WM_COMMAND命令消息的处理类似,但是也有不同之处。
首先,分析处理WM_COMMAND控制通知消息和命令消息的相似处。如前所述,命令消息和控制通知消息都是由窗口过程给OnCommand处理(参见CWnd::OnWndMsg的实现),OnCommand通过wParam和lParam参数区分是命令消息或通知消息,然后送给OnCmdMsg处理(参见CWnd::OnCommnd的实现)。
其次,两者的不同之处是:
命令消息一般是送给主边框窗口的,这时,边框窗口的OnCmdMsg被调用;而控制通知消息送给控制子窗口的父窗口,这时,父窗口的OnCmdMsg被调用。
OnCmdMsg处理命令消息时,通过命令分发可以由多种命令目标处理,包括非窗口对象如文档对象等;而处理控制通知消息时,不会有消息分发的过程,控制通知消息最终肯定是由窗口对象处理的。
不过,在某种程度上可以说,控制通知消息由窗口对象处理是一种习惯和约定。当使用ClassWizard进行消息映射时,它不提供把控制通知消息映射到非窗口对象的机会。但是,手工地添加消息映射,让非窗口对象处理控制通知消息的可能是存在的。例如,对于CFormView,一方面它具备接受WM_COMMAND通知消息的条件,另一方面,具备把WM_COMMAND消息派发给关联文档对象处理的能力,所以给CFormView的通知消息是可以让文档对象处理的。
事实上,BN_CLICKED控制通知消息的处理和命令消息的处理完全一样,因为该消息的通知代码是0,ON_BN_CLICKED(id,memberfunction)和ON_COMMAND(id,memberfunction)是等同的。
此外,MFC的状态更新处理机制就是建立在通知消息可以发送给各种命令目标的基础之上的。关于MFC的状态更新处理机制,见后面4.4.4.4节的讨论。
控制通知消息可以反射给子窗口处理。OnCommand判定当前消息是WM_COMAND通知消息之后,首先它把消息反射给控制子窗口处理,如果子窗口处理了反射消息,OnCommand不会继续调用OnCmdMsg让父窗口对象来处理通知消息。
WM_NOTIFY消息及其处理:
更多精彩
赞助商链接