Merging Two Menus
Posted
by Oskar Wieland
on March 20th, 1999
void MergeMenu( CMenu* pMenuDestination, CMenu* pMenuAdd, bool bTopLevel /*=false*/ )
{
// Abstract:
// Merges two menus.
//
// Parameters:
// pMenuDestination - [in, retval] destination menu handle
// pMenuAdd - [in] menu to merge
// bTopLevel - [in] indicator for special top level behavior
//
// Comments:
// This function calles itself recursivley. If bTopLevel is set to true,
// we append popups at top level or we insert before <Window> or <Help>.
// get the number menu items in the menus
int iMenuAddItemCount = pMenuAdd->GetMenuItemCount();
int iMenuDestItemCount = pMenuDestination->GetMenuItemCount();
// if there are no items return
if( iMenuAddItemCount == 0 )
return;
// if we are not at top level and the destination menu is not empty
// -> we append a seperator
if( !bTopLevel && iMenuDestItemCount > 0 )
pMenuDestination->AppendMenu( MF_SEPARATOR );
// iterate through the top level of <pMenuAdd>
for( int iLoop = 0; iLoop < iMenuAddItemCount; iLoop++ )
{
// get the menu string from the add menu
CString sMenuAddString;
pMenuAdd->GetMenuString( iLoop, sMenuAddString, MF_BYPOSITION );
// try to get the submenu of the current menu item
CMenu* pSubMenu = pMenuAdd->GetSubMenu( iLoop );
// check if we have a sub menu
if( !pSubMenu )
{
// read the source and append at the destionation
VERIFY( pMenuDestination->AppendMenu(
pMenuAdd->GetMenuState( iLoop, MF_BYPOSITION ),
pMenuAdd->GetMenuItemID( iLoop ),
sMenuAddString ));
}
else
{
// create or insert a new popup menu item
// default insert pos is like ap
int iInsertPosDefault = -1;
// if we are at top level merge into existing popups rather than
// creating new ones
if( bTopLevel )
// try to find existing popup
for( int iLoop = 0; iLoop < iMenuDestItemCount; iLoop++ )
{
// get the menu string from the destination menu
CString sDest;
pMenuDestination->GetMenuString( iLoop, sDest, MF_BYPOSITION );
// we got a hit -> merge the two popups
if( sMenuAddString == sDest )
{
// try to get the submenu of the desired destionation menu item
CMenu* pSubMenuDest = MenuDestination->GetSubMenu( iLoop );
if( pSubMenuDest )
{
// merge the popup recursivly and continue with for loop
MergeMenu( pSubMenuDest, pSubMenu );
continue;
}
}
// alternativ insert before <Window> or <Help>
if( iInsertPosDefault == -1 && (sDest == "&Window" || sDest == "&Help" ))
iInsertPosDefault = iLoop;
}
}
// if the top level search did not find a position append the menu
if( iInsertPosDefault == -1 )
iInsertPosDefault = pMenuDestination->GetMenuItemCount();
// create a new popup and insert before <Window> or <Help>
CMenu NewPopupMenu;
VERIFY( NewPopupMenu.CreatePopupMenu() );
// merge the new popup recursivly
MergeMenu( &NewPopupMenu, pSubMenu );
// insert the new popup menu into the destination menu
VERIFY( pMenuDestination->InsertMenu(
iInsertPosDefault,
MF_BYPOSITION | MF_POPUP | MF_ENABLED,
(UINT)NewPopupMenu.GetSafeHmenu(),
sMenuAddString ));
// don't destroy the new menu
NewPopupMenu.Detach();
}
}
}

Comments
There are no comments yet. Be the first to comment!