vfp 生成html,[转载]vfp 做 b/s 的方法

VFP 做B/S的新方法(二)

前言:以前,我也和其他VFP爱好者一样,认为VFP的最大不足是不能做B/S应用开发,

现在我已改变了看法,VFP完全可以胜任B/S应用开发,而且性能非常好,也很容易

使用,问题的关键是你是否掌握好的开发方法。自从掌握ASP + COM编程方法后,我一直

在探索VFP做B/S应用更好的开发方法,特别是寻找一种方法解决COM对象在Application级启动

无法使用ASP内置对象的问题,在没有资料参考的情况下,我试了几种方法,有的也确实解决

了问题,但都有缺点。在一次大胆的想法并编程设验后,我成功地找到了这种方法,这让我

欣喜若狂。现在我把它公开,让用VFP的朋友分享,也听听你们宝贵的意见。

和上一篇介绍的一样,总的方法还是使用ASP + VFP编写COM组件实现,但在传递引用ASP

内置对象上却采用新的方法,上一篇使用的是COM+的上下文对象引用ASP内置对象,这次让ASP

直接传递,不要小看这个改进,所谓“外行看热闹,内行看门道”,它带来的好处是很明显的,

下面以例子说明。当然,能够采用这样的方法是拜VFP9.0在COM编程方面的功能增强所赐的

(VFP8.0我不清楚,但VFP7.0及以下版本是不能这样用的)。

下面是一个简单的应用示例,cplr.asp页面实现将输入的产品名称、价格存入或更新到数据表,

按“转到产品查询页面”按钮可以转到产品查询页面;cpcx.asp页面实现按输入的产品名称查询

数据表,并将查询结果显示在表格中,按“转到产品录入页面”按钮可以转到产品录入页面。

一、ASP文件和Global.asa 文件,这三个文件放在Web根目录下。

1、cplr.asp文件,内容只一行,传递ASP内置对象,并执行COM组件的cplr方法。

ob.cplr server,application,session,request,response

%>

2、cpcx.asp文件,内容只一行,传递ASP内置对象,并执行COM组件的cpcx方法。

ob.cpcx server,application,session,request,response

%>

3、Global.asa 文件,在Global.asa 文件末尾加上这一行,使com组件对象为Application级。

说明:别人一般都是将表单输入的内容作为参数传递给com组件对象的方法,而且每个ASP文件

里每一个方法的参数都可能不同,差别大,不容易写。这里却是将ASP内置的五个对象作参数传递,

因为参数相同,顺序都设同一样,这样的无区别参数使用起来非常容易,相当于无参数;asp文件也

简化到最小,仅执行一个方法,编好后就不再需要修改和维护了;每个ASP文件在COM组件对象里都有

一个方法和HTM模板文件相对应,采用同名机制可以方便记忆和使用,如cplr.asp对应cplr方法和

cplr.htm输出模板文件。

二、输出模板文件

建一新目录,就C:foxBS 吧,当然其他名称也没问题,下面的所有文件都放在此目录下。

1、cplr.htm 文件内容为

产品录入页面

请输入产品名称:

请输入产品价格:

[[cmsg]]

2、cpcx.htm 文件内容为

产品查询页面

请输入要查询的产品名称:

查询结果显示

产品名称产品价格录入日期
[[cCPMC]][[cCPJG]][[cRQ]]

说明:采用输出模板文件的好处是非常多的,甚至是必须的。第一、它实现界面设计与

代码设计相分离,变动它们时互不影响;第二,它简化了代码的设计,代码的设计只需认真考虑

业务处理逻辑,生成需置换的变量和字段,然后用textmerge()函数就求得html输出字符串了;

第三、它也简化了界面的设计,输出HTML文本可不再手工编写,用网页制作工具可方便制作好看

的界面,在相应输出的地方写上变量域或字段域就好了。在我的例子里,不使用VFP默认的域界

符<< >>,而使用[[ ]],是为了与HTML的< >相区分。

三、com组件编写

1、产品表.dbf

在表设计器里设计,三个字段分别为

产品 C 20 建索引

价格 N 9 :2

日期 D

记得在“产品”字段建索引。

2、在VFP新建一项目,项目名称是foxBS,编译时将生成foxBS.dll,名称与Global.asa文件中

progid="foxbs.foxbs" 左边的foxbs相同,右边的foxbs是类名。

3、在项目中新建一程序文件bsclass.prg ,其他名称也行,内容为

DEFINE CLASS foxBS as Session OLEPUBLIC

PROTECTED cPath,cpcx_htm,cplr_htm,CRLF

*!* -----------------------------------------------------------------------

*!* init过程,启动时运行

*!* 赵贤书原创于海口,2006年1月26日首发于梅子论坛 *!*

PROCEDURE init

SET EXACT ON

SET DELETED ON

this.CRLF=CHR(13)+CHR(10)

this.cPath=justpath(application.ServerName)+"" && 取得VFP COM对象的路径

USE (this.cPath+"产品表") ORDER 产品 SHARED && 共享方式打开表

this.cpcx_htm=FILETOSTR(this.cPath+"cpcx.htm")

this.cplr_htm=FILETOSTR(this.cPath+"cplr.htm")

=STRTOFILE("foxBS.init 运行"+this.CRLF,this.cpath+"debug.txt",.t.)

ENDPROC

*!* -----------------------------------------------------------------------

*!* cplr过程 , 处理 cplr.asp , 模板cplr.htm

PROCEDURE cplr(oServer,oApplication,oSession,oRequest,oResponse)

LOCAL outhtml,cname,cJG,nJG

cMSG=""

*!*---------------------------------

*!* 初次打开CPLR.ASP页面时执行的代码

IF oRequest.form("cname").count=0

outhtml=textmerge(this.cplr_htm,.f.,"[[","]]")

oResponse.write(outhtml)

=STRTOFILE("foxBS.cplr cplr.asp 初次打开"+this.CRLF,this.cpath+"debug.txt",.t.)

RETURN

ENDIF

*!* ---------------------------------

*!* 按下 转到产品查询页面 按钮时执行的代码

IF oRequest.form("B3").count>0

oResponse.Redirect("cpcx.asp")

RETURN

ENDIF

*!* ---------------------------------

*!* 按下 确定输入 按钮时执行的代码

cNAME=oRequest.form("cname").item(1)

cJG=oRequest.form("cJG").item(1)

nJG=VAL(cJG)

IF ALLTRIM(cNAME)<>"" and nJG<>0

SELECT 产品表

SEEK cNAME

IF FOUND()

nYJG=价格

REPLACE 价格 WITH nJG,日期 WITH DATE()

cMSG="产品 "+cNAME+" 原价格"+STR(nYJG,9,2)+" 新价格"+STR(nJG,9,2)+" 已更新至数据表中!"

ELSE

INSERT INTO 产品表 VALUES (cNAME,nJG,DATE())

cMSG="产品 "+cNAME+" 价格"+STR(nJG,9,2)+" 已录入数据表中!"

ENDIF

ELSE

cMSG="请输入产品名称和价格!"

ENDIF

outhtml=textmerge(this.cplr_htm,.f.,"[[","]]")

oResponse.write(outhtml)

=STRTOFILE("foxBS.cplr 运行"+this.CRLF,this.cpath+"debug.txt",.t.)

*!* -----------------------------

ENDPROC

*!* -------------------------------------------------------------------------

*!* cpcx过程 , 处理 cpcx.asp ,模板cpcx.htm

PROCEDURE cpcx(oServer,oApplication,oSession,oRequest,oResponse)

LOCAL outhtml,cname,cCPMC,cCPJG,cRQ

cCPMC=CHR(41377) && CHR(41377) 为中文全角空格

cCPJG=CHR(41377)

cRQ=CHR(41377)

*!* ------------------------------

*!* 初次打开CPCX.ASP页面时执行的代码

IF oRequest.form("cname").count=0

outhtml=textmerge(this.cpcx_htm,.f.,"[[","]]")

oResponse.write(outhtml)

=STRTOFILE("foxBS.cpcx cpcx.asp 初次打开"+this.CRLF,this.cpath+"debug.txt",.t.)

RETURN

ENDIF

*!* ---------------------------------

*!* 按下 转到产品录入页面 按钮时执行的代码

IF oRequest.form("B3").count>0

oResponse.Redirect("cplr.asp")

RETURN

ENDIF

*!* ---------------------------------

*!* 按下 产品查询 按钮时执行的代码

cname=oRequest.form("cname").item(1)

IF ALLTRIM(cname)<>""

SELECT 产品表

SEEK cname

IF FOUND()

cCPMC=产品

cCPJG=STR(价格,9,2)

cRQ=DTOC(日期,1)

ELSE

cCPMC="无区配记录"

cCPJG=CHR(41377)

cRQ=CHR(41377)

ENDIF

ELSE

cCPMC="名称不能为空"

cCPJG=CHR(41377)

cRQ=CHR(41377)

ENDIF

outhtml=textmerge(this.cpcx_htm,.f.,"[[","]]")

oResponse.write(outhtml)

=STRTOFILE("foxBS.cpcx 运行"+this.CRLF,this.cpath+"debug.txt",.t.)

*!* -----------------------------

ENDPROC

*!* ------------------------------------------------------------------------

*!* destroy过程,退出时运行

PROCEDURE destroy

SELECT 产品表

USE

=STRTOFILE("foxBS.destroy 运行"+this.CRLF,this.cPath+"debug.txt",.t.)

ENDPROC

ENDDEFINE

项目建好后,在编译时选择Multi-threaded COM Server(dll)(多线程COM组件),就可生成

COM组件并自动注册了。现在,在IE里浏览cplr.asp 或 cpcx.asp 就可以运行此B/S应用。

说明:

1、this.cPath=justpath(application.ServerName)+"" 得到的是COM组件foxBS.dll

文件所在的路径,这样写而不直接用 this.cPATH="c:foxbs" 是为了com组件实现路径的无

关性,application.ServerName 中的application也不是ASP中的application,而是VFP中的

application--应用程序对象,这里即COM组件本身。之所以要解释这么多,是因为有一网友在

上篇中误会,以为该路径是指向WEB根目录。

2、方法过程中的参数顺序一定要和ASP文件中的参数顺序一致。

3、cCPMC=CHR(41377)中使用中文全角空格是为了表格在没有数据时更好地显示。

四、 下面总结这种方法的好处:

1、实现在Application级com组件对象对ASP内置对象的引用。

2、也同样实现Session级和页面级COM对象对ASP内置对象的引用,在引用方法变化时,无需

更改COM组件,因此,很容易根据性能、扩展性要求随意变化,实现高扩展性、可伸缩性。

3、ASP文件简化到最低程度,仅相关于开关指示作用,编写后不再需要修改和维护,而所有的

界面、功能编写集中在html文件和COM组件。

4、使用输出模板,可以实现界面设计、代码设计相分离,互不影响,界面设计、代码设计也

更加容易,因此可以适应编写大应用系统的要求。

5、Application级com组件对象只需一个实例就可为所有的ASP文件请求和用户提供服务,在一个

不太大的系统中,这样性能最好,稳定性也高。

当然,也有缺点,如;com组件特别是用于ASP的COM组件难于调试,重新编译COM组件需暂停Web

服务,这些缺点都不是VFP的COM组件所独有,所有的语言使用ASP+COM做B/S应用的都存在这样的麻烦,

但这些问题对一个有经验的编程人员来说不算什么,方法总比困难多。

后记:以上的内容是做服务器端组件的方法,但在B/S应用中仅有服器端组件是不够的,客户端与用户

的互动就可能需要VB脚本、JAVA脚本。如果foxer们也想用VFP怎么办?告诉你答案:就是用VFP编写客户端

组件,这样就不需要VB脚本和JAVA脚本了,特别是客户端要打印特定格式的内容,VB脚本和JAVA脚本都无法

解决,使用VFP客户端组件却可轻松搞定。遗憾的是,在客户端组件编写方面我还没经验,不能告诉大家好

的方法,希望大家也去探索探索,告诉我好的方法。 下一步,我打算将ASP内置组件在VFP内的语法整理

一下,这将又是一个原创的好贴子,让Foxer 们也不用走太多弯路。希望大家积极支持我,不要让好的、

原创的贴子沉下去,让更多Foxer看、学习。

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值