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 Tech Support » TBN_DROPDOWN for dynamic creation of menus for drop down buttons within a toolbar... Collapse All
Subject Author Date
Art Poley Sep 9, 2004 - 11:15 AM

Hello...

 

I need to be able to dynamically generate menus for a dropdown button within a CExtToolControlBar.  Previously, I would simply do the following:

 

ON_NOTIFY(TBN_DROPDOWN, IDR_VIEWTOOLBAR, OnDropDown)

 

 m_wndToolBar.GetToolBarCtrl().SetExtendedStyle( TBSTYLE_EX_DRAWDDARROWS );
 TBBUTTONINFO tbi;
 tbi.dwMask= TBIF_STYLE;
 tbi.cbSize= sizeof(TBBUTTONINFO);
 m_wndToolBar.GetToolBarCtrl().GetButtonInfo(ID_VIEW_SETCURRENTVIEW, &tbi);
 tbi.fsStyle |= TBSTYLE_DROPDOWN;
 m_wndToolBar.GetToolBarCtrl().SetButtonInfo(ID_VIEW_SETCURRENTVIEW, &tbi);

 


void CMainFrame::OnDropDown(NMHDR* pNotifyStruct, LRESULT* pResult)
{

   // Create & track my menu here...

}

 

With Prof-UIS, I can get a menu associated with a button via:

 

 CMenu _menu;
 VERIFY( _menu.LoadMenu(IDR_VIEWMENU) );
 int nBtnIdx = m_wndViewToolBar.CommandToIndex(ID_VIEW_SETCURRENTVIEW);
 m_wndViewToolBar.SetButtonMenu( nBtnIdx, _menu.Detach() );
 CExtBarButton* pButton = m_wndViewToolBar.GetButton(nBtnIdx);
 pButton->SetNoRotateVerticalLayout();
 pButton->SetSeparatedDropDown();

 

What I need is to be able to dynamically create a menu for the button whenever a dropdown occurs for that button.  How do I do this in Prof-UIS?

 

Thanks in advance,

 

*** Art Poley ***

Technical Support Sep 10, 2004 - 3:59 AM

Dear Art,

Yes, you can construct Prof-UIS popup menus dynamically and modify any kind of menus on-the-fly (those dropped down from toolbar/menu bar buttons or context menus). We advise you to use pre-defined command identifiers. For example, MFC uses the standard ID_FILE_MRU_FILE1 command identifier in menus to replace it with the list of recent files dynamically when a popup menu appears on the screen. So, add some IDR_MY_POPUP_MENU menu resource to your project. This menu should contain one popup item with one command inside. Let this command be identified by ID_MY_DYNAMIC_LIST. At runtime, the item specified with ID_MY_DYNAMIC_LIST should be replaced with a list of your custom commands and/or popup submenus. In the CMainFrame::OnCreate() update the command manager and assign the popup menu to some button in the toolbar:

VERIFY(
g_CmdManager->UpdateFromMenu(
    pApp->m_pszProfileName, // command profile name string
    IDR_MY_POPUP_MENU // resource ID of button’s popup menu
       )
     );
. . .
INT nBtnIdx =
   m_wndToolBar.CommandToIndex(
   ID_MY_BUTTON_THAT_SHOULD_HAVE_MENU
    );
ASSERT( nBtnIdx >= 0 );
CMenu my_button_menu;
VERIFY( my_button_menu.LoadMenu( IDR_MY_POPUP_MENU ) );
VERIFY( 
  m_wndToolBar.SetButtonMenu( nBtnIdx, my_button_menu.Detach() ) 
     ); 


Now let’s add a message handler for the CExtPopupMenuWnd::g_nMsgPrepareMenu registered windows message. This will allow you to modify any menus on-the-fly. Add this line to the CMainFrame class declaration:<code>
afx_msg LRESULT OnExtMenuPrepare(WPARAM wParam, LPARAM lParam); 
and this entry to to the frame’s message map:
ON_REGISTERED_MESSAGE(
   CExtPopupMenuWnd::g_nMsgPrepareMenu,
   OnExtMenuPrepare
 ) 


Here is the method’s body:
LRESULT CMainFrame::OnExtMenuPrepare(WPARAM wParam, 
  LPARAM lParam)
{
CExtPopupMenuWnd::MsgPrepareMenuData_t * pData 
 =  reinterpret_cast < 
        CExtPopupMenuWnd::MsgPrepareMenuData_t * 
     > ( wParam );
ASSERT( pData != NULL );
CExtPopupMenuWnd * pPopup = pData->m_pPopup;
ASSERT( pPopup != NULL );
// NOW WE CAN FIND AND REMOVE THE PREDEFINED COMMAND
INT nItemPos = pPopup->ItemFindPosForCmdID( ID_MY_DYNAMIC_LIST )
if( nItemPos >= 0 )
{ // if the predefined command was found
 pPopup->ItemRemove( nItemPos );
// NOW WE CAN INSERT ANY OTHER ITEMS AT nItemPos POSITION
 pPopup->ItemInsert(  command_identifier, nItemPos );
 // or
 pPopup->ItemInsertCommand(  command_identifier, nItemPos );
} // if the predefined command was found
} 


Please note that the CMainFrame::OnExtMenuPrepare() method is called only once for each popup menu tree (NOT for each popup menu sublevel!). So, in the general case the routing of dynamic menu initialization is a recursive function. You need to use pPopup->ItemInsert() if your commands are registered in the command manager or pPopup->ItemInsertCommand() otherwise.