Inserting submenus in an existing SDI menu

In the SDI app I am working on, I needed to be able to insert a new submenu in the apps main menu based on the currently selected object. (My app uses the nested splitter code found elsewhere on CodeGuru to provide multiple views into a selected sound on an advanced MIDI soundcard). I found no information on how to do it, so after a bit of trial and error I came up with the technique shown in the following code. Please note that this code is NOT directly reusable; but it should give you an idea of what needs to be done. The submenus are all contained in a separate menubar, IDR_OBJECT_MENUS; everything else should be clear to the experienced MFC user :')
// Add a an additional popup menu to the main menu which is 
// specific to the currently selected object type. If pViewClass is NULL,
// no menu is added.
void CMainFrame::AddViewMenu(CRuntimeClass* pViewClass)
{
	const int INSERT_POSITION = 3;
	const int DEFAULT_MENU_COUNT = 6; // INCOMPLETE - change when test menu is
	removed!
		enum { PROGRAM_MENU, LAYER_MENU, KEYMAP_MENU, SAMPLE_MENU };
	
	CMenu* pMenu = GetMenu();
	ASSERT(pMenu->GetMenuItemCount() == DEFAULT_MENU_COUNT
		|| pMenu->GetMenuItemCount() == DEFAULT_MENU_COUNT + 1);
	
	// If there is already an extra menu present, remove it
	if (pMenu->GetMenuItemCount() == DEFAULT_MENU_COUNT + 1)
		pMenu->RemoveMenu(INSERT_POSITION, MF_BYPOSITION);
	
	// Now based on the specific view type, add the appropriate menu
	int iMenuToAdd = -1;
	if (pViewClass == RUNTIME_CLASS(CProgramView))
		iMenuToAdd = PROGRAM_MENU;
	else if (pViewClass == RUNTIME_CLASS(CLayerView))
		iMenuToAdd = LAYER_MENU;
	else if (pViewClass != NULL)
		ASSERT(FALSE); // INCOMPLETE - other types!
	
	if (iMenuToAdd != -1)
	{
		// get the menu to add
		CMenu objectMenu;
		objectMenu.LoadMenu(IDR_OBJECT_MENUS);
		CMenu* pPopupMenu = objectMenu.GetSubMenu(iMenuToAdd);
		ASSERT(pPopupMenu != NULL);
		
		// get its string - *^&) Windows can't figure it out for itself
		CString strMenuItem;
		objectMenu.GetMenuString(iMenuToAdd, strMenuItem, MF_BYPOSITION);
		
		// Add it
		VERIFY(pMenu->InsertMenu(INSERT_POSITION, MF_BYPOSITION | MF_POPUP, 
			(UINT)pPopupMenu->GetSafeHmenu(), strMenuItem));
		
		// remove from the other menu!
		objectMenu.RemoveMenu(iMenuToAdd, MF_BYPOSITION);
	}
	
	DrawMenuBar();
}



Comments

  • Don't get messages when adding a submenu from a DLL to the main menu!

    Posted by Legacy on 01/04/2002 12:00am

    Originally posted by: Juergen Suetterlin

    Hy folks,
    I'm trying to modify my main menu out of a dynamically loaded (runtime) DLL.

    My application uses loadlibrary() to load my DLL and can open it. The I call an exported function inside the DLL which adds a submenu to the main menu (procedure found also at codeguru). But when I select the added submenu all sub entries are grayed and the debuggers says this: "Warning: no message line prompt for ID 0x8015." but in the resource the item was alligned to an ID and the ID was alligned to a funciton.

    Can anyone help me?

    J�rgen

    Reply
  • Works fine now thnaks to Julien Roger's fix !!!

    Posted by Legacy on 07/11/2001 12:00am

    Originally posted by: Alf

    In fact it works without it on Win 95 / 98 / NT systems,
    but crashes on Win 2000 / XP systems. With the "fix" it
    works now fine !

    Reply
  • Disable a sub menu at runtime

    Posted by Legacy on 01/10/2001 12:00am

    Originally posted by: Usha

    I want to disable a sub menu at Runtime. Can u help me with that

    Thanks
    usha

    Reply
  • problem with Win95

    Posted by Legacy on 08/12/1999 12:00am

    Originally posted by: latha

    This code works fine with NT but gives an assertion failure when i try to access the sub menu in Win95. Please let me know a solution for the same.

    Reply
  • ON_UPDATE_COMMAND_UI does not work on the inserted menu

    Posted by Legacy on 03/24/1999 12:00am

    Originally posted by: David Geldreich

    If you try to associate an ON_UPDATE_COMMAND_UI on one of the command included in the inserted menu command routing will work but in ON_UPDATE_COMMAND_UI, pCmdUI->Enable(FALSE) will not work.

    It is because things like pCmdUI->m_pMenu->EnableMenuItem(pCmdUI->m_nID, MF_GRAYED|MF_DISABLED|MF_BYCOMMAND); will return -1.

    One solution is to keep a pointer to the inserted menu and do ourself, change pCmdUI->m_pMenu before calling CCmdUI functions.

    Reply
  • This doesn't work

    Posted by Legacy on 12/25/1998 12:00am

    Originally posted by: Vasu Y

    This piece of code doesn't work for me.
    It is adding the new Pop-up menu to the Main menu, but if you click on the newly added pop-up menu, it is giving a Debug-Assertion Failure.

    Can somebody help me out.
    The following is the piece of code.

    CMenu* pMainMenu = pMainFrame->GetMenu();
    short iMenuToAdd;
    iMenuToAdd = 0;
    CMenu objectMenu;
    objectMenu.LoadMenu(IDR_MENU2);
    CMenu* pPopupMenu = objectMenu.GetSubMenu(iMenuToAdd);
    ASSERT(pPopupMenu != NULL);
    short count = 0;
    count = pPopupMenu->GetMenuItemCount();
    // get its string - *^&) Windows can't figure it out for itself
    CString strMenuItem;
    objectMenu.GetMenuString(iMenuToAdd, strMenuItem, MF_BYPOSITION);

    VERIFY(pMainMenu->AppendMenu( MF_POPUP,
    (UINT)pPopupMenu->Detach(), strMenuItem));

    Reply
  • modifying SDI/MDI menus

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

    Originally posted by: Brian Smith

    Instead of
    
    

    VERIFY(pMenu->InsertMenu(INSERT_POSITION, MF_BYPOSITION | MF_POPUP,
    (UINT)pPopupMenu->GetSafeHmenu(), strMenuItem)); // remove from the other menu!
    objectMenu.RemoveMenu(iMenuToAdd, MF_BYPOSITION);

    you could call:

    VERIFY(pMenu->InsertMenu(INSERT_POSITION, MF_BYPOSITION | MF_POPUP,
    (UINT)pPopupMenu->Detach(), strMenuItem));

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

Top White Papers and Webcasts

  • One of the country's marquee events, Microsoft's annual event 'Ignite' lights up various major cities, with an average attendance of over 30,000. In 2016, the Microsoft Learning group had several mandates to incorporate different campaigns and programs into the event, under a defined budget, with limited resources, and of course, under tight timelines. Read this case study to learn how Microsoft was able to use cloud-based tools to aggregate, organize, display, and distribute content quickly, and at scale, …

  • 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