Dynamic menu using mfc

后端 未结 4 1203
北恋
北恋 2020-12-03 05:40

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 en

相关标签:
4条回答
  • 2020-12-03 06:06
    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);
    
    0 讨论(0)
  • 2020-12-03 06:09
      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);
    
    0 讨论(0)
  • 2020-12-03 06:11

    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 menu or 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.

    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.

    0 讨论(0)
  • 2020-12-03 06:20

    You can create a CMenu object dynamically like this:

    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_RANGE to 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.

    0 讨论(0)
提交回复
热议问题