Introduction
This function will merge two menus. This can be used for context menus as well as for top level menus. At top level known popup menus will be appended or new popups will be created before Window
or Help
. Thanks to M. Knaup (mknaup@bigfoot.de) for the modifications. The function calls itself recursively and does not care about consecutive separators.
bool
MergeMenu(CMenu * pMenuDestination, const CMenu * pMenuAdd, bool bTopLevel )
{
int iMenuAddItemCount = pMenuAdd->GetMenuItemCount();
int iMenuDestItemCount = pMenuDestination->GetMenuItemCount();
if( iMenuAddItemCount == 0 )
return true;
if( !bTopLevel && iMenuDestItemCount > 0 )
pMenuDestination->AppendMenu(MF_SEPARATOR);
for( int iLoop = 0; iLoop < iMenuAddItemCount; iLoop++ )
{
CString sMenuAddString;
pMenuAdd->GetMenuString( iLoop, sMenuAddString, MF_BYPOSITION );
CMenu* pSubMenu = pMenuAdd->GetSubMenu(iLoop);
if (!pSubMenu)
{
UINT nState = pMenuAdd->GetMenuState( iLoop, MF_BYPOSITION );
UINT nItemID = pMenuAdd->GetMenuItemID( iLoop );
if( pMenuDestination->AppendMenu( nState, nItemID, sMenuAddString ))
{
iMenuDestItemCount++;
}
else
{
TRACE( "MergeMenu: AppendMenu failed!\n" );
return false;
}
}
else
{
int iInsertPosDefault = -1;
if( bTopLevel )
{
ASSERT( sMenuAddString != "&?" && sMenuAddString != "?" );
CString sAdd( sMenuAddString );
sAdd.Remove('&'); bool bAdded = false;
for( int iLoop1 = 0; iLoop1 < iMenuDestItemCount; iLoop1++ )
{
CString sDest;
pMenuDestination->GetMenuString( iLoop1, sDest, MF_BYPOSITION );
sDest.Remove( '&' );
if( sAdd == sDest )
{
CMenu* pSubMenuDest = pMenuDestination->GetSubMenu( iLoop1 );
if( pSubMenuDest )
{
if( !MergeMenu( pSubMenuDest, pSubMenu ))
return false;
bAdded = true;
break;
}
}
if( iInsertPosDefault == -1 &&
( sDest == "Window" || sDest == "?" || sDest == "Help" ))
iInsertPosDefault = iLoop1;
}
if( bAdded )
{
continue;
}
}
if( iInsertPosDefault == -1 )
iInsertPosDefault = pMenuDestination->GetMenuItemCount();
CMenu NewPopupMenu;
if( !NewPopupMenu.CreatePopupMenu() )
{
TRACE( "MergeMenu: CreatePopupMenu failed!\n" );
return false;
}
if( !MergeMenu( &NewPopupMenu, pSubMenu ))
return false;
HMENU hNewMenu = NewPopupMenu.GetSafeHmenu();
if( pMenuDestination->InsertMenu( iInsertPosDefault,
MF_BYPOSITION | MF_POPUP | MF_ENABLED,
(UINT)hNewMenu, sMenuAddString ))
{
iMenuDestItemCount++;
}
else
{
TRACE( "MergeMenu: InsertMenu failed!\n" );
return false;
}
NewPopupMenu.Detach();
}
}
return true;
}</pmenuadd>
License
This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt, please contact the author via the discussion board below.
A list of licenses authors might use can be found here.
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.