如何勾选具有子菜单项的菜单项。 (Visual Studio 2008 C ++ / MFC)

时间:2010-08-04 15:43:52

标签: c++ winapi mfc

我有一个包含子菜单的菜单。

例如:

  • 项目1
  • 项目2
  • 项目3
    • 项目A
    • 项目B

Item3下有项目。

在任何给定时间1,2或3下的项目都应该被检查。由于我没有Item3的ID,因此当我尝试对Item3进行检查以指示其中一个孩子有复选标记时,我必须使用MF_BYPOSITION指示符。如果选中A或B,则Item3应具有复选标记。我可以检查项目1和2以及A和B - 但无法确定项目3。

我无法成功使用::CheckMenuItem()ModifyMenu()来设置复选标记。

有人能指出我成功做到这一点的例子吗?文档似乎表明它可以完成,但我无法做到。

修改

这是一个菜单,设置为dlg框的菜单。菜单栏有三个项目 - 其中一项下降到上面显示的内容。

另请注意,它用作右键单击的弹出窗口,但我会在任何一种情况下采取任何建议。

2 个答案:

答案 0 :(得分:2)

我之前为弹出菜单做过这个。您需要按位置访问子菜单,而不是ID。使用上面的示例,第3项将位于第2位:

CMenu popupMenu;
popupMenu.LoadMenu(IDR_MYMENU);
popupMenu.GetSubMenu(0)->CheckMenuItem(2,MF_BYPOSITION|MF_CHECKED);
.
.
.
popupMenu.GetSubMenu(0)->TrackPopupMenu(...);

但是,我还没有使用菜单栏中的项目。

Tim的OP编辑:

完整性

要使其与菜单项一起使用,您必须获取hmenu

// MENU_POSITION is the zero based location of the menu you want to use. (file, edit, view, help... etc)
HMENU mainMenu = ::GetMenu(m_hWnd);
HMENU subMenu = GetSubMenu( mainMenu, MENU_POSITION);
SetMenuState(subMenu);

答案 1 :(得分:1)

不久之前我遇到了类似的问题 - 标准的MFC菜单栏包含至少一个子菜单,并且需要能够在子菜单父项中添加复选标记检查了子菜单 child 项目。

最简单的解决方案(对我来说)就像在标准的OnUpdateMenuItem(CCmdUI * pCmdUI)调用中执行更新一样简单。在我的例子中,我使用ON_UPDATE_COMMAND_UI_RANGE()将一堆菜单ID提供给同一个更新调用,但是对于单个ON_UPDATE_COMMAND_UI()映射,主体是相同的。

我使用的代码(编辑为更容易插入到其他人的工作中)是:

void CMyApp::OnUpdateMenu(CCmdUI* pCmdUI)
{
   // Note, a submenu parent (which has no editable ID in the resource editor) has the SAME ID as the first child item
   if (pCmdUI->m_nID == ID_FIRST_CHILD_MENU && pCmdUI->m_pSubMenu != NULL) {
      // Get the child menu so we can see if any child items are checked
      CMenu* pSubMenu = pCmdUI->m_pSubMenu;
      BOOL fChildChecked = FALSE;
      for (UINT i = 0; !fChildChecked && i < pSubMenu->GetMenuItemCount(); ++i) {
         // Do something to decide if this child item should be checked...
         UINT nChildID = pSubMenu->GetMenuItemID(i);
         fChildChecked = IsThisChildChecked(nChildID);
      }

      // The POSITION of the current menu item is stored in pCmdUI->m_nIndex
      CMenu* pMenu = pCmdUI->m_pMenu;
      UINT flags = MF_BYPOSITION;
      if (fActiveChild) flags |= MF_CHECKED;
      pMenu->CheckMenuItem(pCmdUI->m_nIndex, flags);
   }

   // Set the enabled state of the menu item as you see fit...
   pCmdUI->Enable(TRUE);
}

Etvoilà当子菜单项的任何子菜单项都有复选标记时,子菜单项会自动获得复选标记。

希望这可以帮助其他人寻找类似的解决方案!

约翰