代码之家  ›  专栏  ›  技术社区  ›  Tim

如何在包含子菜单项的菜单项上打勾。(Visual Studio 2008 C++/MFC)

  •  2
  • Tim  · 技术社区  · 14 年前

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

    如:

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

    项3下有项。

    在任何给定时间1、2或3以下的项目都应进行检查。因为我没有第3项的ID,所以我必须使用 MF_BYPOSITION 当我试图在项3上设置一个复选标记以指示它的一个子项具有复选标记时的指示器。如果检查了a或b,项目3应该有一个复选标记。我可以检查项目1和2,以及A和B-但无法计算出项目3。

    我也没能成功使用 ::CheckMenuItem() ModifyMenu() 设置复选标记。

    有人能给我举一个成功的例子吗?这些文件似乎表明这是可以做到的,但我一直做不到。

    编辑

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

    还要注意,它被用作右键单击的弹出窗口,但在这两种情况下,我都会接受任何建议。

    2 回复  |  直到 9 年前
        1
  •  2
  •   Tim    14 年前

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

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

    但是,我还没有对菜单栏中的项目执行此操作。

    由Tim编辑操作:

    为了完整性

    要使它与菜单项一起工作,您必须获得菜单

    // 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);
    
        2
  •  1
  •   John C    12 年前

    几分钟前,我也遇到了类似的问题——一个包含至少一个子菜单的标准MFC菜单栏,需要能够向 子菜单 父项,当任何子菜单 小孩 检查了个项目。

    最简单的解决方案(对我来说)和在标准的onUpdateMenuItem(ccmdui*pcmdui)调用中执行更新一样简单。在我的例子中,我使用了_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);
    }
    

    埃特维尔石油公司 当子菜单项中的任何一个子菜单项具有复选标记时,子菜单项自动获得复选标记。

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

    约翰