用它搜索web站点的标题/描述数据库,并在浏览器画面上将URL连接作为标题列出。这就产生了一个与Microsoft的 Internet Explorer搜索相同的显示结果。将一些asp web 站点的标题、描述、URL存在一个样本数据库Access 中。web站点标题在画面上显示的是URL连接,并允许访问者在另一个画面内阅读站点。一个导航条允许将字符串查询结果的标题列表进行分页。
数据库 在源代码中要注册Access SearchExample.mdb 数据库文件,将Microsoft ODBC 数据源管理器作为系统DSN。将SearchExampleDSN 作为数据源名(Data Source Name)输入。在进入代码之前,首先来看看数据库表的结构:
ID
AutoNumber (Primary Key)
Title
Text (255)
Text
Memo
URL
Text (255)
此表名为SearchTable,有四个定义域; ID、 Title 、 Text和 URL 。有一个唯一的初始域,随着每一个新增加的记录自动增加是个好办法。这就是我们的ID域,在代码中并没有真正地使用它。
Title(标题)域是一个255字符的文本域,存储web 站点的标题,查询成功后列出。
URL 域也是一个255字符的文本域,存储所引用站点的URL。
Text(正文)域的长度超出了文本域255个字符的限度,所以将其类型定义为Memo。Access Memo 类型和 SQL Server Text 类型的困难在于不要使用SQL 的LIKE 声明搜索它们内容的忠告。为了饶过这个问题,我们需要走额外的一步,将Memo 域的内容存储在一个字符串变量中,然后用访问者的查询字符串来搜索这一变量。
主机ASP和HTM文件
为了使我们的搜索组件正常工作,我们将使用3个文件,虽然使用其它的结构更容易实施。
第一个文件是htm 文件,将浏览器屏幕分割成两个独立的画面。剩下的两个文件被分别插入这两个画面中。将浏览器窗口左侧的画面称为SearchFrame ,因为我们将在这个画面中输入搜索查询。这个画面还将列出web 站点标题连接供我们选择。
右侧的画面叫做R ltFrame ,这不奇怪,因为最终要在这个画面中浏览搜索的结果。第一个主文件没有BODY 标记,并包含了FRAMESET and FRAME 标记:
SearchFrameSet.htm
< HTML >< HEAD >< TITLE >Search Example< /TITLE >< /HEAD >
< FRAMESET ROWS="100%" COLS="250,*" >
< FRAME NAME="SearchFrame" SRC="SearchPage.asp" SCROLLING="AUTO" >
< FRAME NAME="ResultFrame" SRC="ResultPage.htm" SCROLLING="AUTO" >
< /FRAMESET >
< /HTML >
在这里将ROWS 和 COLS 设置成一定的象素长度(250 ), 或者是占窗口的百分比( 100% ),或者是添满剩余的部分( * ),以此来确定两个画面的大小和位置。如果你想探索画面所有可能的配置,可以参考一本好的HTML书。
在这里重要的是用来填充画面的代码文件和画面本身所使用的名字。左侧画面宽度是250象素,在其区域内装载SearchPage.asp 文件。正是这个文件包含了我们的ASP组件。右侧的画面装载ResultPage.htm 文件,作为我们在左侧搜索到的连接的阅读器。在SearchPage.asp 文件中,我们只是简单地创建组件的一个示例,并调用显示我们的搜索页的Public 方法(稍后创建)。
||||||SearchPage.asp
< HTML >< HEAD >< TITLE >Search Frame< /TITLE >< /HEAD >
< BODY BGCOLOR="Silver" TEXT="Navy" LINK="Navy" VLINK="Gray" >
< FONT FACE="Arial" SIZE="2" COLOR="Navy" >
< %
Set objSearch = mobjServer.CreateObject("prjSearch.clsSearch")
objSearch.ShowSearchFrame()
% >
< /FONT >
< /BODY >< /HTML >
我将组件与FONT 标记包在一起以便让它更好看。除了这一个标记,我在这个例子程序中没有增加任何文本格式标记。通常我在组件中自由地运用表格、队列、文本格式标记来构成一个专业用户接口。在这个例子中暂且放弃这些。右侧的画面中装载了最简单的htm 文件:
ResultPage.htm
< HTML >< HEAD >< TITLE >Result Page< /TITLE >< /HEAD >< BODY >
< CENTER >Introduction Result Page< /CENTER >
< /BODY >< /HTML >
它基本上是一个启动页面。在左侧的画面内选择了我们想要浏览的web 站点的标题后,要用这个画面的名字装载它。现在我们想要浏览的web 站点页面已经就位,现在准备编写产生SearchPage.asp 动态内容的真正VB方法。
Visual Basic 工程文件
将代码分成4个私用 VB 方法,从一个包裹了所有方法调用的Public 方法中调用它。在Visual Basic中开始一个新的ActiveX DLL 工程文件。将工程文件命名为prjSearch,将默认类命名为 clsSearch 。确认在Properties 窗口中将类的例示属性设为5(MultiUse)。
增加对Microsoft Active Server Pages Object Library 和Microsoft ActiveX Data Objects 2.0 Library 的引用。
声明类变量
有些读者要求本文涉及用属性程序设置主机ASP文件的服务器端ASP组件内的变量的解释和代码举例。熟悉VB面向对象编程的读者可以跳过这部分。在我们的类代码中,将模块级变量设置为Private ,提供Let 和 Get 属性程序将那些变量暴露给主机ASP文件。这将我们的变量装入类中,这样一来它们就只能被从头至尾执行属性程序的用户所设置。我们所要声明的第一组变量是用来保持ScriptingContext 对象变量的:
"~~~~~ Scripting Context Declarations
Private mobjScriptingContext As ScriptingContext
Private mobjRequest As Request
Private mobjResponse As Response
Private mobjServer As Server
为了更加灵活机动,我们允许我们的画面名和源文件名在主机ASP文件内部修改。在VB方法内,这些变量的值将决定标题将在哪出现,及访问者选择的站点在哪显示。如果画面名或源文件名在FrameSet FRAMES 标记内被改变了,默认变量就不匹配了。在主机ASP文件中将这些变量设置为新的FRAME 值,就一切恢复正常了。将这些值设置为同样的ASP源文件还可以避免画面混在一起。
< %
Set objSearch = mobjServer.CreateObject("prjSearch.clsSearch")
objSearch.SearchFrameURL = "NewSearchPage.asp"
objSearch.ResultFrameURL = "NewResultPage.htm"
objSearch.SearchFrameName = "NewSearchFrame"
objSearch.ResultFrameName = "NewResultFrame"
objSearch.MaxSearchReturn = 10
objSearch.ShowSearchFrame()
% >
在这个例子中我们改变了源文件和画面的值。我们还将在列表中显示的标题数从默认的5改为10。当我不能肯定什么样的设置对于一个程序的功能最好的时候,我就把选择的权利留给最终用户。属性程序就是做这个的。
所以我们声明6个私用变量,用来写Get和 Let 属性,并允许我们从主机ASP文件中设置这些变量。例子中另外一个变量是一个只对Get程序的ASP文件只读变量。
"~~~~~~ Let/Get Property Procedure Variables
Private mintMaxSearchReturn As Integer
Private mstrSearchFrameURL As String
Private mstrResultFrameURL As String
Private mstrSearchFrameName As String
Private mstrResultFrameName As String
"~~~~~~ Get Property Proceedure Variable
Private mintRecordsSearched As Integer
"~~~~~~ Modular Class Variable
Private mintSearchStart As Integer
||||||变量初始化
尽管这些变量可以由外部设置(通过属性程序),我们还是希望替他们设置好默认值--以防没有机会在ASP文件中设置他们。这在类的初始化方法中完成:
Private Sub Class_Initialize()
"~~~~~ Set variables to default values
mintMaxSearchReturn = 5
mstrSearchFrameURL = "SearchPage.asp"
mstrResultFrameURL = "ResultPage.htm"
mstrSearchFrameName = "SearchFrame"
mstrResultFrameName = "ResultFrame"
End Sub
当创建一个类的例示时(主机ASP文件调用它时),我们的变量将被初始化为以上值。可以在代码内改变变量的值和/或从对象外部通过方法设置它们。
为了让我们的代码能够利用ASP对象模块,光初始化变量是不够的,必须获取ASP对象。当容纳了我们组件的ASP页被访问浏览器打开时,OnStartPage 方法就被调用,这些ASP对象变量就被赋予ASP对象的值。
Public Sub OnStartPage(PassedScriptingContext As ScriptingContext)
"~~~~~ Set the ASP object variables to use in this class
Set mobjScriptingContext = PassedScriptingContext
Set mobjRequest = mobjScriptingContext.Request
Set mobjResponse = mobjScriptingContext.Response
Set mobjServer = mobjScriptingContext.Server
End Sub
作为一个好的程序员,当离开当前命令行外壳时要将这些对象设置为nothing。
Public Sub OnEndPage()
"~~~~~ Clean up in an instance
Set mobjScriptingContext = Nothing
Set mobjRequest = Nothing
Set mobjResponse = Nothing
Set mobjServer = Nothing
End Sub
从属性方面设置变量
因为我们将这些变量设置为Properties,它们就只能被这个类模块内部的代码所使用。但是用户确实需要从模块外部设置这些变量的途径。这样我们就需要使用暴露为Public 的属性程序。
下面的代码是Get 和LEt 属性方法设置 mintMaxSearchReturn 变量:
Public Property Get MaxSearchReturn() As Integer
MaxSearchReturn = mintMaxSearchReturn
End Property
Public Property Let MaxSearchReturn(ByVal RHS As Integer)
If RHS >= 0 Then
mintMaxSearchReturn = RHS
End If
End Property
注意Get属性将当前mintMaxSearchReturn变量赋值为MaxSearchReturn 程序的返回值 - 这是一个基本函数。mintMaxSearchReturn 变量是在类内部声明的变量之一,它的初始化值为5。通过向组件中设置一个对象变量,ASP主机文件可以得到这个变量的值,然后用对象变量来使用这一方法:
aspVariable = objVariable.MaxSearchReturn
要从ASP主机文件中设置变量中的一个值,我们通过赋一个值 调用Let 方法:
objVariable.MaxSearchReturn = 8
现在Let 方法通过给RHS (右侧) 变量赋值8而接收到这个值。增加一个校验来确定值大于0(负数没有意义)。这就显示了属性程序的威力,因为它允许我们控制用户可以给私用变量赋予哪些值。如果通过了校验,就将这个值赋予mintMaxSearchReturn变量。这是在初始化方法赋值之后完成的,因此主机ASP文件就会至少让最后一个词与初始化方法有关系。在这种情况下代码最终说了算。
下面是属性程序的其余部分:
Public Property Get SearchFrameURL() As String
SearchFrameURL = mstrSearchFrameURL
End Property
Public Property Let SearchFrameURL(ByVal RHS As String)
mstrSearchFrameURL = RHS
End Property
Public Property Get ResultFrameURL() As String
ResultFrameURL = mstrResultFrameURL
End Property
Public Property Let ResultFrameURL(ByVal RHS As String)
mstrResultFrameURL = RHS
End Property
Public Property Get SearchFrameName() As String
SearchFrameName = mstrSearchFrameName
End Property
Public Property Let SearchFrameName(ByVal RHS As String)
mstrSearchFrameName = RHS
End Property
Public Property Get ResultFrameName() As String
ResultFrameName = mstrResultFrameName
End Property
Public Property Let ResultFrameName(ByVal RHS As String)
mstrResultFrameName = RHS
End Property
Public Property Get RecordsSearched() As String
RecordsSearched = mintRecordsSearched
End Property
注意通过仅仅提供Get 方法,我们从本质上创建了一个类以外的只读变量。