How to: Automate Word 2010 to convert a document to PDF using VC++

Many a times, people need to convert a Word document to PDF. There are several ways to achieve that. Here, I am discussing a way by automating Word 2010 to convert the document to PDF using VC++. To demonstrate this, I will use Visual Studio 2010, MFC Dialog based application and Word 2010.

We will start with creating a MFC Dialog based application in Visual Studio 2010. Then we will discuss about how to automate Word. In this sample, I will use #import directive to reference the Word library. There are other ways to do automation using VC++. For more information, go through the following links.

Office Automation Using Visual C++
http://support.microsoft.com/kb/196776

HOW TO: Handle Word Events by Using Visual C++ .NET and MFC
http://support.microsoft.com/kb/309294

How to catch Word application events by using Visual C++
http://support.microsoft.com/kb/183599

  1. Create a new Dialog based MFC application in Microsoft Visual Studio 2010 and give the name as ConvertDocumentToPDF
  2. Design the dialog as given below.image
  3. Change the ID of the controls as given below:
    IDC_EDIT1 – IDC_SourceDocument
    IDC_EDIT2 – IDC_DestinationPDF
    IDC_BUTTON1 – IDC_BtnConvert
  4. Open Class Wizard and add member variables for IDC_SourceDocument and IDC_DestinationPDF as shown below:
    image
  5. Open the ConverDocumentToPDFDlg.cpp and add the following code above Class CAboutDlg declaration

    #import “C:\Program Files (x86)\Common Files\microsoft shared\Office14\mso.dll”
    #import “C:\Program Files (x86)\Common Files\microsoft shared\VBA\VBA6\VBE6EXT.olb”
    #import “C:\Program Files (X86)\Microsoft Office\Office14\msword.olb” named_guids, rename(“RGB”, “MsoRGB”), rename(“ExitWindows”, “_ExitWindows”), rename(“FindText”, “_FindText”)

    using namespace Word;

  6. Add the button click event for the Convert button.
  7. Copy the following code to the button click event handler.

    CoInitialize(NULL);

    // Create the Word Application instance
    Word::_ApplicationPtr wordApp;
    HRESULT hr = wordApp.CreateInstance(__uuidof(Word::Application));

    if(FAILED(hr))
    {
    AfxMessageBox(L”Couldn’t create Word instance”);
    return;
    }

    // Make the Word instance visible.
    // This can be omitted, if you want Word to run in background
    wordApp->Visible = VARIANT_TRUE;

    // Get the Documents object
    Word::DocumentsPtr wordDocuments = wordApp->Documents;

    // Update the member variable associated with the controls
    //
    http://msdn.microsoft.com/en-us/library/t9fb9hww(v=VS.80).aspx
    UpdateData();

    // Convert CString to _bstr_t
    _bstr_t sourceFilePath(m_SourceDocument);

    // Open the SourceFile
    Word::_DocumentPtr wordDocument = wordDocuments->Open(&_variant_t(sourceFilePath));

    if(wordDocument == NULL)
    {
    AfxMessageBox(L”Couldn’t open the document”);
    return;
    }

    // File format should be VARIANT with vt as VT_I4
    VARIANT fileFormat;
    fileFormat.vt = VT_I4;
    fileFormat.intVal = Word::WdSaveFormat::wdFormatPDF;

    // Save the file as PDF
    _bstr_t destinationFilePath(m_DestinationPDF);
    wordDocument->SaveAs2(&_variant_t(destinationFilePath), &fileFormat);

    // Close the document and Quit Word
    wordDocument->Close();
    wordApp->Quit();

    CoUninitialize();

  8. Build and run the application.

    One thing to be noted is the way of specifying the FileFormat argument in SaveAs2 method. SaveAs2 method accepts VARIANT * as the argument. Hence the wdFormatPDF enumeration should be wrapped inside a VARIANT as given below:

// File format should be VARIANT with vt as VT_I4
VARIANT fileFormat;
fileFormat.vt = VT_I4;
fileFormat.intVal = Word::WdSaveFormat::wdFormatPDF;

Let me know if there is any question.