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;
}