Word Automation C++ Class
In this article, I will describe the implementation of a C++ class that automates Microsoft Word application. The class uses low-level COM and is quite handy in its usage. The idea came into my mind when I answered two queries on this topic on a discussion forum in just one day!
I named the class 'CAutoWord'. It can open a Word documment file and print its contents on the default printer. Everything works in the background. A typical application can be an NT service which generally runs without any UI. It has following exposed methods.
1. CAutoWord() : Constructor function that initializes COM.
2. int InitAutomation() : Initializes the automation. In case of failure, it returns -1 else 0 is returned.
3. int PrintDocument() : This function will load the file and print the contents on the default printer. Negative return value indicates that an error occurred.
More functions can be added using the same framework.
Usage Scenario
The code snippet given below demonstrates its usage.
#include "AutoWord.h"
int PrintWordDocument(CString szFilePath)
{
// Instantiate an object of CAutoWord
CAutoWord AutoWord;
// Set filepath
int iRetVal = AutoWord.InitAutomation();
if (iRetVal != 0)
{
printf("LoadDocument operation failed.");
}
// Set filepath
char* strFilePath = szFilePath.GetBuffer(szFilePath.
GetLength));
// Print the WORD document
iRetVal = AutoWord.PrintDocument(strFilePath);
if (iRetVal == 0)
{
AfxMessageBox(szFilePath+" was sent to printer.");
}
else
{
AfxMessageBox("Print operation failed.");
}
return iRetVal;
}
Implementation
Following is CAutoWord class declaration :
#include <oaidl.h>
class CAutoWord
{
void Destroy(); // Cleaup function
public:
// Opens, Prints and closes a document
int PrintDocument(char* strFilepath);
// Initializes the automation class and prepares
// it for use.
int InitAutomation();
// Constructor : Initializes COM libraries
CAutoWord();
// Destructor : Calls Detroy() and UnInitializes COM.
virtual ~CAutoWord();
private:
// Keeps value of Dispatch pointer to
// 'Word.Application' instance
IDispatch* m_pDispApp;
// Keeps a pointer to 'Documents' property of
// m_pDispApp interface.
IDispatch* m_pDocuments;
};
Most of the work is done InitAutomation() and PrintDocument() functions.
InitAutomation() creates an instance of the 'Word.Application' object and obtains the pointer to the instance's IUnknown interface.
IUnknown* pUnk;
HRESULT hr = ::CoCreateInstance( clsid,
NULL,
CLSCTX_LOCAL_SERVER,
IID_IUnknown,
(void**) &pUnk);
Calling QueryInterface() on IUnknown gives a pointer to the IDispatch interface (m_pDispApp).
hr = pUnk->QueryInterface(IID_IDispatch,
(void**)&m_pDispApp);
Using GetIDsOfNames(), we get Dispatch Id of 'Documents' property of m_pDispApp interface.
LPOLESTR szDoc = L"Documents";
hr = m_pDispApp->GetIDsOfNames(IID_NULL,
&szDoc,
1,
LOCALE_SYSTEM_DEFAULT,
&dispID);
Now, Invoke() function is called that gives us Dispatch pointer to its 'Documents' property. The pointer is saved in m_pDocuments member variable.
hr = m_pDispApp->Invoke(dispID,
IID_NULL,
LOCALE_SYSTEM_DEFAULT,
DISPATCH_PROPERTYGET,
&dp,
&varRetVal,
NULL,
NULL);
...
m_pDocuments = varRetVal.pdispVal;
PrintDocument() method gets the Dispatch Id of 'Open' method of m_pDocuments interface. Then the invoke function is called with the Word Document's filepath as a parameter. This returns a pointer to the Dispatch interface to this Word document. We call it pDocument.
LPOLESTR szOpenDoc = L"Open";
HRESULT hr = m_pDocuments->GetIDsOfNames(IID_NULL,
&szOpenDoc,
1,
LOCALE_SYSTEM_DEFAULT,
&dispOpenID);
hr = m_pDocuments->Invoke(dispOpenID,
IID_NULL,
LOCALE_SYSTEM_DEFAULT,
DISPATCH_METHOD,
&dpOpen,
&varRetVal,
&excepInfo,
NULL);
...
IDispatch* pDocument = varRetVal.pdispVal;
After pDocument is obtained, it's 'PrintOut' method is called. This actually prints out the contents of the Word Document on the default printer and the document is closed.
LPOLESTR szPrintDoc = L"PrintOut";
hr = pDocument->GetIDsOfNames(IID_NULL,
&szPrintDoc,
1,
LOCALE_SYSTEM_DEFAULT,
&dispPrintID);
hr = pDocument->Invoke(dispPrintID,
IID_NULL,
LOCALE_SYSTEM_DEFAULT,
DISPATCH_METHOD,
&dpPrint,
&varRetVal,
NULL,
NULL);
...
LPOLESTR szCloseDoc = L"Close";
hr = pDocument->GetIDsOfNames(IID_NULL,
&szCloseDoc,
1,
LOCALE_SYSTEM_DEFAULT,
&dispCloseID);
hr = pDocument->Invoke(dispCloseID,
IID_NULL,
LOCALE_SYSTEM_DEFAULT,
DISPATCH_METHOD,
&dpClose,
&varRetVal,
&excepInfo,
NULL);
The Destroy() method simply quits the Word Application's instance.
LPOLESTR szQuit = L"Quit";
HRESULT hr = m_pDispApp->GetIDsOfNames(IID_NULL,
&szQuit,
1,
LOCALE_SYSTEM_DEFAULT,
&dispQuit);
hr = m_pDispApp->Invoke(dispQuit,
IID_NULL,
LOCALE_SYSTEM_DEFAULT,
DISPATCH_METHOD,
&dpQuit,
&varRetVal,
&excepInfo,
NULL);
The Demo project uses CAutoWord class to print the Word files.
Downloads
Download source - 2 KbDownload demo project - 4 Kb

Comments
how to export/extract image in word doc?
Posted by jauming on 04/12/2009 08:36amCool -- but how to get other methods besides print to work ?
Posted by Mike Pliam on 09/29/2007 05:34pmThis is a nice piece of work -- but how can one get a list of the available methods and how to invoke them? Are they in a typelib (*tlb) somewhere? Where? Why are there no replies to these comments / questions ? Has the author gone into hiding?
ReplyVery Good !!!
Posted by anantwakode on 02/17/2006 06:19amVery Good !!!
ReplyUsing SaveAs method on document object
Posted by poc0123 on 11/10/2005 01:47pmhas anybody used this method with more than one dispparam, ie more that just the filename to save doc to? i tried and it's failing... -- poc
ReplyExport text
Posted by ceekay on 02/16/2005 08:07amI need to be able to select the entire document and export it to txt in C++
ReplyHow can I change the printer instead of printing to the default printer.
Posted by Legacy on 05/14/2003 12:00amOriginally posted by: Shruti Pandey
Hi,
I need to do load balancing of the prints, so I need to be able to set different printers on the network rather than just go to the default printer. How can I do that ??? I would really appreciate it if you could help me out.
Thanks alot
Reply-Shruti
How to save as HTML?
Posted by Legacy on 12/03/2001 12:00amOriginally posted by: Martin Bostrom
ReplyPrint Preview ?
Posted by Legacy on 08/04/2001 12:00amOriginally posted by: ramanan
It's realy nice article. But my q'tion is
How can i preview the document without printing ?
thanks in advance
Ramanan
Reply
How to print to a printer driver whch creates a file ?
Posted by Legacy on 04/25/2001 12:00amOriginally posted by: Peter van de Velde
I tried the code but when I try to print to a file (for example acrobat writer) Word will require user interaction
Replywhile it wants a file name. How can I avoid total user interaction ?