ActiveX深入淺出(二) (轉)

worldblog發表於2007-12-07
ActiveX深入淺出(二) (轉)[@more@]


深入淺出(二)
作 者 : 揚眉


   What an Event

   事件是用來通知使用的員,某件事情發生了,好讓程式設計師可以相應的處理。事件在VB中比比皆是,例如,當滑鼠點選控制元件事會發生Click事件,文字框內容改變了會發生Change事件,等等。但這兒要講的不同於這些東西,也不同於InitProperties, ReadProperties, WriteProperties前面提到過的事件,那些是已經定義好了的。我們要做的是定義自己的事件。自定義的事件必須宣告在模組的宣告部分,然後就能夠在任何地方任何時候,只要你覺得應該有事件了,就可以觸發它。例如,一個代表眨眼的事件應該這樣宣告:

   Public Event Blink()

   在括號中,你可以放置任何你想要傳遞給事件的引數。對於一個Click事件,這個引數可能滑鼠點選時x和y座標。而這在理,應為只是眨眼,就用不到額外的引數了。

   觸發事件,得使用RaiseEvent方法。對於我們的眨眼事件,我們把它和一個計時器聯絡起來,這樣它就能夠時不時的眨眼了:

   Private Sub Blinker_Timer()

   RaiseEvent Blink

   End Sub

   就這樣,一個事件就完成了,沒有任何技巧或者秘密可言。現在留給程式原作的,只要編寫相應的事件處理過程就行了,就像下面這樣:

   Private Sub BodyControl1_Blink()

   De.Print "嘻嘻,我又眨眼了!"

   End Sub

   到這兒,大部分關於ActiveX控制元件的基本問題都講了。後面的將是一些更高階的內容,包括圖片和字型屬性,“關於”對話方塊,執行時之讀屬性等等。在繼續之前,再看看前面的內容,好好的在理解一下。好了嗎?OK,現在開始更為激動的歷程。

   首先,我們先來看看對於屬性,還有什麼可以挖掘的東西,比如顏色或者圖片之類的東西。

   高階屬性設計

   色彩值被存貯在長整形變數中,但是如果你只是定義一個長整形變數,顯然是不能夠得到像vb中所提供的那個顏色選單:

   這看起來很複雜,實際上做起來卻一點也不難:所有你要做的只是把屬性宣告為OLE_COLOR型別,就像下面這段程式碼所作的那樣:

   Public Property Get BackColor() As OLE_COLOR

   BackColor = UserControl.BackColor

   End Property

   Public Property Let BackColor(ByVal New_BackColor As OLE_COLOR)

   UserControl.BackColor = New_BackColor

   PropertyChanged "BackColor"

   End Property

   記得前面曾經提過除了Let,Get,還有第三種屬性過程嗎?現在揭開迷底:它就是Set屬性過程,當要給變數賦值的時候,是不能用Let,而必須用Set來代替。這是因為儲存在控制元件內部的物件變數,儲存的並不是物件的複製,而只是物件的引用,也就是一個地址了。為了同一般變數的複製儲存區別開來,VB引入了Set屬性過程。

   或許你可能知道:字型和圖片就是儲存在物件中的,而且,它們都擁有各自的的對話方塊來設定相關屬性。要用到這些對話方塊,所有我們要作的就是把圖片或者字型申宣告為Picture或者Font物件型別,並且為其設定Set屬性過程。

   Public Property Get Font() As Font

   Set Font = lblText.Font

   End Property

   Public Property Set Font(ByVal New_Font As Font)

   Set lblText.Font = New_Font

   PropertyChanged "Font"

   End Property

   看看上面的程式碼,你是不是在想:也沒有什麼很難的啊。確實,就是這樣簡單啊。下面,我們來看看如何為控鍵建立只讀屬性。這也是在控制元件的設計中用的比較多的一個內容。

   只讀屬性

   最簡單的方法,就是不要在Let/Set屬性過程中加入任何東西。但通常,這並不能滿足要求,有時,你可能需要一個執行時只讀的屬性。所謂執行時——和設計時相對應,是指控制元件最終在一個開發完成的程式中執行,而設計時指的是控制元件被使用在開發程式的過程中。

   要實現執行時只讀,要用到Usercontrol的AmbientProperties物件。它提供了很多關於控制元件容器的屬性。中有一個UserMode屬性,當控制元件處在執行時狀態時,UserMode值為真。透過在Let/Get過程中提供對UserMode的檢測,就可以很容易的實現執行是隻讀屬性了:

   Public Property Get MultiLine() As Boolean

   MultiLine = m_MultiLine

   End Property

   Public Property Let MultiLine(ByVal New_MultiLine As Boolean)

   If Ambient.UserMode Then

   Err.Raise 382

   Exit Sub

   EndIf

   m_MultiLine = New_MultiLine

   PropertyChanged "MultiLine"

   End Property

   這段程式碼保護屬性只能夠在設計時被修改,如果在執行時試圖改變它, 就會產生“Property is read-only at run-time”錯誤。

   和AmbientProperties物件相近的還有Extender物件。對於Extender物件,在開始編寫控制元件前有必要好好的瞭解。Extender物件是一個晚期繫結的藉口,開發員可以透過它訪問由控制元件容器(而不是控制元件本身)維護和控制的控制元件屬性。它提供了一些屬性,像Name,Enable,Left,Top,Height,Width等等,這些大多出現在一般的控制元件中,在編寫控制元件屬性前,應該看看是否已經存在在Extender物件中,一方面可以避免重複工作,另一方面也更有。

   但是使用Extender物件還存在一些問題:並不是所有的容器都支援訪問相同的Extender屬性。所以選用Extender物件是必須十分小心,否這做出的控制元件只能為特定的容器所使用。但如果你只是為VB開發控制元件,那就不用有這些顧慮了,儘量的用吧。

   還有一點要注意的是,Extender物件不能在usercontrol的initialize事件中訪問它,但是可以在initProperties和ReadProperties事件中使用。

   列舉

   在控制元件中設定屬性時,使用列舉是一種很常見的的方式。它提供了一個下拉選單和若干選項讓你選擇。這樣方便了的操作,又不用考慮過多的相容性和錯誤處理問題,簡化了屬性設定,而且更加。

   首先,必須建立一個列舉結構,放在宣告部分。然後給出一系列的常量和對應的字串。常量值可以零,或者是任何比它前面一個常量值大的整數。如果沒有給出常量,那麼VB自動為其賦值,第一個未指定的賦值為零,其它的值為前面一個數加一:

   Public Enum eDirection

   Left

   Right = 1

   Up

   Down

   End Enum

   要實現列舉屬性,必須建立一個帶有Let和Get屬性過程的標準屬性。這裡的技巧是將屬性的型別宣告為給出的列舉型別:

   Public Property Get Direction() As eDirection

   Direction = m_Direction

   End Property

   Public Property Let Direction(ByVal New_Direction As eDirection)

   m_Direction = New_Direction

   PropertyChanged "Direction"

   End Property

   唯一要注意的是,只能夠在設計時修改屬性列表,而不允許在執行時這麼做。其它的,像讀,寫,儲存和檢索,都和使用標準屬性是一樣的。

   這就是所有的技巧了。難以置信的簡單,是嗎?你的控制元件是不是看起來更為專業了呢?

   Usercontrol物件

   用 所建立的 ActiveX 控制元件總是由 UserControl 物件加上選中放到 UserControl 上的任何控制元件(稱為子控制元件或則組成控制元件)所組成。就象 Visual Basic 窗體一樣,UserControl 物件具有程式碼模組以及視覺化的設計器。將組成控制元件放到 UserControl 物件的設計器上,就象把控制元件放到窗體上一樣。 在窗體上放置 ActiveX 控制元件的例項時,就建立了 UserControl 物件,以及放在 UserControl 設計器上的所有子控制元件的例項。這些物件都被封裝在控制元件中。

   UserControl 物件有自己的屬性、方法和事件。對於一些屬性,像BorderStyle,BackColor等等,與其自己寫程式碼來實現 BackColor 屬性,不如就直接使用UserControl物件的。這就意味著 ActiveX 控制元件的 BackColor 屬性只需要簡單地 UserControl 物件的 BackColor 屬性就行了。同樣地,也可以在UserControl 物件現有的 Click 事件的基礎上設計您的控制元件的 Click 事件。

   事實上在前面的內容中,我們時時都在和這個物件打交道,但是它有一些特別的東西,是應該值的多一些注意的。它的大部分屬性應該在控制元件的設計時來完成設定。在這兒我解釋一些比較晦澀難懂得屬性的含義,還有一些一望既知,就不多費口舌了。

   Alignable屬性,當被設定成真的時候,VB將自動為控制元件新增一個新的屬性:align。這樣就能夠像放置工具條那樣安排控制元件在容器中的位置,而且這還意味著你的控制元件能夠被放置在MDI程式中。

   CanGetFocus屬性,能夠決定使用者控制元件是否能夠在執行時獲得焦點。當要建立一個圖形控制元件,或者像Timer那樣在執行是不可見的控制元件時,就要設定這個值為False。要注意的是:只要控制元件至少包含一個設定為能夠接收焦點的子控制元件,CanGetFocus 屬性就不能設定為 False。如果 CanGetFocus 設定為 False,則其所有的子控制元件都不能設定為接收焦點。

   ControlContainer屬性定義一個控制元件是否能夠像frames或者PictureBoxes控制元件那樣作為控制元件容器包含其它的控制元件。

   DefaultCancel 屬性可以為控制元件新增Default和 Cancel屬性。在新增 Default 和 Cancel 屬性後,控制元件就可充當標準命令按鈕。也就是說當Default被設為Ture後,按下Enter鍵會觸發控制元件的click事件,而當Cancel屬性被設為Ture時,Esc鍵按下也會觸發click事件。

   你可以透過檢查AmbientProperties物件的DisplayAsDefault屬性來知道控制元件是不是預設控制元件。

   InvisibleAtRuntime能夠讓你建立像Timer之類的控制元件,在執行的時候是不可見的。

   最後,ToolboxBitmap 屬性用來指定放在VB工具箱上的圖示的。建議的大小是32x32,但是實踐證明23x23或24x24工作起來更好,32x32是被縮放到那麼大了再顯示出來的。

   屬性的屬性

   說起來有點繞口,也有點費解,是嗎?。VB允許為控制元件的每個成員設定屬性。這裡麵包含了一些較高階的內容,能夠讓你建造更為專業化的控制元件。在選單欄中點選工具|過程屬性,會出現下面的對話方塊:

   你可以在描敘框內輸入一段對控制元件的說明,在幫助上下文識別符號內輸入一個幫助的關聯ID號,將你的控制元件與一個幫助關聯起來,這樣當點了屬性後再按F1鍵就可以給出這個屬性的幫助內容。

   利用“在屬性瀏覽其中使用本頁”欄位,可以給控制元件的定製屬性頁分配選定的號碼。這樣當使用者從VB的屬性中選擇該成員時,VB將直接線是屬性頁。 “屬性分類”欄位能夠讓屬性在VB的屬性瀏覽器的“按分類序”中出現在特定的類別下。這些類別包括外觀,字型,位置,雜項等等,只要選擇一項就行了。“隱藏該成員”可以讓屬性不在屬性瀏覽器中顯示出來,這對於一些不想讓使用者看到得公有成員有用,但是要記住,它只是隱藏而不是不許被使用。而利用“在屬性瀏覽器中不顯示”可以在控制元件的設計時(而不是在執行時)把屬性從屬性瀏覽器中去掉。作為一般的原則,任何用ReadProperties和WriteProperties實現的永久的屬性,都應當被屬性瀏覽器顯示出來,反之,任何非永久性的屬性就不應被顯露出來。

   “預設使用者介面”用來設定控鍵的預設屬性和方法。比如,因為Caption屬性是Lable控鍵的預設屬性,那麼就可以對程式碼進行一些簡化,把

   Label1.Caption = "Hello"

   可以簡寫為:

   Label1 = "Hello"

   最後是關於資料繫結的部分。在VB中,的應用是很常見的。利用MS的資料訪問功能,可以很容易的把控制元件屬性和資料庫的欄位聯絡起來。當選擇了“屬性為資料繫結”和“繫結屬性到資料欄位”兩個核取方塊後,該屬性就可以以標準繫結控鍵的方式執行,這意味著你可以在為該屬性選擇資料庫控制元件和欄位名稱。

   最後的話

   到這兒,幾乎大部分和使用者控制元件有關的內容都講完了。你現在就可以開始為自己的程式定製合適的控制元件,還可以讓別人分享你的成果。雖然內容不是很多,但要完全吃透也不是件容易的事。所以,多看多練還是必要的,學無止境嘛。

   當然,沒有十全十美的東西,對於ActiveX控制元件也是這樣的。合理的使用使用者控制元件是必須要注意的事情。ActiveX控制元件很容易就會變得很複雜,一不小心的話,你所付出的會遠遠多於你所得到的。

   如果你只是想要一個帶有屬性和方法的物件,那麼類或許是更好的選擇。使用者控制元件與應用程式間相對複雜的介面,會佔用較多的資源。而在程式設計方面,控制元件也要比類複雜一些。但是如果你要求屬性,方法和事件實現永久的資料存貯,後者要在程式的外部實現,那麼就要用到使用者控制元件了。總之,不要以為這是一件容易的是。雖然我在這兒講得很簡單,但是對一個完整的使用者控制元件的設計,編寫,以及測試和所作的工作,絕對不會比一個一般的VB應用程式來的少。
 
 


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10752043/viewspace-989670/,如需轉載,請註明出處,否則將追究法律責任。

相關文章