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
}



Comments

  • Return false if base menu null?

    Posted by David Carr on 03/15/2017 12:21pm

    Further to Legacy's post, shouldn't the code also return false if pBaseMenu is NULL? if (pBaseMenu == NULL) { // Sorry, Wrong Number pMenu = NULL; // LEGACY's CORRECTION mpos = -1; return false; // RETURN FALSE }

    Reply
  • Just what I needed

    Posted by Legacy on 03/25/2003 12:00am

    Originally posted by: moodboom

    Too bad this isn't part of CMenu, thanks for filling that gap.

    Reply
  • undefined function SetMenuState( newID, MF_ENABLED )

    Posted by Legacy on 09/29/1999 12:00am

    Originally posted by: zhiwen

    Undefined function SetMenuState( newID, MF_ENABLED )on VC 6.0;
    
    

    Another bug is at:
    // That was not an legal Menu/Position-Combination
    pMenu == NULL;
    mpos = -1;
    return true;

    it sould be:
    pMenu = NULL;
    ...

    To prevent from inserting twice:

    if (!FindMenuPos( pMenu, ID_DUMPRECORD, pmMenu, m_Pos ))
    {
    FindMenuPos( pMenu, ID_FILE_SAVE_AS, pmMenu, m_Pos );

    m_Pos += 2;

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

    Reply
  • what if menu is defined twice?

    Posted by Legacy on 10/30/1998 12:00am

    Originally posted by: Corey House

    So what happens if you have a menu item defined twice in the menu, does this only return the first one?

    Reply
Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • Enterprise cloud adoption has evolved rapidly from fringe curiosity to the mainstream. As enterprises increasingly move mission-critical workloads to the cloud, it's important to track best practices to ensure a seamless migration process. While CIOs are becoming increasingly mature and pragmatic in their approach to cloud, surprises and challenges still need to be addressed. Read this eBook to learn the key best practices for cloud deployment success, the importance of SLAs in choosing a cloud provider, and …

  • This IDC study assists senior IT leaders in assessing the current state of their hybrid cloud management processes, governance models, technologies, and skills to identify gaps and create a road map for better aligning the organization's management model and tools with the emerging needs of complex, dynamic self-service hybrid cloud environments. This IDC MaturityScape identifies five maturity stages for hybrid cloud management based on a set of specific people, process, and technology dimensions and outcomes. …

Most Popular Programming Stories

More for Developers

RSS Feeds

Thanks for your registration, follow us on our social networks to keep up-to-date