博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
更新处理函数在对话框的菜单中不能工作
阅读量:7025 次
发布时间:2019-06-28

本文共 5769 字,大约阅读时间需要 19 分钟。

 

void   CTestDlg::OnUpdateFileExit(CCmdUI*   pCmdUI {         pCmdUI-> Enable(FALSE);   //没有显示为禁用.         pCmdUI-> SetCheck(TRUE);   //   没有文字前显示选定标记.         pCmdUI-> SetRadio(TRUE);   //   没有在文字前显示点.         pCmdUI-> SetText( "Close ");   //没有更改菜单文字. }

 

原因 

在下拉菜单显示的时候,   WM_INITMENUPOPUP消息被先发送以显示菜单项。MFC   CFrameWnd::OnInitMenuPopup   函数遍历菜单项并为每个菜单项调用更新命令处理函数(如果有的话).菜单的外观被更新以反映它的状态(启用/禁用,选择/取消选择)   
更新用户界面机制在基于对话框的应用程序中不能工作,因为CDialog没有OnInitMenuPopup   处理函数,而使用CWnd 's   默认处理函数,该函数没有为菜单项调用更新命令处理函数。 

 

解决 
适用下列步骤解决此问题     

在消息映射中添加ON_WM_INITMENUPOPUP   项:   

 

BEGIN_MESSAGE_MAP(CTestDlg,   CDialog)   //{
{AFX_MSG_MAP(CTestDlg) ........................ ........................ //}}AFX_MSG_MAP ON_WM_INITMENUPOPUP() END_MESSAGE_MAP()

 

 

在你的对话框类中添加OnInitMenuPopup成员函数且复制下列代码到该函数(注意:代码基本上是从CFrameWnd::OnInitMenuPopup(在WinFrm.cpp中)复制过来的):   

void   CTestDlg::OnInitMenuPopup(CMenu   *pPopupMenu,   UINT   nIndex,BOOL   bSysMenu) {         ASSERT(pPopupMenu   !=   NULL);         //   Check   the   enabled   state   of   various   menu   items.         CCmdUI   state;         state.m_pMenu   =   pPopupMenu;         ASSERT(state.m_pOther   ==   NULL);         ASSERT(state.m_pParentMenu   ==   NULL);         //   Determine   if   menu   is   popup   in   top-level   menu   and   set   m_pOther   to         //   it   if   so   (m_pParentMenu   ==   NULL   indicates   that   it   is   secondary   popup).         HMENU   hParentMenu;         if   (AfxGetThreadState()-> m_hTrackingMenu   ==   pPopupMenu-> m_hMenu)                 state.m_pParentMenu   =   pPopupMenu;         //   Parent   ==   child   for   tracking   popup.         else   if   ((hParentMenu   =   ::GetMenu(m_hWnd))   !=   NULL)         {                 CWnd*   pParent   =   this;                       //   Child   windows   don 't   have   menus--need   to   go   to   the   top!                 if   (pParent   !=   NULL   &&                       (hParentMenu   =   ::GetMenu(pParent-> m_hWnd))   !=   NULL)                 {                       int   nIndexMax   =   ::GetMenuItemCount(hParentMenu);                       for   (int   nIndex   =   0;   nIndex   <   nIndexMax;   nIndex++)                       {                         if   (::GetSubMenu(hParentMenu,   nIndex)   ==   pPopupMenu-> m_hMenu)                         {                                 //   When   popup   is   found,   m_pParentMenu   is   containing   menu.                                 state.m_pParentMenu   =   CMenu::FromHandle(hParentMenu);                                 break;                         }                       }                 }         }         state.m_nIndexMax   =   pPopupMenu-> GetMenuItemCount();         for   (state.m_nIndex   =   0;   state.m_nIndex   <   state.m_nIndexMax;             state.m_nIndex++)         {                 state.m_nID   =   pPopupMenu-> GetMenuItemID(state.m_nIndex);                 if   (state.m_nID   ==   0)                       continue;   //   Menu   separator   or   invalid   cmd   -   ignore   it.                 ASSERT(state.m_pOther   ==   NULL);                 ASSERT(state.m_pMenu   !=   NULL);                 if   (state.m_nID   ==   (UINT)-1)                 {                       //   Possibly   a   popup   menu,   route   to   first   item   of   that   popup.                       state.m_pSubMenu   =   pPopupMenu-> GetSubMenu(state.m_nIndex);                       if   (state.m_pSubMenu   ==   NULL   ||                         (state.m_nID   =   state.m_pSubMenu-> GetMenuItemID(0))   ==   0   ||                         state.m_nID   ==   (UINT)-1)                       {                         continue;               //   First   item   of   popup   can 't   be   routed   to.                       }                       state.DoUpdate(this,   TRUE);       //   Popups   are   never   auto   disabled.                }                 else                 {                       //   Normal   menu   item.                       //   Auto   enable/disable   if   frame   window   has   m_bAutoMenuEnable                       //   set   and   command   is   _not_   a   system   command.                       state.m_pSubMenu   =   NULL;                       state.DoUpdate(this,   FALSE);                 }                 //   Adjust   for   menu   deletions   and   additions.                 UINT   nCount   =   pPopupMenu-> GetMenuItemCount();                 if   (nCount   <   state.m_nIndexMax)                 {                       state.m_nIndex   -=   (state.m_nIndexMax   -   nCount);                       while   (state.m_nIndex   <   nCount   &&                         pPopupMenu-> GetMenuItemID(state.m_nIndex)   ==   state.m_nID)                       {                         state.m_nIndex++;                       }                 }                 state.m_nIndexMax   =   nCount;         } }

状态 

设计使然。 

 

更多信息 

命令用户界面处理函数也被CWnd::OnCommand   调用以确认命令在传递之前没有被禁用。这就是禁用的菜单项的命令处理没有被调用的原因(虽然没有以灰色显示(不可用))。在这种情况下,菜单项没有被重画以反映菜单项的状态.这是Wincore.cpp   文件中的相关代码:   

//在传递命令之前,确定命令没有被禁用       CTestCmdUI   state;       state.m_nID   =   nID;       OnCmdMsg(nID,   CN_UPDATE_COMMAND_UI,   &state,   NULL);       if   (!state.m_bEnabled)       {             TRACE1( "Warning:   not   executing   disabled   command   %d\n ",   nID);             return   TRUE;       }

重现此行为的步骤 

使用应用程序向导建立一个基于对话框的应用程序 

 

建立一个新的菜单资源,并且向其上添加文件和文件/退出菜单项。 

在对话框的属性中设置对话框的菜单为上述菜单. 

使用类向导为文件/退出菜单项添加一个UPDATE_COMMAND_UI处理并添加下列语句之一到处理函数。 

pCmdUI-> Enable(FALSE);   //没有显示为禁用. 
pCmdUI-> SetCheck(TRUE);   //   没有文字前显示选定标记. 
pCmdUI-> SetRadio(TRUE);   //   没有在文字前显示点. 
pCmdUI-> SetText( "Close ");   //没有更改菜单文字. 
编译运行此程序。

转载于:https://www.cnblogs.com/rogee/archive/2011/01/03/1924389.html

你可能感兴趣的文章
varnish缓存实现动静分离
查看>>
安装numpy、scipy、matplotlib
查看>>
子网划分
查看>>
C# 获取当前ip
查看>>
linux下phpMyAdmin提示缺少mysqli扩展的解决方法
查看>>
一起搭建linux监控平台之nagios(三)被监控端的环境部署
查看>>
whirlpool的环境配置
查看>>
RabbitMq集群环境部署
查看>>
Lync 2013 的配置与使用
查看>>
希尔排序
查看>>
3.2Python的循环结构语句:
查看>>
分享从带头拼死拼活开发软件项目到不去现场异地坐镇远程遥控照样可以把上海的软件项目管理好...
查看>>
Linux运维系统工程师系列---08
查看>>
python eval的常见错误封装及利用原理
查看>>
MySQL主从介绍、准备工作、准备工作、配置从、测试主从同步
查看>>
js中用EL表达式获取模型视图数据
查看>>
IS-IS 中间系统到中间系统的认证
查看>>
大家来看看哦
查看>>
【Animations】属性动画概述(2)
查看>>
C#中pictureBox上如何设置label透明
查看>>