c++mfccmenu

Why can't I disable/gray out menuitem? (MFC)


I'm trying to disable/gray out menu items using the CMenu::EnableMenuItem() method.

I have a CMenu* variable pMenu which references the top menu of the dialog. I can get the submenu using pMenu->GetSubMenu(int) and using submenu->GetMenuStringA(), verify the names of the submenus/menu items that I get back. I'm having trouble with the EnableMenuItem() method though. Let's say theres a File menu. Within it there are New and Open popup menus and Import, Close, and Close All menu items. The New and Open have submenu items. (e.g New->Document) Using submenu->EnableMenuItem([position of submenu/menuitem], MF_BYPOSITION | MF_GRAYED); I can disable New or Open, however the function fails for Import, Close and Close All, as well as all the menu items with New and Open.

Note: When I say EnableMenuItem() fails, I don't mean that it returns -1. It returns the previous status, but the menu doesn't become disabled or grayed out.

In the MSDN documentation for EnableMenuItem(): http://msdn.microsoft.com/en-us/library/h62wh3y1.aspx it claims that this will work for both pop up and standard menu items. It only seems to work for pop up ones, though.


Solution

  • A stated by ScottMcP-MVP MFC does the menu configuration in the ON_UPDATE_COMMAND_UI handler : When a user of your application pulls down a menu, each menu item needs to know whether it should be displayed as enabled or disabled. The target of a menu command provides this information by implementing an ON_UPDATE_COMMAND_UI handler. For each of the command user-interface objects in your application, use the Properties window to create a message-map entry and function prototype for each handler.

    When the menu is pulled down, the framework searches for and calls each ON_UPDATE_COMMAND_UI handler, each handler calls CCmdUI member functions such as Enable and Check, and the framework then appropriately displays each menu item.

    That means that you have to store in your own classes the expected state for the menu item that can be checked/unchecked. You will have to put one ON_UPDATE_COMMAND_UI macro per menu element near the ON_COMMAND macro, and that element will refer a function receiving the CCmdUi object that you can modify to your needs. But as you are using MFC, you normally do not do that by hand but just use the properties of the windows containing the menu.