Here is an example of one potential way to format your code..........
///////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////
//
// mtlc
//
bool CExtCmdProfile::UpdateFromMenu ( HMENU hMenu,
int nResourceId,
bool bCustomize,
bool bReplaceOld,
bool bRecursive,
bool bLoadTips )
{
//////////////////////////////////////
// declare local variables
int nMenuItemCount;
int nMenuItemIdx;
CString save_LastMenuName;
CExtCmdItem * pCmdItem = NULL;
CExtCmdItem * pTestCmdItem;
MENUITEMINFO mii;
int nLen;
bool bResult;
BOOL bExist;
int iCustomizables;
int iCustomizable;
bool yesAdd;
if ( hMenu == NULL )
{
return false;
}
if ( !( ::IsMenu ( hMenu ) ) )
{
return false;
}
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
//
// loop through each of the menu items.........this will get the
// primary top level items for this menu
//
nMenuItemCount = ::GetMenuItemCount ( hMenu );
for ( nMenuItemIdx = 0; nMenuItemIdx < nMenuItemCount; nMenuItemIdx++ )
{
//////////////////////////////
// want this definition within the loop
// so we get a fresh copy for every command
// several lines of code are dependent upon detecting
// a blank menutext
CExtCmdItem _cmd;
CExtSafeString sMenuText;
// get the menu item info
::memset ( &mii, 0, sizeof ( MENUITEMINFO ) );
mii.cbSize = sizeof ( MENUITEMINFO );
mii.fMask = MIIM_CHECKMARKS |
MIIM_DATA |
MIIM_ID |
MIIM_STATE |
MIIM_SUBMENU |
MIIM_TYPE;
mii.cch = __MAX_UI_ITEM_TEXT;
mii.dwTypeData = sMenuText.GetBuffer ( __MAX_UI_ITEM_TEXT );
ASSERT ( mii.dwTypeData != NULL );
if ( mii.dwTypeData == NULL )
{
ASSERT ( FALSE );
////////////////////////////
// bad data type --> jump to next item
continue;
}
///////////////////////////////////////////////////////////////
// this call will load the menu text
if ( !::GetMenuItemInfo ( hMenu, nMenuItemIdx, TRUE, &mii ) )
{
sMenuText.ReleaseBuffer ();
ASSERT ( FALSE );
////////////////////////////
// could not get item information -->jump to next item
continue;
}
sMenuText.ReleaseBuffer ();
if ( ( mii.fType & MFT_SEPARATOR ) != 0 )
{
////////////////////////////
// this is a separator --> jump to next item
continue;
}
//////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////
// if sub-menu process it recursively
if ( mii.hSubMenu != NULL )
{
if ( !bRecursive )
{
////////////////////////////
// should not be here --> jump to next item
continue;
}
/////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////
// after this call...want to reset the g_LastMenuName value
bResult = UpdateFromMenu ( mii.hSubMenu, nResourceId, bCustomize, bReplaceOld, true, true );
////////////////////////////
// done with this submenu --> jump to next item
continue;
} // if( mii.hSubMenu != NULL )
// register command
if ( ! CExtCmdManager::IsCommand ( mii.wID ) )
{
////////////////////////////
// invalid command --> jump to next item
continue;
}
///////////////////////////////////////////////////////
// if this is menuItem 0, then this is the parent of all of the
// children
_cmd.m_nCmdID = mii.wID;
sMenuText.Replace ( _T ( "\n" ), _T ( "" ) );
sMenuText.Replace ( _T ( "\r" ), _T ( "" ) );
sMenuText.Replace ( _T ( "&" ), _T ( "" ) ); // mtlc
sMenuText.TrimLeft ();
sMenuText.TrimRight ();
/////////////////////////////////////////
// begin mtlc additions
_cmd.m_fromMenu = 1;
_cmd.m_fromToolBar = 0;
_cmd.m_menuIds.Add ( ( UINT ) nResourceId );
// end mtlc additions
/////////////////////////////////////////
if ( !sMenuText.IsEmpty () )
{
int nSep = sMenuText.ReverseFind ( _T ( ’\t’ ) );
if ( nSep >= 0 )
{
nLen = sMenuText.GetLength ();
///////////////////////////////////////////////////////
// parse the accellerator
_cmd.m_sAccelText = sMenuText.Right ( nLen - nSep );
_cmd.m_sAccelText.TrimLeft ();
_cmd.m_sAccelText.TrimRight ();
////////////////////////////////////////////////////////
// virtual key codes
if ( _cmd.m_sAccelText.GetLength () > 0 )
{
_cmd.m_HotKey.StringToVirtual ( _cmd.m_sAccelText );
} // end of translate to the internal virtual key code structure
//////////////////////////////////////////////////
// parse the menu text
_cmd.m_sMenuText = sMenuText.Left ( nSep );
_cmd.m_sMenuText.TrimLeft ();
_cmd.m_sMenuText.TrimRight ();
}
else
{
_cmd.m_sMenuText = sMenuText;
}
} // if( ! sMenuText.IsEmpty() )
//////////////////////////////////////
// load the tool tips
if ( bLoadTips )
{
_cmd.TipsLoad ();
}
/////////////////////////////////////////////////
// do the actual storage
bResult = CmdSetup ( _cmd, bReplaceOld );
//////////////////////////////////////////////////////////////////////
// do we want to add this to the customizable command list?
// if so, then do not add it more than once for the same command id
if ( bCustomize == true )
{
bExist = m_cmds.Lookup ( _cmd.m_nCmdID, pCmdItem );
if ( bExist == TRUE )
{
yesAdd = true;
iCustomizables = m_CustomizableCommands.GetCount ();
for ( iCustomizable = 0; iCustomizable < iCustomizables; iCustomizable++ )
{
pTestCmdItem = ( CExtCmdItem * ) m_CustomizableCommands.GetAt ( iCustomizable );
if ( pTestCmdItem->m_nCmdID == pCmdItem->m_nCmdID )
{
yesAdd = false;
break;
}
} // end of this customizable
if ( yesAdd == true )
{
m_CustomizableCommands.Add ( pCmdItem );
} // end of we had not seen this command before.
} // end of this is a valid command
} // end of remember this customizable command
} // for all menu level items
/////////////////////////////////
// all done
return true;
}
// end of UpdateFromMenu method
//////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////
//
//
// mtlc...
// this is the primary method that in in the ’Call From App’
// chain
//
bool CExtCmdProfile::UpdateFromMenu ( UINT nResourceID,
CExtCmdManager * parentMgr,
bool bCustomizable,
bool bReplaceOld,
bool bLoadTips )
{
///////////////////////////////////////
// declare local variables
CMenu *menu;
MENUINFO *menuInfo;
bool bResult;
menuCustomize *newMenuCustomizer;
__PROF_UIS_MANAGE_STATE;
menu = new CMenu ();
if ( !g_ResourceManager->LoadMenu ( *menu, nResourceID ) )
{
ASSERT ( FALSE );
return false;
}
///////////////////////////////////////////////////////
// mtlc
// want to get the information about this menu, and remember
// this menu in the ’customizable’ list.
if ( bCustomizable == true )
{
//////////////////////////////////////////////////
// create the structures
newMenuCustomizer = new menuCustomize ();
menuInfo = new MENUINFO ();
::memset ( menuInfo, 0, sizeof ( MENUINFO ) );
menu->GetMenuInfo ( menuInfo );
////////////////////////////////////////////////////////////
// remember it
newMenuCustomizer->bCustomizable = bCustomizable;
newMenuCustomizer->pProfile = this;
newMenuCustomizer->theParentMenu = menu;
newMenuCustomizer->menuInfo = menuInfo;
newMenuCustomizer->nResourceId = nResourceID;
newMenuCustomizer->MenuName = "No Name Supplied";
parentMgr->m_CustomizableMenus.Add ( newMenuCustomizer );
} // end of customizable menu
///////////////////////////////////////////////////////////////////////////////////////
// pass it along to the method that will actually do the work
bResult = UpdateFromMenu ( menu->GetSafeHmenu (), nResourceID, bCustomizable, bReplaceOld, true, bLoadTips );
//////////////////////////////////////
// if not customizable...release the menu class object
if ( bCustomizable != true )
{
delete menu;
}
/////////////////////////
// all done
return bResult;
} // end of UpdateFromMenu method