Finding a menu item position from command id

Indentify a Menupos based on it's Command-ID

This is taken from a Doc/View-App that is mostly straight from the AppWizard of VC5.

I recently got the Problem, that I had to insert Menuitem at a specific position _below_ a defined MenuItem. Unfortunaletly I found no easy way to enumerate all item in the menubar, so I had to do it myself. In MFC there is a func to get the Command-ID if you know the Menu and Position but no func gives you the Menu and the Menupos from the CommandID :-(

This function will find the first menu item with the given command id looping through the submenu until it is found. 

It is used like this:

CWnd* pWnd = AfxGetMainWnd();

CMenu *pMenu = pWnd->GetMenu();

int m_Pos = 0;

CMenu *pmMenu = pMenu;

// Insert the Menuitem ID_DUMPRECORD exactly 2 Positions below FileSaveAs

FindMenuPos( pMenu, ID_FILE_SAVE_AS, pmMenu, m_Pos );

m_Pos += 2;

InsertMenu(pmMenu, m_Pos, MF_BYPOSITION, ID_DUMPRECORD, "Print Record" );

with a little Hack for InsertMenu:

void CMainFrame::InsertMenu(CMenu* pMenu, UINT oldID, int Flags, UINT newID, const char * MenuText)

{

if( pMenu == NULL )     return;

if(pMenu->GetMenuState( newID, Flags) == 0xFFFFFFFF )

pMenu->InsertMenu(oldID, Flags, newID, MenuText );

else

SetMenuState( newID, MF_ENABLED );

}

void CMainFrame::InsertMenu(UINT oldID, int Flags, UINT newID, const char * MenuText)

{

CWnd* pWnd = AfxGetMainWnd();

CMenu *pMenu = pWnd->GetMenu();

InsertMenu(pMenu, oldID, Flags, newID, MenuText);

}

So that my InsertMenu inserts the MenuItem if it dos not exist, if it exist, it will be enabled.

Find a specific Menupos based on the Command-ID

I havn't cheched it with cascading submenues, but IF MS tells the truth about their MFC-functions, there should be no problems.

bool CMainFrame::FindMenuPos(CMenu *pBaseMenu, UINT myID, CMenu * & pMenu, int & mpos)

{

// REMARK: pMenu is a pointer to a Cmenu-Pointer

int myPos;

if( pBaseMenu == NULL )

{

// Sorry, Wrong Number

pMenu == NULL;

mpos = -1;

return true;

}

for( myPos = pBaseMenu->GetMenuItemCount() -1; myPos >= 0; myPos-- )

{

int Status = pBaseMenu->GetMenuState( myPos, MF_BYPOSITION);

CMenu* mNewMenu;

if( Status == 0xFFFFFFFF )

{

// That was not an legal Menu/Position-Combination

pMenu = NULL;

mpos = -1;

return true;

}

// Is this the real one?

if( pBaseMenu->GetMenuItemID(myPos) == myID )

{

// Yep!

pMenu = pBaseMenu;

mpos = myPos;

return true;

}

// Maybe a subMenu?

mNewMenu = pBaseMenu->GetSubMenu(myPos);

// This function will return NULL if ther is NO SubMenu

if( mNewMenu != NULL )

{

// rekursive!

bool found = FindMenuPos( mNewMenu, myID, pMenu, mpos);

if(found)

return true; // return this loop

}

// I have to check the next in my loop

}

return false; // iterate in the upper stackframe