一、概述
我們在編寫程序,開發軟件的過程中如果能利用已有的程序的功能,那 麼可以大大減輕開發過程中程序員的工作量,同時達到事半功倍的效果。例如在工程中,許 多軟件需要文字處理功能,雖然MFC提供了一些方法,但是具體實現起來既費事,又有一定的 困難,如果我們可以直接使用Office提供的功能,豈不美哉!要實現這一目的,只需要利用 ActiveX Automation 技術就可以輕松實現。本文主要講述了自動化的概念,並通過一個操作 Word文檔的例子來幫助讀者理解VC編程中如何實現自動化。
二、自動化
1.自 動化的概念
在Windows程序開發中,自動化是基於COM/DCOM之上的技術:它可以使一 個應用程序來操縱另外一個程序中的對象,使用該程序提供的豐富的功能;或者是一個應用 程序通過提供一些對象及對象的方法和屬性來允許另外一個程序使用它提供的各種功能。其 中,根據程序是受惠者還是施惠者這一原則,將提供對象和對象屬性方法的應用程序稱為自 動化服務器端;使用對象屬性方法的應用程序叫作自動化的客戶端。自動化服務器讓其它程 序告訴它做些什麼,它揭示的函數和數據稱為方法(Methods)和屬性(Properties)。例如 Microsoft Office套件中的成員Word、Excel等都是自動化服務器。根據自動化的客戶端和服 務器端的不同位置,又可以將自動化分為兩類:
1)如果作為服務器端和客戶端的兩 個不同的應用程序都在同一台計算機上,叫作本地自動化;
2)如果作為服務器端和 客戶端的兩個不同的應用程序是基於網絡的,分別處於不同的計算機上,叫作遠程自動化。
需要讀者注意的是,由於利用了COM技術,客戶端無法直接獲得服務器端的對象來實 現對它的訪問,它必須通過獲取一個指向接口的指針來使用對象提供的功能。這個接口稱為 IDispatch,它是一個簡化的使用多種不同語言的特殊接口(包括象VB這樣不能使用指針的語 言)。這部分內容讀者可以在下面的程序實現過程中細細體味。
說到自動化,不能不 提一下ActiveX控件,它其實是在進程中裝入的極小自動化服務器。這意味著它們的執行速度 極快,它們原來被稱為OLE自定義控件,用來替代VB和VC中使用的16位的VBX控件。由於 ActiveX控件通常被保存為.OCX文件,所以又稱它為OCX控件。因為控件是一個小型化的自動 化服務器,它們需要在自動化客戶端使用,我們又將這時的客戶端應用程序稱為容器應用程 序。ActiveX控件除了屬性和方法外,還包含事件(events),當一些事情需要容器應用程序注 意時,控件才會觸發一個事件,如用戶的單擊等。
2.自動化中的數據類型
在 實現自動化編程中,最重要的一個問題是程序員要明白在自動化的客戶端和服務器端數據是 如何傳遞的。如何提供一個統一安全的機制來實現數據傳遞呢?在VC開發平台上,它提供了 一個叫VARIANT的數據類型來解決這個問題。該數據類型有兩部分組成,第一部分為數據的類 型,第二部分才是具體的數據的數值。在VARIANT數據類型的基礎上,VC提供了ColeVariant 類,它對VARIANT數據類型進行了封裝,這意味著在所有使用VARIANT的地方都可以使用 ColeVariant類的對象。在操作日期和貨幣變量時,VC又提供了兩個類:ColeCurrency和 ColeDateTime,具體的內容,讀者可以參考MSDN。
三、操作Word的例子
本文 的例子演示了如何操作Word實現自動化,這個例子主要是為了輔助解釋說明Visual C++編程 中怎樣實現自動化,幫助讀者對自動化的實現過程有一個感性的認識,所以為了簡單起見, 該程序的功能是僅僅選擇一個Word2000的*.Doc文檔,並將它的內容都在該程序的"視 "中顯示出來。為了達到這個目的,就需要啟動Word打開用戶所選擇的文件,進行全選 和剪貼板操作,然後將數據粘貼到"視"中。
在這個例子的具體實現中,我 們的應用程序為自動化的客戶端,Word為自動化的服務器端。首先生成一個新的單文檔應用 程序,給該項目起個名字為"kk",視的基類選擇CEditView,由於Office中的許多 操作是由VBA語言來實現的,所以我們在使用自動化操作Word的過程中,為了清楚Word的工作 過程,我們要對VBA有所了解,這些知識可以通過在Word中錄制宏來實現。錄制宏的步驟如下 :啟動Word2000,選擇工具菜單下的錄制宏子菜單,為一個新的宏起個名字為Macro1,開始 錄制宏,這時候窗口出現一個浮動工具條,點擊上面的按鈕可以停止或暫停宏的錄制。下面 是實現打開一個Word文檔、全部選擇文檔內容並將數據存放到剪貼板上的操作的宏代碼:
' Sub Macro1()
'
Documents.Open FileName:="基於 Visual C.doc", ConfirmConversions:=False, _
ReadOnly:=False, AddToRecentFiles:=False, PasswordDocument:="", _
PasswordTemplate:="", Revert:=False, WritePasswordDocument:="", _
WritePasswordTemplate:="", Format:=wdOpenFormatAuto
Selection.WholeStory
Selection.Copy
End Sub
查看宏代碼可以點擊Word中工具菜單下的Visual Basic 編輯器。從上面的代 碼中可以看出對Word的這幾個操作用到了Documents、Selection這兩個自動化服務器端顯示 出來的對象和它們的方法。
為了操作Word,需要使用它的類型庫,這可以在 Msword9.olb文件中找到,這個文件通常情況下位於Microsoft Office的安裝目錄下面。利用 Visual C++中的ClassWizard可以方便的向應用程序添加新的類型庫,在程序中啟動 ClassWizard ,選擇Add class…. \From a type library …\C:\OFFICE\msword 9.olb,在彈出的對話框中選擇_Application,_Documents,Selection,這樣就可以為客戶 端程序程序中使用到的每個Word對象建立相應的C++類。這些類的定義和實現分別在 msword9.h和msword9.cpp文件中給出。
為了使我們生成的項目支持自動化,為此我們 要在項目中的StdAfx.h的文件末尾添加上下面一行:#include "afxdisp.h";在 應用程序的InitInstance函數的開始添加下面的調用:
if (CoInitialize (NULL)!=0)
{
AfxMessageBox("初始化COM支持庫失敗!");
exit(1);
}
首先通過COleDispatchDriver的成員函數CreateDispatch()創 建一個Word2000的Applicaion對象,然後通過COleDispatchDriver的成員函數 AttachDispatch()將Documents和Selection對象與Application對象提供的IDispatch接口 關聯起來,在程序對上述對象使用完畢後,要使用COleDispatchDriver的成員函數 ReleaseDispatch()來釋放對象和接口之間的連接。
有了上面的准備工作,下面給 出如何實現上述操作目標的具體代碼,該程序在Windows Me環境下,Visual C++6.0開發平台 上編譯通過,運行正常。
void CKkView::OnMenuAutoDisplay()
{
// TODO: Add your command handler code here
static char BASED_CODE szFilter[] ="Word Files(*doc)|*.DOC||";
CFileDialog fd (true,NULL,NULL,OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT,szFilter,NULL);
CString strFilePath;//用來保存打開的文件名;
if(fd.DoModal()==IDOK)
strFilePath=fd.GetPathName();//獲取要打開的Word文檔的名字;
_Application m_App;//定義Word提供的應用程序對象;
Documents m_Docs;//定義Word提供的文檔對 象;
Selection m_Sel;//定義Word提供的選擇對象;
m_Docs.ReleaseDispatch ();
m_Sel.ReleaseDispatch();
m_App.m_bAutoRelease=true;
if(! m_App.CreateDispatch("Word.Application"))
{
AfxMessageBox ("創建Word服務失敗!");
exit(1);
}
//下面是定義VARIANT變 量;
COleVariant varFilePath(strFilePath);
COleVariant varstrNull ("");
COleVariant varZero((short)0);
COleVariant varTrue (short(1),VT_BOOL);
COleVariant varFalse(short(0),VT_BOOL);
m_Docs.AttachDispatch(m_App.GetDocuments());//將Documents類對象m_Docs和 Idispatch接口關聯起來;
m_Docs.Open (varFilePath,varFalse,varFalse,varFalse,
varstrNull,varstrNull,varFalse,varstrNull,
varstrNull,varTrue,varTrue,varTrue);
//打開Word文檔;
m_Sel.AttachDispatch(m_App.GetSelection());//將Selection類對象m_Sel和Idispatch 接口關聯起來;
m_Sel.WholeStory ();//選擇文檔中的全部內容;
m_Sel.Copy ();//將數據拷貝到剪貼板
this->GetEditCtrl( ).Paste ();//將數據粘貼到程序 的"視"中;
m_Docs.ReleaseDispatch();//斷開關聯;
m_Sel.ReleaseDispatch();
}
本文主要講述了基於自動化技術來操作Word ,實現自動化的客戶端的實現思想,為讀者起到拋磚引玉的作用,讀者可以在此基礎上,實 現對Word、Excel、PowerPoint等服務器端進行更復雜的操作。