Click here to Skip to main content
15,867,453 members
Articles / Programming Languages / VC++

Automating Word 2016 using Visual C++ MFC in Visual Studio 2015

Rate me:
Please Sign up or sign in to vote.
4.95/5 (6 votes)
23 Oct 2016CPOL3 min read 34.8K   1.3K   14   6
This article demonstrates some techniques to automate Word 2016 using Visual C++ MFC in Visual Studio 2015.

Introduction

Some months ago, I had a project of chatting application. In the conversation area of that application, I used Rich Edit control for showing text, emoticons, attached files, …. The solution is similar to the project: “A Rich Edit Control That Displays Bitmaps and Other OLE Objects” of Arthur: Mike O'Neill, thanks Mr. Mike very much for your nice article.

After all, the challenge is that how to put all conversations to a word file to let the Rich Edit control display them. After a few minutes of searching on the CodeProject website, I found the article “Automating Excel 2007 and creating charts using C++ MFC application in Visual Studio 2008” of Arthur: abhinavsly, thanks Mr. abhinavsly very much for your nice article. Based on it, I tried to automate Word and complete my project as expected. Now I want to show a small example to automate Word for reference.

In this article, I describe how to open up the Word application, how to insert text, hyperlink, insert picture, do the same thing when you press any key on the keyboard, …. I used Visual Studio 2015 and Office 2016 for this project but I believe that it works in the same way for other Visual Studio or Microsoft Office versions.

Using the Code

Step 1: Install Microsoft Office 2016 or other version

Step 2: Create AutomateWord project as follows:

Image 1

Select “Dialog based” application type, click “Next”, “Finish” for completing creating a new project.

Step 3: Add Class from Typelib in Class Wizard windows:

Image 2

Add class from File, browse to the “MSWORD.OLB”.

Image 3

Then select the following interfaces:

  • _Application
  • Comments
  • _Document
  • Documents
  • _Font
  • Hyperlinks
  • InlineShapes
  • Range
  • Selection

Image 4

Step 4: Add controls to the dialog as below:

Image 5

Step 5: Coding

Open up the “AutomateWordDlg.h” file to add interfaces’ header files:

C++
#include "CApplication.h"
#include "CComments.h"
#include "CDocuments.h"
#include "CDocument0.h"
#include "CFont0.h"
#include "CnlineShapes.h"
#include "CRange.h"
#include "CSelection.h"
#include "CHyperlinks.h"

At this point, you need to comment out all of the below line in interfaces’s header files:

C++
#import "C:\\Program Files\\Microsoft Office\\Office16\\MSWORD.OLB" no_namespace

Unless you will get a large number of errors in the “msword.tlh” file. Right now, you can try to compile your code and it should be completed without any error.

Add the following interface variables to the CAutomateWordDlg class:

C++
CApplication         m_iAppInterface;
CDocuments           m_iDocuments;
CDocument0           m_iActiveDocument;

Before working out with WORD file, you need to create Word application interface:

C++
BOOL CAutomateWordDlg::CreateApplicationInterface(BOOL bIsVisible)
{
       if (!m_iAppInterface.CreateDispatch(_T("Word.Application")))
       {
              AfxMessageBox(_T("Cannot open the Word"));
              return FALSE;
       }

       // Set visibility, show / hide
       m_iAppInterface.put_Visible(bIsVisible);

       return TRUE;
}

In the CreateApplicationInterface(BOOL bIsVisible) function, if bIsVisible variable is set to TRUE, the WORD application will be shown together with this application and vice versa.

Next, fulfill the application by adding business code of buttons and controls as below:

To open an existing WORD file and revise it:

C++
void CAutomateWordDlg::OnBnClickedAutomatewordOpen()
{
        CFileDialog fdlgFileChooser(true, _T("*.*"), 0, 
                                    4 | 2, _T("Microsoft Word Files|*.*"));

        if (fdlgFileChooser.DoModal() == IDCANCEL)
        {
                return;
        }

        if (IsFileExisted(fdlgFileChooser.GetPathName()))
        {
                // Create application interface with visibility option
                if (!CreateApplicationInterface(
                        ((CButton *)GetDlgItem
                        (IDC_AUTOMATEWORD_VISIBLE))->GetCheck() == BST_CHECKED))
                {
                        return;
                }

                COleVariant ovTrue((short)TRUE);
                COleVariant ovFalse((short)FALSE);
                COleVariant ovOptional((long)DISP_E_PARAMNOTFOUND, VT_ERROR);

                // Get Documents
                m_iDocuments = m_iAppInterface.get_Documents();

                // Open a Document
                m_iActiveDocument = 
                        m_iDocuments.Open(COleVariant(fdlgFileChooser.GetPathName()),
                        ovOptional, ovOptional, ovOptional, 
                        ovOptional, ovOptional, ovOptional,
                        ovOptional, ovOptional, ovOptional, 
                        ovOptional, ovOptional, ovOptional,
                        ovOptional, ovOptional, ovOptional);

                CSelection      iSelection = m_iAppInterface.get_Selection();

                // Go to the end of the document before editing
                iSelection.GoTo(COleVariant((short)3), 
                        COleVariant((short)-1), 
                        ovOptional, 
                        ovOptional);  // 3 = wdGoToLine; -1 = wdGoToLast

                EnableControls(TRUE);
        }
}

After opening a WORD file successful, you should move the cursor to the end of document for editing by using CSelection:: GoTo() as above.

To create a new WORD file:

C++
void CAutomateWordDlg::OnBnClickedAutomatewordNew()
{
        // Create application interface with visibility option
        if (!CreateApplicationInterface(
                ((CButton *)GetDlgItem(IDC_AUTOMATEWORD_VISIBLE))->GetCheck() == BST_CHECKED))
        {
                return;
        }

        COleVariant ovTrue((short)TRUE);
        COleVariant ovFalse((short)FALSE);
        COleVariant ovOptional((long)DISP_E_PARAMNOTFOUND, VT_ERROR);

        // Get Documents
        m_iDocuments = m_iAppInterface.get_Documents();

        // Create a new Document
        m_iActiveDocument = m_iDocuments.Add(ovOptional, ovOptional, ovOptional, ovOptional);

        EnableControls(TRUE);
}

To save and close a Document:

C++
void CAutomateWordDlg::OnBnClickedAutomatewordClose()
{
        COleVariant ovOptional((long)DISP_E_PARAMNOTFOUND, VT_ERROR);

        // Save before closing (Prompt the "Save as" dialog if this is a new document)
        m_iActiveDocument.Save();

        // Close the active document
        m_iActiveDocument.Close(ovOptional, ovOptional, ovOptional);

        // Release dispatch for valid re-creating dispatch in Open / New document activities
        m_iAppInterface.ReleaseDispatch();

        EnableControls(FALSE);
}

To save and close all Documents:

C++
void CAutomateWordDlg::OnBnClickedAutomatewordCloseall()
{
        COleVariant ovNoPrompt((short)FALSE);
        COleVariant ovOptional((long)DISP_E_PARAMNOTFOUND, VT_ERROR);

        // Save all documents (Prompt the "Save as" dialog if this is a new document)
        m_iDocuments.Save(ovNoPrompt, ovOptional);

        // Close all documents
        m_iDocuments.Close(ovOptional, ovOptional, ovOptional);

        // Release dispatch for valid re-creating dispatch in Open / New document activities
        m_iAppInterface.ReleaseDispatch();

        EnableControls(FALSE);
}

To add a text to a Document:

C++
void CAutomateWordDlg::OnBnClickedAutomatewordAddText()
{
        COleVariant ovTrue((short)TRUE);
        COleVariant ovFalse((short)FALSE);
        COleVariant ovOptional((long)DISP_E_PARAMNOTFOUND, VT_ERROR);
        CString strText;

        // Get text
        GetDlgItemText(IDC_AUTOMATEWORD_TEXT, strText);

        CSelection  iSelection = m_iAppInterface.get_Selection();

        // Add text into the document
        iSelection.TypeText(strText);

        // Add a paragraph (return & new line)
        iSelection.TypeParagraph();
}

To add a Hyperlink to a Document:

C++
void CAutomateWordDlg::OnBnClickedAutomatewordAddHyperlinks()
{
        COleVariant ovTrue((short)TRUE);
        COleVariant ovFalse((short)FALSE);
        COleVariant ovOptional((long)DISP_E_PARAMNOTFOUND, VT_ERROR);
        CString strText;

        // Get text
        GetDlgItemText(IDC_AUTOMATEWORD_TEXT, strText);

        CSelection  iSelection = m_iAppInterface.get_Selection();

        // Add a hyperlink to the home page.
        CHyperlinks iHyperlinks = iSelection.get_Hyperlinks();

        iHyperlinks.Add(iSelection.get_Range(), 
                        COleVariant(strText), 
                        ovOptional, 
                        ovOptional, 
                        ovOptional, 
                        ovOptional);

        // Add a paragraph (return & new line)
        iSelection.TypeParagraph();
}

To insert a picture to a Document:

C++
void CAutomateWordDlg::OnBnClickedAutomatewordInsertPicture()
{
        COleVariant ovTrue((short)TRUE);
        COleVariant ovFalse((short)FALSE);
        COleVariant ovOptional((long)DISP_E_PARAMNOTFOUND, VT_ERROR);
        CFileDialog fdlgPicture(TRUE);

        if (fdlgPicture.DoModal() == IDCANCEL)
        {
                return;
        }

        CSelection      iSelection = m_iAppInterface.get_Selection();
        CnlineShapes    iInlineShapes = iSelection.get_InlineShapes();
        COleVariant     ovLinkToFile((short)0);
        COleVariant     ovSaveWithDocument((short)1);

        // Insert picture
        iInlineShapes.AddPicture(fdlgPicture.GetPathName(), 
                        ovLinkToFile, 
                        ovSaveWithDocument, 
                        ovOptional);

        // Add a paragraph (return & new line)
        iSelection.TypeParagraph();
}

To set the font of text:

C++
void CAutomateWordDlg::OnBnClickedAutomatewordSetSelectionTextFont()
{
        CFontDialog fdlgFont;
        if (fdlgFont.DoModal() == IDCANCEL)
        {
                return;
        }

        CSelection      iSelection = m_iAppInterface.get_Selection();

        CFont0          iFont = iSelection.get_Font();

        iFont.put_Name(fdlgFont.GetFaceName());
        iFont.put_Size((float)fdlgFont.GetSize() / 10);
        iFont.put_Color(fdlgFont.GetColor());
        iFont.put_Bold(fdlgFont.IsBold());
        iFont.put_Italic(fdlgFont.IsItalic());
}

To do the same thing when you press the BACKSPACE, DELETE, LEFT, RIGHT, UP, DOWN key on the keyboard:

C++
void CAutomateWordDlg::OnBnClickedAutomatewordBackspace()
{
        CSelection  iSelection = m_iAppInterface.get_Selection();

        iSelection.TypeBackspace();
}

void CAutomateWordDlg::OnBnClickedAutomatewordDelete()
{
        CSelection  iSelection = m_iAppInterface.get_Selection();

        COleVariant ovUnit((short)1);
        COleVariant ovCount((short)1);
        iSelection.Delete(ovUnit, ovCount);
}

void CAutomateWordDlg::OnBnClickedAutomatewordLeft()
{
        CSelection  iSelection = m_iAppInterface.get_Selection();

        COleVariant ovUnit((short)1);
        COleVariant ovCount((short)1);
        COleVariant ovExtend((short)(((CButton *)GetDlgItem
        (IDC_AUTOMATEWORD_SELECTION))->GetCheck() == BST_CHECKED));
        iSelection.MoveLeft(ovUnit, ovCount, ovExtend);
}

void CAutomateWordDlg::OnBnClickedAutomatewordRight()
{
        CSelection  iSelection = m_iAppInterface.get_Selection();

        COleVariant ovUnit((short)1);
        COleVariant ovCount((short)1);
        COleVariant ovExtend((short)(((CButton *)GetDlgItem
        (IDC_AUTOMATEWORD_SELECTION))->GetCheck() == BST_CHECKED));
        iSelection.MoveRight(ovUnit, ovCount, ovExtend);
}

void CAutomateWordDlg::OnBnClickedAutomatewordUp()
{
        CSelection  iSelection = m_iAppInterface.get_Selection();

        COleVariant ovUnit((short)5);
        COleVariant ovCount((short)1);
        COleVariant ovExtend((short)(((CButton *)GetDlgItem
        (IDC_AUTOMATEWORD_SELECTION))->GetCheck() == BST_CHECKED));
        iSelection.MoveUp(ovUnit, ovCount, ovExtend);
}

void CAutomateWordDlg::OnBnClickedAutomatewordDown()
{
        CSelection  iSelection = m_iAppInterface.get_Selection();

        COleVariant ovUnit((short)5);
        COleVariant ovCount((short)1);
        COleVariant ovExtend((short)(((CButton *)GetDlgItem
        (IDC_AUTOMATEWORD_SELECTION))->GetCheck() == BST_CHECKED));
        iSelection.MoveDown(ovUnit, ovCount, ovExtend);
}

Build and run your project and enjoy. There are a lot of things we can do for automating Word but I keep this project quite simple for it to be easy to understand. I will try to do more funny things in the next article.

Points of Interest

For more details of Microsoft Office Development with Visual Studio, you can access the below official link:

History

  • 22nd October, 2016: Version 1.0

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior) Viettel
Vietnam Vietnam
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
QuestionEmbedded Word window in my app Pin
Kondratuk24-May-19 4:15
Kondratuk24-May-19 4:15 
QuestionMy vote of five Pin
staytuned26322-Feb-19 3:40
staytuned26322-Feb-19 3:40 
QuestionHow to do Table manipulation Pin
Member 32816665-Jul-18 0:22
Member 32816665-Jul-18 0:22 
Generalwhy not use vole? Pin
jackyxinli24-Oct-16 14:36
jackyxinli24-Oct-16 14:36 
use vole we can do more things rather than yours
GeneralMy vote of 5 Pin
Member 1281283724-Oct-16 14:36
Member 1281283724-Oct-16 14:36 
GeneralMy vote of 4 Pin
alex.jr.09201524-Oct-16 5:34
alex.jr.09201524-Oct-16 5:34 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.