delphi(f4)
时间:2006-06-10 来源:许我一个信仰
附录D 用Delphi实现无线程序
我从来都弄不清楚出血边是由什么构成的。也许我已经习惯了花费大量的时间同时运行beta版的办公工具、beta版的数据库服务器、beta版的操作系统、编译器、以及硬件设备等。无线应用看上去已经满足了出血边的条件。只要看一下RFC文档、白皮书、书籍和应用程序的版权日期,您就可以知道无线应用还非常新。该技术与一些小型的设备和界面有关,这倒是与20年前很相似。
无线设备如蜂窝电话或PDA(个人数字助手)通常提供的屏幕较小、带宽较低、网络连接状况较差(如果您的蜂窝电话是是在密歇根买的,那么试着在西南部犹他州到维加斯之间的地方打个电话,您将会看到那个区域的信号非常微弱)。由于这些原因,该技术有点冷门。摩托罗拉的蜂窝电话看起来像是星际旅行的通讯器(如果现在我们有全息摄影技术的话)。更有趣的是,您可以从桌面上访问建立无线应用程序的工具。确实是这样:Delphi就能实现WAP。WAP是指无线应用协议(Wireless Application Protocol)。因此,我说Delphi实现WAP时,指的是Delphi可以创建提供WML(无线标记语言,Wireless Markup Language)页面的服务器程序。WML是由XML(Extensible Markup Language,可扩展标记语言)衍生而来。
当创建无线应用时,有许多技术是必须的。标记语言,如HTML、XML、WML,肯定是需要的。这三种标记语言的标记之间有许多相似性。Web服务器和无线服务器也是需要的。MIME(Multipurpose Internet Mail Extension,多用途Internet邮件控制)也是必须的。确定内容、定义接口、创建数据存储、编写并测试应用服务器,这些对于创建WAP程序都是必须的。这些技术中的每一种可能都需要一本书来讲述。因此,我们在本附录中相当于作一次垂直切片,对每种技术都稍稍涉猎一下(这与在水平层面上对某一种特定技术继续讨论相对。您可以劝说出版商来出版这样一本书)。从正面来看,读完本附录后,可以回忆起前面章节涉及到的各个独立的主题。
D.1 准 备 工 作
如果要试一下本附录中的练习,您需要把本节列出的工具组合一下。如果只是简单浏览一下,那么可以跳过本节。
要建立本附录的WAP示例程序,您需要把下列工具组合起来(惟一需要出钱买的是Delphi):
· Delphi企业版或Delphi专业版;Web Broker必须单独购买,这些可以在www.inprise.com进行。
· 下载并安装JRE 1.2.2(Java运行时环境),其中包含Java虚拟机。JRE 1.2.2可以在http://java.sun.com/products/jdk/1.2/ 免费下载。
· 从Nokia网址http://www.forum.nokia.com下载WAP工具包。工具包的试用版是免费的。您可能需要提供个人信息进行注册(而Nokia的网站有点令人迷惑),但Nokia的电话还不错。工具包中的仿真器使得调试更为容易(本书的光盘上也有该工具包)。
· 选择下载Nokia的服务器Active Server 2.0。本附录中我们使用了IIS来提供Web页面,但WAP服务器既可以单独使用,也可以与Web服务器联合使用。
· 您需要安装Personal Web Server或IIS(在Windows 2000系统中),或者需要访问您的网络中的IIS服务器,以便对WAP应用进行测试。如果您使用的是Windows NT Workstation版本,您可以安装Personal Web Server。如果您使用Windows 2000 Professional版本,您可以在桌面上安装IIS。或者您可以在Windows NT Server版本的计算机上安装IIS。为避免所有可能情形的组合,本书的例子使用了Windows 2000 Professional。
· 您还需要使用ODBC管理器和Database Desktop,这些都用于数据存储的目的(如果忘了,可以阅读第13章)。
显然,您也可以使用其他的仿真器或具有WAP功能的电话。您还可以使用其他的WAP或Web服务器,每种配置都可能有自身的问题,都需要一些研究和试验。例如在本书中,在具有144M内存和大约2G磁盘的Pentium II便携式电脑上运行Windows 2000 Professional系统和Delphi 6企业版。数据库是使用Database Desktop用Paradox表格式建立起来的。IIS在便携式电脑上使用localhost或IP地址127.0.0.1独立运行,它将作为Web服务器使用。当程序在PC上调试好之后,即可将其传送到企业内部网或Internet的Web服务器上。
D.2 无线标记语言基础
WML,或称无线标记语言,是XML(可扩展标记语言)的近亲。如果您熟悉HTML或XML,那么WML就不成问题。如果缺乏标记语言方面的经验,您可以先看一下WML、WAP、WMLScript方面的书籍(参考书目中列出的《WAP Development with WML and WMLScript》一书中信息很丰富,作者是Bert Forta)。
WML文档的页面称为桌面(DECK),通常由一组相互链接的卡片(CARD)组成。一个单独的HTML文件就是一个文档。在WML中,一个文件包含一个桌面,桌面中至少包含一个卡片;而桌面还包含许多卡片。单个的卡片大体上与单独的HTML文档等价。由于WAP设备屏幕的限制,在每个卡片上可以定义的内容的种类和数量与HTML文档相比都非常少,因而必须更加简明。
D.2.1 定义桌面(或WML文档)
基本的WML文档包含一个序言,起始标记<wml>和终止标记</wml>,以及至少一对<card></card>标记。下面是一个基本的文档,结果显示在Nokia blueprint仿真器中,如图D.1所示。
<?xml version="1.0"?>
<!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EN"
"http://www.wapforum.org/DTD/wml_1.1.xml">
<wml>
<card>
<p>
Hello World!
</p>
</card>
</wml>
图D.1 Nokia blueprint仿真器,表示通用的具有WAP功能
的电话,这里显示了上述WML文档的结果
在起始标记<wml>之前是序言。序言中包括了所用的标记语言版本,以及该版本定义的路径。最容易的方法是将该信息保存为模板,并将其粘贴到每个文档中。与<html>和</html>类似,<wml>和</wml>标记分别定义了WML文档的起始和结束。对于桌面(WML文档)中的每个卡片而言,都有一对卡片标记。所显示的文本必须放置在一对段落标记<p></p>中。
像HTML一样,有许多标记和标记属性。下面将涉及到其中的一些。请记住,WML是大小写敏感的,而您可能需要对几种不同的WAP设备测试WML文档,以确保内容的一般性。
D.2.2 定义卡片
卡片是与一页数据等价的。虽然数据未必适合于在无线设备的小屏幕上观看,但WAP设备确实提供了垂直滚屏功能。保持卡片的简明,可以使您的程序更为友好。
卡片标记的两个属性很有用:id和title。id属性对于在同一桌面的不同卡片之间定位很有用。它与HTML的书签标记工作方式类似。title属性为卡片提供了标题,可供无线设备在可见区域的顶部显示,但该属性不是必须的。在上一节的Hello World!例子中,卡片的起始标记如下所示。
<card id="main" title="Hello">
当要在桌面之内定位时,可以将id用于超文本引用属性中,如下所示:
<a href="#main" >Main</a> <br/>
上面的语句将显示为超链接,通常由下划线字体表示(这里的Main文本)。当选择该超链接时,有Main所引用的卡片将称为当前卡片。
D.2.3 格式化标记
段落标记<p>和</p>是必须的。您也可以使用其他格式化标记,如行结束标记<br/>。可以注意到WML中br标记的结尾多出一条斜线。WML有许多微小之处与HTML并不一致,例如上面的行结束标记;如果您需要在协议之间来回切换,应该在手头准备语言的参考手册。
WML还支持字体格式化标记,如<b></b>,<i></i>,以及<u></u>,分别可用于黑体、斜体和下划线字体。这些标记必须是对称的。
<b><i>Text</b></i>
虽然上面的代码在HTML中是可以接受的,但在WML中却无法正常工作。要使其能够在WML中正确工作,可以进行修改,正确的写法如下:
<b><i>Text</i></b>
通常情况下,WML的语法比HTML更为严格。
D.2.4 导航按钮
在图D.1中,可以看到有些导航按钮放置在电话的关键之处。这些按钮,加上数字键盘,是用于用户输入的。在可视区域之下,左右分别有两个按钮,这两个按钮是软件键。您可以利用WML对这两个键进行编程,以辅助浏览。
<card id="main">
<do type="options" label="Back">
<prev/>
</do>
<p>
Some more text!
</p>
</card>
do标记定义了与某个特定软件键相关联的事件响应。所表示的键在type选项中指定;当显示上面定义的卡片时,该键的文本是Back。例子中对该事件的响应是返回到前一个卡片。可以注意到,与options软件键相关联的事件是在包含显示文本的段落之前定义的。软件键的外观和位置如图D.2所示。
图D.2 定义软件键以辅助浏览,示例代码中创建了向后浏览的功能
D.2.5 模板
因为WAP设备只涉及到有限的带宽,因此每个请求要尽可能多的发送信息。这就是需要在一个文档中发送多个卡片的原因。但不要发送不必要的冗余数据。首先,重复的数据容易出错,其次,这会浪费有限的带宽。
为补救可能的冗余和浪费,定义了模板标记。模板可以在桌面一级重新定义并应用到同一桌面中的所有卡片。例如,如果要对每个卡片都定义一个返回按钮,那么可以在桌面的开头定义一次模板标记。下面的片断示范了模板的位置。
<wml>
<template>
<do type="options" label="back">
<prev/>
</do>
</template>
<card title="Hello">
如果显示上面的代码中的桌面,那么每个卡片都会具有返回功能。
可以认为,桌面等价于全局作用域,而卡片等价于本地作用域。一次,如果在卡片一级定义了与桌面一级相同的事件,那么卡片一级的事件是优先的。可以利用这一点对桌面模板进行选择性的重载。
<card id="main">
<do type="options" label="back">
<noop/>
</do>
上面的片断重新将options软件键设置为noop,即没有操作,这可能是由汇编语言程序员发明的。对上面的代码中的id对应的卡片而言,对事件的重新设置将使桌面一级的相应事件失效。
D.2.6 输入域和变量
WML并不像HTML那样支持复杂的显示布置,如表格和帧等。但如果不支持用户输入,WML可能不会太有用。输入标记用于为卡片定义输入域。该标记放置在段落标记对之内。下面给出了一个输入域的例子,摘自CGI例子服务器name_lookup.exe。
<input name="LastName" emptyok="false" format="*m" type="text" />
输入语句定义了一个名为LastName的变量。输入域必须包含数据,例如emptyok=“false”。格式化掩码*m表示可以输入任意数目、任意类型的字符,最后的属性表示输入域的数据类型是文本。
这只是WML中少量的标记和属性。WML有语法和关键字。对于更为高级的WML用法,可以阅读关于WML、WAP、XML和WMLScript的参考资料。可以从书后的参考书目开始,也可以去Osborne.com网站查找。
D.3 无线应用与Delphi
Delphi如何支持无线应用?答案非常直接。WAP应用可以通过URL请求数据。而使用Web Broker组件建立的Delphi服务器可根据特定的URL返回动态页面。无论WAP应用运行在WAP服务器或Web服务器上,这一点都是正确的。
可接受的WAP URL中可以包含脚本的名字和查询信息,这在第17章已经讨论过。惟一重要的不同点在于,我们必须告知Web服务器可接受的MIME类型,包括WAP类型、以及要求Web服务器返回格式化好的WML内容。简而言之,我们需要用于返回WML数据的WAP服务器(如Nokia的Active Server)或Web服务器,以及动态生成WML代码的Web Broker服务器。
在下一节中,我们将使用IIS来提供WML页面,因此首先需要将WML头类型添加到IIS。要添加WML MIME头类型,可按照下列步骤进行,同时可以参考图D.3(假定您已经安装了IIS):
1. 在Windows 2000 Professional系统中,启动控制面板。
2. 在控制面板中,双击管理工具小应用程序。
3. 在管理工具中,启动服务控制管理器。
4. 前3步会打开MMC(Microsoft Management Console),在Windows NT 4.0中的步骤是类似的。从MMC中选择Web站点,然后右击鼠标显示上下文菜单。单击Properties菜单项来显示Web Site Properties对话框。
5. 在Web Site Properties对话框中,选择HTTP Headers属性页并在MIME Map组中单击File Types按钮。
6. 按照图D.3中前台的File Types对话框所示列表,添加所需的扩展和MIME类型(Web Site Properties对话框显示在后台)。
图D.3 File Types对话框用于向IIS添加经过认可的MIME
类型,这使得IIS能够提供例子所需要的WML页面
在完成上述步骤后,IIS就可以向WAP浏览器提供WML页面了。在Web Broker服务器内部,我们也需要指出相应的内容是WML。我将在下一节中示范所需的步骤,那时就可以创建一个WAP服务器程序了。
D.4 使用Delphi创建无线服务器
用Delphi实现的无线应用可以使用Web Broker组件,如第17章示范的TPageProducer。像其他程序一样,我们首先需要对程序所提供的服务进行描述。
注意:举例来说,如果示例程序能够从Outlook读出联系信息,那么它就是有用的。无需向电话输入数据,所有的记录表、联系信息、以及任务信息都能够读入到WAP电话上。
本节中的例子程序提供了一个电话目录。用户可以浏览站点,而且即使她连一个电话号码和联系方式都记不住也能打电话,只要输入接电话的人的部分或全部姓氏即可。服务器将返回可能匹配的姓名列表,用户可以从中进行选择。但找到一个特定的匹配时,将返回与该姓名相关的所有信息。
D.4.1 建立联系表
Contacts.db表是使用Database Desktop定义的。本书光盘上的表中包含了姓名以及两个电话号码;它可以表示一些更有用的信息,如客户联系信息列表等。
该表定义如下:
ID Auto Increment Primary Key
FIRST_NAME Alpha 10
LAST_NAME Alpha 15
HOME_PHONE Alpha 14
MOBILE_PHONE Alpha 14
在创建该表后,将其复制到IIS可访问的目录中。由于CGI脚本在c:\inetpub\scripts目录下运行,我将表复制到该目录下。
现在表已经建好,可以用我们创建的脚本进行访问;向表添加几条记录并创建指向其位置的ODBC别名,这样创建示例数据库的步骤就结束了(第13章列出了使用DataSource Administrator创建ODBC别名的步骤)。
D.4.2 使用Web Broker创建CGI服务器
根据对工作的描述,完成任务需要定义三个WML文档(如果多作一些工作,可以用更少的文档达到目的,但这与我们的讨论并不相关)。第一个桌面包含了主要的输入卡片,用户可以在这里输入所需联系信息对应的姓氏或姓氏掩码。第二个桌面返回一个卡片,其中包含了可能匹配的超链接列表,而第三个桌面的卡片则包含所需联系信息的所有匹配数据。
注意:在实际的程序中,如果第二个桌面包含两个卡片,一个卡片中包含可能匹配的超链接列表,而另一个卡片则包含匹配的细节信息,那么可以更好地利用带宽并使得响应更快。超链接可以定位到同一桌面中的卡片,而不是再从服务器获取文档。
在例子程序中,服务器定义为单独的CGI可执行程序,由Web Server Application向导创建。服务器包含了三个TPageProducer组件、一个TDatabase组件、两个TQuery组件。还定义了三个动作组件,以便向用户提供三种可能的动作,这就是我们所需要的。
CGI脚本名为name_lookup.exe。将脚本放置到脚本子目录中。如果在Windows 2000工作站按照IIS,默认情况下该目录是c:\inetpub\scripts。从第17章可知,服务器名是作为URL路径信息的一部分添加的。每个服务器都有一个默认路径。对本例而言,服务器可通过下列URL调用:
http://localhost/scripts/name_lookup.exe/
由于没有在脚本之后给出特定的路径信息,将使用默认的路径进行调用。在本例中,将调用名为root的默认TWebAction组件。在页面生成器的内容返回之前,需要设置Response.ContentType,以表明需要返回WML文档。
procedure TWebModule1.WebModuleBeforeDispatch(Sender: TObject;
Request: TWebRequest; Response: TWebResponse; var Handled:
Boolean);
begin
Response.ContentType := 'text/vnd.wap.wml';
end;
页面生成器负责返回文档内容。root动作组件的内容如下列出。
<?xml version="1.0"?>
<!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EN"
"http://www.wapforum.org/DTD/wml_1.1.xml">
<wml>
<!-- Request the user input -->
<card title="Phone List">
<do type="accept" label="Find">
<go href=
"http://localhost/scripts/name_lookup.exe/search?LastName=
$(LastName)" />
</do>
<p>
Enter last name:
<input name="LastName" emptyok="false" format="*m"
type="text" />
</p>
</card>
</wml>
root动作组件包含了一个单独的卡片,其中定义了Find软件键,使得用户可以输入搜索信息。
从超文本引用可知,Find命令将把赋值给LastName变量的数据作为查询发送到search路径。服务器端将运行name_lookup.exe,而路径search和查询信息LastName=value将发送到脚本。
脚本将检查路径和查询信息,然后运行相应的TWebAction组件。所需的TWebAction组件是由路径信息确定的。这里会运行具有/search路径的TWebAction组件。浏览第17章,可以看到脚本使用了TQuery组件并动态建立了要显示的超链接列表以及其他特定的查询信息。代码与第17章中TQueryTableProducer部分的代码非常相似,因此这里不再解释。
第三个桌面及其卡片只需返回格式化的数据。从上面的文档和代码可知,HTML和WML服务器之间最重要的区别是所返回的内容、内容的类型和相应的客户。大部分情况下,客户端都可能是WAP浏览器。其他方面的信息,您可以从前面的章节中了解。
D.4.3 测试程序
所有的程序都需要进行测试。找到尽可能多的工具来促进测试的进行是成功的关键因素。对本例来说,可下载使用Nokia公司的WAP Toolkit。仿真器可通过该工具包(如图D.4的背景所示)运行。WML文档的输出显示在仿真器中(如图D.4的前台所示)。由于IIS在本地计算机上运行,Web服务器的URL是localhost。
图D.4 Nokia WAP Toolkit和仿真器,可用于测试WAP程序的工具之一
要使用Nokia WAP工具包测试WAP例子程序,需要运行WAP工具包和仿真器并键入脚本的完整路径。完整的URL路径是http://localhost/scripts/name_lookup.exe/。要测试程序的各项功能,对每一屏幕都进行输入并搜索示例数据。
1. 选择Options软件键。
2. 从Options菜单选择Edit Selection菜单项,然后单击Select软件键。
3. 使用数字小键盘将数据输入到输入域中,单击OK软件键。
4. 单击Options软件键,找到Find菜单项,并单击Select软件键(请记住,软件键的值是与特定的卡片相关的)。
5. 定位到某个返回的超链接,单击Options,然后单击Follow Link。
注意:最后,使用Delphi、IIS和WAP工具包一起进行集成调试可能会有些困难。当我写本书的时候,还未能解决一些细节问题。如果您能够在Delphi中步进调试WAP服务器,请给我发个电子邮件([email protected])。在此期间,我们只好编一些输出语句,用较老的风格进行调试。我猜测,用于测试和调试WAP服务器的工具很快能变得更好用。
最后,如果存在与输入的值相匹配的数据,该数据将返回到用户。在实际的程序中,还需要检查输出的有效性,并确保浏览功能正常工作。
D.5 小 结
附录D示范了Delphi可以方便地为无线设备建立动态的Web解决方案。Delphi企业版携带了Web Broker工具。Delphi专业版用户需要购买Web Broker工具。在WAP服务器和Web服务器之间的区别在于:对于WAP,客户浏览器运行在WAP电话上,而服务器需要返回WML内容。
您现在已经掌握了这些技术。您已经拥有了最好的工具之一。愿力量与你同在。