MS Office中的COM应用.docx
《MS Office中的COM应用.docx》由会员分享,可在线阅读,更多相关《MS Office中的COM应用.docx(15页珍藏版)》请在冰点文库上搜索。
![MS Office中的COM应用.docx](https://file1.bingdoc.com/fileroot1/2023-5/23/c8ae6e73-2d78-42ea-8730-245975d148c0/c8ae6e73-2d78-42ea-8730-245975d148c01.gif)
MSOffice中的COM应用
12.2 MSOffice中的COM应用
MSOffice中的COM是应用最广泛的自动化技术,该功能所描述的是利用VisualC++应用程序控制MicrosoftOffice组件。
自动化(OLE自动化)技术允许将现有的程序的功能合并到VC++的应用程序中。
自动化技术建立在组件对象模型(COM)的基础上,系统的COM随操作系统一起安装的动态链接库(DLL)提供一组服务。
例如,应用程序中使用MicrosoftWord的拼写和语法检查功能,而不让用户看到MicrosoftWord:
可以使用Office的OCR技术,自动化也可以使用MicrosoftExcel的所有图表、打印和数据分析工具等。
该技术的特点大大简化了开发过程,加快了开发的进度。
12.2.1 VC++实现Office自动化
1.问题阐述
熟悉VBA的开发者对于这一操作都非常熟悉,在VC++中读取MSWord系统并没有显示的这一功能,但是在Microsoft的Office产品中,都提供了OLEAutomation自动化程序的接口,在VC++中如何实现Office的自动化技术呢?
2.实现技巧
VC++实现Office自动化,通常可以采取以下3种方式实现。
1)利用VisualC++的类向导机制,从Office类型库生成包装类
生成的这些类,以及诸如COleVariant、COleSafeArray和COleException之类的其他MFC类可简化自动化任务,操作更加简单,所以建议采用该方法。
2)通过#import指令引入Office类型库,创建智能指针的方式
智能指针的功能非常强大,但不建议使用它,因为它与MicrosoftOffice应用程序一起使用时,经常会出现引用计数问题。
3)利用C++直接调用COM服务
C++相比上面两种方式实现起来比较困难,但是有时为了避免采用MFC造成的资源开销过大或避免使用#import方式所带来的问题,通常采用此种方式。
类型库与C/C++头文件类似,它包含服务器发布的接口、方法和属性。
VisualC++附带的OLE/COM对象查看器(Oleview.exe)用来查看类型库。
表12-1列出了MicrosoftOffice95、MicrosoftOffice97、MicrosoftOffice2000、MicrosoftOffice2002和MicrosoftOffice2003的类型库文件名。
表12-1 Office类型库
Office版本和类型
类型库文件
Office版本和类型
类型库文件
Access97
Msacc8.olb
PowerPoint2000
Msppt9.olb
JetDatabase
3.5DAO350.dll
Word2000
Msword9.olb
Binder97
Msbdr8.olb
Access2002
Msacc.olb
Excel97
Excel8.olb
Excel2002
Excel.exe
Graph97
Graph8.olb
Graph2002
Graph.exe
Office97
Mso97.dll
Office2002
MSO.dll
Outlook97
Msoutl97.olb
Outlook2002
MSOutl.olb
PowerPoint97
Msppt8.olb
PowerPoint2002
MSPpt.olb
Word97
Msword8.olb
Word2002
MSWord.olb
Access2000
Msacc9.olb
OfficeAccess2003
Msacc.olb
JetDatabase3.51
DAO360.dll
OfficeExcel2003
Excel.exe
Binder2000
Msbdr9.olb
Graph2003
Graph.exe
Excel2000
Excel9.olb
Office2003
MSO.dll
Graph2000
Graph9.olb
OfficeOutlook2003
MSOutl.olb
Office2000
Mso9.dll
OfficePowerPoint2003
MSPpt.olb
Outlook2000
Msoutl9.olb
OfficeWord2003
MSWord.olb
MFC引入类型库的一般步骤如下。
(1)启动MFC的ClassWizard,出现如图12-19所示的对话框。
图12-19 添加类型库向导1
(2)在Office的目录中找到适合版本的类型库,如图12-20所示。
图12-20 添加类型库向导2
(3)选择类型文件后,根据所实现的功能选择不同的类,当然,也可以全部选择,如图12-21所示。
图12-21 添加类型库向导3
(4)单击【OK】按钮,将所选择的类_Application添加到创建应用程序中,如图12-22所示。
图12-22 添加类型库向导4
在MSWord中,_Application的一个对象代表是Word应用程序本身,在VC++中通过自动化技术控制Word时,则可用_Application声名一个类对象,通过CreateDispatch实例化该对象,代码参考如下:
_Application wordApp;
wordApp.CreateDispatch(_T(Word.Applcation));
实例化对象后,应用程序就启动了应用程序,通过对象实例wordApp可以获得Word版本属性、修改Word标题等,可以参考_Application方法和属性。
3.实例代码
本实例演示了利用VC++创建的应用程序打开Word,并且获取Word的版本号,关闭Word文档。
(1)创建一个基于对话框的工程AutoMation,在窗口上放置一个进度条和两个按钮,用于启动和关闭Word。
启动VC++的ClassWizard,添加MSWord的类型库(MSWord.olb),选择要生成的类_Application。
添加后,在源文件文件夹中增加了msword.h和msword.cpp两个文件。
(2)在CAutoMationApp的InitInstance中添加初始化COM的代码:
HRESULThr=AfxOleInit();
if(FAILED(hr))
{
AfxMessageBox("初始化COM失败!
!
");
}
(3)为了处理VARIANT类型方便,在stdafx.h中包含头文件atlbase.h。
(4)添加按钮的处理消息和定时器处理代码。
打开按钮的响应代码:
voidCAutoMationDlg:
:
OnOpenBtn()
{
if(!
m_App.CreateDispatch(CLSID_Application)) //可以采用CLSID启动
{
AfxMessageBox(_T("请检查是否安装了Office"));
return;
}
if(!
m_App.CreateDispatch(_T("Word.Application")))//启动Word
{
AfxMessageBox(_T("请检查是否安装了Office"));
return;
}
else
{
SetTimer(1,500,NULL);
MessageBox("Word启动");
MessageBox(m_App.GetVersion()); //获取Word版本
m_App.SetCaption("thisisatest"); //设置Word的标题
m_nCurStep=0;
m_ProgressCtrl.SetStep(10);
m_ProgressCtrl.SetRange(0,40);
m_App.SetVisible(TRUE);
}
}
关闭按钮的响应代码:
/************************************************************************/
/*关闭Word
/************************************************************************/
voidCAutoMationDlg:
:
OnCloseBtn()
{
//定义调用QUIT时使用的参数
VARIANTVarIsSave,VarInit,VarRoute;
//退出Word时候的不保存参数
VarIsSave.vt=VT_BOOL;
VarIsSave.boolVal=VARIANT_FALSE;
//初始化VARIANT变量
:
:
VariantInit(&VarInit);
:
:
VariantInit(&VarRoute);
//VarRoute.vt=VT_EMPTY;
//VarInit.vt=VT_EMPTY;
//调用Quit,退出Word应用程序
m_App.Quit(&VarIsSave,&VarInit,&VarRoute);
MessageBox("退出Word编辑!
");
m_ProgressCtrl.SetPos(0);
//释放对象指针
m_App.ReleaseDispatch(); //一定要释放
}
定时器处理代码:
voidCAutoMationDlg:
:
OnTimer(UINTnIDEvent)
{
m_nCurStep+=10;
m_ProgressCtrl.SetPos(m_nCurStep);
intn=m_ProgressCtrl.GetPos();
if(n>40)
{
KillTimer
(1);
}
CDialog:
:
OnTimer(nIDEvent);
}
运行效果如图12-23所示。
图12-23 VC++启动Word
12.2.2 VC++读/写Word文档
1.问题阐述
在第7章阐述了读/写文本文件、ini文件、.inf等非复合文档文件,这些文件系统给出了相应的API函数完成了文件的读写,对Word的读取/写入系统没有提供API函数,VC++如何完成Word的读写呢?
2.实现技巧
写Word文档,首先要从Word应用程序获取文档的类的对象,然后设置文档中接收文字位置,最后将文字写入Word文档。
在上一节加入_Application应用程序类,本节继续加入两个类,即Document类和Selection类,按照以前添加类的步骤,将Documents类和Selection类添加进应用程序。
Documents类是文档对象集类,是所有Document对象的集合。
使用Documents对象集合的Add方法可以新建一篇空白文档并将返回的Document对象添至Documents对象集合之中。
Add方法的原型声明如下:
LPDISPATCH Add(
VARIANT*Template,
VARIANT*NewTemplate,
VARIANT*DocumentType,
VARIANT*Visible)
l 参数Template,指定新文档使用的模板名,如果忽略此参数则使用Normal模板。
l 参数NewTemplate,如果此属性设置为True则将文档作为模板打开。
默认值为False。
l 参数DocumentType其值可取下列WdNewDocumentType常量之一。
Ø WdNewBlankDocument创建一个空白文档,默认值。
Ø WdNewEmailMessage新建一个电子邮件信息。
Ø wdNewWebPage新建一个Web页。
l 参数Visible,如果此参数为True,MicrosoftWord将在可见窗口打开文档。
如果此参数为False,Word仍会打开此文档但文档窗口的Visible属性变为False,默认值为True。
Selection类对象用于选定文档的文字,然后对选定部分进行操作,如设置文字的格式或键入文字。
Selection对象代表窗体中的选定内容,每个窗体中只能有一个Selection对象而且只能激活一个Selection对象。
Selection对象代表的选定内容既可以是文档中的一个区域也可以仅仅是一个插入点。
通过Selection对象的TypeText和GetText可对Word文档进行读写操作。
TypeText的函数作用为写Word文档,其函数的声明如下:
voidTypeText(LPCTSTRText);
GetText的函数的作用是读文档,其函数的声明如下:
CStringGetText();
3.实例代码
本实例演示了如何读写Word文档。
创建一个基于对话框的工程ReadWriteWord。
通过上面的方法引入类型库,增加_Application类、Documents类、Selection类。
在对话框上添加两个文本控件,两个按钮。
文本控件分别用于输入和接收文本。
在CreadWriteWord中的InitInstance初始化COM库添加代码如下:
HRESULThr;
hr=AfxOleInit();
if(FAILED(hr))
{
AfxMessageBox("初始化COM失败");
returnFALSE;
}
在ReadWriteWordDlg.h中包含头文件:
#include"msword.h"
#include"atlbase.h"
在stdafx.h中声明自定义消息标识:
#defineWM_SENDWM_USER+1
声明3个_Application、Documents、Selection的对象,参考代码如下:
//Attribute
_Applicationm_App; //Word应用程序对象
Documentsm_Doc; //Word文档对象
Selectionm_Slection; //文档选择对象
声明一个CEdit类的派生类CMyEdit,在CMyEdit中响应WM_CHAR消息,代码如下:
voidCMyEdit:
:
OnChar(UINTnChar,UINTnRepCnt,UINTnFlags)
{
GetParent()->PostMessage(WM_SEND,(WPARAM)nChar,0); //向父窗口发送字符。
CEdit:
:
OnChar(nChar,nRepCnt,nFlags);
}
在ReadWriteWordDlgl类的OnInitDialog函数中实例化Word应用程序,新建Word文档,参考代码如下:
BOOLCReadWriteWordDlg:
:
OnInitDialog()
{
//**************************************************************
try
{
if(!
m_App.CreateDispatch(_T("Word.Application")))//启动Word
{
AfxMessageBox(_T("请检查是否安装了Office"));
returnFALSE;
}
m_App.SetVisible(true);
m_Doc=m_App.GetDocuments();
CComVariantTemplate(_T(""));
CComVariantNewTemplate(false),DocumentType(0),Visible;
m_Doc.Add(&Template,&NewTemplate,&DocumentType,&Visible);
}
catch(_com_error&e)
{
MessageBox(e.ErrorMessage());
}
//*********************************************************
returnTRUE;
}
在ReadWriteWordDlg类中定义WM_SEND的消息体,在ReadWriteWordDlg.h中添加消息函数声明,在ReadWriteWordDlg.cpp中函数的实现参考代码如下:
/************************************************************************/
/*消息体函数
/************************************************************************/
voidCReadWriteWordDlg:
:
SendMsgToWord(WPARAMwParam,LPARAMlParam)
{
CStringstrTmp="";
UINT nChar=wParam;
strTmp.Format("%c",wParam);
m_Slection=m_App.GetSelection();
m_Slection.TypeText(strTmp);
}
写Word按钮的响应参考代码如下:
voidCReadWriteWordDlg:
:
OnWriteBtn()
{
m_Slection=m_App.GetSelection();//Word文档光标输入点
}
读Word按钮的响应参考代码如下:
/************************************************************************/
/*读Word
/************************************************************************/
voidCReadWriteWordDlg:
:
OnReadBtn()
{
m_Slection.GetSections(); //获取光标点
m_Slection.WholeStory(); //对当前文档全选
SetDlgItemText(IDC_READ_ED,m_Slection.GetText());
}
释放对象的参考代码如下:
/**************************************************************************/
/*最后释放声明的对象
/**************************************************************************/
voidCReadWriteWordDlg:
:
OnDestroy()
{
CDialog:
:
OnDestroy();
m_Slection.ReleaseDispatch(); //释放selection对象
m_Doc.ReleaseDispatch(); //释放Document对象
CComVariantSaveChanges(false),OriginalFormat,RouteDocument;
m_App.Quit(&SaveChanges,&OriginalFormat,&RouteDocument);
m_App.ReleaseDispatch(); //释放应用程序类对象。
}
程序的运行效果如图12-24所示。
利用MSWORD.OLB实现多种格式(DOC、rtf、HTML、XML...)转换成TXT
利用MSWORD.OLB实现多种格式(DOC、rtf、HTML、XML...)转换成TXT
首先加载MSWORD.OLB:
classwizard->automation->addclass->fromatypelibrary,选择programfiles/microsoftoffice/office11(用的是office2003)下的MSWORD.OLB,确定后,在工程中生成msword.htmsword.cpp两个文件。
代码部分:
//doc、html、xml转Txt,
_ApplicationoWord;
DocumentsoDocs;
_DocumentoDoc;
COleVariantvOpt(DISP_E_PARAMNOTFOUND,VT_ERROR); //Foroptionalargs
//StartWord
if(!
(oWord.CreateDispatch("Word.Application",NULL)))
{
AfxMessa