Andrew Truckle
Andrew Truckle

Reputation: 19087

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:

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?

Upvotes: 2

Views: 1673

Answers (2)

SoronelHaetir
SoronelHaetir

Reputation: 15164

Sure, to disable the item retrieve the menu handle using GetMenu then use the EnableMenuItem API and specify MF_BYPOSITION rather than MF_BYCOMMAND.

Or you could use a MENUEX resource and assign an ID to the popup menu items (unfortunately th resource editor can not save MENUEX resources, it can read them but always saves as MENU). If you want to change to MENUEX put it in the .rc2 file of an MFC project.

Upvotes: 1

Landstalker
Landstalker

Reputation: 1368

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.

Upvotes: 1

Related Questions