Command Routing for Popup Menus






4.79/5 (27 votes)
Handle grayed/disabled/checked menu items using the familiar OnUpdate interface
Introduction
While working with popup menus, I needed a way to hook these into the standard CCmdUI MFC OnUpdate
interface. The following block of code does this:
void CmdRouteMenu(CWnd* pWnd,CMenu* pPopupMenu)
{
CCmdUI state;
state.m_pMenu = pPopupMenu;
state.m_pParentMenu = pPopupMenu;
state.m_nIndexMax = pPopupMenu->GetMenuItemCount();
for (state.m_nIndex = 0;
state.m_nIndex < state.m_nIndexMax;
state.m_nIndex++)
{
state.m_nID = pPopupMenu->GetMenuItemID(state.m_nIndex);
// menu separator or invalid cmd - ignore it
if (state.m_nID == 0) continue;
if (state.m_nID == (UINT)-1)
{
// possibly a popup menu, route to child menu if so
CMenu* pSub=pPopupMenu->GetSubMenu(state.m_nIndex);
if(pSub) CmdRouteMenu(pWnd,pSub);
}
else
{
// normal menu item, Auto disable if command is
// _not_ a system command.
state.m_pSubMenu = NULL;
state.DoUpdate(pWnd, FALSE);
}
}
}
Usage Example:
CmdRouteMenu(pWnd,pSubMenu); pSubMenu->TrackPopupMenu(TPM_LEFTBUTTON | TPM_RIGHTBUTTON | TPM_LEFTALIGN,point.x,point.y,pWnd,NULL);
Simply call with the window to handle the OnUpdate
messages (usually your MainWnd) and the menu to be worked on, just before popping up the menu using TrackMenu(...)
. This also works for BMP menu and Gradient menu also found on CodeProject.
Of course, the code above only works if you have the OnUpdate
calls written to handle the menu commands.