Professional UI Solutions
Site Map   /  Register
 
 

Forum

Please Log In to post a new message or reply to an existing one. If you are not registered, please register.

NOTE: Some forums may be read-only if you are not currently subscribed to our technical support services.

Forums » Prof-UIS Tech Support » Changing submenu at run time Collapse All
Subject Author Date
Suhai Gyorgy Mar 3, 2006 - 4:50 AM

Dear Support,
I’ve read your article "How to insert menu items at run time?", and tried to use it to change items in a submenu. I was thinking that since submenu is a popupmenu as well, I would get the CExtPopupMenuWnd::g_nMsgPrepareMenu message for the submenu as well...

But no. So to find out if I’m in the right menu, I guess I have to go through all the menuitems, check if they are of type TYPE_POPUP, and if so, go into that submenu to check if it’s the one I’m looking for. This works as long as I know that the submenu I’m looking for is the child-popup menu of a main popup menu... But how could I make it work for a menu that I don’t know nothing of? It could be anywhere in the tree of submenus.

I’m hoping not sending that messgae for the submenus is only a bug.

Could you please advise? Thank you:
Chris.

Technical Support Mar 3, 2006 - 8:55 AM

Starting from Prof-UIS 2.33, there is a CExtPopupMenuWnd::g_nMsgPrepareOneMenuLevel registered windows message. This message is also sent by the pop-up menu before it appears on the screen. This message has the same parameters but it is sent separately for each pop-up menu level.

Mark Walsen Apr 12, 2006 - 4:14 PM

Following the above advice, changing the submenu at run-time is working well for me, except for one thing. The menu is not immediately updated. The user must dismiss the menu, and display the menu again before the menu shows the menu items that have been inserted and removed with ItemInsert and ItemRemove.

I’m handing the registered message:
ON_REGISTERED_MESSAGE(CExtPopupMenuWnd::g_nMsgPrepareOneMenuLevel, OnExtPrepareOneMenuLevel)

In the handler, I basically do this:

LRESULT CMainFrame::OnExtPrepareOneMenuLevel(WPARAM wParam, LPARAM lParam)
{
CExtPopupMenuWnd::MsgPrepareMenuData_t * pData =
reinterpret_cast< CExtPopupMenuWnd::MsgPrepareMenuData_t * > (wParam);
ASSERT( pData != NULL );
CExtPopupMenuWnd * pPopupMenu = pData->m_pPopup;
LPCTSTR lpszCommandProfileName
= g_CmdManager->ProfileNameFromWnd(pMainFrame->m_hWnd );
CExtCmdItem * pCmdItem = g_CmdManager->CmdGetPtr(lpszCommandProfileName, nCommandID);
if (pCmdItem == NULL)
{
pCmdItem = g_CmdManager->CmdAllocPtr(lpszCommandProfileName, nCommandID);
}
pPopupMenu->ItemInsert(nDynamicCommandID, -1);
if (pCmdItem != NULL && lpszMenuItemText != NULL)
{
pCmdItem->m_sMenuText = "This is a dynamic menu item";
}

...

pData->m_bMenuChanged = true;
return 1;
}

I thought I had found the missing detail when I read about pData->m_bMenuChanged = true in a Prof-UIS article, but that didn’t solve the problem.

What should I do to make the menu immediately show the changes?

Cheers
-- Mark

Technical Support Apr 13, 2006 - 12:16 PM

The CExtPopupMenuWnd::ItemInsert() method inserts a pop-up menu item which is based on the command description in the Command Manager. If you insert command items which do not need a reference to the command manager and which do not need to be updated with the MFC command updating mechanism, you can use the CExtPopupMenuWnd::ItemInsertCommand() method. Please try this method for building your custom pop-up menu. Otherwise you need to register your commands before building any pop-up menu.

Mark Walsen Apr 13, 2006 - 4:46 PM

I found out what the problem was and fixed it. I had already created the CExtCmdItems beforehand; so that was not the problem.

The problem is that the following two statements were in the wrong order:

pPopupMenu->ItemInsert(nDynamicCommandID, -1);
if (pCmdItem != NULL && lpszMenuItemText != NULL)
{
pCmdItem->m_sMenuText = "This is a dynamic menu item";
}

They should be:

if (pCmdItem != NULL && lpszMenuItemText != NULL)
{
pCmdItem->m_sMenuText = "This is a dynamic menu item";
}
pPopupMenu->ItemInsert(nDynamicCommandID, -1);

The ItemInsert function sets menu item text according to the CExtCmdItem::m_sMenuText, which needs to have been set before the call to ItemInsert rather than afterwards.

Thanks!
-- Mark

Technical Support Apr 14, 2006 - 9:18 AM

Yes, you are right. The statement order was wrong.