ActiveX深入淺出(一) (轉)

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

文章標題:深入淺出(一)
載入時間:2001-4-12 17:23:00 瀏覽次數:19
綱要

    可以這樣說,Active平臺代表了的世界觀。使用ActiveX,來構築包括從與互動和適應COM的事務處理監視器,到,全部實現自動化的機構,這就是Microsoft的打算了。桌面用的、基於COM的叫做ActiveX控制元件。所謂ActiveX控制元件不過是遵從一定的標準、與客戶端互動的COM而已。基於元件的應用開發,其方法和組裝電子裝置一樣,可以用已製作好的元件部件來構築應用。這確實是一項很令人神往的技術。雖然說起來高深,但隨著ActiveX的廣泛應用,越來越多的工具都支援建立ActiveX控制元件了。這其中就包括了VB。在VB中設計一個ActiveX並不比一個普通的VB應用難上許多。這篇文章,就是一步步教你如何在VB中建立一個ActiveX控制元件。


ActiveX深入淺出(一)
作 者 : 揚眉


   什麼是ActiveX控制元件?

   一個簡單的回答就是:擁有圖形介面的類。你可能曾經用過類來程式設計,那是一種實現程式碼重用的的好方法。當然,它也提供了很多其它的好處,這兒並不打算一一列舉出來。ActiveX 控制元件將這個概念近一步的深化了,能夠讓你編寫一個視窗小部件(widget),然後把它打包起來,在以後的程式裡用到它,或者作為特定的問題的解決方法,給程式設計師提供更簡便的程式設計方法。 用ActiveX你可以建造“複合式”控制元件,由其它的幾種控制元件組合而成。也就是說,在ActiveX控制元件中你不但可以使用VB中諸如文字框,圖片框之類的普通控制元件,你還可以用其它的ActiveX控制元件來構成你自己的控制元件,實現你想要的功能,並把它打包以背後用。

   ActiveX控制元件的組成

   一個ActiveX控制元件由它的一些成員組成:屬性,方法以及事件。它們之間有什麼樣的邏輯關聯呢?還是用我們的身體來做個例子吧,將身體就看成一個ActiveX控制元件。 這個控制元件首先應該有一些屬性,比如:眼是否睜開屬性。顯然,這個屬性值應該有兩種情況:開或則閉。使用的時候能夠告訴“身體控制元件”讓這個屬性換一個新的值,以決定睜眼或者閉眼,或者得到當前的屬性值,以知道目前的身體狀況。

   方法是控制元件中過程和的統稱,同其它任何的VB函式和過程並沒有什麼不同,你同樣可以向它們傳遞引數,並返回想要的值。假設有一個類描敘了身體這個物件,它應該有“Look”這個方法,並且應該能接受“Direction”這個引數,那麼,這個方法就應該寫成這樣:

   Public Sub Look(Direction As Integer)
   Case Direction
   Case 0
   '向左看
   Case 1
   '向右看
   Case 2
   '向前看
   Case 3
   '向後看
   End Select
   End Sub

   若要求返回值,我們就舉一個“讀”的例子吧。這時你必須把“Read”這個方法宣告成函式而不是過程   :
   Public Function Read() As String
   '讀的一些操作
   Read = "Hello from the World"
   End Function

   在身體控制元件中,我們用的還是“Look”這個方法。當這個方法的時候,就是指定眼睛應該去“看”了。同樣,我們還指定了另外一個方法,“Read”。這一個方法將用來返回看到的東西。

   “方法”這個概念是不是很簡單呢?如果你還不能夠理解,也可以這樣來想:你的控制元件就像是一臺機器,你撥動控制開關(輸入引數),轉動把手(呼叫方法),然後機器的燈閃動,執行起來(方法),最後從機器裡蹦出一些東西(返回值),就是這樣了。但等等……如果你的機器想告訴你什麼事情,它該怎麼做呢?這時就該是“事件”出場了。

   最後,身體控制元件還會提供一個“眨眼”的事件,用來在進行眨眼這個動作的時候,通知開發者發生了這個事件,但是不必知道身體內部的工作方式和為什麼這個事件會被觸發。

   來動手吧,作一個控制元件。不要以為作一個控制元件是非常難的事,雖然它和一般應用程式的編寫是有一點不同的地方。在上面我們已經知道,一個ActiveX控制元件是由屬性,方法和事件組成的,我們先看看如何在程式中實現這些東西,然後再把它們聯絡起來,組合成一個右機的整體。屬性最簡單的形式是用public宣告的公用變數。例如,如果把下面這段程式碼放到你的控制元件工程的宣告部分:

   Public EyeOpen As Boolean

   這樣,你就可以在後邊的程式碼中使用這個屬性了。但是,這種屬性所能夠做的事實在太少了。它幾乎是不能夠正常工作的。因為在程式的設計期間,屬性值的任何變化都必須通知,以便把控制元件例項標記為需要儲存。而又因為屬性值可能顯示在多個地方,因此當屬性值發生改變時必須通知開發環境,以便使它能夠同步顯示“屬性”視窗、“屬性頁”對話方塊等位置上的屬性值。

   上面說的是不是有點難理解呢?要是不明白說的什麼,不要急,你先開啟一個工程,新增一個控制元件,試著改改這個控制元件的一些屬性,在來看看上面的話,是不是明白了呢?我們現在的任務,就是要作一個這樣的控制元件啊。由此可以看出,控制元件程式設計和一般的程式設計還是有一些區別的。那麼,該怎麼實現數行呢?這要使用到屬性過程。

   當一個屬性值被引用或者設定的時候,屬性過程自動的被呼叫。下面我們就來新增一個這樣的屬性:開啟程式碼視窗,再點選“工具”選單,選擇“新增過程”子選單,彈出的對話方塊中,填入過程名“EyeOpen”,然後再把型別設定為“屬性”。當你點了確定之後,VB自動的為你建立了一個屬性過程的原型,程式碼會被新增到程式碼視窗中:

   Public Property Get EyeOpen() As Variant

   End Property

   Public Property Let EyeOpen(ByVal vNewValue As Variant)

   End Property

   剩下的你要做的,是寫入屬性處理程式碼,把這個骨架填滿。

   你可以看到,VB實際上為你寫了兩個,“Get”和“Let”屬性過程,有點疑惑嗎?實際上很簡單:“Get”是當屬性值被引用的時候呼叫的過程,而“Let”則是當屬性值被寫入的時候呼叫的。(事實上還有第三種型別的過程,我們將在後面遇到,這裡先提個醒)要讓一個屬性過程能夠正確的工作,必須還要有一個變數來儲存真正的屬性值。把下面這一行新增到宣告部分:

   Private m_EyeOpen As Boolean

   注意到那個'm_'字首,一般是放在使用者控制元件的內部變數之前。 現在該是填充過程的時候了。先看看Let過程,這個過程帶有一個引數:預設的是名字是vNewValue,variant型別。但我們想要一個布林型別的變數而不是variant,因為眼睛在我們的模型中只有開和閉兩種狀態。所以把這個引數改成“New_EyeOpen As Boolean”。如果你想要這個屬性作為只讀屬性出現,那麼就不要再改動Let過程,讓過程體空在那兒。否則,當想要設定這個屬性值的時候,應該執行這樣的程式碼:

   Public Property Let EyeOpen(New_EyeOpen As Boolean)

   m_EyeOpen = New_EyeOpen

   PropertyChanged "EyeOpen"

   '後面還可以寫一些相關的程式碼,對屬性的設定做出反應

   End Property

   當要在程式中寫入屬性值的時候,就會呼叫這個函式,先把屬性值儲存在一個私有變數裡面,然後執行PropertyChanged這個內部方法,它用來告訴Visual Basic屬性值有了變化,並觸發一個WriteProperties事件。關於這一點的具體的內容,在後面還會提到。

   而Get過程更為簡單!它和標準函式沒有兩樣:

   Public Property Get EyeOpen() As Boolean

   EyeOpen = m_EyeOpen

   End Property

   做完這些就完了嗎?不!忘了前面說的屬性值是需要儲存的,因此當程式設計會話發生轉換的時候,它們能夠保持下來。那麼怎麼樣來儲存和取出屬性值呢?這時就要用到PropertyBag物件了。

   使用PropertyBag

   PropertyBag物件包含兩個方法:一個用來讀出,一個用來寫入。前面提到了,當任何的屬性發生變化得時候,會觸發控制元件的WriteProperties事件。這時就可以把屬性值儲存在屬性包中了。下面的程式碼實現這個功能:

   PropBag.WriteProperty "EyeOpen", m_EyeOpen, True

   PropBag是PropertyBag物件的一個例項。WriteProperty函式包含三個引數,第一格是屬性名稱,後面的是要儲存的值,最後的引數是在無使用者定義屬性的情況下,將寫入的預設值。把這個和ReadPropertiy方法的預設值設定結合起來,就可以為屬性值設定預設值了。如果屬性值和預設值相同,那麼屬性值就不會真正的別儲存。當要讀出的時候,ReadProperty函式發現在屬性包中沒有內容,就會返回預設值。這樣可以節省一些開銷。要注意的是:必須將一個成員屬性的名稱作為字串傳遞。當你將控制元件作國際化處理時,不要改變這一字串的名稱,它必須與該屬性的申明的名稱相匹配。

   當控制元件被重啟動後,你必須過載如所有儲存的屬性值。當每次讀取PropertyBag中的資料時, ReadProperties事件被觸發。在這個事件的處理過程中,你要做的任務就是載入儲存在屬性包中的屬性值,呼叫ReadProperty函式來實現值一點。要注意的是:在讀和寫兩個函式中的預設值設定要一樣。例如:

   m_EyeOpen = PropBag.ReadProperty("EyeOpen", True)

   一個同步預設值的方法是為其設定常量,在需要的時候直接使用常量來代替具體的值,這樣就不用擔心出問題了。例如:

   Private Const m_def_EyeOpen = True

   “m_def_”字首通常放在預設值常量的前面。

   當控制元件被啟動的時候,一般要為屬性設定初始值。這一般是在usercontrol的InitProperties 事件中實現的。這個事件發生於控制元件例項首次實體化時,也就是把控制元件例項放置到窗體上的時候,它在以後的整個設計期間裡都不會再發生。Usercontrol還有一個Initialize事件,它是每次控制元件例項被建立時觸發的。顯然,初始化過程如果放在Initialize事件中就太過頻繁了,沒有這個必要。設計 ActiveX 控制元件需要根本性地轉變一些觀念。需要響應的關鍵事件是往往不同於一般的。下面是我們想要實現的程式碼:

   Private Sub UserControl_InitProperties()

   m_EyeOpen = m_def_EyeOpen

   End Sub

   好,到現在關於屬性的部分基本就結束了,下一篇中我們要講到的是另外的一個成員:方法。

 

 
 


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

相關文章