Word Automation C++ Class


Application Security Testing: An Integral Part of DevOps

Environment: VC++ 6.0, Windows 2000 with MS-Office installed.

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.

 // Print the WORD document
 iRetVal = AutoWord.PrintDocument(strFilePath);
 if (iRetVal == 0)
  AfxMessageBox(szFilePath+" was sent to printer.");
  AfxMessageBox("Print operation failed.");

 return iRetVal;


Following is CAutoWord class declaration :
#include <oaidl.h>

class CAutoWord  
 void Destroy(); // Cleaup function

 // 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
 // Destructor : Calls Detroy() and UnInitializes COM.
 virtual ~CAutoWord(); 

 // 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, 
                                 (void**) &pUnk);
Calling QueryInterface() on IUnknown gives a pointer to the IDispatch interface (m_pDispApp).
hr = pUnk->QueryInterface(IID_IDispatch, 
Using GetIDsOfNames(), we get Dispatch Id of 'Documents' property of m_pDispApp interface.
LPOLESTR szDoc = L"Documents";   
hr = m_pDispApp->GetIDsOfNames(IID_NULL, 
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, 
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, 
hr = m_pDocuments->Invoke(dispOpenID, 
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, 
hr = pDocument->Invoke(dispPrintID, 
LPOLESTR szCloseDoc = L"Close";
hr = pDocument->GetIDsOfNames(IID_NULL, 
hr = pDocument->Invoke(dispCloseID, 

The Destroy() method simply quits the Word Application's instance.

LPOLESTR szQuit = L"Quit";
HRESULT hr = m_pDispApp->GetIDsOfNames(IID_NULL, 
hr = m_pDispApp->Invoke(dispQuit, 
The Demo project uses CAutoWord class to print the Word files.


Download source - 2 Kb
Download demo project - 4 Kb


  • how to export/extract image in word doc?

    Posted by jauming on 04/12/2009 08:36am

    how to export/extract image in word doc?

  • Cool -- but how to get other methods besides print to work ?

    Posted by Mike Pliam on 09/29/2007 05:34pm

    This 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?

  • Very Good !!!

    Posted by anantwakode on 02/17/2006 06:19am

    Very Good !!!

  • Using SaveAs method on document object

    Posted by poc0123 on 11/10/2005 01:47pm

    has 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

  • Export text

    Posted by ceekay on 02/16/2005 08:07am

    I need to be able to select the entire document and export it to txt in C++

  • How can I change the printer instead of printing to the default printer.

    Posted by Legacy on 05/14/2003 12:00am

    Originally posted by: Shruti Pandey


    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

  • How to save as HTML?

    Posted by Legacy on 12/03/2001 12:00am

    Originally posted by: Martin Bostrom

    I've tried to modify the code to save a file to HTML, without any success. First I recorded a macro in Word to see what it would look like in VBasic, then tried to do this in C++. I guess I really don't know what I'm doing with the array of arguments sent to Invoke via the DISPPARAMS structure. Any help would be appreciated.

    Code snippet (*NOT WORKING*):

    VARIANTARG vargFname;
    vargFname.vt = VT_BSTR;
    vargFname.bstrVal = _bstr_t("c:\\temp\\bar.htm");

    VARIANTARG vargFileFormat;
    vargFileFormat.vt = VT_INT;
    vargFileFormat.intVal = 103;

    VARIANTARG vargLockComments;
    vargLockComments.vt = VT_BOOL;
    vargLockComments.boolVal = VARIANT_TRUE;

    VARIANTARG vargPassword;
    vargPassword.vt = VT_BSTR;
    vargPassword.bstrVal = _bstr_t("");

    VARIANTARG vargAddToRecentFiles;
    vargAddToRecentFiles.vt = VT_BOOL;
    vargAddToRecentFiles.boolVal = VARIANT_TRUE;

    VARIANTARG vargWritePassword;
    vargWritePassword.vt = VT_BSTR;
    vargWritePassword.bstrVal = _bstr_t("");

    VARIANTARG vargReadOnlyRecommended;
    vargReadOnlyRecommended.vt = VT_BOOL;
    vargReadOnlyRecommended.boolVal = VARIANT_FALSE;

    VARIANTARG vargEmbedTrueTypeFonts;
    vargEmbedTrueTypeFonts.vt = VT_BOOL;
    vargEmbedTrueTypeFonts.boolVal = VARIANT_FALSE;

    VARIANTARG vargSaveNativePictureFormat;
    vargSaveNativePictureFormat.vt = VT_BOOL;
    vargSaveNativePictureFormat.boolVal = VARIANT_FALSE;

    VARIANTARG vargSaveFormsData;
    vargSaveFormsData.vt = VT_BOOL;
    vargSaveFormsData.boolVal = VARIANT_FALSE;

    VARIANTARG vargSaveAsAOCELetter;
    vargSaveAsAOCELetter.vt = VT_BOOL;
    vargSaveAsAOCELetter.boolVal = VARIANT_FALSE;

    VARIANTARG argArray [11];

    argArray[ 9]=vargFileFormat;
    argArray[ 8]=vargLockComments;
    argArray[ 7]=vargPassword;
    argArray[ 6]=vargAddToRecentFiles;
    argArray[ 5]=vargWritePassword;
    argArray[ 4]=vargReadOnlyRecommended;
    argArray[ 3]=vargEmbedTrueTypeFonts;
    argArray[ 2]=vargSaveNativePictureFormat;
    argArray[ 1]=vargSaveFormsData;
    argArray[ 0]=vargSaveAsAOCELetter;

    DISPPARAMS dpSave = { argArray, NULL, 11, 0 };
    DISPID dispSaveID;
    LPOLESTR szSaveDoc = L"SaveAs";
    hr = pDocument->GetIDsOfNames(IID_NULL, &szSaveDoc, 1, LOCALE_SYSTEM_DEFAULT, &dispSaveID);
    hr = pDocument->Invoke(dispSaveID, IID_NULL, LOCALE_SYSTEM_DEFAULT, DISPATCH_METHOD, &dpSave, &varRetVal, NULL, NULL);
    if (FAILED(hr))
    OutputDebugString("The document could not be saved\n");
    return -1;

  • Print Preview ?

    Posted by Legacy on 08/04/2001 12:00am

    Originally posted by: ramanan

    It's realy nice article. But my q'tion is
    How can i preview the document without printing ?
    thanks in advance


  • How to print to a printer driver whch creates a file ?

    Posted by Legacy on 04/25/2001 12:00am

    Originally 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
    while it wants a file name. How can I avoid total user interaction ?

  • You must have javascript enabled in order to post comments.

Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • As all sorts of data becomes available for storage, analysis and retrieval - so called 'Big Data' - there are potentially huge benefits, but equally huge challenges...
  • The agile organization needs knowledge to act on, quickly and effectively. Though many organizations are clamouring for "Big Data", not nearly as many know what to do with it...
  • Cloud-based integration solutions can be confusing. Adding to the confusion are the multiple ways IT departments can deliver such integration...

Most Popular Programming Stories

More for Developers

RSS Feeds

Thanks for your registration, follow us on our social networks to keep up-to-date
We have made updates to our Privacy Policy to reflect the implementation of the General Data Protection Regulation.