Pages: 1
Print
Author Topic: Creating a custom toolbar?  (Read 4594 times)
gcrews
Member

Posts: 265


« on: February 14, 2013, 11:55:18 AM »

How on earth are you supposed to create a custom global toolbar programmatically in a macro?
Logged
Derek Read
Program Manager (XMetaL)
Administrator
Member

Posts: 2621



WWW
« Reply #1 on: February 14, 2013, 01:29:33 PM »

You need to put your code into On_Default_CommandBars_Complete if you want to modify "global" (docs call these "default") menus and toolbars.
Logged
gcrews
Member

Posts: 265


« Reply #2 on: February 14, 2013, 06:56:21 PM »

That’s what I have been doing but I ran into a slight glitch.  If Xmetal has ever been open before, the first time that my macro creates the toolbar it does not work quite right. The first time I open Xmetal after adding my macro code to a startup file, there are 2 instances of the toolbar when you right click on the menu area as shown in the screenshot. I delete all *.tbr files from my computer after every test, so the duplicates are not leftover from the previous macro run.  Additionally if you are in any DTD specific file the menu is not visible by default. After restarting Xmetal once, the menu is visible in DTD specific documents but there are still 2 items listed when right-clicking. After restarting Xmetal again, it finally only has one new toolbar and it is visible in DTD specific documents.

Here is the code I have in the On_Default_CommandBars_Complete macro:
Code:
var cmdBars = Application.CommandBars;
var oldBar = cmdBars.item("New bar");
if(oldBar != null) {
return;
//oldBar.Delete();
}
var customBar = cmdBars.Add("New bar",sqcbPosTop);
customBar.Visible = true;

I commented out the delete line and just have it return now after reading some of the help files, seeing if that was the issue but it doesn’t seem to be. I need to be able to periodically update toolbar icons and possible add and remove items when I update our customizations.

http://xmetal.com/webhelp/en/xmetaldeveloper/pg/6.0/pg.html#When%20XMetaL%20starts%20or%20closes
“Note: Do not use CommandBarControl.Delete or CommandBar.Delete in this event macro. Also, do not create a new toolbar in this event macro.”
(I can’t tell if this is referring to the On_Application_Open macro or the On_Default_CommandBars_Complete macro)
“If you want to make modifications to the menus and toolbars, you can do it here; however, you cannot affect the visibility of toolbars from this event.”

http://xmetal.com/webhelp/en/xmetaldeveloper/pg/6.0/pg.html#Delete
“Do not use this method inside the On_Default_CommandBars_Complete event macro.”

OK…, so when you and the documentation say you can “modify” the menus in On_Default_CommandBars_Complete what exactly can you modify if you are not supposed to call .Delete(), create new toolbars, change visibility, or call .reset() ?????
The programing guide specifically says “Do not create a new toolbar in this event macro” does that mean I can create new buttons under a toolbar (oh wait I can’t remove ones though so anything I add I will never be able to delete…)?
Am I supposed to create the new menu or delete all the items on that toolbar if it exists in in On_Application_Open? Then in On_Default_CommandBars_Complete populate the toolbar or something?

Up until now it has been fine except I recently added a new toolbar for our writers and noticed the weird double behavior on someone’s computer after the customization update.

The macro has to be robust and updatable. Everything up until this point I can push out any customizations and macro file updates relatively easily.  How am I supposed to update custom toolbar customizations if the macros are only supposed to create the toolbar only once? Have my customization script delete every *.tbr file from the system every time there’s an update? 


* 2-14-2013 4-09-54 PM.gif (3.05 KB, 257x163 - viewed 533 times.)
« Last Edit: February 14, 2013, 08:07:30 PM by gcrews » Logged
Derek Read
Program Manager (XMetaL)
Administrator
Member

Posts: 2621



WWW
« Reply #3 on: February 14, 2013, 08:06:34 PM »

Here's some code I have from my own samples. There is fancier code in the DocBook sample and various other places in the XMetaL MCR files (search for On_Default_CommandBars_Complete) but our developers tend to use eval() and JScript prototypes so they can be difficult to follow (one reason they use prototypes is that allows others to override the code more easily so it comes in handy for patching macros).

Let me know if the following doesn't work for you. You should end up with a single toolbar called "My Custom Toolbar" that has two buttons, neither of which will be enabled because the OnAction property needs to point to an existing macro.

Code:
<MACRO name="On_Default_CommandBars_Complete" hide="true" lang="JScript"><![CDATA[
//check if toolbar already exists
var exists = false;
for (i=1;i<Application.CommandBars.count;i++) {
if(Application.CommandBars.item(i).name == "My Custom Toolbar") exists = true;
}

//if the toolbar doesn't exist then create it
if (!exists) {
var myToolbar = Application.CommandBars.Add("My Custom Toolbar");
//add a button to the toolbar
var newButton             = myToolbar.Controls.Add(sqcbcTypeButton);
newButton.TooltipText     = "This text will appear in a tooltip when someone hovers over the button.";
newButton.OnAction        = "Name of Macro to Run";
newButton.DescriptionText = "This is my long description. It will appear in the status bar.";
//find an icon to reference
var icon = Application.MakeFaceId("Structure (Custom)",4,1);
//assign the icon to the button
newButton.FaceId          = icon;

//add a second button to the toolbar
var newButton             = myToolbar.Controls.Add(sqcbcTypeButton);
newButton.TooltipText     = "This text will appear in a tooltip when someone hovers over the button.";
newButton.OnAction        = "Name of Macro to Run";
newButton.DescriptionText = "This is my long description. It will appear in the status bar.";
//find an icon to reference
var icon = Application.MakeFaceId("Structure (Custom)",4,2);
//assign the icon to the button
newButton.FaceId          = icon;
//...etc...
}
]]></MACRO>

To answer your question about deployment, if you provide your users with a new version of the toolbar (anything in the second section) your users can reset XMetaL to the default workspace by holding the Ctrl key down. That will blow away any custom toolbars added like this and then the code will run again and add your new stuff.
« Last Edit: February 14, 2013, 08:09:43 PM by Derek Read » Logged
gcrews
Member

Posts: 265


« Reply #4 on: February 14, 2013, 08:29:25 PM »

I tried your code, it did the same thing.

1.   Placed code in macro file named zzz.mcr in startup

2.   Started xmetal.

When no documents are open, the toolbar is visable and both of the items in the right-click menu are enabled. When I open a file they are both disabled. It seems to work properly after 2 restarts of Xmetal. It also works if you use the Ctrl key while xmetal is loading but then the new toolbar is floating by default.

Do you know if the following note in the programmer's Guide is referring to the On_Application_Open or On_Default_CommandBars_Complete macro that your not supposed to create new tool-bars?
The  pronoun "this" may be referring to the subject of that topic or the previous paragraph.

http://xmetal.com/webhelp/en/xmetaldeveloper/pg/6.0/pg.html#When%20XMetaL%20starts%20or%20closes
“Note: Do not use CommandBarControl.Delete or CommandBar.Delete in this event macro. Also, do not create a new toolbar in this event macro.”

The delete topic has a note about not using .delete() in On_Default_CommandBars_Complete, so I would assume that note is referring to that macro, but if you are not supposed to create a toolbar in that macro where do you create it?


* 2-14-2013 6-20-38 PM.png (2.9 KB, 241x129 - viewed 542 times.)
« Last Edit: February 15, 2013, 12:32:51 AM by gcrews » Logged
Derek Read
Program Manager (XMetaL)
Administrator
Member

Posts: 2621



WWW
« Reply #5 on: February 15, 2013, 03:32:49 PM »

The duplicate toolbar item showing in the list is a known issue that we haven't bothered to fix due to it not affecting users (and because as always, there are more important things to fix that actually do affect them). Since the entire CommandBar system is being rewritten for 8.0 it might even go away without us never knowing what caused it. If it persists then we'll log it under the new CommandBar system. In our testing of 6.0 and 7.0 it doesn't always happen, but when it does it has no effect on anything and will go away eventually just as you say.

Here are the basic rules in plain English for creating custom toolbars, which my script and the other examples included with XMetaL demonstrate.

  • Toolbar or menu modifications can only be made in On_Default_CommandBars_Complete or in On_Local_CommandBars_Complete.
  • Don't recreate a custom toolbar every time On_Default_CommandBars_Complete runs. If you do, eventually a limit will be reached and subsequent runs of your script will fail to do what you expect.
  • Don't recreate a custom toolbar button or menu item every time On_Default_CommandBars_Complete runs. If you do, eventually a limit will be reached and subsequent runs of your script will fail to do what you expect.
  • To undo the effects of On_Default_CommandBars_Complete, remove the startup macros responsible and restart XMetaL with the Ctrl-key held down to reset the workspace.

The 2nd and 3rd limitations exist because there is a limit on the number of unique ids available for toolbars and toolbar buttons in MFC (something that is completely hidden from you and that you have no control over).
« Last Edit: February 15, 2013, 03:35:07 PM by Derek Read » Logged
gcrews
Member

Posts: 265


« Reply #6 on: February 15, 2013, 04:41:59 PM »

Ok thanks for the information; I changed my code to only add it once. I guess if I need to update the toolbar at a later date I will change the toolbar name and delete the old one if it exits after XMetaL has fully loaded. That wayit only adds it once between customization updates.
Logged
Derek Read
Program Manager (XMetaL)
Administrator
Member

Posts: 2621



WWW
« Reply #7 on: February 15, 2013, 04:52:22 PM »

If you are making changes to toolbars using script then you shouldn't really need to worry about old toolbars (that is the primary benefit of doing this stuff with script). If you need to update your toolbars then make your changes in your MCR file, distribute that and have users reset their workspace with the Ctrl key.

When we update our CMS integrations that is part of the procedure for the update.
Logged
Pages: 1
Print
Jump to:  

email us