【问题标题】:Dynamic menu using mfc使用 mfc 的动态菜单
【发布时间】:2011-04-10 01:38:12
【问题描述】:

我想在我的主菜单中添加一个菜单项,然后在运行时用项目填充它。我该怎么做?除了添加项目之外,由于我不知道 id,我如何为它们提供消息映射条目?

【问题讨论】:

    标签: c++ mfc


    【解决方案1】:

    您可以像这样动态创建CMenu 对象:

    CMenu *menu = new CMenu;
    menu->CreatePopupMenu();
    // Add items to the menu
    menu->AppendMenu(MF_STRING, menuItemID, "Text");
    ...
    

    然后将此子菜单添加到您的主菜单:

    wnd->GetMenu()->AppendMenu(MF_POPUP, (UINT_PTR)menu->m_hMenu, "Menu Name");
    

    至于消息映射,假设您所有的菜单项 ID 都在某个范围内,您可以使用ON_COMMAND_RANGE 将整个范围映射到单个函数。该函数将接收ID作为参数,在函数内部可以根据ID进行不同的操作。

    【讨论】:

      【解决方案2】:
      define the menu's using #define
      
      #define ID_SHOW   2002
      #define ID_HIDE   2004
      
      //create a menu object for main menu
      CMenu *menu    = new CMenu();
      menu->CreateMenu();
      
      //another menu object for submenu
      CMenu *subMenu = new CMenu();
      subMenu->CreatePopupMenu();
      subMenu->AppendMenu(MF_STRING, ID_HIDE, _T("four"));
      subMenu->AppendMenu(MF_STRING, ID_SHOW, _T("three"));
      //append submenu to menu
      menu->AppendMenu(MF_POPUP|MF_STRING, (UINT)subMenu->m_hMenu,  _T("Advanced") );
      SetMenu(menu);
      

      【讨论】:

        【解决方案3】:
          CMenu menuPopup;
          menuPopup.LoadMenu(IDR_CNTXT_PLAN);
        subMenu.CreatePopupMenu();
         subMenu.AppendMenu(MF_STRING, MENU1,"Menu1");
        subMenu.AppendMenu(MF_STRING, MENU2,"Menu2");
        CMenu* pMenu = menuPopup.GetSubMenu(0);
          pMenu->InsertMenu(0,MF_BYPOSITION|MF_POPUP,(UINT)subMenu.m_hMenu,"Layers");
          menuPopup.GetSubMenu(0)->InsertMenu(1,MF_BYPOSITION|MF_SEPARATOR,0,"");
        menuPopup.GetSubMenu(0)->TrackPopupMenu(TPM_LEFTALIGN, point.x, point.y, this);
        

        【讨论】:

          【解决方案4】:

          如果您希望动态添加菜单项并将数据附加到该菜单项,请参考以下示例。

              struct MyStruct
              {
                  int abc;
              };
              CMenu MyMenu;
              MyMenu.CreatePopupMenu();
          
              CMenu MyMainMenu;
              VERIFY(MyMainMenu.LoadMenu(IDR_MAIN_MENU_ID));
              MyMainMenu.InsertMenu(0, MF_POPUP, (UINT_PTR)MyMenu.m_hMenu, _T("Main Menu"));
          
              const int iMenuAdds = 5;
              for (int i = 0; i < iMenuAdds; ++i)
              {
                  MyStruct myStruct;
                  myStruct.abc = i+10001;
          
                  CString MenuDesc;
                  MenuDesc.Format(_T("MenuNo: %d"), i);
                  MENUITEMINFO tmpItem;
                  tmpItem.fMask = MIIM_STRING | MIIM_ID | MIIM_DATA;
                  tmpItem.fType = MFT_STRING;
                  tmpItem.fState = MFS_ENABLED;
                  tmpItem.wID = i + 101; //See note 1. below.
                  tmpItem.dwItemData = (ULONG_PTR)&myStruct; //data set.
                  tmpItem.dwTypeData = MenuDesc.GetBuffer(); //string description
                  tmpItem.cch = MenuDesc.GetLength();
                  tmpItem.cbSize = sizeof(tmpItem);
                  MyMenu.InsertMenuItem(i, (LPMENUITEMINFO)& tmpItem, FALSE);
              }
          

          检索菜单项和相关数据:

          CMenu* pPopup = &MyMenu; //or CMenu* pPopup = MyMainMenu.GetSubMenu(0); depending on parent.
          ULONG_PTR lRetVal = pPopup->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON | TPM_RETURNCMD, point.x, point.y, this, NULL);
          //^^lRetVal should return same value as tmpItem.wID above.
          
          MENUITEMINFO tmpItem;
          tmpItem.cbSize = sizeof(MENUITEMINFO);
          tmpItem.fMask = MIIM_STRING | MIIM_ID | MIIM_DATA;
          tmpItem.fType = MFT_STRING;
          TCHAR dwTypeData[256];
          tmpItem.dwTypeData = dwTypeData;
          tmpItem.cch = 256;
          pPopup->GetMenuItemInfo(lRetVal, &tmpItem, FALSE);
          MyStruct *myStruct = (MyStruct*)tmpItem.dwItemData; //and now we have our data.
          
          1. 用作您的#define & 可用于 ON_COMMAND_RANGE(idFirst, idLast, Function),因此如果您计划使用 ON_COMMAND_RANGE,仍需要定义某种范围。或者:use command range for dynamic menu 或在数据集中创建您自己的。还需要确保使用的任何范围都不会与同一菜单或父菜单上的任何已#defined 菜单项冲突。

          由于问题,我在谷歌搜索中发现了这个线程并且我已经在使用接受的答案方法来添加菜单项。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2014-03-08
            • 1970-01-01
            相关资源
            最近更新 更多