Can I call OfficeCodeBehind (vsto) methods from a Windows Forms app?

D

DarrylR

Is it possible to call OfficeCodeBehind methods externally? I have created a
Word 2003 template using VSTO 2003, and I would like to call a few of the
methods implemented in the OfficeCodeBehind class from a Windows Forms
application. I know that I can link the methods to CommandBar buttons and
execute them by calling the CommandBarButton.Execute method. What I'm hoping
to do is call them using a syntax similar to the Application.Run syntax that
is used to execute VBA macros.

Here's how I'm calling a method implemented in the OfficeCodeBehind class
from my Windows Forms application now:

object objTemplatePath = "c:\\program files\\microsoft
office\\templates\\FirstVSTOtemplate.dot";
object oMissing = System.Reflection.Missing.Value;
Microsoft.Office.Interop.Word.ApplicationClass objApp = new
Microsoft.Office.Interop.Word.ApplicationClass();
Microsoft.Office.Interop.Word.Document objDoc = objApp.Documents.Add(ref
objTemplatePath, ref oMissing, ref oMissing, ref oMissing);
Office.CommandBarControl cbc = objDoc.CommandBars["Menu
Bar"].Controls["Custom Code"];
Office.CommandBarButton cbb =
(Office.CommandBarButton)((Office.CommandBarPopup)cbc).Controls["Populate
Scalars"];
cbb.Execute();

I created a method called PopulateScalars() in OfficeCodeBehind that is
hooked to the Click event of the 'Populate Scalars' menu item. The code
above executes the method, but I have no way to determine when the method
has finished, or what the return value is. What I would like to do ideally
is call the PopulateScalars method directly from my Windows Forms
application.

Any help will be greatly appreciated.

Thanks,
Darryl R.
 
D

DarrylR

Here's what I have discovered since my last posting:

If you include a reference to the CodeBehind dll in your Windows Forms
project, is possible to instantiate an instance of the CodeBehind class from
a Windows Forms application. Once you've instantiated the object, you can
call its Startup method and subsequently call any of its public methods.

Here's an example:

object oMissing = Missing.Value;
object strDocPath = "C:\\Program Files\\Microsoft
Office\\Templates\\ClientReportVSTO.dot";
object oTrue = true;
object oFalse = false;
object oDocType = Word.WdNewDocumentType.wdNewBlankDocument;

Word.ApplicationClass objWdClass = new Word.ApplicationClass();
Word.Document objDoc = objWdClass.Documents.Add(ref strDocPath, ref oFalse,
ref oDocType, ref oTrue);

ClientReportVSTO.OfficeCodeBehind ocb = new
ClientReportVSTO.OfficeCodeBehind();
ocb._Startup(objWdClass, objDoc);
ocb.PopulateScalars();

I'm wondering whether the Document object that you pass to the Startup
method even needs to have the VSTO solution attached. It may be possible to
simply create a new Document object and pass that in. Not sure yet.

What I have noticed, however, is that you still have to marshall data across
processes if you call the methods from a Windows Forms application, which is
disappointing. For example, the PopulateScalars method sets some document
Custom Properties. And instead of using the following syntax (which works
when the method is called by the VSTO class directly - e.g. from the
ThisDocument_Open method) to access the CustomDocumentProperties collection
and set a property value:

string strPropertyName = "ProductId";
object objValue = "theproductid";
Microsoft.Office.Core.DocumentProperties objDocProps =
(Microsoft.Office.Core.DocumentProperties)objDoc.CustomDocumentProperties;
objDocProps[strPropertyName].Value = objValue;

I was forced to use the following syntax in order to avoid the 'cast is
invalid' exception that results from the code above:

string strPropertyName = "ProductId";
object objValue = "theproductid";
object oDocCustomProps = objDoc.CustomDocumentProperties;
Type typeDocCustomProps = oDocCustomProps.GetType();
object oCustomProp = typeDocCustomProps.InvokeMember("Item",
BindingFlags.Default |
BindingFlags.GetProperty,
null, oDocCustomProps,
new object[] {strPropertyName});

typeDocCustomProps.InvokeMember("Item",
BindingFlags.Default |
BindingFlags.SetProperty,
null, oDocCustomProps,
new object[] {strPropertyName, objValue} );

I had hoped that calling the PopulateScalars method from an instance of the
CodeBehind class would emulate calling the methods from within the class
(that it wouldn't require marshalling). If anyone has any information about
this, I'd appreciate it.

Thanks in advance,
Darryl R.
 
C

Cindy M -WordMVP-

Hi DarrylR,

It would probably make the most sense to create a "tools" class in the VSTO
project. Then you can simply copy that class into your Windows Forms project.
Or you can create a separate assembly (like a DLL) with your tools in it, and
reference it from any of your projects.

I don't think it makes sense to run a VSTO project only in order to execute a
method in it from another application.
Is it possible to call OfficeCodeBehind methods externally? I have created a
Word 2003 template using VSTO 2003, and I would like to call a few of the
methods implemented in the OfficeCodeBehind class from a Windows Forms
application. I know that I can link the methods to CommandBar buttons and
execute them by calling the CommandBarButton.Execute method. What I'm hoping
to do is call them using a syntax similar to the Application.Run syntax that
is used to execute VBA macros.

Here's how I'm calling a method implemented in the OfficeCodeBehind class
from my Windows Forms application now:

object objTemplatePath = "c:\\program files\\microsoft
office\\templates\\FirstVSTOtemplate.dot";
object oMissing = System.Reflection.Missing.Value;
Microsoft.Office.Interop.Word.ApplicationClass objApp = new
Microsoft.Office.Interop.Word.ApplicationClass();
Microsoft.Office.Interop.Word.Document objDoc = objApp.Documents.Add(ref
objTemplatePath, ref oMissing, ref oMissing, ref oMissing);
Office.CommandBarControl cbc = objDoc.CommandBars["Menu
Bar"].Controls["Custom Code"];
Office.CommandBarButton cbb =
(Office.CommandBarButton)((Office.CommandBarPopup)cbc).Controls["Populate
Scalars"];
cbb.Execute();

I created a method called PopulateScalars() in OfficeCodeBehind that is
hooked to the Click event of the 'Populate Scalars' menu item. The code
above executes the method, but I have no way to determine when the method
has finished, or what the return value is. What I would like to do ideally
is call the PopulateScalars method directly from my Windows Forms
application.

Cindy Meister
INTER-Solutions, Switzerland
http://homepage.swissonline.ch/cindymeister (last update Jun 8 2004)
http://www.word.mvps.org

This reply is posted in the Newsgroup; please post any follow question or
reply in the newsgroup and not by e-mail :)
 
D

DarrylR

Thanks, Cindy. The calling application will ultimately be a Web service, but
users may need to access the functionality by opening the document directly.
That's the only reason that I'm considering VSTO. I'm trying not to
duplicate the implementation in two places.

Regards,
Darryl R.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top