MFC命令消息(WM_COMMAND)的传接路径
MFC命令消息(WM_COMMAND)的传送路径
框架窗口实际上是大多数命令消息(“命令消息”是MFC的术语,专指WM_COMMAND)的接收者,但命令消息可以在视图类、文档类、甚至应用程序类中被处理,只要在该类的消息映射表中对想要处理的消息添加输入项即可。命令传送使得你可以将命令处理程序放在最合适的地方,避免把它们都堆在框架窗口类。对于菜单项、工具栏按钮以及其他用户界面对象的更新命令也遵循命令传送机制,因此也可以把ON_UPDATE_COMMAND_UI处理程序放在非框架窗口中。
使命令传送工作的机制根植于MFC深层内部。当框架窗口接收到WM_COMMNAD消息时,会调用所有CCmdTarget派生类特有的虚拟OnCmdMsg函数来开始传送过程。CFrameWnd中OnCmdMsg的实现如下:
BOOL CFrameWnd::OnCmdMsg(UINT nID, int nCode) { // pump through current view FIRST CView* pView = GetActiveView(); if (pView->OnCmdMsg(nID, nCode)) return TRUE; // then pump through frame if (CWnd::OnCmdMsg(nID, nCode)) return TRUE; // last but not least, pump through app CWinApp* pApp = AfxGetApp(); if (pApp->OnCmdMsg(nID, nCode)) return TRUE; return FALSE; }
命令消息传送路线如下图:
活动视图首先处理消息,接着是与视图关联的文档、文档模板、框架窗口,最后是应用程序对象。如果路径上的某个对象可以处理消息,那么消息传送就会停止,如果没有对象的消息映射表中包含此消息的输入项,它就会被一路传送给::DefWindowProc。
至于各种命令消息应该由谁来处理,习惯上,
- File菜单中的New、Open和Exit命令由应用程序对象处理,其中CWinApp为它们提供了OnFileNew、OnFileOpen和OnAppExit命令处理程序。
- File菜单中的Save和Save As命令通常由文档对象处理,它提供了名为CDocument::OnFileSave和CDocument::OnFileSaveAs的默认命令处理程序。
- 显示和隐藏工具栏和状态栏的命令由框架窗口使用CFrameWnd成员函数来处理,其他大多数命令则由文档或视图处理。
考虑在哪里旋转消息处理程序时,要记住重要的一点,只有命令消息和用户界面更新才遵循传送机制。标准Windows消息如WM_CHAR、WM_LBUTTONDOWN、WM_CREATE以及WM_SIZE必须在接收这些消息的窗口中处理。鼠标和键盘消息通常传给视图,大多数其他消息则传给框架窗口。文档对象和应用程序对象从不接收非命令消息。