Menu creation, architectural question [VSTO, C#]

M

Mike

Menu creation architectural question [VSTO, C#]:

Hi! I am creating MS Word 2003 template with custom built menus and getting
confused on how it works. What I do not understand is at what point the code
will build the menu? I mean should I run this code every time the template
launches? Should I check if the menu is built already? I get prompts to save
the template but have no clue what causes the prompt? Is this the best
solution/architecture? All I want is to build a template which will be
programmatically attached to a Word 2003 document that’s going to be launched
from a C# executable. What makes it even more interesting is that I see the
menu when I launch (F5) in VS IDE for a second and then it disappears. What
am I doing wrong. Please help.

Any ideas/suggestions are greatly appreciated.



Here’s how I create a menu item:

protected void ThisDocument_New()
{
try
{

this.MainMenuBar = ThisApplication.CommandBars["Menu Bar"];
InitMenuBarItems("&Travel Tools");
this.MenuItem = this.CreateButton((Office.CommandBarPopup)this.MenuBarItem,
"& Expense Report");
this.MenuItem.Click += new
Office._CommandBarButtonEvents_ClickEventHandler(MenuItem_Click);

}
catch(Exception ex)
{
MessageBox.Show(ex.Message, ex.Source, MessageBoxButtons.OK,
MessageBoxIcon.Error);
}
}

private Office.CommandBarButton CreateButton(Office.CommandBarPopup Parent,
string Caption)
{
Office.CommandBarControl cbc = null;
try
{
cbc = Parent.Controls.
Add(Office.MsoControlType.msoControlButton,
Type.Missing, Type.Missing, Type.Missing, true);
cbc.Caption = Caption;
cbc.Visible = true;

}
catch (Exception ex)
{
MessageBox.Show(ex.Message, ex.Source, MessageBoxButtons.OK,
MessageBoxIcon.Error);
}
return (Office.CommandBarButton)cbc;
}


Thank you in advance,
 
P

Peter

I recommend that you create the custom menus in the template either via VBA or manually customizing the menus, rather than through your external executable.

My best practices recommendation (fwiw) is to use a macro to create your custom menus. If the menus are dynamic (depend on document content, for example), you'll want to call the menu creation macro every time a document attached to the template opens. If the menus are static, then just run the macro once, save the template, and don't re-run the macro again unless you're re-generating the whole template (which is recommended to do every once in awhile to reduce template bloat).
Using a macro to generate custom menu items allows you to quickly and easily change them, or generate them fresh.

If you're going to dynamically generate your custom menus for each document, then wrap your menu-generation calls with
Application.CustomizationContext = ActiveDocument.AttachedTemplate
and
ActiveDocument.AttachedTemplate.Saved = True

That will ensure that your menu changes end up in the template, not in the document, and that the "do you want to save changes to the document template?" prompt won't display.

Example:

Dim oPrint As CommandBarButton

' include with dynamic custom menus
Application.CustomizationContext = ActiveDocument.AttachedTemplate

With Application.CommandBars.Add("MyBar", msoBarTop, , True)
.Enabled = True
.Visible = True
With .Controls
Set oPrint = .Add(Type:=msoControlButton)
With oPrint
.Caption = "Special &Print"
.FaceId = 176
.Style = msoButtonIconAndCaption
.OnAction = "Module1.SpecialPrint"
.TooltipText = "Special Print"
.Enabled = True
.Visible = True
.Priority = 1
End With
End With
End With

' include with dynamic custom menus
ActiveDocument.AttachedTemplate.Saved = True

hth,

-Peter

Mike said:
Menu creation architectural question [VSTO, C#]:

Hi! I am creating MS Word 2003 template with custom built menus and getting
confused on how it works. What I do not understand is at what point the code
will build the menu? I mean should I run this code every time the template
launches? Should I check if the menu is built already? I get prompts to save
the template but have no clue what causes the prompt? Is this the best
solution/architecture? All I want is to build a template which will be
programmatically attached to a Word 2003 document that’s going to be launched
from a C# executable. What makes it even more interesting is that I see the
menu when I launch (F5) in VS IDE for a second and then it disappears. What
am I doing wrong. Please help.

Any ideas/suggestions are greatly appreciated.



Here’s how I create a menu item:

protected void ThisDocument_New()
{
try
{

this.MainMenuBar = ThisApplication.CommandBars["Menu Bar"];
InitMenuBarItems("&Travel Tools");
this.MenuItem = this.CreateButton((Office.CommandBarPopup)this.MenuBarItem,
"& Expense Report");
this.MenuItem.Click += new
Office._CommandBarButtonEvents_ClickEventHandler(MenuItem_Click);

}
catch(Exception ex)
{
MessageBox.Show(ex.Message, ex.Source, MessageBoxButtons.OK,
MessageBoxIcon.Error);
}
}

private Office.CommandBarButton CreateButton(Office.CommandBarPopup Parent,
string Caption)
{
Office.CommandBarControl cbc = null;
try
{
cbc = Parent.Controls.
Add(Office.MsoControlType.msoControlButton,
Type.Missing, Type.Missing, Type.Missing, true);
cbc.Caption = Caption;
cbc.Visible = true;

}
catch (Exception ex)
{
MessageBox.Show(ex.Message, ex.Source, MessageBoxButtons.OK,
MessageBoxIcon.Error);
}
return (Office.CommandBarButton)cbc;
}


Thank you in advance,
 
M

Mike

Thank you, Peter. You cannot imagine how much I appreciate your help.

I need to generate static menu whose submenus are dynamic, based on changing
xml datasource files on users' dektops. I also have to use Visual Studio
Tools for MS Office (C#). What should I do in that case? What's the approach
I should be taking ?
Should I start the project as template or as Word application ?

Also, is there a good book/url you can recommend?

Many Thanks in Advance,

--Mike

Peter said:
I recommend that you create the custom menus in the template either via VBA or manually customizing the menus, rather than through your external executable.

My best practices recommendation (fwiw) is to use a macro to create your custom menus. If the menus are dynamic (depend on document content, for example), you'll want to call the menu creation macro every time a document attached to the template opens. If the menus are static, then just run the macro once, save the template, and don't re-run the macro again unless you're re-generating the whole template (which is recommended to do every once in awhile to reduce template bloat).
Using a macro to generate custom menu items allows you to quickly and easily change them, or generate them fresh.

If you're going to dynamically generate your custom menus for each document, then wrap your menu-generation calls with
Application.CustomizationContext = ActiveDocument.AttachedTemplate
and
ActiveDocument.AttachedTemplate.Saved = True

That will ensure that your menu changes end up in the template, not in the document, and that the "do you want to save changes to the document template?" prompt won't display.

Example:

Dim oPrint As CommandBarButton

' include with dynamic custom menus
Application.CustomizationContext = ActiveDocument.AttachedTemplate

With Application.CommandBars.Add("MyBar", msoBarTop, , True)
.Enabled = True
.Visible = True
With .Controls
Set oPrint = .Add(Type:=msoControlButton)
With oPrint
.Caption = "Special &Print"
.FaceId = 176
.Style = msoButtonIconAndCaption
.OnAction = "Module1.SpecialPrint"
.TooltipText = "Special Print"
.Enabled = True
.Visible = True
.Priority = 1
End With
End With
End With

' include with dynamic custom menus
ActiveDocument.AttachedTemplate.Saved = True

hth,

-Peter

Mike said:
Menu creation architectural question [VSTO, C#]:

Hi! I am creating MS Word 2003 template with custom built menus and getting
confused on how it works. What I do not understand is at what point the code
will build the menu? I mean should I run this code every time the template
launches? Should I check if the menu is built already? I get prompts to save
the template but have no clue what causes the prompt? Is this the best
solution/architecture? All I want is to build a template which will be
programmatically attached to a Word 2003 document that’s going to be launched
from a C# executable. What makes it even more interesting is that I see the
menu when I launch (F5) in VS IDE for a second and then it disappears. What
am I doing wrong. Please help.

Any ideas/suggestions are greatly appreciated.



Here’s how I create a menu item:

protected void ThisDocument_New()
{
try
{

this.MainMenuBar = ThisApplication.CommandBars["Menu Bar"];
InitMenuBarItems("&Travel Tools");
this.MenuItem = this.CreateButton((Office.CommandBarPopup)this.MenuBarItem,
"& Expense Report");
this.MenuItem.Click += new
Office._CommandBarButtonEvents_ClickEventHandler(MenuItem_Click);

}
catch(Exception ex)
{
MessageBox.Show(ex.Message, ex.Source, MessageBoxButtons.OK,
MessageBoxIcon.Error);
}
}

private Office.CommandBarButton CreateButton(Office.CommandBarPopup Parent,
string Caption)
{
Office.CommandBarControl cbc = null;
try
{
cbc = Parent.Controls.
Add(Office.MsoControlType.msoControlButton,
Type.Missing, Type.Missing, Type.Missing, true);
cbc.Caption = Caption;
cbc.Visible = true;

}
catch (Exception ex)
{
MessageBox.Show(ex.Message, ex.Source, MessageBoxButtons.OK,
MessageBoxIcon.Error);
}
return (Office.CommandBarButton)cbc;
}


Thank you in advance,
 
P

Peter

I haven't used Visual Studio Tools for Office, but after some online research, it sounds like your best bet would be to use VSTO to create a Word template (it looks like you can actually choose a template as a project type) on which you would then base documents. That recommendation is made without full knowledge of VSTO and your project, though, so you should research and experiment more to see which type of solution best fits your needs.
Even with this new tool, VSTO, There are time-tested general guidelines to help you make a good design choice:
- If you're doing a one-off document, build everything into the document. Then you can distribute the document easily.
- If you're going to be generating multiple documents that will have the same characteristics, then a template placed into the user's template directory is a better choice.
- If you want certain things to be available in every document a user opens, then a template/addin in the startup folder is the way to go.

Because my knowledge of VSTO is limited to some research I did last night, I'm not sure what you mean by a "Word application" project type. Perhaps that is similar to the third option above?

As far as how to create the custom menu items, I recommend that you programmatically build your menus because it makes management of the template much easier and the overhead when the template loads is negligible. The code you posted looks like it will do a fine job.

As far as URLs, I don't know that I have anything extra-ordinary.
A google for ["visual studio tools" office] produced the following URL. It has several video tutorials and some code snippets.
http://weblogs.asp.net/vsto2
It looks like MSDN has many useful pages, too.

hth,

-Peter

PS: I'm feeling a little beyond my depth, so if I'm way off someone correct me. :)

Mike said:
Thank you, Peter. You cannot imagine how much I appreciate your help.

I need to generate static menu whose submenus are dynamic, based on changing
xml datasource files on users' dektops. I also have to use Visual Studio
Tools for MS Office (C#). What should I do in that case? What's the approach
I should be taking ?
Should I start the project as template or as Word application ?

Also, is there a good book/url you can recommend?

Many Thanks in Advance,

--Mike

Peter said:
I recommend that you create the custom menus in the template either via VBA or manually customizing the menus, rather than through your external executable.

My best practices recommendation (fwiw) is to use a macro to create your custom menus. If the menus are dynamic (depend on document content, for example), you'll want to call the menu creation macro every time a document attached to the template opens. If the menus are static, then just run the macro once, save the template, and don't re-run the macro again unless you're re-generating the whole template (which is recommended to do every once in awhile to reduce template bloat).
Using a macro to generate custom menu items allows you to quickly and easily change them, or generate them fresh.

If you're going to dynamically generate your custom menus for each document, then wrap your menu-generation calls with
Application.CustomizationContext = ActiveDocument.AttachedTemplate
and
ActiveDocument.AttachedTemplate.Saved = True

That will ensure that your menu changes end up in the template, not in the document, and that the "do you want to save changes to the document template?" prompt won't display.

Example:

Dim oPrint As CommandBarButton

' include with dynamic custom menus
Application.CustomizationContext = ActiveDocument.AttachedTemplate

With Application.CommandBars.Add("MyBar", msoBarTop, , True)
.Enabled = True
.Visible = True
With .Controls
Set oPrint = .Add(Type:=msoControlButton)
With oPrint
.Caption = "Special &Print"
.FaceId = 176
.Style = msoButtonIconAndCaption
.OnAction = "Module1.SpecialPrint"
.TooltipText = "Special Print"
.Enabled = True
.Visible = True
.Priority = 1
End With
End With
End With

' include with dynamic custom menus
ActiveDocument.AttachedTemplate.Saved = True

hth,

-Peter

Mike said:
Menu creation architectural question [VSTO, C#]:

Hi! I am creating MS Word 2003 template with custom built menus and getting
confused on how it works. What I do not understand is at what point the code
will build the menu? I mean should I run this code every time the template
launches? Should I check if the menu is built already? I get prompts to save
the template but have no clue what causes the prompt? Is this the best
solution/architecture? All I want is to build a template which will be
programmatically attached to a Word 2003 document that’s going to be launched
from a C# executable. What makes it even more interesting is that I see the
menu when I launch (F5) in VS IDE for a second and then it disappears. What
am I doing wrong. Please help.

Any ideas/suggestions are greatly appreciated.



Here’s how I create a menu item:

protected void ThisDocument_New()
{
try
{

this.MainMenuBar = ThisApplication.CommandBars["Menu Bar"];
InitMenuBarItems("&Travel Tools");
this.MenuItem = this.CreateButton((Office.CommandBarPopup)this.MenuBarItem,
"& Expense Report");
this.MenuItem.Click += new
Office._CommandBarButtonEvents_ClickEventHandler(MenuItem_Click);

}
catch(Exception ex)
{
MessageBox.Show(ex.Message, ex.Source, MessageBoxButtons.OK,
MessageBoxIcon.Error);
}
}

private Office.CommandBarButton CreateButton(Office.CommandBarPopup Parent,
string Caption)
{
Office.CommandBarControl cbc = null;
try
{
cbc = Parent.Controls.
Add(Office.MsoControlType.msoControlButton,
Type.Missing, Type.Missing, Type.Missing, true);
cbc.Caption = Caption;
cbc.Visible = true;

}
catch (Exception ex)
{
MessageBox.Show(ex.Message, ex.Source, MessageBoxButtons.OK,
MessageBoxIcon.Error);
}
return (Office.CommandBarButton)cbc;
}


Thank you in advance,
 
Top