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
.
The function
calls itself
recursively
and does not
care about
consecutive
separators.
Collapse
Copy
Code
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;
}