Link to home
Start Free TrialLog in
Avatar of ris
ris

asked on

update command UI in a popup menu

I have a number of popup menus in my app which I show by calling CMenu::TrackPopupMenu().  Unfortunately, the popup menu does not send update-command-UI messages for the commands in the menu until after the menu command is chosen.  So several menu commands which should be disabled show as enabled but function as if they are disabled.

How can I change the following function to cause all the menu items to process update command UI messages before the popup menu is shown (or immediately after, or during the TrackPopupMenu() call)

void StandardPopupMenu(UINT nPopupMenu, CWnd* pCallbackWindow, CPoint TrackPoint)
{
    CMenu PopupMenu;
    VERIFY(PopupMenu.LoadMenu(nPopupMenu));
    //NOTE: every popup menu is one menu deep in the menu resource
    CMenu* pPopupMenu = PopupMenu.GetSubMenu(0);
    ASSERT(pPopupMenu);
    //TODONOW: make sure all of the commands in the menu process
    //  update command UI messages before showing the menu
    VERIFY(pPopupMenu->TrackPopupMenu(TPM_LEFTALIGN|TPM_LEFTBUTTON|TPM_RIGHTBUTTON,
        TrackPoint.x, TrackPoint.y, pCallbackWindow));
} //end StandardPopupMenu()
Avatar of hoabeo
hoabeo

I want to know more about pCallbackWindow, what is it when you call StandardPopupMenu?

Generally, when you pass pCallbackWindow to StandardPopupMenu, you should add update-command-ui handlers to that window.

For example: you add those handlers to your Main Window, and pass the pointer to StandardPoppMenu.


Hope this help,
Avatar of ris

ASKER

CWnd* pCallbackWindow is the window that calls StandardPopupMenu(), and it already has update-command-ui handlers for the applicable menu commands, and those handlers are called.  However, those update-command-ui handlers aren't called before the menu is displayed, but they are called after a menu item is clicked on.  So the behavior is something like this:

1) I right click on the window and that window class's MyWindow::OnContextMenu() handler is called.

2) MyWindow::OnContextMenu() calls StandardPopupMenu(IDR_POPUP_MENU, this, Point)

3) StandardPopupMenu() shows the menu.  Menu items which should be disabled appear enabled

4) I click on a menu item which should be disabled but appears enabled

5) the framework sends an update-command-ui message for that menu item command that I clicked

6) MyWindow::OnUpdateCommandUIMyMenuItem() handles the update-command-ui message for the should-be-disabled menu item that I clicked, and disables the menu item after I clicked it

7) since the menu item is now disabled (after I clicked it) the actual command message for the menu item I clicked is never sent, just as if the menu item had been disabled before I clicked it.

So how can I fix this problem?  Do I have to iterate through the items in pPopupMenu, get the command IDs, and manually set update-command-UI messages to pCallbackWindow before I call pPopupMenu->TrackPopupMenu()?  Will that work?  Is there an easier way?
ASKER CERTIFIED SOLUTION
Avatar of hoabeo
hoabeo

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of ris

ASKER

Wow, code and everything!  Thank you so much!  That is exactly what I needed and it works very nicely!