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 » ContextMenu customized Collapse All
Subject Author Date
Stephan Finkler Jan 5, 2005 - 6:58 AM

Hi,
how can I customize a context menu?
Here my steps:
- add a menu resource ID_CONTEXT_MENU
- in OnCreate:
VERIFY( g_CmdManager->UpdateFromMenu(theApp.m_pszProfileName, ID_CONTEXT_MENU) );

VERIFY( CExtCustomizeSite::MenuInfoAdd( this,
_T("Context"),
ID_CONTEXT_MENU,
false,
false,
NULL, /* Frame */
NULL, /* View */
RUNTIME_CLASS( CGViewDoc ) /* Doc */
) );

- in the view
void CGViewView::OnContextMenu(CWnd* pWnd, CPoint point)
{
GetParentFrame()->BringWindowToTop();
HWND hWnd = GetParentFrame()->GetSafeHwnd();
ASSERT( hWnd );
CExtPopupMenuWnd *pPopupWnd = new CExtPopupMenuWnd;
ASSERT( pPopupWnd);
if( pPopupWnd && ::IsWindow(hWnd) ) {
VERIFY( pPopupWnd->LoadMenu(hWnd, IDM_CGVIEW, false) );
VERIFY( pPopupWnd->TrackPopupMenu(0, point.x, point.y) );
}
}

-----------------------------------
Now I can add per drag and drop new commands to the context menu,
but if I call the context menu with a right mouse click I get the default context menu.

How can I get the modified context menu?

Technical Support Jan 5, 2005 - 1:27 PM

Dear Stephan,

Thank you for the interesting question! Of course, you can have the customizable context menus, but their implementation requires an absolutely different approach. Please select the Toolbars tab of the Customize dialog of the Microsoft Word XP/2003. Among other toolbars, you can find the Shortcut menus toolbar. It can never be visible when the Customize dialog is open. It contains three buttons which serve for grouping numerous context menus in the Microsoft Word. All sub items of these buttons are used as root items for different context menus and you can customize any of them. To implement customizable menus in your application, you can follow the same approach. So, what you need to do is:

1. Create all pop-up menus in the menu resources and update the command manager from these menus.
2. Create the Context menus toolbar and initialize it as an ordinary toolbar in the non-customizable application. You should insert manually toolbar buttons and assign menus for them by invoking the CExtBarButton::SetMenu method.
3. The Context menus toolbar should become automatically hidden when the user closes the Customize dialog. So, set the m_bAutoHideOnCustomizationEnd property of the Context menus toolbar to true. If you want this toolbar to appear automatically when the Customize dialog is open, then set the m_bAutoShowOnCustomizationStart property of the Context menus toolbar to true.
4. All buttons in toolbars and all menu items are implemented as tree-like data structures based on the CExtCustomizeCmdTreeNode class. You need to find appropriate nodes and use them as the data sources for your context menus. To get the root node of the Context menus toolbar, invoke the CExtCustomizeSite::GetToolbarCustomizeInfo method which saves the toolbar’s root node in the ppNodeC parameter. The child nodes correspond to the toolbar’s buttons. You may find any sub node using the CExtCustomizeCmdTreeNode::SearchNode overloaded method. As a result you will get an index of the node that is used as the root node for some context menu.
5. Create your popup menus like you did, but invoke the CExtPopupMenuWnd::UpdateFromCmdTree method instead of CExtPopupMenuWnd::LoadMenu.

Please do not hesitate to contact us if you have any question

Stephan Finkler Jan 6, 2005 - 5:32 AM

5. Create your popup menus like you did, but invoke the CExtPopupMenuWnd::UpdateFromCmdTree method instead of CExtPopupMenuWnd::LoadMenu.

How can I get the pNode para in UpdateFromCmdTree(
        HWND hWndCmdRecv,
        CExtCustomizeCmdTreeNode * pNode,
        bool bTopLevel = true
        );
outside CMainframe( because OnContextMenu is handled in a View) ???

Technical Support Jan 6, 2005 - 8:52 AM

We assume your CMainFrame class is derived both from CFrameWnd or CMDIFrameWnd and from CExtCustomizeSite. To get command tree nodes, you need access the CExtCustomizeSite class methods as we described in the previous message. So, first include the MainFrm.h file into the .cpp file of your view. After that you will be able to get a pointer to the CMainFrame object that is kind of CExtCustomizeSite using the following code inside the view methods:

CMainFrame * pMainFrame =
     STATIC_DOWNCAST( pMainFrame, GetParentFrame() );
If you encounter any difficulties, please do not hesitate to send us a test project so that we can help you.