基于对话框应用程序中菜单更新问题处理

症状:    
    从命令用户界面处理函数(Command   UI   handler)改变菜单状态(启用/禁用,选择/取消选择,更改文字)在由对话框处理时没有正常工作。    
   
  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   默认处理函数,该函数没有为菜单项调用更新命令处理函 数。    
   
  解决方法:   
    
  适用下列步骤解决此问题 

1、在消息映射中添加ON_WM_INITMENUPOPUP项

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

void CThjCtrlWnd::OnInitMenuPopup(CMenu* pPopupMenu, UINT nIndex, BOOL bSysMenu)
{
 CDialog::OnInitMenuPopup(pPopupMenu, nIndex, bSysMenu);

 // TODO: 在此处添加消息处理程序代码 

 if (bSysMenu)
  return;

 //ASSERT(pPopupMenu != NULL);

 ENSURE_VALID(pPopupMenu); 
 // 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 = GetTopLevelParent();
   // 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 nItemIndex = 0; nItemIndex < nIndexMax; nItemIndex++)
   {
    if (::GetSubMenu(hParentMenu, nItemIndex) == 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, FALSE);    // 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;
 }


}
   
 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值