熟悉VB的朋友對使用ActiveX控件一定不會陌生,眾多控件極大地方便了編程,但唯一的缺陷是不能動態加載控件,必須在設計時通過引用,將控件放置在窗體上。VB6.0已能夠解決該問題,只是幫助中沒有明確說明,並且沒有描述到一些關鍵功能,由於以前的版本中可以動態創建進程外服務:如果對象是外部可創建的,可在 Set 語句中用 New 關鍵字、CreateObject 或 GetObject 從部件外面將對象引用賦予變量。如果對象是從屬對象,則需使用高層對象的方法,在 Set 語句中指定一個對象引用:
Dim xlApp1 As Excel.Application Set xlApp1 = New Excel.Application
或
Dim xlApp As Object '定義存放引用對象的變量。 Set xlApp = CreateObject("excel.application") xlApp.Visible = True
這些語法很容易造成誤導,以為動態加載ActiveX控件也是此方法,可能有朋友也象我一樣利用CreateObject嘗試了無數次,卻無功而返,不知微軟公司是出於何種考慮,動態加載ActiveX控件是擴展控件集合的方式實現,通過實際摸索,終於就如何實現動態ActiveX控件找出了一條切實可行的方法,下面以一個具體的實例來詳細說明。
一、ActiveX控件
ActiveX 控件是 Visual Basic 工具箱的擴充部分。使用 ActiveX 控件的方法與使用其它標准內裝的控件,如 CheckBox 控件,完全一樣。在程序中加入 ActiveX 控件後,它將成為開發和運行環境的一部分,並為應用程序提供新的功能。
ActiveX 部件通過客戶端/服務器關系與應用程序— 及與部件相互之間— 交互作用。客戶端是使用部件功能的應用程序代碼或部件。服務器是部件及其關聯的對象。例如,假設應用程序使用 ActiveX 控件來提供一個標准的雇員窗體,供公司的多種應用程序使用。提供雇員窗體的 ActiveX 控件就是服務器,使用這個控件的應用程序就是服務器的客戶端。
二、加載方法
VB6.0中對Controls 集合進行了擴展,以前版本中Controls 集合在窗體上列舉出已加載的控件,這在迭代過程中是很有用的。Controls 集合標識一個叫做 Controls 的內在窗體級變量。如果忽略可選的 object 所在處的整數,則關鍵字 Controls 必須包括在內。我們通常在窗口中使用如下代碼:
Text1.Text="Hello, world"
其實也可以使用如下代碼達到同一目的:
Controls(1).Text="Hello, world"
在VB6.0中除了原來的Clear、Remove 方法外(很奇怪,為什麼微軟在VB5.0中只提供這兩種方法,而沒有提供Add方法,因為沒有Add,這兩種方法也就沒什麼用處),增加了Add方法,該方法就是用於動態加載控件的:
Controls.Add(progid as String, Name as String);
progid: ActiveX部件的ProgID,如:"VB.CheckBox";
Name:ActiveX部件加載後的名稱,如: "MyCheckBox";
若要在窗體上添加一個名為MyButton的按鈕,可以使用:
dim oControl as Object '窗體級變量
注意:這裡聲明為Object對象類型
Private Sub LoadControl() Set oControl = Controls.Add ("VB.CommandButton", "MyButton") oControl.Left = 10 oControl.Top = 10 oControl.Visible = True '使控件可見 End Sub
這是VB6.0的標准語法,它在例程中也是如此演示的,不過該方法雖然現實了控件的動態加載,按鈕顯示在窗體上,可以象普通按鈕一樣按下去,但加載的控件不能預先設計響應事件代碼,如:事件Sub MyButton_Click()將是非法的,當然,可以將要響應的事件封裝在控件內部。就編程的觀點來看該方法沒什麼大的用處,開發ActiveX控件的目的是為了資源共享,為了被其他開發人員利用,所以要提供必要的事件接口,顯然利用該方法不行,通過分析VBControls等相關對象,找出VBControlExtender對象與EventInfo相結合能提供事件陷井捕捉,VBControlExtender對象對動態添加控件特別有用,它提供了一套通用的屬性、方法、事件給開發人員,它的一個突出特點是能編程設計控件的事件,熟習類編程的朋友對帶事件的對象聲明一定不會陌生:
Dim WithEvents objElemt as CElemtVBControlExtender也不例外,聲明的語法一樣,只不過它有個特殊的事件ObjectEvent(Info As EventInfo),它能捕捉到對象使用RaiseEvent產生的所有事件,EventInfo數據結構映射了事件的名稱、參數個數和參數的值。VBControlExtender和 EventInfo相結合,采用Select Case 就可以預先將不同類對象的事件放置一起,各自獨立運作。將上面的代碼改寫一下就能提供Click事件了: