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 » Controls with same ID but different icon/label? Collapse All
Subject Author Date
Robert Webb Oct 21, 2008 - 1:20 AM

It’s not uncommon to have two controls in the interface which lead to the same command, however Prof-UIS wants to give them all the same label, which is not always appropriate.



For example, my main menu may have "Tools->Render->Options" whereas elsewhere the same item may be accessible via a small menu that opens off a toolbar button, and there the item may be labelled "Render Options".  The point being that the label is different for those two items (the label for the first item just being "Options").



We have quite a few examples like this in our interface.  But when I change the label on one item, Prof-UIS changes the other too.  OK, if I tell it to change the label for a specific command ID that would make sense, but when I set the label for a given menu item, it should not change others with the same ID.  And if I load a new menu, it should not change existing menu labels where IDs match.



Same applies to toolbar buttons too, where icons and text are both forced to be the same where IDs match.



This would be a good default, but is it really impossible to avoid for specific controls?



Thanks,

Rob.

Technical Support Nov 3, 2008 - 1:57 PM

Your task requires a different solution. You cannot use generated HMENU as is because customizable toolbars and menus are based on command tree nodes rather than on Win32 menu handles. You should code a small recursive function which creates command tree nodes with CExtCustomizeCmdTreeNode objects created from the generated menu tree structure. The root of this command tree should be the one which corresponds to a toolbar button. If this node has child nodes, the toolbar button is a drop-down button. The child nodes will be used for creating a popup menu displayed by this toolbar button. This task requires knowing additional details because of:

1) The user can drag-n-drop and clone toolbar buttons and menu items:

2) Each toolbar has two command trees: initial and current. The current one describes displayed buttons and sub menus. The initial one is used for resetting the toolbar by re-creation of the current tree from the initial one.

There is an alternative and not complicated approach for displaying your dynamically constructed HMENU tree. You can use some command with known ID_MY_MARKER_COMMAND identifier in menus and handle the CExtPopupMenuWnd::g_nMsgPrepareOneMenuLevel registered message which allows you to construct and/or modify each popup menu sub level between it will appear first time on the screen. Your handler method will search for the ID_MY_MARKER_COMMAND menu command item, remove it and insert menu items from your dynamically constructed HMENU tree into the same place. For instance, the DRAWCLI sample application have such marker items in menus where you can see the Recent File marker menu item in File menu and OLE VERBS GO HERE maker command in Edit menu of menu bar. This approach automatically solves all the issues related to cloned copies of the ID_MY_MARKER_COMMAND command in all the menus. You can use the CExtPopupMenuWnd::ItemInsertCommand() method for dynamic menu construction. You can assign icons to menu items which are not based in the command manager. You can get icons from the command manager using the CExtCmdManager::CmdGetIconPtr() method. This approach allows you to construct fully working menus identical to your your dynamically constructed HMENU tree.

Robert Webb Nov 5, 2008 - 12:15 AM

I tried your idea of creating a tree of CExtCustomizeCmdTreeNode.  But now my buttons don’t appear as drop-downs at all.


I’m calling CExtBarButton::SetBasicCmdNode() with the root of my CExtCustomizeCmdTreeNode tree.  I have deleted the customization data (which we have in a file rather than the registry).  I’m also calling CExtBarButton::SetSeparatedDropDown() and CExtBarButton::SetAutoChangeID() and CExtCmdItem::StateSetSeparatedDD(), but none of these make a difference.  The button no longer has a drop-down.


Any ideas?


Thanks,

Rob.

Technical Support Nov 7, 2008 - 5:05 AM

We think we can help you better if you describe your task as a list of several items so we can try to implement it in a test project or in any of our sample applications. Alternatively, you can send us your test or real project so we can check what’s wrong.

Robert Webb Nov 5, 2008 - 4:28 PM

This forum makes it difficult to spot new posts, so I’m not sure if you saw my second reply yesterday:


==========================

I tried your idea of creating a tree of CExtCustomizeCmdTreeNode.  But now my buttons don’t appear as drop-downs at all.


I’m calling CExtBarButton::SetBasicCmdNode() with the root of my CExtCustomizeCmdTreeNode tree.  I have deleted the customization data (which we have in a file rather than the registry).  I’m also calling CExtBarButton::SetSeparatedDropDown() and CExtBarButton::SetAutoChangeID() and CExtCmdItem::StateSetSeparatedDD(), but none of these make a difference.  The button no longer has a drop-down.


Any ideas?

==========================


It seems like this method should be less convoluted than the other, but I can’t even get the button to show a drop-down.  What am I missing?  Is there a sample that uses this method?


Thanks,

Rob.

Technical Support Nov 7, 2008 - 5:06 AM

We think we can help you better if you describe your task as a list of several items so we can try to implement it in a test project or in any of our sample applications. Alternatively, you can send us your test or real project so we can check what’s wrong.

Robert Webb Nov 4, 2008 - 5:39 PM

Thanks for the suggestion.  However we’d like our toolbar drop-down menus to be tear-offs, and it seems that the second technique you describe (using g_nMsgPrepareOneMenuLevel) might have problems with that.  Is that right?  Would the first technique work? (Create tree of CExtCustomizeCmdTreeNode).


Thanks,


Rob.

Technical Support Nov 5, 2008 - 12:41 PM

No. We need to explain you some details about tear-off menus:

1) Tear-off menu can be connected to any CExtControlBar-based control bar - not only to CExtToolControlBar toolbar.

2) The CExtPopupMenuWnd should have the TPMX_TEAROFF flag (you can set it using the CExtPopupMenuWnd::TrackFlagsSet() method) and the CExtPopupMenuWnd::_IsTearOff() virtual method should return true value. In case of non-customizable menus you will need to use your own-derived class and implement this virtual method. This is convenient if your popup menus are created dynamically. You can insert your popup menu class instance as sub-menu into other popup menu using the CExtPopupMenuWnd::ItemInsertSpecPopup() method.

3) The window which handle is specified in the hWndCmdRecv parameter in invocation of the CExtPopupMenuWnd::LoadMenu(), CExtPopupMenuWnd::UpdateFromMenu() or CExtPopupMenuWnd::CreatePopupMenu() should handle the CExtPopupMenuWnd::g_nMsgTearOff registered message like the CExtCustomizeSite::OnHookWndMsg() method does. It should initialize the m_hWndTearOff property of data structure passed in message parameters with window handle of control bar window used in tear off effect tracking.

That’s all.

Technical Support Oct 21, 2008 - 1:09 PM

By default all toolbar buttons and menu items are based on CExtCmdItem command descriptions in the command manager. In the case of menus, it’s possible to initialize menu command items which are not based on command manager by using the CExtPopupMenuWnd::ItemInsertCommand() API instead of the CExtPopupMenuWnd::ItemInsert () API or by specifying true in the bNoRefToCmdMngr parameter of the CExtPopupMenuWnd::LoadMenu() and CExtPopupMenuWnd::UpdateFromMenu() APIs. In case of customizable toolbars and menus you can specify unique toolbar/menu texts using the CExtCustomizeCmdTreeNode::SetTextInToolbar() and CExtCustomizeCmdTreeNode::SetTextInMenu() APIs.

Robert Webb Oct 21, 2008 - 10:56 PM

Thanks for the tip, however I’m a bit lost.  The menus in question are created on the fly (in code, not from a resource) using plain old CMenu and AppendMenu() to add items.  Somewhere down the track I guess Prof-UIS gets itself involved somehow and changes my menu labels (if their IDs are also used elsewhere).



Are menu items subclasses as Prof-UIS classes at some point?  What call does that?  Is there a way to get the label set with CMenu::AppendMenu() to stick?  Or will I need to do something later after Prof-UIS has done its thing to turn them back?


Also, I have a similar problem with buttons on the ribbon bar.  Same command ID, but should show a different icon in different places.  If worse comes to worst, I can use different IDs, but I’m curious about whether it can be done with the same IDs (and using different IDs won’t be so easy for me with the menu problem).



Thanks,

Rob.

Robert Webb Oct 28, 2008 - 7:07 PM

Hi,



Still waiting for feedback on this.



Currently we create a menu using CMenu::CreateMenu() & CMenu::CreatePopupMenu(), and add items using CMenu::AppendMenu().  We then attach the menu to a toolbar button using CExtToolControlBar::SetButtonMenu(buttonIndex, menu.Detach()).



So we don’t use Prof-UIS calls to create the menu, but the command manager still manages to change their labels, so I presume somewhere down the track Prof-UIS subclasses my menus from Prof-UIS classes.  Is this the case?  If so, what call does this?



It looks like maybe I can create the menu using Prof-UIS calls instead by creating a CExtPopupMenuWnd, then using ItemInsert() or ItemInsertCommand() to populate it.  Then how do I access an item after creating it in order to call CExtCustomizeCmdTreeNode::SetTextInMenu() as you suggest?  And how do I put the whole menu on a toolbar button?  SetButtonMenu() requires a HMENU.



Thanks,

Rob.

Technical Support Oct 30, 2008 - 4:26 AM

We are sorry for the delay with this reply. By default all the menu command items are based on CExtCmdItem command descriptions stored in a CExtCmdProfile command profile inside the CExtCmdManager command manager (the g_CmdManager global smart pointer variable). The CExtCmdItem object contains all the text properties of a command. The CExtCmdProfile command profile also contains the CExtCmdIcon icon objects which can be optionally assigned to commands. You are constructing menus dynamically. This approach is OK. But please ensure the dynamically constructed menu commands have command identifiers which are not intersected with statically defined menu commands in the menu resources of your projects. Prof-UIS uses the 29000 . . . 31000 range of identifiers for everything including menu commands, toolbar commands and any resource identifiers. It’s also not recommended to intersect with this range.

It’s also possible to use you dynamically constructed menus without changing dynamically generated identifiers of menu commands. The CExtPopupMenuWnd popup menu also supports menu command items which are not based on the command manager. Such menu command items should be inserted into popup menu using the CExtPopupMenuWnd::ItemInsertCommand() method (instead of the CExtPopupMenuWnd::ItemInsert() method) or using the false value in the bNoRefToCmdMngr parameter of the CExtPopupMenuWnd::LoadMenu() and CExtPopupMenuWnd::UpdateFromMenu() methods.

Robert Webb Oct 30, 2008 - 5:48 PM

Hmm, this is restating what you previously said and not answering my questions.

What we want to do: dynamically create a menu which will appear as a drop-down from a toolbar button, and allow it to use the same ID as items in the main menu and same icon, but with different text.

Currently we use native MFC: CMenu::CreateMenu(), CMenu::CreatePopupMenu(), and CMenu::AppendMenu().  Is it correct that there’s no way to stop Prof-UIS from replacing their text if their IDs match other controls?

If that’s the case we need to create them using Prof-UIS commands.  ItemInsertCommand() is probably not for us, since we would still like some attachment to the command manager (eg inherit icon defined for other control).  So your alternative suggestion was to use SetTextInMenu().  For this we need a pointer to a menu item as a CExtCustomizeCmdTreeNode.  So one of my previous questions was how to do this.

It looks like maybe we can call the undocumented CExtPopupMenuWnd::_CmdNodeGet() to get the root node and its children may hopefully be the menu items?

Next puzzle however is how to attach the CExtPopupMenuWnd as a drop-down for a toolbar button.  For that we need to call SetButtonMenu(), but that takes an HMENU as an argument, which brings me back to my other previous question.  Is there an underlying HMENU we can access from a CExtPopupMenuWnd?  I notice the ExportToMenu() method, but I presume this re-creates the whole menu rather than giving access to the existing one.  So how do we attach a CExtPopupMenuWnd menu as a drop-down for a toolbar button?

Thanks,

Rob.