|
|
Our Hot Pick: Rising Antivirus 2006 - Certified by TUV & Checkmark! Get 10% discount by entering this coupon code: ONDISCOUNT10
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.
|
|
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.
"DarrylR" <darrylr[ at ]nospam.com> wrote in message news:uLEwxePAGHA.2984[ at ]TK2MSFTNGP09.phx.gbl...
[Quoted Text] > 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.
|
|
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.
[Quoted Text] > 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 :-)
|
|
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.
"Cindy M -WordMVP-" <C.Meister-C[ at ]hispeed.ch> wrote in message news:VA.0000b4b0.0185cd8d[ at ]speedy...
[Quoted Text] > 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.
|
|
|