by Matthew Gray - GUI Computing
在進(jìn)行這項課題的研究之前,VB6 WebClasses(網(wǎng)頁(yè)類(lèi))對于我來(lái)說(shuō)是充滿(mǎn)神秘的。因此尋找一個(gè)充滿(mǎn)精力的高手來(lái)揭開(kāi)它的面紗是非常艱巨的。但VB6的組件將使得這一困難變得容易解決?;谶@一原因,請跟著(zhù)我繼續滿(mǎn)懷信心地閱讀下去,我們將會(huì )對網(wǎng)頁(yè)類(lèi)及其特點(diǎn)有一個(gè)較為深刻的了解。
在VB6產(chǎn)生以前,創(chuàng )建IIS應用的唯一方法是編寫(xiě)ASP程序,通過(guò)使用憑借VB,Delphi或其他語(yǔ)言建立的組件來(lái)創(chuàng )建COM DLLs(動(dòng)態(tài)鏈接庫)。(可以參見(jiàn)Jim Karabatsos的文章,VB6——一個(gè)最近問(wèn)題的首要見(jiàn)解)。對于同樣的開(kāi)發(fā)任務(wù),如果你不介意使用一些VBScript和一些Visual Basic的話(huà)(當然還可能包括一些Delphi),這將是一個(gè)非常好的選擇。這是我個(gè)人的意見(jiàn),但并不完全是個(gè)人性質(zhì)的。
網(wǎng)頁(yè)類(lèi)改變了一切,使得你可以編寫(xiě)VB6代碼,該代碼包容在A(yíng)ctiveX DLL中(位于服務(wù)器端),這些DDL可以訪(fǎng)問(wèn)來(lái)自瀏覽器的HTTP請求。這就意味著(zhù)你可以使用VB6代碼在A(yíng)SP中做任何事情,并工作于VB6 IDE中,這是一種巨大的獎賞。
在這種方式下工作意味著(zhù)你不必了解ASP(許多人也不希望了解),因為IIS應用只需要創(chuàng )建一頁(yè)包含網(wǎng)頁(yè)類(lèi)的ASP網(wǎng)頁(yè)(并且只要你不熱衷與此就不必編輯它)。在這之后,所有的任務(wù)都將由新鮮并充滿(mǎn)活力的VB來(lái)完成(好象這并沒(méi)有打開(kāi)一個(gè)充滿(mǎn)可能性的世界?)
IIS應用的本質(zhì)特點(diǎn)是將許多工作轉移到組件的內部去完成,從而徹底將用戶(hù)接口與應用的內核部分徹底地分離開(kāi)。
整個(gè)UI都可以由在HTML中帶有記名標簽的HTML/圖形設計器來(lái)產(chǎn)生(動(dòng)態(tài)數據會(huì )在將來(lái)替換這些標簽)。網(wǎng)頁(yè)類(lèi)在事件中處理這些標簽并產(chǎn)生動(dòng)態(tài)的HTML,在寫(xiě)HTML模板的時(shí)候你可以替換這些標簽。然而,網(wǎng)頁(yè)類(lèi)并不局限于產(chǎn)生純粹的HTML。它們可以返回任何有效的MIME類(lèi)型,包括諸如動(dòng)態(tài)HTML,XML等。
IIS應用在這方面的發(fā)展特點(diǎn)十分類(lèi)似于標準的VB應用,如果你注意觀(guān)察了以下的一般生命周期:
VB應用:創(chuàng )建窗體,編寫(xiě)代碼,調試和測試,打包和發(fā)布。
IIS應用:創(chuàng )建HTML文件,編寫(xiě)代碼,調試和測試,打包和發(fā)布。
對于那些希望遠離這種做法的人來(lái)說(shuō),如下的說(shuō)法聽(tīng)起來(lái)更加合理:
創(chuàng )建HTML文件,重建基于HTML的ASP,編寫(xiě)VB代碼(DDLs或者其他組件),調試和測試,編寫(xiě)ASP代碼,“調試”和測試,打包和發(fā)布——太麻煩了!
那么網(wǎng)頁(yè)類(lèi)又是什么呢?
網(wǎng)頁(yè)類(lèi)是一種用Visual Basic創(chuàng )建的位于Internet 信息服務(wù)器(IIS)上的COM DLL(動(dòng)態(tài)鏈接庫)。網(wǎng)頁(yè)類(lèi)允許你創(chuàng )建服務(wù)器端的應用,并能夠處理所有網(wǎng)頁(yè)服務(wù)器上的任務(wù),將HTML頁(yè)作為用戶(hù)接口,支持在任何瀏覽器下進(jìn)行瀏覽。
一般來(lái)說(shuō),當編譯的時(shí)候,網(wǎng)頁(yè)類(lèi)產(chǎn)生一個(gè)相應的ASP頁(yè)來(lái)用于駐留服務(wù)器上的網(wǎng)頁(yè)類(lèi)。這個(gè)ASP頁(yè)基本上通過(guò)了網(wǎng)頁(yè)類(lèi)并包括它的應用、請求、響應以及服務(wù)器和會(huì )話(huà)對象,以使得VB可以使用在代碼級這些對象(需要注意的是自己進(jìn)行這項工作將會(huì )十分容易,并由此擁有自己的網(wǎng)頁(yè)類(lèi),但是VB6的網(wǎng)頁(yè)類(lèi)將會(huì )提供比ASP對象更多的東西(這些我們將在后面看到))。
網(wǎng)頁(yè)類(lèi)的生命周期
Initialise,BeginRequest,EndRequest,Start和Terminate都是網(wǎng)頁(yè)類(lèi)生命中最關(guān)鍵的事件。從事件的名字中可以推斷出,這些事件顯然可以與基于表單應用的Load和Unload事件相比較。一個(gè)IIS應用的BeginRequest 和EndReques事件可以執行一些Load和Unload事件所能夠執行的功能,這些事件可以用來(lái)初始化你的應用程序運行所需要的數值,并在請求結束之后清除數據和其他的值。Begin 和EndRequest事件是網(wǎng)頁(yè)類(lèi)所獨有的。一個(gè)網(wǎng)頁(yè)類(lèi)可以在其生命進(jìn)程中接收多個(gè)請求。這些事件允許網(wǎng)頁(yè)類(lèi)作為一個(gè)獨立的實(shí)體去處理每一個(gè)請求。Start事件一般在事件BeginRequest第一次應用被激活時(shí)發(fā)生,Terminate事件將告訴運行時(shí)間DLL(動(dòng)態(tài)鏈接庫)去清除網(wǎng)頁(yè)類(lèi)的初始值。
注意:如果網(wǎng)頁(yè)類(lèi)的StateManagement屬性被設置為wcNoState,網(wǎng)頁(yè)類(lèi)將在其每次送一個(gè)響應給瀏覽器時(shí)激活Terminate事件。如果網(wǎng)頁(yè)類(lèi)的StateManagement屬性被設置為wcRetainInstance,網(wǎng)頁(yè)類(lèi)僅僅在其調用ReleaseInstance方法以后激活Terminate事件。從我的經(jīng)驗來(lái)說(shuō),你將在大部分情況下運行于后一種模式。
網(wǎng)頁(yè)類(lèi)包括一些什么呢?
網(wǎng)頁(yè)類(lèi)包括一個(gè)或多個(gè)WebItems,它們可以是如下兩種東西的一種:
模板(HTML模板文件)——與你的網(wǎng)頁(yè)類(lèi)相關(guān)的一個(gè)HTML文件,該網(wǎng)頁(yè)類(lèi)通常包含特殊的標簽,數據可以在網(wǎng)頁(yè)類(lèi)中通過(guò)VB代碼進(jìn)行定制。
Custom WebItems。你建立的Custom WebItems并不與一個(gè)HTML頁(yè)面相關(guān),而是被用來(lái)產(chǎn)生對于瀏覽器的一般性響應。你也可以在這里建立一個(gè)定制事件,以便當頁(yè)面下載或用戶(hù)選擇了HTML元素時(shí)調用它(例如,你可以通過(guò)你的事件去完成諸如在頁(yè)面上增添一個(gè)標準的頁(yè)眉、從數據庫中讀取數據這一類(lèi)的工作)。
網(wǎng)頁(yè)類(lèi)事件
一個(gè)網(wǎng)頁(yè)類(lèi)可以擁有三種不同類(lèi)型的事件:
標準網(wǎng)頁(yè)類(lèi)事件。這些事件被包裝在針對每個(gè)WebItem的網(wǎng)頁(yè)類(lèi)中。當被用戶(hù)的請求激活時(shí)(例如點(diǎn)擊超鏈接),Respond事件將設定用戶(hù)的缺省操作——如果沒(méi)有事件句柄與這個(gè)操作相關(guān),那么響應事件將被激活。ProcessTag事件處理模板文件中特定的標簽并且將其內容用你指定的數據替代。UserEvent事件處理在運行時(shí)間創(chuàng )建的網(wǎng)頁(yè)類(lèi)事件。
模板事件。這些事件被HTTP請求激活(例如,超鏈接,圖象,確認按鈕)。網(wǎng)頁(yè)類(lèi)設計器分析了所有的HTML模板并找到產(chǎn)生HTTP請求的標簽并顯示它們,從而你可以針對這些編寫(xiě)模板事件代碼。
客戶(hù)WebItem事件。開(kāi)發(fā)者編寫(xiě)這些事件用于與之相關(guān)的WebItems,非常類(lèi)似于你在VB中編寫(xiě)的事件。
有用的屬性和方法
下面是你在應用中所需要的最普通的屬性和方法:
UrlFor是網(wǎng)頁(yè)類(lèi)在瀏覽器需要調用一個(gè)特定的模板或WebItem時(shí)用來(lái)指定URL的方法。你可以傳給它一個(gè)模板或WebItem的名字或者一個(gè)可選的事件名來(lái)代表將被激活的一個(gè)用戶(hù)事件。
UrlData主要用來(lái)存儲狀態(tài)信息。該數據被附加在UrlFor URL的后面,并在可以檢索。WriteTemplate方法能夠處理模板并能夠處理HTML文件中的標簽(如果存在的話(huà))。
你可以使用網(wǎng)頁(yè)類(lèi)的NextItem屬性來(lái)移動(dòng)處理不同的Webitem。這可能會(huì )激活Respond事件,因為你調用了Webitem,在那里你(非??赡埽┫M{用WriteTemplate來(lái)處理模板中的標簽。
狀態(tài)管理
當我們使用網(wǎng)頁(yè)類(lèi)的時(shí)候如何進(jìn)行狀態(tài)管理呢?
這里有幾種途徑你可以用來(lái)存儲針對網(wǎng)頁(yè)應用的狀態(tài):
使用服務(wù)器端網(wǎng)頁(yè)類(lèi)對象或其他對象來(lái)保存客戶(hù)請求之間的狀態(tài)信息。
使用數據庫來(lái)保存請求之間的狀態(tài)信息。
對于每一個(gè)請求,你可以利用cookies ,URLData屬性或者隱含的HTML字段將狀態(tài)信息在服務(wù)器和瀏覽器之間進(jìn)行移動(dòng)。
你也可以將這幾種方法結合起來(lái)進(jìn)行使用。很重要的一點(diǎn)是,你需要注意我上面描述過(guò)的網(wǎng)頁(yè)類(lèi)的StateManagement屬性。
一個(gè)簡(jiǎn)單的網(wǎng)頁(yè)類(lèi)實(shí)例
是不是覺(jué)得這是不可思議的?這里有一個(gè)小的例子,可以帶你走向正確的方向——解釋起來(lái)可能有些投機的成分,但實(shí)際上十分容易編程。
這個(gè)小的應用是用來(lái)輸出在HTML表格中所有的服務(wù)器變量,因此它是十分基礎的。為了建立它,你需要如下的工具:
Visual Basic 6.0
IIS 3.0(或以上版本)或Personal Web Server 3.0(或以上版本)
HTML 編輯器
標準的瀏覽器
1.使用合適的HTML編輯器創(chuàng )建一個(gè)HTML的模板。為了動(dòng)態(tài)地插入數據例如表格或者任一HTML,你可以通過(guò)VB代碼簡(jiǎn)單地將標簽放置于你HTML文件中需要插入數據的地方并在標簽前面加上WC@(注意:你可以在網(wǎng)頁(yè)類(lèi)中改變這個(gè)標簽頭):
<WC@ServerVars>Server vars table goes here</WC@ServerVars>
以下是用于這個(gè)例子的HTML文件:
<html>
<head>
<title>WebClasses Server Variables Example</title>
</head>
<body bgcolor="#c1a27d">
<center><H3>Server Variables</H3></center>
<p align="center"><WC@SERVERVARS>Insert
Server vars table Here</WC@SERVERVARS></p>
</body>
</html>
下面在你的網(wǎng)頁(yè)類(lèi)中你可以針對你實(shí)際的表格來(lái)編寫(xiě)代碼代替這個(gè)標簽。
2.啟動(dòng)新的IIS應用并將你的項目命名為WCExample。
3.將你的網(wǎng)頁(yè)類(lèi)命名為“clsExample”并將你的NameInUrl屬性置為“default(缺?。?#8221;(這將是你的應用的起始頁(yè),即產(chǎn)生的ASP頁(yè)用來(lái)駐留你的網(wǎng)頁(yè)類(lèi))。注意:關(guān)于網(wǎng)頁(yè)類(lèi)設計器的更多的信息請參見(jiàn)VB6的幫助文件。
4.保存你的項目。
5.將你的HTML模板加入到你的網(wǎng)頁(yè)類(lèi)設計器中??梢酝ㄟ^(guò)右鍵單擊設計器中的類(lèi)名或網(wǎng)頁(yè)圖標來(lái)進(jìn)行實(shí)現。將模板改名為ServerVars。
6.刪除WebClass_Start()中的代碼并將其替換為
Set WebClass.NextItem = WebClass.ServerVars
這將告訴網(wǎng)頁(yè)類(lèi)通過(guò)ServerVars模板啟動(dòng)應用。
在ServerVars_Respond()事件中插入如下的代碼:
ServerVars.WriteTemplate
這將告訴網(wǎng)頁(yè)類(lèi)輸出模板并用合適的輸出來(lái)代替標簽。
7.為了動(dòng)態(tài)地產(chǎn)生服務(wù)器變量表,現在你需要將代碼放置于服務(wù)器的serverVars_ProcessTag事件中。這個(gè)事件將得到上述參數,并通過(guò)填寫(xiě)TagContents參數來(lái)產(chǎn)生“TagContents”。
TagName代表HTML模板中標簽的全名。
TagContents是HTML中你準備用來(lái)代替TagName的內容。
SendTags是一個(gè)布爾操作符用來(lái)允許,它使你能夠決定是否將XML標志作為HTML頁(yè)的一部分送到客戶(hù)端。該參數缺省設置為False,但你應當設置這個(gè)屬性為T(mén)rue以便于調試應用程序。
8.將如下的代碼拷貝到ServerVars_ProcessTag 事件中:
CDim name As Variant
Select Case TagName
Case "WC@ServerVars"
TagContents = "<TABLE BORDER=1>"
TagContents = TagContents & "<TR><TD><b>Server Variables:</b></TD>"
TagContents = TagContents & "<TD><b>Value</b></TD></TR>"
For Each name In Request.ServerVariables
TagContents = TagContents & "<TR><TD>" & name & "</TD>"
TagContents = TagContents & "<TD>" & Request.ServerVariables(name)
TagContents = TagContents & "</TD></TR>"
Next
TagContents = TagContents & "</TABLE>"
Case Else
‘no other tags
TagContents = "No tags found"
End Select
這個(gè)例子將顯示ASP請求對象在小站點(diǎn)的使用。
9.編譯你的動(dòng)態(tài)鏈接庫。你需要注意產(chǎn)生的ASP頁(yè)(用你的NameInUrl 屬性來(lái)命名),并且你的項目DDL現在存在于你的項目目錄下。當應用程序第一次運行時(shí),網(wǎng)頁(yè)類(lèi)的運行時(shí)刻組件(MSWCRUN.DLL)將被創(chuàng )建,并且在你的網(wǎng)頁(yè)類(lèi)的生命周期中啟動(dòng)這個(gè)事件。
10.在服務(wù)器上使用你的別名將瀏覽器指向你的ASP頁(yè),并且你將看到如下這類(lèi)東西:

現在僅僅是個(gè)簡(jiǎn)單的例子,但希望它能給你一些在創(chuàng )建IIS應用方面的啟迪。
總結
和其他許多新技術(shù)一樣,網(wǎng)頁(yè)類(lèi)這種方法需要一些時(shí)間來(lái)進(jìn)行改善。這也許是一種帶有偏見(jiàn)的觀(guān)點(diǎn),但我現在更傾向于結合使用ASP和VB。之所以做出這種選擇,是因為一方面在這種結合的環(huán)境中我自我感覺(jué)良好,另一方面,我不敢確信制作服務(wù)器端的DDL使用其他選擇永遠是最佳的(盡管使用HTML模板確實(shí)在某些情況下也不是很好)。
但是對于那些不希望借助原始工具進(jìn)行編程的人們來(lái)說(shuō),網(wǎng)頁(yè)類(lèi)確實(shí)是一種十分適合的非常好的開(kāi)發(fā)手段。
作者: Matthew Gray
聯(lián)系客服