在Word中嵌入應用程序
Microsoft Word以其強大的文字處理能力、靈活多變的排版方法、所見即所得以及友好的用戶界面等特點,博得了廣大用戶的肯定。但是,若能將其他一些功能,如機器翻譯、中文校對、全文檢索、實時語音合成等嵌入其中,則可以擴展Word的功能,使開發者能夠更加充分地利用Word資源,加快開發速度。
開發Word應用程序常用的有以下幾種編程語言:Word Basic、VBA(Visual Basic for Applications)和Word API。 盡管Word Basic和VBA功能強大,但作為簡單修改Word的工具,多少有些大材小用。筆者認為,Word API是開發Word應用程序的首選工具,尤其是可以利用C語言代碼的快速、高效和靈活的特點,而且可以使用Word Basic接口函數和Windows動態連接庫編程環境,實現對Word功能的添加。
Word API的使用方法
Word API生成的是一個可在Word中直接運行的Word加載項,它是一個以WLL為擴展文件名的單機動態連接庫。這種WLL是標準的Windows動態連接庫的特殊形式。可以用任何一個創建Windows DLL的環境來編譯、鏈接和建立WLL。
Microsoft Word Developer's Kit(MS Word開發工具箱)中,提供了Word API的接口函數,下面分別加以介紹。
1. Word加載項的啟動和卸載函數
(1) void FAR PASCAL wdAutoOpen(short DocID)
在Word中加載WLL的同時,Word會自動執行這個函數。在執行過程中,函數wdAutoOpen完成以下幾個任務:
·向Word登記WLL中定義的所有函數;
·將WLL中的操作命令添加到Word的主菜單、快捷菜單和工具條中;
·給WLL的操作命令指定快捷鍵;
·完成WLL功能的初始化(如:機器翻譯、中文校對的詞庫讀入等)。
(2) void FAR PASCAL wdAutoRemove(void)
當WLL被卸載時,如果WLL程序中定義了wdAutoRemove(void)函數,Word將在卸載時執行這個函數。在該函數中,可以保存退出時我們定義功能函數生成的必要數據。
2. Word加載項中的登記函數
要想讓Word中的某個主菜單項、快捷菜單項、工具條按鈕或快捷鍵完成我們定義的某個函數,就必須在加載WLL時,先向Word登記我們的應用函數。Word API的接口函數CAPIRigister可以完成登記任務。該函數定義形式如下:
| short CAPIRegister(short DocID, LPUCHAR lpszFunctionName, LPUCHAR lpszDescription); |
3. 在Word中將加載函數添加到主菜單項、快捷菜單項、工具條按鈕和快捷鍵中在WLL中應用函數登記完成之后,就可以在主菜單、快捷菜單和工具條中添加自己的菜單項和快捷鍵。這些工作由下面的函數完成
| AddButton、NewToolbar、ToolsCustomi zeMenu、ToolsCustomizeMenuBar和ToolsCustomizeKeyboard。 |
·在Word工具條中添加一個按鈕:
| short CAPIAddButton (short DocID, LPSTR lpszToolbar, short cPosition, LP STR lpszMacro ,LPSTR lpszFace ); |
*S在Word中添加新的工具條:
| short CAPIAddToolbar(short DocID,LPSTR lpszToolbar); |
·在主菜單中添加新的菜單項:
| short CAPIAddMenu(short DocID,LPSTR lpszMenuName,short Position,short Me nuType); |
·在菜單項中添加新的菜單命令:
| short CAPIAddMenuItem(short DocID, LPSTR lpszMenu, LPSTR lpszName ,LPSTR lpszMenuText,short Position, short MenuType); |
·定義一個新的快捷鍵:
| short CAPIAddkey (short DocID, short keyCode, LPSTR lpszName)。 |
要想定義組合鍵的快捷鍵方式,就需把幾個鍵在Word Basic中的代碼數字的二進制進行按位‘或’運算,將結果傳遞給第二個參數KeyCode。例如:快捷鍵CTRL+S的KeyCode是(256 OR 83)=339。
4. Word API調用Word Basic函數前,函數參數和返回值的數據緩沖區的建立Word中的所有字處理功能都可由對應的Word Basic函數來實現。正是利用這一點,在WLL中可以通過調用Word Basic函數來實現對Word的定制。因此,必須利用Word API函數InitWCB設立調用Word Basic函數時傳遞參數與返回值的數據緩沖區。
| Void InitWCB (WCB far *lpwcb,short retType, LPSTR lpBuffer,short cBufferSize); |
InitWCB的參數說明如下:
例如,下面這段程序是獲取所選區域的字符串字體情況:
WCB wcb; file://Word的參數和返回值傳遞的數據區
shortisbold;
InitWCB(&wcb,TypeShort,NULL,0);
file://設立傳遞Word Basic函數參數和返回值的數據區wcb
WORDFUNCTION(wdBold);
file://調用Word Basic函數Bold()
isbold=wcb.wdoprReturn.Short;
file://從數據區wcb中取出Word Basic函數Bold()的返回值
5. Word Basic函數調用方法
Word中的命令是與Word Basic函數一一對應的。因此,Word API可以通過接口函數用C語言直接調用Word Basic函數來實現Word命令。
注意:在Word API中調用Word Basic命令函數名時均須在Word Basic函數名前加上2個英文字母‘wd’,如:Word Basic函數Bold在Word API中的函數名應為wdBold。
根據這些函數有無返回值與是否為響應對話框的情況,在Word API頭文件basedef.h定義了三種調用方法:WORDCALL、WORDFUCTION和WORDDIALOG。
·若被調用的Word Basic函數無返回值,用Word API接口函數WORDCALL來調用,形式是:WORDCALL(函數名);
· 若被調用的Word Basic函數有返回值,用Word API接口函數WORDFUNCTION來調用,形式是:WORDFUNCTION(函數名);
·若被調用的Word Basic函數是有關對話框操作,用Word API函數WORDDIALOG來調用,形式是:WORDDIALOG(函數名)。
例如:Word Basic中,給所選區域字符標粗體的函數Bold與判斷所選區域字符是否為粗體的函數Bold()的調用方法就不同:
·函數Bold是一個操作,無須返回值,所以調用形式是WORDCALL(wdBld)。
·函數Bold()是一個判斷,必須有返回值,所以調用形式是WORDFUNCTION(wdBold);
6. Word Basic函數參數的傳遞方法
在調用Word Basic帶參函數時,需要通過Word API特定接口函數來傳遞參數。同時,對不同類型的函數,參數的傳遞方法也不同。
(1) 逐個傳遞參數
這種傳遞參數的方法適用于參數位置固定的函數,例如:Word Basic函數:
MenuText$(Type,MenuNumber[,Context])
其中的三個參數是按次序排列的。由于Word API調用Word Basic函數方式是函數名作為WORDCALL、WORDFUCTION和WORDDIALOG的參數,無法一次添加Word Basic函數參數,所以傳遞Word Basic函數參數時需要在InitWCB函數設置數據緩沖區后,依次通過數據緩沖區傳遞參數,第一個賦給Type,第二個賦給MenuNumber,如果有第三個參數則賦給Context。
在向這類函數傳遞參數時,根據待傳遞參數數據類型的不同,有以下4個函數可以選用
·傳遞short型參數的函數:
| void AddShortParam(WCB far *lpwcb, short ShortVal); |
·傳遞long型參數的函數:
| void AddLongParam(WCB far *lpwcb, long LongVal); |
*S 傳遞double型參數的函數:
| void AddDoubleParam(WCB far *lpwcb, double DoubleVal); |
·傳遞字符串參數的函數:
| void AddStringParam(WCB far *lpwcb, LPSTR lpStr); |
例如,下面部分程序的作用是給所選區域字符串著綠色:
| InitWCB(&wcb,TypeShort,NULL,0); AddShortParam(&wcb,4); file://4是綠色在Word中的標識, 將一個short參數放//入參數緩沖區 WORDCALL(wdCharColor); file://調用Word Basic函數CharColor |
(2) 傳遞指定參數
這種傳遞參數的方法適用于參數有標識名指明的函數。這種函數的參數有定義了的標識,傳遞時沒有次序問題。例如:Word Basic中插入空表的函數TableInsertTable: Ta
| bleInserTable [.ConvertForm][,.NumberColumns][,.NumRows][,.InitialColWidth][ ,.Wizard][,.Format] [,.Apply] |
因此,向TableInserTable函數傳遞參數時,只需指明哪一個標識即可。這種情況一般用于具有較多參數的函數。
在向這類函數傳遞參數時,與上面的類似,也是根據參數數據類型的不同,有以下4個函數可以選用:
| ·void AddShortDlgField(WCB far *lpwcb,short ShortVal,short FieldId,shor t fMode); ·void AddLongDlgField(WCB far *lpwcb,long LongVal,short FieldId,short f Mode); ·void AddDoubleDlgField(WCB far *lpwcb,double DoubleVal,short FieldId,s hort fMode); ·void AddStringDlgField(WCB far *lpwcb,LPSTR lpStr,short FieldId,shortf Mode,short cBufferSize); |
其中,傳給FieldId的所有標識名都已在WORD API文件wdfid.h中被定義了。
下面的例子是要在光標所在位置插入一個4*12的空表:
| InitWCB(&wcb, TypeShort , NULL, 0); AddStringDlgField(&wcb, "4",fidNumColumns, fMode, 0); AddStringDlgField(&wcb, "12",fidNumRows, fMode, 0); WORDCALL(wdTableInsertTable); |
上面的fidNumColumns和fidNumRows是在Word API文件wdfid.h中定義的參數標識名。調用函數AddString DlgField,將表的行數"4"和列數"12"直接傳給Word Basic的函數TableInsertTable的兩個參數NumColumns和NumRows。
注意:在Word API文件wdfid.h中被定義了的函數參數的標識名是與Word Basic函數的參數標識名一一對應的,但不同的是,Word API的參數標識名是在WordBasic的參數標識名前加了‘fid’構成的。如:Word Basic的函數TableInsertTable有兩個參數是NumColumns和NumRows,那么,在Word API中的參數標識名就應是fidNumColumns和fidNumRows。
創建WLL的程序框架
本文給出一個用Word API完成的完整WLL框架,來實現如下圖所示Word中的修改。
在Word中加載或卸載WLL
經過編譯、鏈接生成DLL文件(動態連接庫文件)后,必須將文件的擴展文件名.dll改為.wll,以便在加載WLL時能被Word正確識別為Word加載項。
將自己編寫的WLL加載到Word中有以下幾種方法:
·模板方式加載:在Word中主菜單‘文件’中找到‘模板’,進去后按下‘添加’按鈕,選中自己編寫的WLL模板文件(文件擴展名為wll)后‘確定’,加載WLL即可完成。
·打開文件方式加載:像打開一般的Word文檔一樣,打開WLL模板文件,即可完成加載 。
·Word自動完成加載:將WLL模板文件復制..windordstartup目錄下,像Word中的常用模板一樣,在啟動Word時,Word會自動將WLL模板文件加載到Word中。
卸載WLL的方法只有一種:在Word中主菜單‘文件’中找到‘模板’,將‘共用模板及加載項’框中‘translate.wll’前的復選鈕鉤掉后‘確定’,卸載WLL的工作即可完成。