要說做OLE Automation容器,我還是喜歡VB,簡單死了。用VC,TMD能麻
煩死你,不過使用起來“麻煩”也正是說明它相當靈話。其實用VC實現自
動化容器也只是麻煩,並不難。我們一起來試試看怎麼樣?
要做Excel的OLE自動化,前提當然是你得對Excel的可編程對象十分了解,
了解它的最好方法就是使用VBA。為了讓大家有個比較,我們將首先用一
段VB代碼來實現一個最簡單的Excel功能,再償試用VC來實現同樣的功能,
看看工作量的差別有多大。
用VB實現自動化容器的好處是你根本不用知道什麼是自動化,這就是我最
喜歡的傻瓜用法。真的嗎?真的!不信我信就試試看!各位,請打開筆記
本,啟動VB6,建立一個標准工程,然後選擇“工程”->“引用”,再選
中“Microsoft Excel 8.0 Object Library”點OK,Excel對像庫就裝載
進來了,就這麼簡單!然後在窗體建立一個命令按鈕並輸入如下代碼:
Private Sub Command1_Click()
Dim xlsApp As Application
Dim xlsWorkSheet As Worksheet
Dim xlsRange As Range
' 第一段
Set xlsApp = CreateObject("Excel.Application.8")
xlsApp.Visible = True
'第二段
xlsApp.SheetsInNewWorkbook = 1
'第三段
With xlsApp.Workbooks
If (.Count = 0) Then
.Add
End If
End With
'第四段
Set xlsWorkSheet = xlsApp.Worksheets.Item(1)
xlsWorkSheet.Range("A1").Value = "用VB做,多簡單!"
End Sub
上述代碼啟動Excel並在A1單元格中輸入了幾個字,這可能是做這
個操作所用的最少代碼(省略了錯誤處理)。第一段建立了一個
Excel對象並將Excel程序的窗口顯示出來;第二段設置在一個新工
作簿中的工作表數為1;第三段檢查如果沒有可用的工作簿則添加一
個;第四段則向A1單元格裡寫入了一句話。
快運行一遍程序看看,是不是很簡單?哈哈!別高興得太早,我們
要接觸VC做OLE自動化了!心髒不好的朋友請把速效救心丹放在身邊!
如果你接觸過OLE自動化,那一定知道IDispatch接口了,它是OLE自
動化的核心接口,恐怕這是至今為止最慢的一個接口了,呵呵!
微軟的軟件工程師們就是熱心腸,他們怕用MFC的廣大程序員累著,
專門做了一個類來封裝IDispatch接口,這個類就是COleDispatchDriver,
它包裝了IDispatch接口的復雜性,然而IDispatch復雜在什麼地方
呢?到MSDN上查一下,也許你會注意到它的Invoke接口函數了?該
函數應該算是IDispatch的核心函數,因為它將負責所有從自動化對
象中調用方法、設置屬性值以及取得屬性值的所有操作。
也許你看到該函數的原型以後會很softly的說:“TNND!這參數也TMD
太多了!”是呀!要不然怎麼說VC程序員的眼神兒要好呢!光對齊
參數就得要求你8.6的好眼睛,至於老花眼,干脆就不能做OLE程序,
更別提COM接口了!嘻嘻!下面我們仔細研究一下該函數吧:
dispIdMember:該參數是一個DISPID類型。它唯一地指定了待調用
的函數或屬性。要知道,Invoke可不像我們這樣按名稱來確定一個
函數或一個屬性,它是拿這個參數做為函數指針數組的索引。如果
你只知道該函數的名字而不知道這個索引值怎麼辦呢?不要緊,你
可以用IDispatch::GetIDsOfNames從函數名稱得到DISPID。怎麼樣?
這個參數是不是很好填?
請注意Invoke的wFlags參數,它可以是
DISPATCH_METHOD、
DISPATCH_PROPERTYGET、
DISPATCH_PROPERTYPUT
分別表示Invoke函數的工作性質為:調用方法、取得屬性值、設置
屬性值。COleDispatchDriver將上述三個操作分成了三個函數:
InvokeHelper、GetProperty和SetProperty,分解了Invoke函數的
功能。
另外,請注意pDispParams
參數,為了支持有不同參數個數的不同方法,Invoke使用了參數數
組來批量的接受參數,這個很苯的方法卻很實用,你覺得呢?
哇塞!要是這麼詳細地說下去,我不得寫一本書?!得!我們還是
啟動VC玩兒點實用的吧!用向導生成一個Dialog base的框架,並畫
一個按鈕。接下來就是一堆復雜的工作了!
首先在stdafx.h裡加入對IDispatch接口提供支持的頭文件:
#include 《afxDisp.h》
再在應用程序類的InitInstance()函數裡加入:
AfxOleInit(); // 初始化OLE Automation庫
我們應該怎麼引用Excel對象庫呢?按Ctrl+W啟動Class Wizard,
再選擇“Add Class...”->“From a type library...”,然後
選擇“c:\program files\microsoft office\office”目錄下的
“Excel8.olb”,隨後在“confirm classes”對話框的List box
中將列出所有Excel8對象庫中可用的對象。按住ctrl鍵再用箭頭
選中Sheets、_Application、_Worksheet、_Workbook、Workbooks、
Range幾個對象,按確定。哈!你看到在ClassView窗口中多出的
幾個類嗎?現在Excel就可以任由我們擺布啦!
好了,VC的靈話性在這兒將會體現出來了,我們生成的幾個Excel
對象有很多已定義好的函數,但它們可能並不完全適合我們,哈!
我們可以跟據需要來修改這些函數!!當然不能亂改,前提是我
們必須對Excel VBA有詳細的了解!
比如Workbooks類中的Add函數有一個Template參數用於指定模板文
件,但大多數情況我們用不著模板文件,怎麼辦呢?你是否記得在
VBA中這個參數是一個可選項?那就改呗!我們可以用C++的特性,
重載這個函數!在左邊的Workbooks上右鍵->“Add member
function...”,然後在function type中輸入“LPDISPATCH”,在
fucntion declaration輸入“Add()”然後按OK。然後按如下方法