在實際應用中,程式設計者往往喜歡程式能自動生成word說明文檔,說明程式運作的狀況或運作的結果;或者程式能提取資料庫的内容生成word表格,使使用者能 友善的檢視和修改,列印。但是VC++中調用word的确不容易,特别是對word中各種函數的使用,本文以作者的工作經驗詳細介紹一下如何調用word 和進行word表格的填寫,有同樣需求的編友也可檢視一下MSDN中的Automation Microsoft Office 97 and Microsoft office 2000。下面介紹以Microsoft Office 2000 Word為例。

類型庫
一個類型庫是一個提供COM對象功能資訊的檔案或檔案的一部分,而且類型庫包含了有關類的資訊。注意,類型庫并不存儲實際的對象,而隻是存儲 有關這些對象的資訊。類型庫詳細說明了一個自動化客戶機為對象需要調用的方法和屬性的資訊,比如說它詳細的描述了接受或傳回的值。
每一個Microsoft Office應用程式都在一個dll檔案中提供了多種類型庫資源,這種dll檔案叫做目标庫(*.olb)。下面的表列出了Microsoft Office 97和Microsoft office 2000類型庫檔案的名字。
|
在VC++調用word中,我們需要導入msword9.olb才能使用word中的各種功能。

用VC++建立一個自動化客戶機
The COleDispatchDriver Class
vc提供了一個COleDispatchDriver類來處理自動化對象的IDispatch接口,關于COleDispatchDrive類的屬性和函數請讀者自行查閱類庫,這裡就不再贅述。
1. 建立一個新的Dialog-Base MFC AppWizard Exe工程名為"WordAutomation";注意在MFC AppWizard - Step 2 of 4中的Automaiton選項上打上勾,如下圖所示:
圖一 使用AppWizard生成基于對話框的的工程,如上所示選上Automation選項。
2. 在View菜單中,點選ClassWizard,然後進入Automation标簽中點選Add Class,選擇From A Type Library。找到Microsoft Office 2000類型庫msword.olb,選擇_Application,_Document,_Documents,Selection四個類,如有其他需 要(例如畫表也可選擇其他的類)。
圖二 使用ClassWizard從類型庫中建立所需的類
這個過程會在工程中建立兩個新的檔案:msword8.h和msword8.cpp,這些檔案構成了word類型庫的所選擇的類和類的成員函 數。在ClassView視圖中檢視從word類型庫生成的所有的類,然後輕按兩下_Application類來檢視它的定義,你就會注意到 _Application類是來源于COleDispatchDriver。
// _Application wrapper class
class _Application : public COleDispatchDriver
{
......
}
至于這些類和成員函數的功能和用法,我有一個簡便的方法,那就是使用word中工具菜單中的宏的錄制功能,把你所想要進行的操作先用宏錄 制下來,然後檢視這些宏代碼,你就會清楚要使用哪個類,哪些成員函數和成員函數應該帶些什麼參數了。雖然這些代碼都是用VB寫的,但你可以很容易的轉換成 VC++中的代碼。
圖三 進行word寫的VBA宏代碼
VC++會自動地在WordAutomation.cpp中的CWordAutomationApp::InitInstance()中生成如下的代碼,使得COM的服務能有效。
if (!AfxOleInit())
{
AfxMessageBox(IDP_OLE_INIT_FAILED);
return FALSE;
}
3. 接下來選擇對話框資源IDD_WORDAUTOMATION_DIALOG,在對話框中增加一個按鈕命名為IDC_WORD_NEW,在按鈕的處理函數中增加如下的代碼:
COleVariant vTrue((short)TRUE),
vFalse((short)FALSE),
vOpt((long)DISP_E_PARAMNOTFOUND, VT_ERROR);
//開始一個新的Microsoft Word 2000執行個體
_Application oWordApp;
if (!oWordApp.CreateDispatch("Word.Application", NULL))
{
AfxMessageBox("CreateDispatch failed.", MB_OK | MB_SETFOREGROUND);
return;
}
//建立一個新的word文檔
Documents oDocs;
_Document oDoc;
oDocs = oWordApp.GetDocuments();
oDoc = oDocs.Add(vOpt, vOpt, vOpt, vOpt);
//如果是word 98,則應該帶兩個參數,如oDocs.Add(vOpt, vOpt)
//把文本添加到word文檔
Selection oSel;
oSel = oWordApp.GetSelection();
oSel.TypeText("one");
oSel.TypeParagraph();
oSel.TypeText("two");
oSel.TypeParagraph();
oSel.TypeText("three");
//儲存word文檔
_Document oActiveDoc;
oActiveDoc = oWordApp.GetActiveDocument();
oActiveDoc.SaveAs(COleVariant("c://doc1.doc"),
COleVariant((short)0),
vFalse, COleVariant(""), vTrue, COleVariant(""),
vFalse, vFalse, vFalse, vFalse, vFalse);
//退出word應用程式
oWordApp.Quit(vOpt, vOpt, vOpt);
4. 在WoreAutomation.cpp中增加包含頭檔案msword9.h。
注意:增加的頭檔案應該在stdafx.h檔案之後,否則就會導緻編譯錯誤。

利用VC++進行word表格的填寫
我們先利用word的宏的錄制功能,把所要進行的表格填寫的操作錄制下來,檢視VBA的代碼如下所示:
圖四 進行word表格填寫的VBA宏代碼
其中MoveDown為Selection類所定義對象的成員函數,Unit:=wdParagraph, Count:=1為其所帶參數的值。wdParagraph宏的數值是多少,可使用宏的調試器在調試中查出。在VC++中MoveDown所帶參數為三 個,在VBA的幫助中我們可以查到第三個參數不寫會有一個預設值,但在VC++中這個參數不能省略,怎麼知道它數值是多少呢?我們可以照葫蘆畫瓜把它寫進 宏中,Extend:=wdMove,再在調試中查出,其餘的類推。
再次選擇對話框資源IDD_WORDAUTOMATION_DIALOG,在對話框中增加一個按鈕命名為IDC_WORD_TABLEWRITE,在按鈕的處理函數中增加如下的代碼:
BeginWaitCursor();
COleVariant vTrue((short)TRUE), vFalse((short)FALSE),
vOpt((long)DISP_E_PARAMNOTFOUND, VT_ERROR);
_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("建立Word2000服務失敗!");
exit(1);
}
//下面是定義VARIANT變量;
COleVariant varFilePath("word表格.doc");
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.MoveDown(COleVariant((short)4),COleVariant((short)1),COleVariant((short)0));
m_Sel.MoveDown(COleVariant((short)5),COleVariant((short)1),COleVariant((short)0));
m_Sel.TypeText("123456789");
m_Sel.MoveRight(COleVariant((short)1),COleVariant((short)1),COleVariant((short)0));
m_Sel.TypeText("李明");
m_Sel.MoveRight(COleVariant((short)1),COleVariant((short)1),COleVariant((short)0));
m_Sel.TypeText("25");
m_Sel.MoveRight(COleVariant((short)1),COleVariant((short)1),COleVariant((short)0));
m_Sel.TypeText("技術員");
m_Sel.MoveRight(COleVariant((short)1),COleVariant((short)1),COleVariant((short)0));
m_Sel.TypeText("大學");
m_Sel.MoveRight(COleVariant((short)1),COleVariant((short)1),COleVariant((short)0));
m_Sel.TypeText("上海市虹口區民主路315号");
//save word file
_Document oActiveDoc;
oActiveDoc = m_App.GetActiveDocument();
oActiveDoc.SaveAs(COleVariant("c://填寫後表格.doc"),
COleVariant((short)0),
vFalse, COleVariant(""), vTrue, COleVariant(""),
vFalse, vFalse, vFalse, vFalse, vFalse);
m_Docs.ReleaseDispatch();//斷開關聯;
m_Sel.ReleaseDispatch();
//退出WORD
m_App.Quit(vOpt, vOpt, vOpt);
m_App.Quit(vOpt, vOpt, vOpt);
m_App.ReleaseDispatch();
EndWaitCursor();
MessageBox("word表格填寫完畢!","提示",MB_ICONEXCLAMATION);