Search code examples
c++menumfc

Can I disable a menu item on the menu bar and / or dynamically display it?


Here is a new View menu that I have added to my software:

View Menu

My editor (a CDialog) has two modes. This View menu is only applicable to one of the modes.

At the moment I am disabling the menu items like this:

CMenu* pMenu = GetMenu();
if (pMenu != nullptr)
{
    pMenu->EnableMenuItem(ID_VIEW_REFRESH, MF_BYCOMMAND | MF_GRAYED);
    CMenu* pViewMenu = pMenu->GetSubMenu(3);
    if (pViewMenu != nullptr)
        pViewMenu->EnableMenuItem(1, MF_BYPOSITION | MF_GRAYED);
}

This works fine. But is there any way to either:

  • Disable the actual View menu item on the menu bar?
  • Remove / Add the menu as needed?

At the moment the menu is always there and I just disable the items dependant on the active editor mode. It is part of my editor menu in the resources:

POPUP "View"
BEGIN
    MENUITEM "Refresh\tF5",                 ID_VIEW_REFRESH, INACTIVE
    POPUP "Zoom", GRAYED
    BEGIN
        MENUITEM "Zoom In\tCTRL +",             ID_ZOOMLEVEL_ZOOMIN
        MENUITEM "Zoom Out\tCTRL -",            ID_ZOOMLEVEL_ZOOMOUT
        MENUITEM SEPARATOR
        MENUITEM "400%",                        ID_ZOOMLEVEL_400
        MENUITEM "300%",                        ID_ZOOMLEVEL_300
        MENUITEM "250%",                        ID_ZOOMLEVEL_250
        MENUITEM "200%",                        ID_ZOOMLEVEL_200
        MENUITEM "175%",                        ID_ZOOMLEVEL_175
        MENUITEM "150%",                        ID_ZOOMLEVEL_150
        MENUITEM "125%",                        ID_ZOOMLEVEL_125
        MENUITEM "100%\tCTRL + 0",              ID_ZOOMLEVEL_100
        MENUITEM "75%",                         ID_ZOOMLEVEL_75
        MENUITEM "50%",                         ID_ZOOMLEVEL_50
        MENUITEM SEPARATOR
        MENUITEM "Custom...",                   ID_ZOOM_CUSTOM
    END
END

Is this possible?


Solution

  • Let's suppose your menu is called IDR_MAINFRAME:

    enter image description here

    Create your mainFrame and add IDR_MAINFRAME menu:

    CMainFrame* pFrame = new CMainFrame;  
    pFrame->LoadFrame(IDR_MAINFRAME, WS_OVERLAPPEDWINDOW | FWS_ADDTOTITLE, NULL, NULL);
    

    You must get the main menu like this:

    CMenu menu;
    menu.LoadMenu(IDR_MAINFRAME);
    

    Now, you can disable a specific item:

    menu.EnableMenuItem (1,  MF_BYPOSITION|MF_DISABLED|MF_GRAYED); 
    pFrame->SetMenu(&menu);  
    

    See result below :

    enter image description here

    Note that Edition is a main menu (similar to your View menu) for my application.
    To enable your menu (View menu) dynamically, call EnableMenuItem a second time like this:

    menu.EnableMenuItem (1,  MF_BYPOSITION);   
    

    Hope it help you.

    Update

    I also had to use this code to get the menu bar to update visually:

    DrawMenuBar();
    

    With this code the menu did not visually update until the mouse was put over the menu text.