Finding a menuitem from command id

WEBINAR: On-demand webcast

How to Boost Database Development Productivity on Linux, Docker, and Kubernetes with Microsoft SQL Server 2017 REGISTER >

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

  • The software-defined data center (SDDC) and new trends in cloud and virtualization bring increased agility, automation, and intelligent services and management to all areas of the data center. Businesses can now more easily manage the entire lifecycle of their applications and services via the SDDC. This Aberdeen analyst report examines how a strong foundation in both the cloud and internal data centers is empowering organizations to fully leverage their IT infrastructure and is also preparing them to be able …

  • On-demand webcast Continuous integration and continuous deployment (CI/CD) allow DevOps teams to be more efficient. When starting from a production environment, the use of Microsoft SQL Server 2017 in Docker containers and Kubernetes clusters can facilitate a DevOps CI/CD pipeline. Using SQL Server tools also allows you to easily integrate core DevOps application lifecycle management practices to database development. Watch this on-demand presentation to learn how defining the database dependency as …

Most Popular Programming Stories

More for Developers

RSS Feeds

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