Professional UI Solutions
Site Map   /  Register
 
 

Forum

Please Log In to post a new message or reply to an existing one. If you are not registered, please register.

NOTE: Some forums may be read-only if you are not currently subscribed to our technical support services.

Forums » Prof-UIS General Discussion » Adding A Top-Level Menu To View/Doc Menu Collapse All
Subject Author Date
John Burns Jan 11, 2005 - 1:59 PM

 


Could you please give some hints or examples as to how to add a new top-level popup menu to the View/Doc menu (not IDR_MAINFRAME).


It would also be handy to know how to insert the new popup menu in a particular location - e.g. between ’Edit’ & ’View’ or between ’View’ and whatever is next.


Thank you,


John A. Burns


 

Sergiy Lavrynenko Jan 12, 2005 - 11:26 AM

Dear John,

The CExtMenuControlBar window is the kind of the CExtToolControlBar window, i.e. menu bar is based on toolbar. So, the top-level submenu menu in the menu bar is implemented as the set of toolbar buttons (the CExtBarButton-based objects). Each toolbar button has own popup menu. The set of menu bar’s buttons is initialized only once in the SDI frame window or in the dialog. The menu line in the MDI applications is automatically changed when user opens or closes the MDI child windows or switches between them. The CExtMenuControlBar object destroys its entire buttons and creates new ones when it had to display new menu line. This operation is implemented in the CExtMenuControlBar::_UpdateMenuBar() internal virtual method which you may override. Your method should be based on the source code of the base method and finally insert some your custom buttons into required positions. Please note, each button in toolbar or menu bar should have own command identifier and the command item in the command manager with the same identifier. The menu bar automatically allocates the command identifiers for entire its buttons with invoking of g_CmdManager->CmdAllocPtr(). It also marks all the dynamically allocated commands with invoking of pCmdItem->StateSetMenubarTemp(). Last is essential for MDI applications where all the buttons of the menu bar needs to be re-created and, as result, the commands of the deleted buttons need to be de-allocated. But your application may allocate some number of command items preliminary if the maximal count of custom popup items is not changed at run-time.

The modification of popup menu items can be done on-the-fly immediately before any popup window become displayed on the screen. You should handle the CExtPopupMenuWnd::g_nMsgPrepareMenu registered windows message in your main frame window. This is demonstrated in the DRAWCLI sample application where the main frame window handles this message in the CMainFrame::OnExtMenuPrepare() method and re-sends it to the active view window that performs the menu modification in the similar message handler method. Please do not forgot to include the following lines into the message map of your frame/view classes:

    ON_REGISTERED_MESSAGE(
        CExtPopupMenuWnd::g_nMsgPrepareMenu,
        OnExtMenuPrepare
        )

Best regards, Sergiy.

John Burns Jan 14, 2005 - 9:27 AM

 


Thank you Sergiy, the solution was fairly easy to implement, and works as advertised.


I do, however, have another related question:


During the CExtMenuControlBar::_UpdateMenuBar() method would it be possible to add items to the menu button submenus? Actually, I would like to add items to a main menu button submenu item that is actually a submenu itself?


Is it possible to iterate over the items and submenus etc. in the CExtMenuControlBar::_UpdateMenuBar method?


Once again, thanks!


John Burns


 

Sergiy Lavrynenko Jan 14, 2005 - 11:25 AM

Ok John, I assume you have created the CYourMenuControlBar class that is derived from CExtMenuControlBar and the _UpdateMenuBar() virtual method was overridden but has the same body as in base class. Here is the bottom part of the CYourMenuControlBar::_UpdateMenuBar() method:

 } // else from if( pMenuInfo != NULL )
 if( _IsMdiApp() )
 {
  if( !IsOleIpObjActive() )
   if( _InstallMdiDocButtons( FALSE ) )
    bDoRecalcLayout = TRUE;
  VERIFY( _SyncActiveMdiChild() );
 }
 
 if( bDoRecalcLayout )
 {
  Invalidate();
  _RecalcLayoutImpl();
  UpdateWindow();
 }
 return TRUE;

Immediately before these lines, please insert the following code:
 // allocate dynamic command
 CExtCmdItem * pCmdItem =
  g_CmdManager->CmdAllocPtr(
   g_CmdManager->ProfileNameFromWnd(
    GetSafeHwnd()
    )
   );
 if( pCmdItem == NULL )
 {
  ASSERT( FALSE );
  return FALSE;
 }
 pCmdItem->StateSetMenubarTemp();
 pCmdItem->StateSetBasic();
 pCmdItem->m_sToolbarText =
  _T("MyDynamicButton");
 // insert it into position nBtnIdx
 int nBtnIdx = 1;
 this->InsertButton(
  nBtnIdx,
  pCmdItem->m_nCmdID
  );
 // assign menu to this button
 CMenu menu;
 VERIFY(
  menu.LoadMenu(
   IDR_IED_MENU_BRUSH
   )
  );
 VERIFY(
  this->SetButtonMenu(
   nBtnIdx,
   menu.Detach()
   )
  );

It seems ... That’s all :)

Best regards, Sergiy.

John Burns Jan 15, 2005 - 4:18 AM

 


Hi Sergiy,


I’m sorry for not being more clear as to what I’m trying to do here. Perhaps if I try to demonstrate more graphically:


MyTopLevelMenu
>MyTopLevelMenuItem1
>etc
>MyTopLevelMenuSubmenu...
>>MyTopLevelMenuSubmenuItem1
>>etc
>>Insert An Item Here
>>MyTopLevelMenuSubmenuItem(y)
>MyTopLevelMenuItem(x)


To summarize, the position at which I wish to insert items, is in a submenu nested in a top level menu. Is this possible in CTMExtMenuControlBar::_UpdateMenuBar?


It would be interesting to know how to iterate over the menu items, and submenus etc.


Thanks again,


John Burns


 

Sergiy Lavrynenko Jan 15, 2005 - 6:59 AM

Dear John,


You should use the _UpdateMenuBar() method only for the topmost menu level that is implemented as a set of toolbar buttons in the menu bar. You should handle the CExtPopupMenuWnd::g_nMsgPrepareMenu registered windows message for any other menu levels. Please note, this message sent only once for the top level of each popup menu tree. So, your message handler may need to invoke some recursive function which will analyze the whole popup menu tree and modify it as required. I recommend you to insert some pre-defined commands into your menu and then find them on any popup menu sublevel, remove and insert useful commands in the same place. This technique is used in the most recently used (MRU) file list implementation of MFC where the ID_MRU_FILE_FIRST command is replaced with a set of commands for opening MRU files on-the-fly.

Best regards, Sergiy.