Finding a menuitem from 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
}

More by Author

Get the Free Newsletter!

Subscribe to Developer Insider for top news, trends & analysis

Must Read