ASP講座之十:自己動手寫組件
作者:Eve Cole
更新時間:2009-05-30 19:54:53
在前面的內容中,我們學習了組件的使用,網上的組件雖然不少,但往往小小的一個組件就要你掏出美元來,而國產的組件又太少,想掏點人民幣還沒地兒好掏,算了,您乾脆自己寫吧,其實編寫組件並不難,無非是剛開始寫低水平的組件,慢慢開始寫高水平的組件而已。要寫ActiveX Server Components,有多種工具可供選擇:Visual Basic、C++、Java等等,這裡選擇最簡單的VB6.0,只要你以前用過VB,包你不到1小時之內,做一個小組件出來。
一、 組件編寫速成-編寫組件最基本的步驟本部分主要講解編寫組件的基本步驟,如果你有進一步學習的慾望,請參照VB6.0幫助文檔中“創建ActiveX DLL”部分(MSDN Library中文檔文件名稱為Vbcon98.chm)。
目的:寫一個最簡單的加法器元件,這個元件有兩個屬性,一個方法。我們從最熟悉的地方開始,那就是先假設這個元件已經存在,看看在ASP使用該元件的程式碼:
<%
Dim objSum
' 先建立該元件,元件標識為TestDll.Sum
Set objSum = Server.CreateObject("TestDll.Sum")
' 記住TestDll.Sum 中的“TestDll”,“Sum”。
objSum.augend = 10.52 'augend 屬性為被加數
objSum.addend = 382.41 'addend 屬性為加數
Result = objSum.Plus 'Plus 方法求和
Response.Write Result
Set objSum = Nothing
%>
請務必記住這幾個關鍵字:TestDll、Sum、augend、addend、Plus,這將與接下來的工作緊密關聯。以下是詳細步驟:
1. 執行VB6.0,在「檔案」功能表中,按一下「新工程」→在「新工程」對話方塊中,雙擊「ActiveX DLL」圖示→Visual Basic 將會自動新增一個工程到該新工程中。 Class1(在「工程資源管理器」中可以看到,如圖1)。
2.按F4 鍵開啟「屬性」視窗。雙擊“名稱”屬性把“Class1”改成Sum。
3.在「工程」功能表中,按一下「工程1 屬性」開啟「工程屬性」對話方塊。在「工程名稱」中填寫TestDll,在「工程描述」中填寫「建立ActiveX DLL範例」。如圖2。
提示:ASP建立元件中的識別TestDLL.Sum這兩項的意思明白了吧。
4.在“檔案”選單中,按一下“儲存工程”,分別使用下方的名稱儲存工程檔案:SetupDll.cls和SetupDll.vbp。
5.為Sum 類別建立屬性:
(1) 在「工具」功能表中,選擇「新增過程」開啟「新增過程」對話方塊。在“名稱”方塊中,輸入augend,按一下“屬性”,然後按一下“確定”,如圖3(注意:目前焦點應在程式碼窗口,否則“新增過程”選單無效)。
(2) 在「工具」功能表中,選擇「新增過程」開啟「新增過程」對話方塊。在“名稱”方塊中,輸入addend,按一下“屬性”,然後按一下“確定”。
6.為Sum 類別建立方法:
在「工具」功能表中,按一下「新增過程」以開啟「新增流程」對話方塊。在“名稱”方塊中,輸入Plus,在類型中,你可以選擇“子程序”或“函數”,本例中由於要返回加數與被加數之和,故單擊“函數”,然後單擊“確定”。
現在,前面ASP程式碼中的五個關鍵字詞都已用上,這下很多東西都明白了吧。
7.類別模組Sum程式碼視窗中所有程式碼如下:
Option Explicit
Private mdbl_augend As Double
Private mdbl_addend As Double
Public Property Get augend() As Double
augend = mdbl_augend
End Property
Public Property Let augend(ByVal vNewValue As Double)
mdbl_augend = vNewValue
End Property
Public Property Get addend() As Double
addend = mdbl_addend
End Property
Public Property Let addend(ByVal vNewValue As Double)
mdbl_addend = vNewValue
End Property
Public Function Plus()
Plus = augend + addend
End Function
你已經注意到以上程式碼與系統產生的程式碼有點不同,主要是Public Property Get augend() As Variant部分用實際的資料類型Double取代了。
注意:實際上,當執行x = objSum.augend 語句時,呼叫的是Property Get 過程,取得mdbl_augend的值,而執行objSum.augend = 10.52 語句時,將呼叫Property Let 過程,將10.52賦給mdbl_augend。
8.最後一步,在“檔案”選單中,按一下“產生.Dll(K)…”,產生檔案SetupDll.dll。
到這裡,組件已創建好了。現在,我們可以先在VB6中編寫一個測試工程,測試該檔案正確與否。
1.在「檔案」功能表中,按一下「新建工程」 →雙擊「標準EXE」。
2.在「工程」功能表中,按一下「引用」 →在「引用」對話方塊中按下「瀏覽」按鈕,選擇剛剛編譯過的「SetupDll.dll」檔案→按一下「確定」。
3.最後在程式碼視窗中編寫如下程式碼:
Option Explicit
Private Sub Form_Load()
Dim objSum As TestDll.Sum
Set objSum = New Sum
objSum.augend = 10.52
objSum.addend = 382.41
MsgBox objSum.Plus
End Sub
運行一下,結果正確,接下來我們在ASP使用這個元件。將SetupDll.dll拷貝到Web伺服器中,並用「Regsvr32.exe setupdll.dll」指令註冊該元件,然後在瀏覽器中執行本部分開頭的ASP程式。如果不行的話,你可以嘗試先用VB6的打包工具打包,然後再安裝,組件會自動註冊,而且一些必需的VB6運行文件也會自動安裝。
說明:本部分所有程式均在下載套件的Setupdll.zip中。
上面的例子我們使用屬性過程Property Get和Property Let來新增屬性(Property Get讀取屬性的值,而Property Let給屬性賦值),若需要對設定的值進行校驗,可在Property Let過程中編寫適當代碼。如下面程式碼:
Public Property Let augend(ByVal vNewValue As Double)
If vNewValue < 100 Then
MsgBox "搞什麼!小於100的值,自己心算就行了"
Else
mdbl_augend = vNewValue
End If
End Property
二、 為組件添加屬性和方法的其他途徑
1.新增屬性最簡單的方法:新增公共變量,如上例最簡單的程式碼如下:
Option Explicit
Public augend As Double ' 新增augend 屬性
Public addend As Double ' 新增addend 屬性
Public Function Plus() As Double
Plus = augend + addend
End Function
但是,此方法只能設定可讀/寫屬性,且不能對所賦值進行校驗。如果只需新增唯讀屬性:在上例中,刪除Public Property Let augend(ByVal vNewValue As Double)過程,則augend便成了一隻讀屬性,不能賦值。當然,要新增只寫屬性,只要刪除Property Get過程就可以了。
2.使用類別生成器實用工具
VB6中還有一個新增屬性和方法的工具:在“外接程式”選單中,按一下“外接程式管理員”,在跳出的外接程式管理員對話方塊中選擇“VB Class Builder Utility”,並在載入行為中選擇「載入/卸載」(如圖4)。然後再在“外接程式”選單中點擊“類別產生器實用工具”,您一看就會使用。
三、 告訴你幾個要注意的問題
1. 上面的例子是一個簡單到不能再簡單的組件,比較實用的組件一般都至少還有一個模組(Module)。
2. 如果不小心, Visual Basic 可產生「單執行緒」元件。
也許最常見的一個陷阱是使用了沒有被設計為在ASP 下運行的元件,例如「單線程」元件。因此,請確保在“專案屬性”頁的“通用”標籤上將線程模組設定為“單元線程”。
3. 關於“類型不匹配”錯誤。
一個好的建議是最好聲明Out 參數為Variant,注意上例中沒有這樣設定。
4. 關於全域變數的使用。
盡量避免在元件中使用全域變數。在Visual Basic 術語中,這表示在標準的.BAS 模組中沒有Public 或Global 變數。因為Global 變數並不是真正意義上的全域。每個執行緒都有自己的副本,如果幾種方法恰好在同一執行緒中執行,它們將看到相同的變數;否則它們訪問的是這些變數的不同副本。這表示您可能給了一個全域變數賦值(在執行緒A 中),但其另一個使用者(在執行緒B 中執行)看不到新值。原因是Visual Basic 內部使用「線程本地儲存(TLS)」來引用全域變數。這意味著每個執行緒都有自己的Public 變數的副本,並且因為它存在多個副本,全域資料並不是真正「全域的」。也就是說,恰好在同一線程中運行的用戶才會訪問到同一個變量,不論他們是否期望如此。
最後順便提一下,VB6.0引進了一個全新的Visual Basic應用程式:IIS應用程式。你可以像創建ActiveX DLL一樣創建IIS應用程序,任何用Active Server Pages創建的應用程式都可以在VB開發環境中創建,你可以用單一的VB應用程式完全取代所有的Active Server Pages。