Discussion:
Example VB Word Add-In Please
(too old to reply)
Trevor Lowing
2005-02-26 12:33:06 UTC
Permalink
I've written add-ins for Outlook and Visio without too much trouble but
Word is driving me insane. Does anyone have a simple example of adding
a commandbar with a button that correctly installs itself, sinks the
button event (and remembers between application starts) and removes
itself when you remove the add-in? All I can find on the MSDN site is an
example of adding an item to the "file" menu but when I tried to extend
it pass that I get duplicate commandbars.


As I side note, I tried deleting normal.dot but I still have a ton of
extra buttonbars. I tried having my add-in delete all the bars and save
normal.dot but they still came back. I also tried setting the
customization space to normaldocument but that didn't help either.


Thanks.
--
---------------------------------
Trevor Lowing
Satellite Beach, Fl

tlowing@-removenospam-lowing.org
---------------------------------
Need help with:
Access?
http://www.mvps.org/access/
Outlook?
http://www.slipstick.com/
Visio?
http://www.mvps.org/visio/
HTML/CSS?
http://www.NCDesign.org
Scripting(VBScript/JScript/WSH/XML)?
http://www.DevGuru.com
http://cwashington.netreach.net/
http://developer.irt.org/script/script.htm
---------------------------------
Jezebel
2005-02-27 00:01:27 UTC
Permalink
A simpler approach in Word is to open the add-in itself as a document,
configure the custom command bars as you want, then save and close. The
custom commandbars will display when the add-in as loaded.
Post by Trevor Lowing
I've written add-ins for Outlook and Visio without too much trouble but
Word is driving me insane. Does anyone have a simple example of adding a
commandbar with a button that correctly installs itself, sinks the button
event (and remembers between application starts) and removes itself when
you remove the add-in? All I can find on the MSDN site is an example of
adding an item to the "file" menu but when I tried to extend it pass that
I get duplicate commandbars.
As I side note, I tried deleting normal.dot but I still have a ton of
extra buttonbars. I tried having my add-in delete all the bars and save
normal.dot but they still came back. I also tried setting the
customization space to normaldocument but that didn't help either.
Thanks.
--
---------------------------------
Trevor Lowing
Satellite Beach, Fl
---------------------------------
Access?
http://www.mvps.org/access/
Outlook?
http://www.slipstick.com/
Visio?
http://www.mvps.org/visio/
HTML/CSS?
http://www.NCDesign.org
Scripting(VBScript/JScript/WSH/XML)?
http://www.DevGuru.com
http://cwashington.netreach.net/
http://developer.irt.org/script/script.htm
---------------------------------
Trevor Lowing
2005-02-27 00:51:30 UTC
Permalink
Does that approach support distributing your Add-In in a way users are
used to installing applications (add/remove programs)? Does that change
the security restrictions at all (macro security) compared to the DLL
approach?
Post by Jezebel
A simpler approach in Word is to open the add-in itself as a document,
configure the custom command bars as you want, then save and close. The
custom commandbars will display when the add-in as loaded.
Post by Trevor Lowing
I've written add-ins for Outlook and Visio without too much trouble but
Word is driving me insane. Does anyone have a simple example of adding a
commandbar with a button that correctly installs itself, sinks the button
event (and remembers between application starts) and removes itself when
you remove the add-in? All I can find on the MSDN site is an example of
adding an item to the "file" menu but when I tried to extend it pass that
I get duplicate commandbars.
As I side note, I tried deleting normal.dot but I still have a ton of
extra buttonbars. I tried having my add-in delete all the bars and save
normal.dot but they still came back. I also tried setting the
customization space to normaldocument but that didn't help either.
Thanks.
--
---------------------------------
Trevor Lowing
Satellite Beach, Fl
---------------------------------
Access?
http://www.mvps.org/access/
Outlook?
http://www.slipstick.com/
Visio?
http://www.mvps.org/visio/
HTML/CSS?
http://www.NCDesign.org
Scripting(VBScript/JScript/WSH/XML)?
http://www.DevGuru.com
http://cwashington.netreach.net/
http://developer.irt.org/script/script.htm
---------------------------------
--
---------------------------------
Trevor Lowing
Satellite Beach, Fl

tlowing@-removenospam-lowing.org
---------------------------------
Need help with:
Access?
http://www.mvps.org/access/
Outlook?
http://www.slipstick.com/
Visio?
http://www.mvps.org/visio/
HTML/CSS?
http://www.NCDesign.org
Scripting(VBScript/JScript/WSH/XML)?
http://www.DevGuru.com
http://cwashington.netreach.net/
http://developer.irt.org/script/script.htm
---------------------------------
Jezebel
2005-02-27 04:17:54 UTC
Permalink
I took you to mean 'add-in' in the usual Word sense -- ie, a .dot file in
Word's start-up folder. If you mean 'add-in' as a separate DLL, then we're
talking about a different issue, certainly. But even with a DLL, you
normally need *some* macro code (usually in a Word add-in) to instantiate
the DLL object -- so you have the same macro security issue either way.

An installation method I've used (from VB) is to create a dummy exe, then
use the package and deployment wizard to prepare the installation package
including all the Word bits and pieces (add-ins, templates, etc), and modify
setup1.exe to instantiate Word, check the folder locations, and move the
add-in and templates accordingly, with the moves added to the Uninstall log
so they get deleted if the user removes the application.
Post by Trevor Lowing
Does that approach support distributing your Add-In in a way users are
used to installing applications (add/remove programs)? Does that change
the security restrictions at all (macro security) compared to the DLL
approach?
Post by Jezebel
A simpler approach in Word is to open the add-in itself as a document,
configure the custom command bars as you want, then save and close. The
custom commandbars will display when the add-in as loaded.
Post by Trevor Lowing
I've written add-ins for Outlook and Visio without too much trouble but
Word is driving me insane. Does anyone have a simple example of adding a
commandbar with a button that correctly installs itself, sinks the button
event (and remembers between application starts) and removes itself when
you remove the add-in? All I can find on the MSDN site is an example of
adding an item to the "file" menu but when I tried to extend it pass that
I get duplicate commandbars.
As I side note, I tried deleting normal.dot but I still have a ton of
extra buttonbars. I tried having my add-in delete all the bars and save
normal.dot but they still came back. I also tried setting the
customization space to normaldocument but that didn't help either.
Thanks.
--
---------------------------------
Trevor Lowing
Satellite Beach, Fl
---------------------------------
Access?
http://www.mvps.org/access/
Outlook?
http://www.slipstick.com/
Visio?
http://www.mvps.org/visio/
HTML/CSS?
http://www.NCDesign.org
Scripting(VBScript/JScript/WSH/XML)?
http://www.DevGuru.com
http://cwashington.netreach.net/
http://developer.irt.org/script/script.htm
---------------------------------
--
---------------------------------
Trevor Lowing
Satellite Beach, Fl
---------------------------------
Access?
http://www.mvps.org/access/
Outlook?
http://www.slipstick.com/
Visio?
http://www.mvps.org/visio/
HTML/CSS?
http://www.NCDesign.org
Scripting(VBScript/JScript/WSH/XML)?
http://www.DevGuru.com
http://cwashington.netreach.net/
http://developer.irt.org/script/script.htm
---------------------------------
Trevor Lowing
2005-02-27 04:44:09 UTC
Permalink
I guess I'm back to my original question. Does someone have a simple
example of a VB COM Add-In for Word that loads a Commandbar and a button
on connection, successfully maintains the button event sinks between
startups and removes the commandbar and buttons when the Add-In is
disconnected?

BTW, the installer I like to use to redistribute my apps is Inno Setup:

http://www.jrsoftware.org/isinfo.php

http://www.istool.org/default.aspx/
Post by Jezebel
I took you to mean 'add-in' in the usual Word sense -- ie, a .dot file in
Word's start-up folder. If you mean 'add-in' as a separate DLL, then we're
talking about a different issue, certainly. But even with a DLL, you
normally need *some* macro code (usually in a Word add-in) to instantiate
the DLL object -- so you have the same macro security issue either way.
An installation method I've used (from VB) is to create a dummy exe, then
use the package and deployment wizard to prepare the installation package
including all the Word bits and pieces (add-ins, templates, etc), and modify
setup1.exe to instantiate Word, check the folder locations, and move the
add-in and templates accordingly, with the moves added to the Uninstall log
so they get deleted if the user removes the application.
Post by Trevor Lowing
Does that approach support distributing your Add-In in a way users are
used to installing applications (add/remove programs)? Does that change
the security restrictions at all (macro security) compared to the DLL
approach?
Post by Jezebel
A simpler approach in Word is to open the add-in itself as a document,
configure the custom command bars as you want, then save and close. The
custom commandbars will display when the add-in as loaded.
Post by Trevor Lowing
I've written add-ins for Outlook and Visio without too much trouble but
Word is driving me insane. Does anyone have a simple example of adding a
commandbar with a button that correctly installs itself, sinks the button
event (and remembers between application starts) and removes itself when
you remove the add-in? All I can find on the MSDN site is an example of
adding an item to the "file" menu but when I tried to extend it pass that
I get duplicate commandbars.
As I side note, I tried deleting normal.dot but I still have a ton of
extra buttonbars. I tried having my add-in delete all the bars and save
normal.dot but they still came back. I also tried setting the
customization space to normaldocument but that didn't help either.
Thanks.
--
---------------------------------
Trevor Lowing
Satellite Beach, Fl
---------------------------------
Access?
http://www.mvps.org/access/
Outlook?
http://www.slipstick.com/
Visio?
http://www.mvps.org/visio/
HTML/CSS?
http://www.NCDesign.org
Scripting(VBScript/JScript/WSH/XML)?
http://www.DevGuru.com
http://cwashington.netreach.net/
http://developer.irt.org/script/script.htm
---------------------------------
--
---------------------------------
Trevor Lowing
Satellite Beach, Fl
---------------------------------
Access?
http://www.mvps.org/access/
Outlook?
http://www.slipstick.com/
Visio?
http://www.mvps.org/visio/
HTML/CSS?
http://www.NCDesign.org
Scripting(VBScript/JScript/WSH/XML)?
http://www.DevGuru.com
http://cwashington.netreach.net/
http://developer.irt.org/script/script.htm
---------------------------------
--
---------------------------------
Trevor Lowing
Satellite Beach, Fl

tlowing@-removenospam-lowing.org
---------------------------------
Need help with:
Access?
http://www.mvps.org/access/
Outlook?
http://www.slipstick.com/
Visio?
http://www.mvps.org/visio/
HTML/CSS?
http://www.NCDesign.org
Scripting(VBScript/JScript/WSH/XML)?
http://www.DevGuru.com
http://cwashington.netreach.net/
http://developer.irt.org/script/script.htm
---------------------------------
Jonathan West
2005-02-27 09:38:30 UTC
Permalink
Post by Trevor Lowing
I guess I'm back to my original question. Does someone have a simple
example of a VB COM Add-In for Word that loads a Commandbar and a button on
connection, successfully maintains the button event sinks between startups
and removes the commandbar and buttons when the Add-In is disconnected?
This article may help you

http://support.microsoft.com/kb/238228
--
Regards
Jonathan West - Word MVP
www.intelligentdocuments.co.uk
Please reply to the newsgroup
Trevor Lowing
2005-02-27 16:06:18 UTC
Permalink
Thanks, but as I mentioned I already have Add-Ins working for Outlook
and Visio and the article covers Excel and Outlook. Specifically, the
code to add and remove commandbars and buttons is buggy for Word. The
best solution I've got is to completely remove and reinstall the bar and
buttons on start. There is still a problem with the bar and button not
being removed when I uninstall the Add-In.
Post by Jonathan West
Post by Trevor Lowing
I guess I'm back to my original question. Does someone have a simple
example of a VB COM Add-In for Word that loads a Commandbar and a
button on connection, successfully maintains the button event sinks
between startups and removes the commandbar and buttons when the
Add-In is disconnected?
This article may help you
http://support.microsoft.com/kb/238228
--
---------------------------------
Trevor Lowing
Satellite Beach, Fl

tlowing@-removenospam-lowing.org
---------------------------------
Need help with:
Access?
http://www.mvps.org/access/
Outlook?
http://www.slipstick.com/
Visio?
http://www.mvps.org/visio/
HTML/CSS?
http://www.NCDesign.org
Scripting(VBScript/JScript/WSH/XML)?
http://www.DevGuru.com
http://cwashington.netreach.net/
http://developer.irt.org/script/script.htm
---------------------------------
Tom Winter
2005-02-28 16:36:08 UTC
Permalink
OK, I've got some stuff that might help you out. If you go to my web site
here:

http://www.amosfivesix.com/downloads/

There are a couple of sample projects that you can download. I would
recommend the Word 97 COM Add-in Sample Project. Now this sample does more
than what you are asking, so it might be confusing. Sorry I don't have a
more streamlined sample that does just what you are looking for. The Word 97
sample also links up the command buttons using "old fashioned" macros,
rather than event sinking that was introduced in Word 2000.

Here are the basics of what you should do:

At DESIGN time:
* Create an empty TEMPLATE to hold your menu customizations. You'll then
need to write some code to create the menu items in this template. Make sure
the CustomizationContext is set to your template. Make sure the menu items
all have their TAG property set uniquely. This is how you'll find them
later. Remember, this code to create the menu items is only going to be
needed at DESIGN time. You run the code once to create the menu items in the
template file. Then save the template file.

At INSTALL time:
* Install your COM Add-in as appropriate. Install the template file in the
same folder as your COM Add-In. You don't need to worry about finding Word's
STARTUP folder or any goofiness like that.

At RUN time:
* In your COM Add-In, during OnConnection or OnStartupComplete, use
something like:
oWordApplication.AddIn.Add VB.App.Path & "NameOfTemplate.dot" , True
This will load the add-in as a global template. The menu items should now
show up in the user interface. Remember, there is no code in your add-in to
create the menu items. Simply loading the template gives you your menu
items! Don't forget to do
oWordApplication.AddIns("NameOfTemplate.dot").Delete to remove the add-in
during OnDisconnection. or OnBeginShutdown().

* Now you need to sink up to your menu items. Do something like
Set oMyButton =
oWordApplication.CommandBars.FindControl(Tag:="UniqueTagIGaveToEachButton")

That's about it. Since your buttons are ONLY in your custom template, you
don't have to worry about them hanging around after you uninstall the
template. And since your COM Add-In loads the template manually, you don't
have to worry about Word's STARTUP folder. This works great for static
menus. If the menu needs to change at run time (add or remove an item based
on something), it may get more complicated, but this basic scenario should
work for you.

If you need more details let me know. I may work the whole thing up into a
sample project.
--
Tom Winter
Thanks, but as I mentioned I already have Add-Ins working for Outlook and
Visio and the article covers Excel and Outlook. Specifically, the code to
add and remove commandbars and buttons is buggy for Word. The best
solution I've got is to completely remove and reinstall the bar and
buttons on start. There is still a problem with the bar and button not
being removed when I uninstall the Add-In.
Post by Jonathan West
Post by Trevor Lowing
I guess I'm back to my original question. Does someone have a simple
example of a VB COM Add-In for Word that loads a Commandbar and a button
on connection, successfully maintains the button event sinks between
startups and removes the commandbar and buttons when the Add-In is
disconnected?
This article may help you
http://support.microsoft.com/kb/238228
--
---------------------------------
Trevor Lowing
Satellite Beach, Fl
---------------------------------
Access?
http://www.mvps.org/access/
Outlook?
http://www.slipstick.com/
Visio?
http://www.mvps.org/visio/
HTML/CSS?
http://www.NCDesign.org
Scripting(VBScript/JScript/WSH/XML)?
http://www.DevGuru.com
http://cwashington.netreach.net/
http://developer.irt.org/script/script.htm
---------------------------------
Trevor Lowing
2005-03-01 04:14:36 UTC
Permalink
Tom,

Thanks for the examples. I'm still hung up on the document template
issue. I did stumble across a really nice article that explains the
issue in some detail:

http://dave.thielen.com/articles/Word%20Add-In%20Part%201.htm

When you create menu objects, you’ll need to keep a couple of things
in mind. First, you must store the returned menu objects in a location
that will exist for the life of the program. The menus are COM objects
and if no persistent C# object is holding them, they are designated for
garbage collection and your events will stop working the next time the
garbage collector runs.

Second the call
CommandBarPopup.Controls.Add(MsoControlType.msoControlButton,
Type.Missing, Type.Missing, Type.Missing, false) must have false for the
final parameter. If this is set to true, as soon as any other add-in
sets Application.CustomizationContext to another value, all your menus
go away.

Apparently temporary (the 5th parameter) isn’t the life of the
application, but the life of the present CustomizationContext set as the
CustomizationContext. If another add-in changes the
CustomizationContext, your menu disappears. Given a user can normally
have several add-ins, you can never set the 5th parameter to true. The
downside is you’re adding your menus to the default template (Normal if
you don’t change it) permanently. I don’t think you can have menus exist
for the life of the application, but not have them added to the template.
Give Users a Template

Another approach is to give users a template to use with your add-in.
The template doesn’t have to do anything, but on startup, you look for
that template and add your menus only if the template exists. You also
add your menus to your template. In essence, you’re using the existence
of the template as an Attribute. This is a clean way to have your add-in
appear only when you want it to and have it not touch any other part of
Word.

Each time your program starts, you need to determine if your menu has
already been added (CommandBarControl.Tag is useful for this). If it
isn’t there, add it. If it is there, either delete it and then add it or
set your events on the existing items. I delete and add it because over
the course of writing the program, the menu items change at times. If
you delete and add it, save the location of the menu and add it there.
If a user customizes her menu by moving the location of your menu, you
don’t want to force it back to the original position the next time Word
runs.

When you set the menus, this changes the template and Word normally asks
the user when she exits if she wants to save the changed template. To
avoid this, get the value of the default Template.Saved before making
the changes and set Template.Saved to that value after you’re done. If
the template was not dirty when you first got the value, it will be set
back to the clean value upon completion:

// the template to use

private Template TemplateOn

{

get

{

// find the WordObject template - if not use AttachedTemplate
because that's better than nothing.

Templates tpltColl = ThisApplication.Templates;

foreach (Template tpltOn in tpltColl)

if (tpltOn.Name == "MY_TEMPLATE.DOT")

return tpltOn;

return ThisApplication.NormalTemplate;

}

}



...



// find the WordObject template - if not use AttachedTemplate because
that's better than nothing.

Template thisTemplate = TemplateOn;



// set the customization to our template and see if the template is dirty

bool clean = thisTemplate.Saved;

ThisApplication.CustomizationContext = thisTemplate;

...

thisTemplate.Saved = clean;

One warning: Don’t look at the Template.Dirty value using the debugger.
The act of looking at it sets it to dirty. This is a true Heisenbug.
(The Heisenberg theory is that the act of observing a particle affects
the particle.)

And even after you take all these measures, there is one more issue.
Sometimes when you close all documents so you have Word running but no
document open, the menu events still fire fine but calls to
CommandBarControl.Enabled throw exceptions. Once you create a new
document, the problem usually goes away—unless you have two instances of
Word, close the first one, then bring up a document in the second one.
Then the problem remains. The solution to this is covered in Part II.
Post by Tom Winter
OK, I've got some stuff that might help you out. If you go to my web site
http://www.amosfivesix.com/downloads/
There are a couple of sample projects that you can download. I would
recommend the Word 97 COM Add-in Sample Project. Now this sample does more
than what you are asking, so it might be confusing. Sorry I don't have a
more streamlined sample that does just what you are looking for. The Word 97
sample also links up the command buttons using "old fashioned" macros,
rather than event sinking that was introduced in Word 2000.
* Create an empty TEMPLATE to hold your menu customizations. You'll then
need to write some code to create the menu items in this template. Make sure
the CustomizationContext is set to your template. Make sure the menu items
all have their TAG property set uniquely. This is how you'll find them
later. Remember, this code to create the menu items is only going to be
needed at DESIGN time. You run the code once to create the menu items in the
template file. Then save the template file.
* Install your COM Add-in as appropriate. Install the template file in the
same folder as your COM Add-In. You don't need to worry about finding Word's
STARTUP folder or any goofiness like that.
* In your COM Add-In, during OnConnection or OnStartupComplete, use
oWordApplication.AddIn.Add VB.App.Path & "NameOfTemplate.dot" , True
This will load the add-in as a global template. The menu items should now
show up in the user interface. Remember, there is no code in your add-in to
create the menu items. Simply loading the template gives you your menu
items! Don't forget to do
oWordApplication.AddIns("NameOfTemplate.dot").Delete to remove the add-in
during OnDisconnection. or OnBeginShutdown().
* Now you need to sink up to your menu items. Do something like
Set oMyButton =
oWordApplication.CommandBars.FindControl(Tag:="UniqueTagIGaveToEachButton")
That's about it. Since your buttons are ONLY in your custom template, you
don't have to worry about them hanging around after you uninstall the
template. And since your COM Add-In loads the template manually, you don't
have to worry about Word's STARTUP folder. This works great for static
menus. If the menu needs to change at run time (add or remove an item based
on something), it may get more complicated, but this basic scenario should
work for you.
If you need more details let me know. I may work the whole thing up into a
sample project.
--
---------------------------------
Trevor Lowing
Satellite Beach, Fl

tlowing@-removenospam-lowing.org
---------------------------------
Need help with:
Access?
http://www.mvps.org/access/
Outlook?
http://www.slipstick.com/
Visio?
http://www.mvps.org/visio/
HTML/CSS?
http://www.NCDesign.org
Scripting(VBScript/JScript/WSH/XML)?
http://www.DevGuru.com
http://cwashington.netreach.net/
http://developer.irt.org/script/script.htm
---------------------------------
Tom Winter
2005-03-01 14:28:51 UTC
Permalink
Well, if you are doing your add-in in .NET, then I probably can't help you
much. I was assuming VB6. .NET is a whole different world.

As for the Temporary parameter having to be false for adding controls, that
is true. Word does not support temporary controls. I believe Word will allow
you to pass True for Temporary, but it basically ignores it. All command bar
changes are saved in a template somewhere no matter what. I've never seen
buttons disappear when the customization context is changed and I've never
heard anything like this talked about before. It's possible that I've just
missed this behavior. In the end, Dave's conclusion that you must have
Temporary as False is correct.

Dave's idea of using a template to hold the menu items is the way to go, and
basically the same thing I said. I took a slightly different take on it.
Basically there are two ways you can go:

1. If your menus are static. That is, the menu items never change (appear,
disappear, enable, disable, etc.). This is the case for me, but that might
actually be unusual. If this is the case for you, you can follow my previous
instructions. Create the menus once at DESIGN time, then at RUN time, locate
the menus and sink up to them. You won't need any menu creation/deletion
code in your add-in.

2. If your menus change at run time. That is, the menu items change at times
(appear, disappear, enable, disable). In this case, you can take Dave's
approach. Just have the template there (as a "global template"/"traditional
add-in") so that you can add menu items to it at run-time and change it as
needed. Always make sure you've got your CustomizationContext correct when
making any changes and make sure you watch the .Saved attribute of the
template as Dave said.

The whole point of having the template is that unlike (some) other Office
applications, "menu changes" are always saved in a template somewhere, be it
Normal.dot, a document template or a global template. Since it's considered
bad form to mess with a user's Normal.dot, you should provide your own
template to hold the menu changes.

Hope that helps. If you need any more help with the general idea, let me
know!
--
Tom Winter
Tom,
Thanks for the examples. I'm still hung up on the document template issue.
I did stumble across a really nice article that explains the issue in some
http://dave.thielen.com/articles/Word%20Add-In%20Part%201.htm
When you create menu objects, you’ll need to keep a couple of things in
mind. First, you must store the returned menu objects in a location that
will exist for the life of the program. The menus are COM objects and if
no persistent C# object is holding them, they are designated for garbage
collection and your events will stop working the next time the garbage
collector runs.
Second the call
CommandBarPopup.Controls.Add(MsoControlType.msoControlButton,
Type.Missing, Type.Missing, Type.Missing, false) must have false for the
final parameter. If this is set to true, as soon as any other add-in sets
Application.CustomizationContext to another value, all your menus go away.
Apparently temporary (the 5th parameter) isn’t the life of the
application, but the life of the present CustomizationContext set as the
CustomizationContext. If another add-in changes the CustomizationContext,
your menu disappears. Given a user can normally have several add-ins, you
can never set the 5th parameter to true. The downside is you’re adding
your menus to the default template (Normal if you don’t change it)
permanently. I don’t think you can have menus exist for the life of the
application, but not have them added to the template.
Give Users a Template
Another approach is to give users a template to use with your add-in. The
template doesn’t have to do anything, but on startup, you look for that
template and add your menus only if the template exists. You also add your
menus to your template. In essence, you’re using the existence of the
template as an Attribute. This is a clean way to have your add-in appear
only when you want it to and have it not touch any other part of Word.
Each time your program starts, you need to determine if your menu has
already been added (CommandBarControl.Tag is useful for this). If it isn’t
there, add it. If it is there, either delete it and then add it or set
your events on the existing items. I delete and add it because over the
course of writing the program, the menu items change at times. If you
delete and add it, save the location of the menu and add it there. If a
user customizes her menu by moving the location of your menu, you don’t
want to force it back to the original position the next time Word runs.
When you set the menus, this changes the template and Word normally asks
the user when she exits if she wants to save the changed template. To
avoid this, get the value of the default Template.Saved before making the
changes and set Template.Saved to that value after you’re done. If the
template was not dirty when you first got the value, it will be set back
// the template to use
private Template TemplateOn
{
get
{
// find the WordObject template - if not use AttachedTemplate
because that's better than nothing.
Templates tpltColl = ThisApplication.Templates;
foreach (Template tpltOn in tpltColl)
if (tpltOn.Name == "MY_TEMPLATE.DOT")
return tpltOn;
return ThisApplication.NormalTemplate;
}
}
...
// find the WordObject template - if not use AttachedTemplate because
that's better than nothing.
Template thisTemplate = TemplateOn;
// set the customization to our template and see if the template is dirty
bool clean = thisTemplate.Saved;
ThisApplication.CustomizationContext = thisTemplate;
...
thisTemplate.Saved = clean;
One warning: Don’t look at the Template.Dirty value using the debugger.
The act of looking at it sets it to dirty. This is a true Heisenbug. (The
Heisenberg theory is that the act of observing a particle affects the
particle.)
And even after you take all these measures, there is one more issue.
Sometimes when you close all documents so you have Word running but no
document open, the menu events still fire fine but calls to
CommandBarControl.Enabled throw exceptions. Once you create a new
document, the problem usually goes away—unless you have two instances of
Word, close the first one, then bring up a document in the second one.
Then the problem remains. The solution to this is covered in Part II.
Post by Tom Winter
OK, I've got some stuff that might help you out. If you go to my web site
http://www.amosfivesix.com/downloads/
There are a couple of sample projects that you can download. I would
recommend the Word 97 COM Add-in Sample Project. Now this sample does
more than what you are asking, so it might be confusing. Sorry I don't
have a more streamlined sample that does just what you are looking for.
The Word 97 sample also links up the command buttons using "old
fashioned" macros, rather than event sinking that was introduced in Word
2000.
* Create an empty TEMPLATE to hold your menu customizations. You'll then
need to write some code to create the menu items in this template. Make
sure the CustomizationContext is set to your template. Make sure the menu
items all have their TAG property set uniquely. This is how you'll find
them later. Remember, this code to create the menu items is only going to
be needed at DESIGN time. You run the code once to create the menu items
in the template file. Then save the template file.
* Install your COM Add-in as appropriate. Install the template file in
the same folder as your COM Add-In. You don't need to worry about finding
Word's STARTUP folder or any goofiness like that.
* In your COM Add-In, during OnConnection or OnStartupComplete, use
oWordApplication.AddIn.Add VB.App.Path & "NameOfTemplate.dot" , True
This will load the add-in as a global template. The menu items should
now show up in the user interface. Remember, there is no code in your
add-in to create the menu items. Simply loading the template gives you
your menu items! Don't forget to do
oWordApplication.AddIns("NameOfTemplate.dot").Delete to remove the add-in
during OnDisconnection. or OnBeginShutdown().
* Now you need to sink up to your menu items. Do something like
Set oMyButton =
oWordApplication.CommandBars.FindControl(Tag:="UniqueTagIGaveToEachButton")
That's about it. Since your buttons are ONLY in your custom template, you
don't have to worry about them hanging around after you uninstall the
template. And since your COM Add-In loads the template manually, you
don't have to worry about Word's STARTUP folder. This works great for
static menus. If the menu needs to change at run time (add or remove an
item based on something), it may get more complicated, but this basic
scenario should work for you.
If you need more details let me know. I may work the whole thing up into
a sample project.
--
---------------------------------
Trevor Lowing
Satellite Beach, Fl
---------------------------------
Access?
http://www.mvps.org/access/
Outlook?
http://www.slipstick.com/
Visio?
http://www.mvps.org/visio/
HTML/CSS?
http://www.NCDesign.org
Scripting(VBScript/JScript/WSH/XML)?
http://www.DevGuru.com
http://cwashington.netreach.net/
http://developer.irt.org/script/script.htm
---------------------------------
Trevor Lowing
2005-03-01 23:50:09 UTC
Permalink
Tom,

Actually I am using VB6 but for most cases the code is easily converted.
My scenario goes something like this: Assume a workplace where
knowledge workers produce reports based on numerous custom templates. I
want to add two buttons whenever a user creates any type of document
(from any template).

How should I be adding the buttons? When should I remove the buttons?
Should I create a generic template to load at startup and add the
buttons to new documents on the documentchange event and copy over the
button position information too? If so, when do I delete the buttons so
they aren't permanently added to the other custom forms (templates)?

Thanks
--
---------------------------------
Trevor Lowing
Satellite Beach, Fl

tlowing@-removenospam-lowing.org
---------------------------------
Need help with:
Access?
http://www.mvps.org/access/
Outlook?
http://www.slipstick.com/
Visio?
http://www.mvps.org/visio/
HTML/CSS?
http://www.NCDesign.org
Scripting(VBScript/JScript/WSH/XML)?
http://www.DevGuru.com
http://cwashington.netreach.net/
http://developer.irt.org/script/script.htm
---------------------------------
Post by Tom Winter
Well, if you are doing your add-in in .NET, then I probably can't help you
much. I was assuming VB6. .NET is a whole different world.
Tom Winter
2005-03-02 15:30:42 UTC
Permalink
Well, I'll ask a couple more questions.

1. Do you want the buttons to ALWAYS be seen/available in Word, or only when
a document based on one of your custom templates is open? If you want them
always to be visible, then put the button in a global template. If the other
way, then either, a) put the buttons in the custom template, though that
would require duplicating the buttons and probably the code behind them
across all the templates, or b) put the buttons in a global template, then
check using documentchange and hide/show the buttons as appropriate.

I would think carefully if it's REALLY necessary to show/hide the buttons.
The documentchange event has some goofy quirks so I've heard. It would be
easier to just pop up a message box saying "you can't do that right now" if
the current document isn't based on one of your custom templates.

2. Do the buttons "change" alot, such as the hiding/showing, etc. If not,
then just create the buttons once for a global template, at design-time
while you are sitting there in front of the computer. Then you don't have to
worry about extra things like when to create/delete/hide/show.

Also, remember that buttons aren't added to DOCUMENTS, they are added to
TEMPLATES. Application.CustomizationContext says which template is being
changed when you do stuff under Application.CommandBars. If your button
changes are made to a global template, then you don't have to worry about
copying button positions, etc., since a global template is always loaded.

It can be hard to wrap your head around, but the best way to think of things
is that menu CHANGES are stored in templates. I mean CHANGES since we're not
talking just adding buttons, we're talking removing buttons. Try this:

1. Create a new TEMPLATE. (FILE | NEW, click TEMPLATE, hit OK). Save it
somewhere so you know where it is.
2. In the template, go to TOOLS | CUSTOMIZE.
3. Make sure SAVE IN at the bottom of the customize window says the name of
your template (instead of normal.dot) (This is like setting
Application.CustomizationContext.)
4. Remove a menu from the main menu bar. For example, drag off the EDIT menu
so that it disappears from the menu bar.
5. Hit close on the Customize window.
6. Save your template again
7. Close the template.
8. Now notice if you work with some other documents, the EDIT menu has come
back.
9. Now go to TOOLS | TEMPLATES AND ADD-INS.
10. Under Global Templates and Add-Ins, click the ADD button
11. Locate the template we saved in step 1 and click OK.
12. It will get added to the global template list. Hit OK.
13. Notice that your EDIT menu has disappeared. That's because the "menu
change" of removing the Edit menu is saved in that template.
14. Go back to TOOLS | TEMPLATES AND ADD-INS.
15. Select your template from the list and click REMOVE.
16. Click OK. You'll see the EDIT menu is back again.

So "menu changes" (additions, deletions, other things like changing the
icons, etc.) are saved in templates. So the only time you'll see those menu
changes is if the template they are saved into is "in effect". The only time
a template is in effect is if it is a global template (listed in TOOLS |
TEMPLATES AND ADD-INS) or the current document is based on that template.

OK, hope that helped clear some things up. If you make your menu changes to
a template at DESIGN time, those menu changes are stored in the template. To
have those menu changes be in effect, all you have to do is load the
template. To make the menu changes go away, unload the template.
--
Tom Winter
Post by Trevor Lowing
Tom,
Actually I am using VB6 but for most cases the code is easily converted.
My scenario goes something like this: Assume a workplace where knowledge
workers produce reports based on numerous custom templates. I want to add
two buttons whenever a user creates any type of document (from any
template).
How should I be adding the buttons? When should I remove the buttons?
Should I create a generic template to load at startup and add the buttons
to new documents on the documentchange event and copy over the button
position information too? If so, when do I delete the buttons so they
aren't permanently added to the other custom forms (templates)?
Thanks
--
---------------------------------
Trevor Lowing
Satellite Beach, Fl
---------------------------------
Access?
http://www.mvps.org/access/
Outlook?
http://www.slipstick.com/
Visio?
http://www.mvps.org/visio/
HTML/CSS?
http://www.NCDesign.org
Scripting(VBScript/JScript/WSH/XML)?
http://www.DevGuru.com
http://cwashington.netreach.net/
http://developer.irt.org/script/script.htm
---------------------------------
Post by Tom Winter
Well, if you are doing your add-in in .NET, then I probably can't help
you much. I was assuming VB6. .NET is a whole different world.
Tom Winter
2005-03-02 15:41:37 UTC
Permalink
OK, I take back a little bit of what I said. ;) After playing, you CAN save
menu changes in documents. But I really wouldn't recommend it. And I don't
think I applies to what you want to do anyway. Just wanted to be complete in
my explanation!
--
Tom Winter
Post by Tom Winter
Well, I'll ask a couple more questions.
1. Do you want the buttons to ALWAYS be seen/available in Word, or only
when a document based on one of your custom templates is open? If you want
them always to be visible, then put the button in a global template. If
the other way, then either, a) put the buttons in the custom template,
though that would require duplicating the buttons and probably the code
behind them across all the templates, or b) put the buttons in a global
template, then check using documentchange and hide/show the buttons as
appropriate.
I would think carefully if it's REALLY necessary to show/hide the buttons.
The documentchange event has some goofy quirks so I've heard. It would be
easier to just pop up a message box saying "you can't do that right now"
if the current document isn't based on one of your custom templates.
2. Do the buttons "change" alot, such as the hiding/showing, etc. If not,
then just create the buttons once for a global template, at design-time
while you are sitting there in front of the computer. Then you don't have
to worry about extra things like when to create/delete/hide/show.
Also, remember that buttons aren't added to DOCUMENTS, they are added to
TEMPLATES. Application.CustomizationContext says which template is being
changed when you do stuff under Application.CommandBars. If your button
changes are made to a global template, then you don't have to worry about
copying button positions, etc., since a global template is always loaded.
It can be hard to wrap your head around, but the best way to think of
things is that menu CHANGES are stored in templates. I mean CHANGES since
we're not talking just adding buttons, we're talking removing buttons. Try
1. Create a new TEMPLATE. (FILE | NEW, click TEMPLATE, hit OK). Save it
somewhere so you know where it is.
2. In the template, go to TOOLS | CUSTOMIZE.
3. Make sure SAVE IN at the bottom of the customize window says the name
of your template (instead of normal.dot) (This is like setting
Application.CustomizationContext.)
4. Remove a menu from the main menu bar. For example, drag off the EDIT
menu so that it disappears from the menu bar.
5. Hit close on the Customize window.
6. Save your template again
7. Close the template.
8. Now notice if you work with some other documents, the EDIT menu has
come back.
9. Now go to TOOLS | TEMPLATES AND ADD-INS.
10. Under Global Templates and Add-Ins, click the ADD button
11. Locate the template we saved in step 1 and click OK.
12. It will get added to the global template list. Hit OK.
13. Notice that your EDIT menu has disappeared. That's because the "menu
change" of removing the Edit menu is saved in that template.
14. Go back to TOOLS | TEMPLATES AND ADD-INS.
15. Select your template from the list and click REMOVE.
16. Click OK. You'll see the EDIT menu is back again.
So "menu changes" (additions, deletions, other things like changing the
icons, etc.) are saved in templates. So the only time you'll see those
menu changes is if the template they are saved into is "in effect". The
only time a template is in effect is if it is a global template (listed in
TOOLS | TEMPLATES AND ADD-INS) or the current document is based on that
template.
OK, hope that helped clear some things up. If you make your menu changes
to a template at DESIGN time, those menu changes are stored in the
template. To have those menu changes be in effect, all you have to do is
load the template. To make the menu changes go away, unload the template.
--
Tom Winter
Post by Trevor Lowing
Tom,
Actually I am using VB6 but for most cases the code is easily converted.
My scenario goes something like this: Assume a workplace where knowledge
workers produce reports based on numerous custom templates. I want to add
two buttons whenever a user creates any type of document (from any
template).
How should I be adding the buttons? When should I remove the buttons?
Should I create a generic template to load at startup and add the buttons
to new documents on the documentchange event and copy over the button
position information too? If so, when do I delete the buttons so they
aren't permanently added to the other custom forms (templates)?
Thanks
--
---------------------------------
Trevor Lowing
Satellite Beach, Fl
---------------------------------
Access?
http://www.mvps.org/access/
Outlook?
http://www.slipstick.com/
Visio?
http://www.mvps.org/visio/
HTML/CSS?
http://www.NCDesign.org
Scripting(VBScript/JScript/WSH/XML)?
http://www.DevGuru.com
http://cwashington.netreach.net/
http://developer.irt.org/script/script.htm
---------------------------------
Post by Tom Winter
Well, if you are doing your add-in in .NET, then I probably can't help
you much. I was assuming VB6. .NET is a whole different world.
Trevor Lowing
2005-03-03 11:40:40 UTC
Permalink
Tom,

Basically I want the two buttons to appear on every new document. I
think I have it doing that now but it won't remember button positioning
and for Word the buttons won't go away after they disconnect the Add-In.
What is the "global template"? Normal.dot?

Thanks
--
---------------------------------
Trevor Lowing
Satellite Beach, Fl

tlowing@-removenospam-lowing.org
---------------------------------
Need help with:
Access?
http://www.mvps.org/access/
Outlook?
http://www.slipstick.com/
Visio?
http://www.mvps.org/visio/
HTML/CSS?
http://www.NCDesign.org
Scripting(VBScript/JScript/WSH/XML)?
http://www.DevGuru.com
http://cwashington.netreach.net/
http://developer.irt.org/script/script.htm
---------------------------------
Post by Tom Winter
Well, I'll ask a couple more questions.
1. Do you want the buttons to ALWAYS be seen/available in Word, or only when
a document based on one of your custom templates is open? If you want them
always to be visible, then put the button in a global template. If the other
way, then either, a) put the buttons in the custom template, though that
would require duplicating the buttons and probably the code behind them
across all the templates, or b) put the buttons in a global template, then
check using documentchange and hide/show the buttons as appropriate.
I would think carefully if it's REALLY necessary to show/hide the buttons.
The documentchange event has some goofy quirks so I've heard. It would be
easier to just pop up a message box saying "you can't do that right now" if
the current document isn't based on one of your custom templates.
2. Do the buttons "change" alot, such as the hiding/showing, etc. If not,
then just create the buttons once for a global template, at design-time
while you are sitting there in front of the computer. Then you don't have to
worry about extra things like when to create/delete/hide/show.
Also, remember that buttons aren't added to DOCUMENTS, they are added to
TEMPLATES. Application.CustomizationContext says which template is being
changed when you do stuff under Application.CommandBars. If your button
changes are made to a global template, then you don't have to worry about
copying button positions, etc., since a global template is always loaded.
It can be hard to wrap your head around, but the best way to think of things
is that menu CHANGES are stored in templates. I mean CHANGES since we're not
1. Create a new TEMPLATE. (FILE | NEW, click TEMPLATE, hit OK). Save it
somewhere so you know where it is.
2. In the template, go to TOOLS | CUSTOMIZE.
3. Make sure SAVE IN at the bottom of the customize window says the name of
your template (instead of normal.dot) (This is like setting
Application.CustomizationContext.)
4. Remove a menu from the main menu bar. For example, drag off the EDIT menu
so that it disappears from the menu bar.
5. Hit close on the Customize window.
6. Save your template again
7. Close the template.
8. Now notice if you work with some other documents, the EDIT menu has come
back.
9. Now go to TOOLS | TEMPLATES AND ADD-INS.
10. Under Global Templates and Add-Ins, click the ADD button
11. Locate the template we saved in step 1 and click OK.
12. It will get added to the global template list. Hit OK.
13. Notice that your EDIT menu has disappeared. That's because the "menu
change" of removing the Edit menu is saved in that template.
14. Go back to TOOLS | TEMPLATES AND ADD-INS.
15. Select your template from the list and click REMOVE.
16. Click OK. You'll see the EDIT menu is back again.
So "menu changes" (additions, deletions, other things like changing the
icons, etc.) are saved in templates. So the only time you'll see those menu
changes is if the template they are saved into is "in effect". The only time
a template is in effect is if it is a global template (listed in TOOLS |
TEMPLATES AND ADD-INS) or the current document is based on that template.
OK, hope that helped clear some things up. If you make your menu changes to
a template at DESIGN time, those menu changes are stored in the template. To
have those menu changes be in effect, all you have to do is load the
template. To make the menu changes go away, unload the template.
Jonathan West
2005-03-03 12:21:20 UTC
Permalink
Tom,
Basically I want the two buttons to appear on every new document. I think
I have it doing that now but it won't remember button positioning and for
Word the buttons won't go away after they disconnect the Add-In. What is
the "global template"? Normal.dot?
No. Do not under any circumstances use normal.dot for this.

A global template is an add-in (not COM add-in). If you go to Tools,
Templates and Addins in Word, you will see a list of the installed add-ins.
Add-ins are loaded automatically by Word on startup if they are located in
Word's startup folder.

If you have a couple of unchanging buttons that you want permanently
available, then I suggest you create a template, put these two buttons on
it, include a bit of stub VBA code that is triggered by the buttons which
then calls routines in your main add-in. Then put the template into Word's
startup folder so the buttons appear every time Word is started.

These 2 articles may be useful background reading for you.

What do Templates and Add-ins store?
http://www.word.mvps.org/FAQs/Customization/WhatTemplatesStore.htm

Distributing macros to other users
http://www.word.mvps.org/FAQs/MacrosVBA/DistributeMacros.htm
--
Regards
Jonathan West - Word MVP
www.intelligentdocuments.co.uk
Please reply to the newsgroup
Trevor Lowing
2005-03-06 13:54:21 UTC
Permalink
Jonathan,

After reading the great Templates article you pointed me to I was
wondering if I could have my Add-In look for a template in the Startup
folder. If my template is not found I could have it create a new
document, add the buttons and save it to the startup folder as a .Dot
template. What do you think?
--
---------------------------------
Trevor Lowing
Satellite Beach, Fl

tlowing@-removenospam-lowing.org
---------------------------------
Need help with:
Access?
http://www.mvps.org/access/
Outlook?
http://www.slipstick.com/
Visio?
http://www.mvps.org/visio/
HTML/CSS?
http://www.NCDesign.org
Scripting(VBScript/JScript/WSH/XML)?
http://www.DevGuru.com
http://cwashington.netreach.net/
http://developer.irt.org/script/script.htm
---------------------------------
Post by Jonathan West
Post by Trevor Lowing
Tom,
Basically I want the two buttons to appear on every new document. I
think I have it doing that now but it won't remember button
positioning and for Word the buttons won't go away after they
disconnect the Add-In. What is the "global template"? Normal.dot?
No. Do not under any circumstances use normal.dot for this.
A global template is an add-in (not COM add-in). If you go to Tools,
Templates and Addins in Word, you will see a list of the installed
add-ins. Add-ins are loaded automatically by Word on startup if they are
located in Word's startup folder.
If you have a couple of unchanging buttons that you want permanently
available, then I suggest you create a template, put these two buttons
on it, include a bit of stub VBA code that is triggered by the buttons
which then calls routines in your main add-in. Then put the template
into Word's startup folder so the buttons appear every time Word is
started.
These 2 articles may be useful background reading for you.
What do Templates and Add-ins store?
http://www.word.mvps.org/FAQs/Customization/WhatTemplatesStore.htm
Distributing macros to other users
http://www.word.mvps.org/FAQs/MacrosVBA/DistributeMacros.htm
Jonathan West
2005-03-06 14:16:50 UTC
Permalink
Post by Trevor Lowing
Jonathan,
After reading the great Templates article you pointed me to I was
wondering if I could have my Add-In look for a template in the Startup
folder. If my template is not found I could have it create a new document,
add the buttons and save it to the startup folder as a .Dot template. What
do you think?
I think it would be simpler to arrange things so that when your add-in is
installed, a template is also installed in the startup folder.
--
Regards
Jonathan West - Word MVP
www.intelligentdocuments.co.uk
Please reply to the newsgroup
Charles Kenyon
2005-03-06 19:43:23 UTC
Permalink
The simplest way to do this is with a .dot Add-In that has your toolbars
already built in. It goes in the Word Startup folder. When it is removed,
its modifications go away as well.
--
Charles Kenyon

Word New User FAQ & Web Directory: http://addbalance.com/word

Intermediate User's Guide to Microsoft Word (supplemented version of
Microsoft's Legal Users' Guide) http://addbalance.com/usersguide

See also the MVP FAQ: http://www.mvps.org/word which is awesome!
--------- --------- --------- --------- --------- ---------
This message is posted to a newsgroup. Please post replies
and questions to the newsgroup so that others can learn
from my ignorance and your wisdom.
Post by Trevor Lowing
I've written add-ins for Outlook and Visio without too much trouble but
Word is driving me insane. Does anyone have a simple example of adding a
commandbar with a button that correctly installs itself, sinks the button
event (and remembers between application starts) and removes itself when
you remove the add-in? All I can find on the MSDN site is an example of
adding an item to the "file" menu but when I tried to extend it pass that
I get duplicate commandbars.
As I side note, I tried deleting normal.dot but I still have a ton of
extra buttonbars. I tried having my add-in delete all the bars and save
normal.dot but they still came back. I also tried setting the
customization space to normaldocument but that didn't help either.
Thanks.
--
---------------------------------
Trevor Lowing
Satellite Beach, Fl
---------------------------------
Access?
http://www.mvps.org/access/
Outlook?
http://www.slipstick.com/
Visio?
http://www.mvps.org/visio/
HTML/CSS?
http://www.NCDesign.org
Scripting(VBScript/JScript/WSH/XML)?
http://www.DevGuru.com
http://cwashington.netreach.net/
http://developer.irt.org/script/script.htm
---------------------------------
Loading...