Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » Greying out menu items in MFC App

This thread is locked; no one can reply to it. rss feed Print
Greying out menu items in MFC App
Fenris
Member #1,820
January 2002
avatar

I am having a lot of trouble getting a menu item in an MFC app to behave itself.

I have a Game menu with New Game and Reset Game, and want to gray out the reset option until a game has been started to avoid problems.

In the menu editor, I have set the item Reset Game (ID_GAME_RESET) to GRAYED, and have double checked that this is correctly written to the .rc file.

I also gray it out explicitly within my InitInstance() code for the application like so:

CMenu *menu;

//get the file menu from frame
menu = m_pMainWnd->GetMenu()->GetSubMenu(0);

//gray out the reset option
menu->EnableMenuItem(ID_GAME_RESET, (MFS_GRAYED | MF_BYCOMMAND) );

but neither of these attempts work and the damn thing is still enabled.

Interestingly, when I check the status of that menu item using:

if( menu->GetMenuState(ID_GAME_RESET, MF_BYCOMMAND) & MFS_GRAYED )

the first time it says that it is greyed, even though it isnt in the menu, and on all successive calls it says it is enabled.

Is kind of thing a common occurance when using VC or am I just messing something up?

Cheers,
Fenris

Oscar Giner
Member #2,207
April 2002
avatar

No it's normal. It's a strange behabiour of MFC. This is done in a different way:

Open the ClassWiward, and select the menu item you want to be able to change. Add a function for the UPDATE_COMMAND_UI message. The declaration of this function will look like this:

void CMainFrame::OnUpdateMenuName(CCmdUI* pCmdUI)

In order to enable/disable the menu, just call the Enable member of pCmdUI, like this:

pCmdUI->Enable(FALSE);

This function is called every time the menu is going to be showed.

The problem you have is that the default implementation of this function calls pCmDUI->Enable(TRUE), so no matter how many times you try to disable it, it will get enabled just before showing.

The pCmpUI object has a lot more things you can change, check the docs about the CCmdUI class.

This same aplies to buttons and other objects when you use them in toolbars.

Korval
Member #1,538
September 2001
avatar

As an aside, the nifty thing about those OnUpdate messages is that they work almost everywhwere. If you use that ID for a toolbar button or menu item (in both a right-click menu and a regular menu), then the settings in OnUpdate will work. That is, irregardless of how the ID is used (to some extent. Dialog buttons don't work this way), it will be enabled/disabled by the same code.

Oscar Giner
Member #2,207
April 2002
avatar

Yes that's one of the things I really like about MFC. If two objects share the same ID, all callbacks routines you define for one apply for the other. Very useful when the same operation can be accessed from a toolbar or from a menu: just write one function and give both (the menu item and the toolbar button) the same ID :)

Fenris
Member #1,820
January 2002
avatar

I did try the option of adding a handler for the UPDATE_COMMAND_UI message, and it seemed to work when I was messing around making the item toggle on/off, but the problem is that I need that menu item grayed out to start with. How do I get something grayed out by default at startup? Is there any function I can call at will to force the stupid thing to do what I want it to?

Oscar Giner
Member #2,207
April 2002
avatar

If you created the menu with the MSVC, resource editor, there's a check 'grayed' you can turn on to make the menu grayed by default. But you'll need to ass UPDATE_COMMAND_UI message anyway if you want to enable it later, and remember that this message is called always. Usually, the code for this is something like this:

void CMainFrame::OnUpdateMenuName(CCmdUI* pCmdUI)
{
    if (item_is_enabled)
    {
        pCmdUI->Enable(TRUE);
    }
    else
    {
        pCmdUI->Enable(FALSE);
    }
}

Go to: