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:
Select “Dialog based” application type, click “Next”, “Finish” for completing creating a new project.
Step 3: Add Class from Typelib in Class Wizard windows:
Add class from File, browse to the “MSWORD.OLB”.
Then select the following interfaces:
_Application
Comments
_Document
Documents
_Font
Hyperlinks
InlineShapes
Range
Selection
Step 4: Add controls to the dialog as below:
Step 5: Coding
Open up the “AutomateWordDlg.h” file to add interfaces’ header files:
#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:
#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:
CApplication m_iAppInterface;
CDocuments m_iDocuments;
CDocument0 m_iActiveDocument;
Before working out with WORD file, you need to create Word application interface:
BOOL CAutomateWordDlg::CreateApplicationInterface(BOOL bIsVisible)
{
if (!m_iAppInterface.CreateDispatch(_T("Word.Application")))
{
AfxMessageBox(_T("Cannot open the Word"));
return FALSE;
}
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:
void CAutomateWordDlg::OnBnClickedAutomatewordOpen()
{
CFileDialog fdlgFileChooser(true, _T("*.*"), 0,
4 | 2, _T("Microsoft Word Files|*.*"));
if (fdlgFileChooser.DoModal() == IDCANCEL)
{
return;
}
if (IsFileExisted(fdlgFileChooser.GetPathName()))
{
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);
m_iDocuments = m_iAppInterface.get_Documents();
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();
iSelection.GoTo(COleVariant((short)3),
COleVariant((short)-1),
ovOptional,
ovOptional);
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:
void CAutomateWordDlg::OnBnClickedAutomatewordNew()
{
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);
m_iDocuments = m_iAppInterface.get_Documents();
m_iActiveDocument = m_iDocuments.Add(ovOptional, ovOptional, ovOptional, ovOptional);
EnableControls(TRUE);
}
To save and close a Document:
void CAutomateWordDlg::OnBnClickedAutomatewordClose()
{
COleVariant ovOptional((long)DISP_E_PARAMNOTFOUND, VT_ERROR);
m_iActiveDocument.Save();
m_iActiveDocument.Close(ovOptional, ovOptional, ovOptional);
m_iAppInterface.ReleaseDispatch();
EnableControls(FALSE);
}
To save and close all Documents:
void CAutomateWordDlg::OnBnClickedAutomatewordCloseall()
{
COleVariant ovNoPrompt((short)FALSE);
COleVariant ovOptional((long)DISP_E_PARAMNOTFOUND, VT_ERROR);
m_iDocuments.Save(ovNoPrompt, ovOptional);
m_iDocuments.Close(ovOptional, ovOptional, ovOptional);
m_iAppInterface.ReleaseDispatch();
EnableControls(FALSE);
}
To add a text to a Document:
void CAutomateWordDlg::OnBnClickedAutomatewordAddText()
{
COleVariant ovTrue((short)TRUE);
COleVariant ovFalse((short)FALSE);
COleVariant ovOptional((long)DISP_E_PARAMNOTFOUND, VT_ERROR);
CString strText;
GetDlgItemText(IDC_AUTOMATEWORD_TEXT, strText);
CSelection iSelection = m_iAppInterface.get_Selection();
iSelection.TypeText(strText);
iSelection.TypeParagraph();
}
To add a Hyperlink to a Document:
void CAutomateWordDlg::OnBnClickedAutomatewordAddHyperlinks()
{
COleVariant ovTrue((short)TRUE);
COleVariant ovFalse((short)FALSE);
COleVariant ovOptional((long)DISP_E_PARAMNOTFOUND, VT_ERROR);
CString strText;
GetDlgItemText(IDC_AUTOMATEWORD_TEXT, strText);
CSelection iSelection = m_iAppInterface.get_Selection();
CHyperlinks iHyperlinks = iSelection.get_Hyperlinks();
iHyperlinks.Add(iSelection.get_Range(),
COleVariant(strText),
ovOptional,
ovOptional,
ovOptional,
ovOptional);
iSelection.TypeParagraph();
}
To insert a picture to a Document:
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);
iInlineShapes.AddPicture(fdlgPicture.GetPathName(),
ovLinkToFile,
ovSaveWithDocument,
ovOptional);
iSelection.TypeParagraph();
}
To set the font of text:
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:
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