C++ 使用 mfc 的动态菜单

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3673546/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 13:27:00  来源:igfitidea点击:

Dynamic menu using mfc

c++mfc

提问by Ira

I would like to add a menu item to my main menu and then populate it with items at run time. How would I do this? And besides adding items how would I have a message map entry for them since I do not know the id?

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

回答by casablanca

You can create a CMenuobject dynamically like this:

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

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

Then add this sub-menu to your main menu:

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

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

As for the message map, assuming all your menu item IDs are within a certain range, you can use ON_COMMAND_RANGEto map the entire range to a single function. This function will receive the ID as a parameter, and within the function, you can perform different operations based on the ID.

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

回答by ashwini hajgude

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);

回答by user3706458

  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);

回答by ReturnVoid

Following example if you wish to dynamically add menu item & also attach data to that menu item.

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

    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);
    }

To retrieve menu item & associated data:

检索菜单项和相关数据:

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. Used as your #define & can be used for ON_COMMAND_RANGE(idFirst, idLast, Function), so would still need to have some sort of defined range if you were planning on using ON_COMMAND_RANGE. Alternatively: use command range for dynamic menuor create your own within the data set. Also need to make sure any ranges used do not conflict with any already #defined menu items on the same or parent menu.
  1. 用作您的 #define & 可用于 ON_COMMAND_RANGE(idFirst, idLast, Function),因此如果您计划使用 ON_COMMAND_RANGE,仍然需要有某种定义的范围。或者:使用动态菜单的命令范围或在数据集中创建您自己的。还需要确保使用的任何范围不与相同或父菜单上任何已#defined 的菜单项冲突。

Added above as I found this thread from googling due to an issue & I was already using the accepted answers method for adding menu items.

在上面添加,因为我由于问题从谷歌搜索中发现了这个线程,我已经在使用公认的答案方法来添加菜单项。