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 }