初识MFC:ON_COMMAND_UI与ON_UPDATE_COMMAND_UI过程的区别

  software:VS2012.

  当我们给菜单子项添加事件处理时,发现有两个消息类型可选:COMMAND和UPDATE_COMMAND_UI,那这两个消息有什么区别呢?

  分别用这两种方式添加事件处理,我们可以看到在消息映射表中添加的宏分别是:ON_COMMAND和ON_UPDATE_COMMAND_UI。

  其中ON_COMMAND,我们比较熟悉,是对命令消息(来自菜单、工具条、状态栏、加速键等)的操作函数映射的宏(Remark:It indicates which function will handle a command message from a command user-interface object such as a menu item or toolbar button.)。

  而ON_UPDATE_COMMAND_UI,顾名思义,就是映射更新用户界面(菜单状态)的函数的宏(There should be exactly one ON_UPDATE_COMMAND_UI macro statement in your message map for every user-interface update command that must be mapped to a message-handler function.)。

  但一个较大的区别就是,ON_COMMAND是在每次选择时就已经确定了菜单的状态,ON_UPDATE_COMMAND_UI是当用户在应用的下拉菜单时,确定每个菜单项的显示状态。而且ON_COMMAND映射的函数是无参的,ON_UPDATE_COMMAND_UI是带一个(CCmdUI *)类型的参数。(封宏如下:)

 1 //---ON_COMMAND---
 2 #define ON_COMMAND(id, memberFxn) \
 3     { WM_COMMAND, CN_COMMAND, (WORD)id, (WORD)id, AfxSigCmd_v, \
 4         static_cast<AFX_PMSG> (memberFxn) },
 5 
 6 /*----------------------------------------------*/
 7 
 8 //---ON_UPDATE_COMMAND_UI---
 9 #define ON_UPDATE_COMMAND_UI(id, memberFxn) \
10     { WM_COMMAND, CN_UPDATE_COMMAND_UI, (WORD)id, (WORD)id, AfxSigCmdUI, \
11         (AFX_PMSG) \
12         (static_cast< void (AFX_MSG_CALL CCmdTarget::*)(CCmdUI*) > \
13         (memberFxn)) },

 

  其中,CCmdUI没有基类。它仅在一个CCmdTarget派生类的ON_UPDATE_COMMAND_UI处理程序中使用。

举一个在ON_UPDATE_COMMAND_UI实现的例子:

 1 void CViewMsgView::OnUpdateMenuUI( CCmdUI * pCmdUI )
 2 {
 3     CMainFrame * pFrame = ( CMainFrame * )AfxGetMainWnd();
 4     if ( pCmdUI->m_nID == pFrame->m_nMenuItemIndex )
 5     {
 6         pCmdUI->Enable(FALSE);
 7         pCmdUI->SetCheck();
 8     }
 9     else
10     {
11         pCmdUI->SetCheck(0);
12     }
13 }

 

  借鉴了一下其他博友对此种设计的解释:(http://www.cnblogs.com/orez88/articles/2217823.html)

  传统SDK程序要改变选单命令项状态,可以呼叫EnableMenuItem或是 CheckMenuItem,但这使得程序杂乱无章,因为你没有一个固定的位置和固定的原则处理命令项状态。MFC提供一种直接并且仍旧依赖讯息观念的方式,解决这个问题,这就是UPDATE_COMMAND_UI讯息。

  其设计理念是,每当选单被拉并尚未显示之前,其命令项(以及对应之工具栏按钮)都会收到UPDATE_COMMAND_UI讯息,这个讯息和WM_COMMAND有㆒样的绕行路线,我们(程序员)只要在适当的类别上放置其处理函式,并在函式上做某些判断,便可决定如何显示命令项。

   这种方法的最大好处是,不但把问题的解决方式统化,更因为 Framework传给UPDATE_COMMAND_UI处理程序的参数是个「指向CCmdUI对象的指针」,而CCmdUI对象就代表着对应的选单命令项,因此你只需呼叫 CCmdUI 所准备的,专门用来处理命令项外观的函式(如Enable或SetCheck)即可。我们的工作量大为减轻。  

 

 

 

 

 

 

 

 

 

 

  总之,UPDATE_COMMAND_UI方便了对菜单命令项状态的处理。

posted @ 2015-04-30 15:34  netosoul  阅读(913)  评论(0)    收藏  举报