用它搜索web站点的标题/描述数据库,并在浏览器画面上将URL连接作为标题列出。这就产生了一个与Microsoft的 Internet Explorer搜索相同的显示结果。将一些asp web 站点的标题、描述、URL存在一个样本数据库Access 中。web站点标题在画面上显示的是URL连接,并允许访问者在另一个画面内阅读站点。一个导航条允许将字符串查询结果的标题列表进行分页。
![](/images/load.gif)
数据库 在源代码中要注册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 域的内容存储在一个字符串变量中,然后用访问者的查询字符串来搜索这一变量。
![](/images/load.gif)
主机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 >
![](/images/load.gif)
在这里将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)。
![](/images/load.gif)
增加对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 方法,我们从本质上创建了一个类以外的只读变量。