让对话框对UPDATE_COMMAND_UI生效

转载 2007年09月27日 09:47:00
[作者]:菩提树下的杨过 [来源]:互联网 [收录时间]:2007-8-2 22:29:29

问题:一般情况下我们用UPDATE_COMMAND_UI来修改菜单的状态(enable/disable, check/uncheck, change text),但这个方法在一个基于对话框上的菜单却没有效果
void CTestDlg::OnUpdateFileExit(CCmdUI* pCmdUI)
{

pCmdUI->Enable(FALSE);
pCmdUI->SetCheck(TRUE);
pCmdUI->SetRadio(TRUE);
pCmdUI->SetText("Close");
//以上方法在MDI、SDI程序中都能起作用,在对话框中却没有效果,根本没有调用这个函数。
}

原因分析:当显示一个下拉的菜单的时候,在显示菜单前会发送WM_INITMENUPOPUP消息。而CFrameWnd::OnInitMenuPopup函数会刷新这个菜单项,同时如果有UPDATE_COMMAND_UI响应函数,则调用它。通过它来更新反应每个菜单的外观效果(enabled/disabled, checked/unchecked).
在一个基于对话框的程序中,因为没有OnInitMenuPopup函数,所以不会调用UPDATE_COMMAND_UI响应函数,而是使用了CWnd类的默认处理, 这种处理没有调用UPDATE_COMMAND_UI响应函数。

解决方法如下:
第一步:
在对话框类的.cpp文件,添加一个ON_WM_INITMENUPOPUP入口到消息映射里面
BEGIN_MESSAGE_MAP(CTestDlg, CDialog)
//}}AFX_MSG_MAP
ON_WM_INITMENUPOPUP()
END_MESSAGE_MAP()
第二步:
在对话框类的.h文件添加消息函数声明。
// Generated message map functions
//{{AFX_MSG(CDisableDlgMenuDlg)
afx_msg void OnInitMenuPopup(CMenu *pPopupMenu, UINT nIndex,BOOL bSysMenu);
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
第三步:
在对话框类的.cpp文件添加如下函数代码(大部分代码取自WinFrm.cpp文件的函数CFrameWnd::OnInitMenuPopup):
void C******Dlg::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;
}
}

更详细的信息可参考
http://support.microsoft.com/default.aspx?scid=kb;en-us;242577

 

MFC编程总结之一-----让对话框对UPDATE_COMMAND_UI生效

在编程过程中,有些查找过的问题,或许但是急于解决问题,而没有很深沉的理解解决问题的具体内涵,或许已经理解了但是马上编程代码却需要话费很大的经历,这里笔者将慢慢总结开发过程中遇到的问题及其相关解决方案,...
  • mjesse88
  • mjesse88
  • 2013年12月24日 13:40
  • 518

基于对话框的UPDATE_COMMAND_UI的响应问题

问题:一般情况下我们用UPDATE_COMMAND_UI来修改菜单的状态(enable/disable,check/uncheck, change text),但这个方法在一个基于对话框上的菜单却没有...
  • u012372584
  • u012372584
  • 2016年02月02日 14:48
  • 245

对话框菜单不响应UPDATE_COMMAND_UI

问题 从命令用户界面处理函数(Command UIhandler)改变菜单状态(启用/禁用,选择/取消选择,更改文字)在由对话框处理时没有正常工作。 void CTestDlg::OnUpdate...
  • qianchenglenger
  • qianchenglenger
  • 2014年02月18日 17:44
  • 679

菜单命令更新机制

本文主要了介绍了MFC菜单命令更新机制和CMenu的使用对比。
  • xiao3404
  • xiao3404
  • 2016年10月16日 21:55
  • 428

VC 对话框程序 menu菜单响应UPDATE_COMMAND_UI 消息

问题:一般情况下我们用UPDATE_COMMAND_UI来修改菜单的状态(enable/disable, check/uncheck, change text),但这个方法在一个基于对话框上的菜单却没...
  • xbmoxia
  • xbmoxia
  • 2014年10月16日 10:33
  • 1314

模式对话框和无模式对话框 区别

按工作方式不同,可将对话框分成两类:  ??模式对话框(modal dialog box模态对话框):在关闭模式对话框之前,程序不能进行其他工作(如一般的“打开文件”对话框)  ??无模式对话框(...
  • wangzhen0331
  • wangzhen0331
  • 2014年04月21日 15:33
  • 617

MFC 基础知识:主对话框与子对话框(一)

(仅供使用VS MFC初学者学习,高手莫见笑) 在MFC中通常会使用点击一个按钮,弹出一个子对话框的基础知识,这些都是学习MFC的基础知识,也是非常重要的知识,这里我就简单的讲讲这些知识。 一.设置主...
  • Eastmount
  • Eastmount
  • 2013年06月08日 02:21
  • 10505

VS2013/MFC编程入门之五(对话框:创建对话框模板和修改对话框属性)

在上一讲中介绍了MFC的消息映射机制,属于原理方面的知识。对于VC++编程入门学习者来说可能有些抽象,本文会把消息映射的知识渗透到后面的教程中。本节开始为大家讲解偏应用的知识-创建对话框。   ...
  • zhaoyinhui0802
  • zhaoyinhui0802
  • 2016年11月23日 16:32
  • 4487

对话框小程序

MainActivity package com.example.dialogdemo; import android.os.Bundle; import android.app.Activity...
  • hypertelorism
  • hypertelorism
  • 2016年03月21日 09:18
  • 165

常用对话框:字体对话框

字体对话框的作用是用来选择字体。我们也经常能够见到。MFC使用CFontDialog类封装了字体对话框的所有操作。字体对话框也是一种模态对话框。        CFontDialog类的构造函数 ...
  • I_amKing
  • I_amKing
  • 2014年12月09日 14:15
  • 710
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:让对话框对UPDATE_COMMAND_UI生效
举报原因:
原因补充:

(最多只允许输入30个字)