首页 > 代码库 > 菜单基本操作(二)

菜单基本操作(二)

本文仅用于学习交流,商业用途请支持正版!转载请注明:http://www.cnblogs.com/mxbs/p/6285902.html 

  利用MFC编程时,菜单项状态的维护依赖于CN_UPDATE_COMMAND_UI消息,我们可以手工或利用ClassWizard在消息映射中添加ON_UPDATE_COMMAND_UI宏来捕获CN_UPDATE_COMMAND_UI消息。

  如图示,接下来,我们使Edit子菜单下的Cut菜单项变为可用状态。

技术分享

  打开类向导对话框,在框架类中添加如下函数,选择对象ID为ID_EDIT_CUT,Message列表框中选择UPDATE_COMMAND_UI消息,单击Add Handler添加消息响应函数,Edit Code。

技术分享

技术分享

  这样,在框架类文件中添加了如下信息,

    头文件中信息:

           afx_msg void OnUpdateEditCut(CCmdUI *pCmdUI);

    源文件信息一:

      BEGIN_MESSAGE_MAP(CMainFrame, CFrameWndEx)

             …

             ON_UPDATE_COMMAND_UI(ID_EDIT_CUT, &CMainFrame::OnUpdateEditCut)

      END_MESSAGE_MAP()

    源文件信息二:

      void CMainFrame::OnUpdateEditCut(CCmdUI *pCmdUI)

      {

             // TODO: Add your command update UI handler code here

      }

      备注:UI即用户接口(User Interface)UPDATE_COMMAND_UI消息只能应用于菜单项,不能应用于永久显示的顶级菜单(即弹出式菜单)项目。

  利用CCmdUI类的Enable函数实现菜单项的可用或禁用功能,代码如下:

      void CMainFrame::OnUpdateEditCut(CCmdUI *pCmdUI)

      {

             // TODO: Add your command update UI handler code here

             pCmdUI ->Enable();//默认为可用

            // pCmdUI ->Enable(false);//false为不可用

      }

  运行可以看到工具栏和菜单项中的剪切功能都可用了。那么二者是如何关联的呢?通过分别查看Resource View下的Menu和Toolbar可以知道,菜单栏和工具栏下的剪切功能ID都是ID_EDIT_CUT,由此可知,如果要把工具栏上的一个工具按钮和菜单栏中的某个菜单项相关联,只要将它们的ID设为一致即可                       

技术分享          技术分享

  以禁用【文件】子菜单下的【新建】菜单项为例:

    利用菜单项标识访问菜单项进行状态设置:

    添加UPDATE_COMMAND_UI消息响应函数,具体代码如下:

      void CMainFrame::OnUpdateFileNew(CCmdUI *pCmdUI)

      {

             // TODO: Add your command update UI handler code here

             pCmdUI ->Enable(false);

      }

  运行可发现【新建】菜单项已经被禁用。

  CCmdUI类有一个成员变量m_nID用于保存当前菜单项、工具栏按钮、或者是其他由CCmdUI对象表示的UI对象的标识。我们可以利用其进行判断是哪一个菜单项,当然实际应用时无需判断。

      void CMainFrame::OnUpdateFileNew(CCmdUI *pCmdUI)

      {

             // TODO: Add your command update UI handler code here

             if(ID_FILE_NEW == pCmdUI ->m_nID)

                  pCmdUI ->Enable(false);

      }

  CCmdUI类还有一个成员变量m_nIndex用于保存当前菜单项的位置索引。

      if(2 == pCmdUI -> m_nIndex) //利用位置索引进行判断

    注意:计算菜单项索引时必须把分隔栏菜单项计算在内。

  在【剪切】菜单项的UI命令中利用位置索引进行判断时,会发现工具栏上的按钮状态并没有改变,这是因为菜单项和工具栏按钮的位置索引计算方式不同,它们都是从0计数,但可能位置索引不是一一对应的,因此为了保证二者状态的一致性,最好采用菜单项标识工具栏按钮标识(二者一致)的方式来进行设置

MFC采用的命令更新机制:

  我们可以用类向导添加UPDATE_COMMAND_UI消息响应函数,而MFC在后台所做的工作是:当要显示菜单时,操作系统发出WM_INITMENUPOPUP消息,然后由程序窗口的基类如CFrameWnd接管。它会创建一个CCmdUI对象,并与程序的第一个菜单项相关联,调用该对象的一个成员函数DoUpdate(),这个函数发出CN_UPDATE_COMMAND_UI消息,这个消息带有一个指向CCmdUI对象的指针。这时系统会判断是否存在一个ON_UPDATE_COMMAND_UI宏去捕获这个菜单项消息。如果有则调用相应的消息响应函数进行处理,在这个函数中可以利用传递的CCmdUI对象去调用相应的函数来修改菜单状态。当更新完第一个菜单项后,同一个CCmdUI对象就设置为与第二个菜单项相关联,依此顺序进行,直到完成所有菜单项的处理。

  总结:如果要在程序中设置某个菜单项的状态,首先通过ClassWizard为这个菜单项添加UPDATE_COMMAND_UI消息响应函数,然后在这个函数中进行状态的设置即可。

 

  如果有疑问,可以联系giserdev@163.com,更多内容请参考:http://www.cnblogs.com/mxbs/,技术交流请加QQ群:586571286。

菜单基本操作(二)