Demystifying Microsoft Office Object Model – Part I
July 26th, 2009After programming with the Microsoft Office applications like Word, Excel, and PowerPoint for some time, I feel that using these applications in your own solutions can be quite overwhelming for the first timers. So, I thought of writing this post to introduce the concepts to everyone who wants to program/use Office applications in their own solutions.
The idea of this post is to get you acquainted with the generic concepts related to programming Microsoft Office applications (from here on, whenever I use this term I am mainly referring to Word/Excel/PowerPoint; however, this doesn’t mean that other Office applications cannot be automated). I assume that you already know how to create WinForms/MFC projects using Microsoft Visual Studio. So, let’s begin…
Most widely used Microsoft Office suite applications like Word, Excel, and PowerPoint provide developers with various interfaces, using which they can automate many tasks of these applications; called Office Object Model. Office Object Model is nothing, but a set of interfaces/classes/objects (different terms – same meaning) which allows programmers to call/ check/operate various features of these applications programmatically, which is also called *Automation*.
Apart from being desktop applications, Microsoft Office Applications are also COM components, which expose custom Interfaces for you to utilize in your own solutions. Using these components in a C++ based application involves using the COM APIs (like CoCreateInstance etc.). On the other hand, if you are creating a .Net framework based application then you need something called Microsoft Office Primary Interop Assemblies (PIA) installed on your machine. These are the assemblies provided by Microsoft for use in .Net applications specifically. You can download these from following URLs:
Now, before we get into the thick of things, let’s see what it means to use Microsoft Office applications in custom solutions. We will create two applications, viz., a MFC based Dialog box application and a C# based WinForms application. We will then launch Word from these two, and insert a very magical sentence in a new Word document: “Hello World!”…
.
Create a MFC based Dialog box application. Add a button to your main dialog box; double click on it and Visual Studio will generate a click event handler for your button. Leave it as it is for now, we’ll come back to it in a few minutes.
To be able to automate Word from MFC based application, we need to define (or rather generate) few classes which will handle to task of instantiating required COM interface, and making function calls to these interfaces for us. For this, right click on your project node (in solution explorer window) and select Add -> Class… From the Add Class dialog box, select “MFC Class from TypeLib” template and click Add (you may have to select the MFC node in the Categories tree to see this Template); as below:
In the Add Class from TypeLib wizard, select “Microsoft Word XX.0 Object Library” (the value of XX will be 12 if you have Office 2007, and 11 if you have Office 2003 installed on your machine). From the list of available interfaces, select the ones shown in the following screenshot:
On clicking the “Finish” button, the wizard will generate header files corresponding to the classes which we have selected above.
At this moment, if you try to compile your project, you may receive many errors. This is due to a known issue with MFC Class generation wizard (don’t know if Microsoft knows about this, but at least I know it..
), and to fix this open each one of the generated files, and comment the following line:
#import "C:\\Program Files\\Microsoft Office\\Office12\\MSWORD.OLB" no_namespace
This #import is actually not required when using MFC classes generated from TypeLib.
Now, copy and paste the following code snippet in your newly created button’s event handler:
::CoInitialize(NULL); // Initialize the COM related stuff VARIANT vMissing; // VARIANT defining a missing/optional parameter. vMissing.vt = VT_ERROR; vMissing.scode = DISP_E_PARAMNOTFOUND; CApplication wordApp; // Variable to hold our Application class object wordApp.CreateDispatch(_T("Word.Application")); // create the instance of Word wordApp.put_Visible(TRUE); // make our instance visible to user CDocuments docs(wordApp.get_Documents()); // Get the Application.Documents collection object CDocument0 doc ( docs.Add( // Add a new Document to the Documents collection. &vMissing, &vMissing, &vMissing, &vMissing) ); // All the four input parameters are optional. CSelection selection ( wordApp.get_Selection() ); // Get the current selection/cursor position in the newly created document. selection.put_Text ( _T("Hello World!") ); // Here goes our magical sentence in the document. selection.ReleaseDispatch(); // free the COM resrouces held by our Selection object. doc.ReleaseDispatch(); // free the COM resrouces held by our Document object. docs.ReleaseDispatch(); // free the COM resrouces held by our Documents collection object. wordApp.ReleaseDispatch(); // free the COM resrouces held by our Application object. ::CoUninitialize(); // Clean up previously loaded COM related stuff
Also, remember to #include the four header files in the file where you will paste the above code (XXXDlg.cpp).
That’s it; go ahead compile and run your project. When you click your button, it should launch Word with a new document containing “Hello World!” in it… (isn’t that magical?… well I told you so
)
If you are a .Net guy, and looking for a similar example in C#, here are the steps you need to perform…
Create a C# based WinForms application; add a button and its click event handler to your form. In the event handler button copy and paste the following code snippet:
object vMissing = Type.Missing; //object defining missing/optional parameters // Create a new instance of Word Microsoft.Office.Interop.Word.Application wordApp = new Microsoft.Office.Interop.Word.Application(); // Make it visible to the user wordApp.Visible = true; // Get the Documents collection Microsoft.Office.Interop.Word.Documents docs = wordApp.Documents; // Add a new document to the Documents collection Microsoft.Office.Interop.Word.Document doc = docs.Add(ref vMissing, ref vMissing, ref vMissing, ref vMissing); // Get the current selection/cursor position in the newly created document. Microsoft.Office.Interop.Word.Selection selection = wordApp.Selection; // Here goes our magical sentence in the document. selection.Text = "Hello World!";
Now, before you can compile your project, you need to add reference to the assembly which contains definitions of the classes for used above. For this, right click on the *References* folder in your project’s solution explorer, and select Add Reference. From the list of available .Net assemblies select Microsoft.Office.Interop.Word assembly, and click Ok.
Well, that’s it for today. We will discuss about the classes, terms and other related concepts that I have used in today’s snippets in the coming posts, soon. Till then, take care and happy coding



