命令和通知实际都是一种特殊的消息类型。在SDK编程中,菜单和控件的动作均会产生一个
WM_COMMAND命令消息,通过对消息参数
wParam的区分可以识别出具体是哪个控件或菜单发出的命令。在MFC应用程序框架下,菜单和控件产生的消息将有所区分,
选取菜单产生的消息被称作命令,而
点击控件所产生的消息则被称作
通知。 由于命令和通知的本质仍是一种消息,因此在基本原理上仍是同消息一致的,即也是通过消息循环进入OnWndMsg()进而为对应的处理函数所响应。但是在 使用上,命令和消息还是有区别的,其中一个最主要的区别是消息只有CWnd类的派生类所接收,而命令和通知则可以为所有从CCmdTarget派生出去的 类对象所接收,从MFC类的继承关系可以看出,除CWnd外CWinThread、CDocument和CDocItem等也都可以接收命令和通知。除此 之外,命令和通知在从消息循环进入到OnWndMsg()后的这段过程也是同消息传递略有出入的,图2(a)和(b)分别给出了命令和通知的传递流程:
图2 命令/通知传递流程 这里CWnd::OnCommand()在检查完各项细节后、CWnd::OnNotify()在检查完不同条件后都调用了虚函数 OnCmdMsg()。这样,对于不同的菜单项和控件就可以有不同的实现。从下面给出的命令传递过程示例代码可以看出命令/通知的传递与消息的映射是非常 类似的:
// 头文件 //{{AFX_MSG(CDIP_SystemView) afx_msg void OnEmboss(); afx_msg void OnUpdateEmboss(CCmdUI* pCmdUI); //}}AFX_MSG DECLARE_MESSAGE_MAP() …… // 源文件 BEGIN_MESSAGE_MAP(CDIP_SystemView, CScrollView) /{{AFX_MSG_MAP(CDIP_SystemView) ON_COMMAND(IDM_EMBOSS, OnEmboss) ON_UPDATE_COMMAND_UI(IDM_EMBOSS, OnUpdateEmboss) //}}AFX_MSG_MAP END_MESSAGE_MAP() …… void CDIP_SystemView::OnEmboss () { return; } …… void CDIP_SystemView::OnUpdateStartPos(CCmdUI* pCmdUI) { pCmdUI->Enable(m_bCanUse); } |
这里ON_COMMAND宏将特定命令的处理同一个类成员函数建立了关联。而宏ON_UPDATE_COMMAND_UI则负责对命令的更 新,即通过CCmdUI对象控制菜单/控件的是否可用或其他一些状态变化的更新。对命令的更新也可以将其理解为存在一个含有每个菜单入口的大表,各菜单入 口含有菜单是否可用的标志。在显示菜单时通过快速检查该表而做出其所对应的每一个菜单项是否可用的决定。如果可用标志发生了变化,该表也将得到及时的更新