## 用C ＋＋ Builder开发Web程序 ★ 张云潮
Web应用程序是运行在服务器端的可执行程序或动态链接库。它们可以响应用户要求，动态产生超文本页面，并将信息提供给客户浏览器。
由于Web应用程序的标准并不相同，程序的写法各异，这样就给开发者造成不小的困扰，因为开发人员不太可能了解每一种标准的写法。而C＋＋ Builder可以很好地解决这个问题。 C＋＋ Builder将Web应用程序的开发封装成组件，使开发者面对一致的开发界面，使用一致的开发原理，惟一不同的地方在于开始产生程序时所选择的程序结构，至于程序的编写细节和方式都一模一样。本文通过两个实例介绍利用C＋＋ Builder开发Web应用程序的具体步骤。
简单的Web程序
首先，点击C＋＋ Builder IDE 的菜单项File|New option，选中 Web Server Application 图标，向导程序提示如图1所示的三种选择：
图1
由于CGI(Common Gateway Interface)运行时需要一个独立的进程，而ISAPI/NSAPI动态链接库运行时要映射到Web服务器进程中，所以ISAPI/NSAPI需要的资源比CGI要少。但ISAPI/NSAPI动态链接库的这个特点为调试程序造成了一定的困难，因此较好的办法是先创建一个CGI程序，并进行调试，然后再把它转化成ISAPI/NSAPI动态链接库。所以在这里选择“CGI Standalone executable”，生成一个TWebModule 对象。
Web应用程序实际上是Web服务器在功能上的扩展，就好像Windows应用程序是Windows在功能上的扩展一样。当Web应用程序从Web服务器检索到一个HTTP请求消息时，就对HTTP请求消息进行分析，生成HTML页面传递给Web服务器，再由Web服务器传递给客户。C＋＋ Builder Web应用程序的一个关键部件是Web Module，它收集和管理着一组TwebActionItem对象，用TwebRequest对象来描述HTTP请求消息，并根据HTTP请求消息来指派其中一个动作去响应客户的请求，实际上就是填写TWebResponse对象的Content特性。其工作结构如图2所示。
图2
一个Web应用程序可以创建若干个动作项，以供Web调度器（TwebDispatcher）指派。C＋＋ Builder 是用一个专门的动作项编辑器（Action Editor）来创建和管理动作项的。右键单击Web模块，在弹出的菜单中选择“Action Editor”命令。然后添加一个动作项，通过它的PathInfo属性可以设置动作项在Web服务器上的入口路径，而default属性设置当PathInfo属性为空时该动作项是否执行。
为该动作项编写如下代码：
void __fastcall TWebModule1::WebModule1WebActionItem1Action(TObject ＊Sender, TWebRequest ＊Request, TWebResponse ＊Response,bool ＆Handled)
{
AnsiString cont = AnsiString(“<HTML>
<BODY><H3>Hello!</H3>”);
cont = cont ＋ AnsiString(“<BR>”);
cont = cont ＋ AnsiString(“<H2>Now is”) ＋ TimeToStr(Time()) ＋AnsiString(“</H2>”);
cont = cont ＋ AnsiString(“</BODY>
</HTML>”);
Response－>Content = cont;
}
在处理动作项的OnAction事件的句柄中，可以通过Request参数来访问客户的请求消息。要响应客户的请求，实际上就是把用HTML描述的页面赋值给Response的Content属性，Web调度器会自动把相应结果传递给Web服务器，再由Web服务器传递给客户。
至此，一个简单的Web应用程序创建完毕，现在可以通过Web浏览器测试它（运行界面如图3所示）。要注意的是Web应用程序所在路径应有可执行权限。
图3
处理用户输入的Web程序
下面在上述例子的基础上继续创建一个用于处理用户输入的Web程序。再添加一个动作项TWebActionItem。在WebModule1加入TPageProducer 对象，利用它事先准备好的HTML模板生成HTML文档。如图4所示：
图4
首先，利用Microsoft FrontPage 做一个运行后如图5所示的用户输入表（HTML代码略）。
图5
为TWebActionItem2的OnAction 事件编写如下代码:
void __fastcall TWebModule1::WebModule1WebActionItem2Action(TObject ＊Sender, TWebRequest ＊Request, TWebResponse ＊Response,bool ＆Handled)
{
Response－>Content=PageProducer1－>Content();
}
然后处理用户输入，把用户输入写入一个新的HTML页面。这就需要再增加一个TpageProducer组件PageProducer2 用于处理用户输入页面。
把以下代码添加到 HTMLDoc 属性中:
<html>
<head>
<title>Thank You!</title>
</head>
<body >
<p>您好 <＃T1>!</p>
<p>感谢您添写了我们的调查表单，您的Email地址为<＃T2>，以后我们会与您联系!</p>
</body>
</html>
上述代码是一个HTML模板，它包括两个特殊的标识<＃T1> 和<＃T2>，它们是用户输入表中两个编辑域的名称，在产生的HTML页面中将被用户数据所代替。在PageProducer2的 OnHTMLTag事件中添加以下代码：
void __fastcall TWebModule1::PageProducer2HTMLTag(TObject ＊Sender, TTag Tag, const AnsiString TagString,TStrings ＊TagParams, AnsiString ＆ReplaceText)
{
ReplaceText = Request－>QueryFields－>Values[TagString] ＋Request－>ContentFields－>Values[TagString];
}
继续增加一个动作项WebActionItem3 ，设其PathInfo=“/t3”, 在其OnAction 事件中编写如下代码：
void __fastcall TWebModule1::WebModule1WebActionItem3Action(TObject ＊Sender, TWebRequest ＊Request, TWebResponse ＊Response,bool ＆Handled)
{
Response－>Content=PageProducer2－>Content();
}
当用户按下Submit按钮后，为使PageProducer2 获得响应，修改PageProducer1 的HTMLDoc 属性：
<form method=“POST”
action=“http://sopdrilling.com.cn/bcbtest/project1.exe/t3”>
编译后测试，填写完表单后按下Submit按钮，显示如图5所示页面。