Foxpro 进一步订制VFP的向导和生成器
作为最好的数据库管理系统,VFP 给我们提供了高度的可自定义的交互式的开发环境(interactive development environment IDE)。你可以修改菜单,安装新的生成器和向导,实现开发工具条,修改项目管理器的行为,以及很多其它事来使你的IDE 更高效。这些定制甚至比我们所知道的和喜欢的VFP语言更好,连相对不熟炼的VFP 开发者都可以按他们自己的方法定制开发环境。
本节将配合实际程序示例,向你展示如何建立简单的工具增加你和你的开发组的效率。我们将着眼于修改VFP 的向导和生成器来提供额外的或自定义功能,并使用VFP 6中的BuilderD 技术创建你自己的生成器。
修改VFP 的向导和生成器
如果你象我一样,你可能不常用VFP 的生成器和向导,因为它们不完全能满足你的需要。可能它们不具备足够的灵活性或可能你只是不喜欢他们的工作方式。直到VFP 6以前,没有办法改变生成器和向导的行为,因为Microsoft 没有提供源代码。但是,现在我们不但获得了生成器和向导的源代码,也获得了类浏览器,组件管理器的源代码。
生成器和向导的源代码可以在VFP主目录下的TOOLS\XSOURCE目录中的XSOURCE.ZIP 文件中找到。当你解压该文件时,它建立一个VFPSOURCE 目录,其中包含了所有的源代码。向导的源代码 可以在WIZARDS 目录下找到,生成器的在BUILDERS目录下 (虽然一些WIZARDS目录中的公共文件也被生成器使用)。
因此,现在我们有了源代码,我们可个按我们的需要来修改生成器和向导,对吗? 好了,一个较好的办法是建立新的生成器和向导时,使用源代码中的大多数类和程序,但以派生子类并复制和修改PRGs 或建立封装PRGs的方法来忽略他们原有的行为。本文将详细说明如何对各生成器和向导这样做。
一但你建立了你自己的生成器和向导,怎样告诉VFP 使用你的而不是原来的吗? 生成器是注册在BUILDER.DBF 且向导是在WIZARD.DBF中,两个表都在VFP主目录下的WIZARDS 子目录中。这些表具有相同的结构,如下表所示。
| 字段 | 描述 |
| NAME | 生成器或向导描述名。 |
| DESCRIPT | 生成器或向导的说明。 |
| BITMAP | 未使用。 |
| TYPE | 生成器或向导是对哪一对象类型的。在 BUILDER.DBF 情况下,它一般是一个对象的基类 ( 虽然已有以 MULTISELECT , AUTOFORMAT 和 RI 字段 ) 。对于 WIZARDS.DBF ,它可能是 FORM , REPORT ,和 QUERY 。 |
| PROGRAM | 包含生成器和向导的 APP 文件名。 |
| CLASSLIB | APP 文件中要实例的类。 |
| CLASSNAME | APP 文件中的主要类的类库。 |
| PARMS | 传递到生成器或向导的参数。 |
表 1. BUILDER.DBF 和 WIZARD.DBF的结构
当你调用一个生成器时,VFP 调用_BUILDER 系统变量中指定的程序 (默认是BUILDER.APP)。BUILDER.APP 查看它所在的环境 (例如,生成器是被那一个对象调用),在BUILDER.DBF 表中查找与环境匹配的记录 (例如,在TYPE 字段中查找对象的基类),并调用注册后的生成器。除系统变量_WIZARD外,向导也是以相同的方法处理,_WIZARD是用于指向可在WIZARD.DBF找到的WIZARD.APP。
要告诉VFP 使用一个不同的生成器或向导,插入一条说明如何运行你的生成器或向导的新记录到BUILDER.DBF或 WIZARD.DBF表中。如果你想在运行新的向导或生成器的同时也可以选择运行原有的生成器或向导,在WIZARD.DBF表中保留原有的生成器或向导记录。如果你想替换原有的,简单的修改它的TYPE值为另外的值(我使用一个"X"前缀,如 "XGRID"),而不是删除该记录;
使用该方法,你可以简单的以恢复TYPE 的值来恢复使用原来的生成器或向导。 我们将考查创建一个Grid 生成器的替代物,参照完整性生成器,Upsizing 向导,和WWW 搜索页向导。
创建更有用的Grid 生成器
VFP Grid 生成器提供了一种快速方法来整合grid 的列并建立你所希望的视觉外观。但是,关于该生成器,有我所不喜欢的一些东西:
- 它不会自动调整列的宽度。必须自己调整列的宽度以适应数据宽度的需要。
- 在生成器的外观页面中的控件类型组合框只列出了已存在于列中的VFP 基类和类; 没有办法添加你自己的类到该列表中。
- 它创建的列和列头是VFP 的基类。你也许想用你自己的类替代它(必须是以编程的方式定义的),例如,单击一个列头而按该列排序。
要建立一个VFP Grid 生成器的替代物,首先建立了SFGRIDBLDR 项目(它在你解压该文档所附的示例程序时建立的GRID 子目录中) 并添加以下文件: BUILDER.VCX (在VFP 向导源目录中的BUILDERS\BUILDERS 子目录中),GRIDBLDR.VCX (在 BUILDERS\GRIDBLDR 目录中),THERM.VCX,WIZCTRL.VCX,WIZMOVER.VCX (所有都在WIZARDS\WZCOMMON目录中),DUMMY.PRG,和 WBGRID.PRG (在BUILDERS目录中)。我如何知道要添加那些文件到项目中呢? 这很简单:只需要查看GRIDBLDR 项目的内容。
其次,派生GridBuilder 类到SFGridBuilder (在 SFGRIDBLDR.VCX类库中) 并复盖ResetColumns 方法,该方法用于调整选定列的宽度到适当的大小 (我只实现了该想法,未实现上述列表中的其它两个)。该方法的代码在下面列出。这里要注意两个有趣的东西。首先,我希望写很多复杂的代码,根据字段宽度、字体和字号来计算出列的宽度,等等。有趣的是,它放弃了生成器中已存在的任务的方法 (SetColWidth),而只是传递字段宽度到该方法中,生成器传给它一个不同的值。其它事情是分配到loColumn。Width 的计算宽度被注释了。理由是我还没有调试好,改变列宽后,当生成器关闭时,会造成问题,所以我把列宽设置为,列宽是保存在wbaCols中。(如果你需要,wbaCols 是一个公共数组。我没有创建生成器,因此不要责怪我采用这种方式)
因此,效果是当一个字段添加网格中时,它没有立即获得适当的列宽,但是一但你执行了一些其它操作 (添加另一个字段,转到生成器的另一个页面中,关闭生成器等等。)它就会取得适当的列宽。
local lnRows, ; lcField = wbaCols[lnI, 2] |
最后我为我的生成器建立了GRIDMAIN.PRG (使用了BUILDERS\GRIDBLDR 中的GRIDMAIN.PRG 的办法) 并使它成为项目的主文件。该程序用SET CLASSLIB命令添加SFGRIDBLDR.VCX 到打开的类库中,这样它可以找到我们的SFGridBuilder 类。GRIDMAIN 也自动注册它自己到VFP BUILDER 表中(如果是直接运行该APP 文件)。
要查看该生成器的行为,建立并运行SFGRIDBLDR.APP 来作为grids生成器注册它。如果你在运行该APP后,观察观查BUILDER.DBF,你会发现它是"未注册的" ,原始的grid 生成器的 TYPE 字段由"GRID" 改成了"XGRID" 并在它后面为它自己添加了一条TYPE 字段为"GRID"的新记录。下一步,新建一个表单,拖动grid 到表单中,并调用生成器。新的生成器看起来与原来的没有任何区别,但是当你添加字段到表格时,你会发现字段宽度自动调整到了适当大小。
创建一个更好的参照完整性生成器
我有一小点关于VFP自身的参照完整性(RI)生成器的问题:
- 当你单击确认按钮来保存修改后的RI 时,它两次(而不是一次)让你确认。不是我太自信,但是我相信取消按钮的用途是允许我们返回; 我单击确认按钮因为它是确认,因此我不需要一条 "你真的,真的确认你要这样做吗" 的确认对话框。
- 在你压缩数据库前,你不能运行RI 生成器。
- 我确实砂需要它备份我的当前的储存过程为一个叫做RISP.OLD的我总是要自己删除它的文件。
- 生成的代码中至少有一处BUG ,应该用正确的功能来防止它。关于该BUG的细节,参见"VFP中的错误处理一文"。
- 它生成的代码既多又缺少注释。要试着理解这些代码是做什么的是一个艰苦的过程,而且如果是在一个复杂的数据库中,RI 代码可能超过VFP 编译后的代码的64K 限制。如果你看过Jim Booth 和 Steve Sawyer写的 "Visual FoxPro 6.0应用程序开发的有效技术" 一书,你会有一个较好的快速,简洁的子程序来维护RI。Steve的 NEWRI 子程序是数据驱动的,因此它是在运行时而不是在生成时检查哪些规则需要强制执行。结果是清楚的,紧密而不是VFP RI生成器生成的大实用的代码。
- 它所支持的规则仅是忽略、级联和限制。你所需要的其它选项又怎样呢,例如无效(设置子表的外部关键字为.NULL.) 或指定一个新值 (设置外部关键字为的默认值)?
修正这些项相对容易些,因为我们有RI 生成器的源代码。我建立了SFRIBUILDR.APP,一个 VFP RIBUILDR.APP的替换物。我没有实现附加的规则 (上面提及的最后一项) 但是我处理了其它的所有项。我首先建立了SFRIBUILDR 项目(它在解压后的程序的主目录下的RI 目录中) 并添加了VFP的RIBUILDR.VCX(在VFP向导源程序所在目录下的BUILDERS\RIBUILDR 目录中)。
接着,我派生VFP RI生成器类到 SFRIBUILDR.VCX 类库中的SFRIBuildr。我忽视(overrode)了Load 方法以便在数据库中有被删除的记录时不会发生错误 (你可以参见我注释的已存在的代码)。我忽视了确认按钮的Click 方法,以便不出现确认对话框和不复制当前的储存过程到RISP.OLD中,并修复了生成的代码中的错误。同时,如果它检查到NEWRI.PRG 存在于你的系统中 (与SFRIBUILR.APP在同一目录),它会把该代码放入数据库的储存代码中而不会生成其它代码。这个修改需要一个新的方法 RIMakeNewTr用一个不同的名字建立触发器(__RI_Handler) 而不是原来的RI 生成器的生成的(__RI_<action>_<table>,如__RI_Delete_Customer)。因为这些方法中有大量的代码,在这里就不写出来了; 但是,如果你查看提供的源代码,你会看见我确实只注释了很少的代码行,并添加了很少的代码。
最后,我从BUILDERS\RIBUILDR目录中复制RIMAIN.PRG 到我的生成器所在的目录,添加它到项目中,并使它面为主程序。我修改了该程序所指向的类库,使它能找到我的VFP RI 生成器类的子类所在的类库 (SFRIBUILDR.VCX) 并自动注册该生成器到VFP BUILDER 表中(如果是直接运行该APP)。
生成并运行SFRIBUILDR.APP 导致该文件作为RI生成器注册取代了通常的RIBUILDR.APP。要看这一点,按以下步骤进行:
- 移动本文附带的示例文件到WIZARDS\RI 目录。
- 如果你有Steve的 NEWRI.PRG,将其复制到该目录。
- 运行COPYDEMO.PRG。该程序将复制VFP TESTDATA 数据库到DATA 目录中,这样我们不会改动原始的数据库。
- 运行 DELETETEST.PRG。这会演示一个VFP RI 生成器生成代码的流程。第一次浏览显示ALFKI 客户的几个订货,然后试着删除该客户。因为CUSTOMER 到 ORDERS 表间存在着级联删除,且ORDERS 到 ORDITEMS表间的规则为限制,该客户将不能被删除。但是,请注意错误对话框出现了六次(而不是你所希望的一次) ,然后另一个浏览显示该客户已被删除(CUST_ID 是 .NULL.)。
- 因为我们已经把数据弄乱了,再一次运行COPYDEMO.PRG重新复制TESTDATA 数据库到DATA 目录中。
- 以独占方式打开DATA\TESTDATA数据库。
- 生成并运行SFRIBUILDR.APP 来注册它为RI 生成器。
- 打开数据库设计器,选择修改参照完整性,然后在RI 生成器对话框中,单击确认按钮。注意没有出现确认对话框。选择修改储存过程并注意代码的不同(如果你有NEWRI.PRG,该代码会放入储存过程中; 否则,生成的RIDelete 和 RIUpdate 方法代码中的bug 已修正)。如果你有Steve 的 NEWRI.PRG,修改CUSTOMER 表,并注意各触发器方法的名字。同时,你不会看到RISP.OLD 文件了。
- 再次运行DELETETEST.PRG。这一次,你只会看到一次错误信息且ALFKI 客户没有被删除。
创建一个更好的升迁(Upsizing) 向导
Jim Falino 在使用升迁向导时失败了,因此他创建了一个具有他所希望的行为的版本。
- 向导在每一个具有至少一个数值,浮点,通用 或备注字段的表中,建立一个timestamp 字段。Jim 不希望向导自动建立任何timestamp 字段,因此他移去了该功能。
- 向导为具有主关键字段的表自动建立一组索引。这在有时是令人满意的,Jim 决定在默认情况下不建立组索引,因此在建立主关键字时,他加入了NONCLUSTERED 子句。
- 由于数据库对象名字在SQL Server 中必须唯一,对于具有非唯一名的东西不能升迁。例如,如果你为多个表的主关键字段建立了相同索引名的索引则你不能升迁关键字索引 (如使用"ID" 为每一个表的主关键字段)。Jim 的方案是重命名主关键字索引为UQ_<table name>,因为名字在在 SQL Server中是不重要的。
- 可用的表的列表框滑有排序; 表出现的顺序是它们在DBC中的顺序。在一个拥有上百个表的DBC中,要找到一个特定的表是件痛苦的事。Jim 设置了SuperMover 对象的SortLeft 属性(用于指明左边的列表框是否需要排序) 为 .T.
- 向导可以为DBC中的每一个表,用相同和定义建立一个远程视图。但是,但是它命名视图与原表同名,并重命名表为一个唯一名。由于有些人喜欢对视图使用命名约定(例如,在原表名前加上一个"V"),Jim 修改了向导中的这一点。
- Jim 修复了一个问题:向导有时会重新排列字段复合索引的顺序。
- VFP 数值型字段类型升迁为浮点型,即使 SQL Server 中有数值型数据类型也一样。这致使VFP中多于两位小数的数值型字段被截短,并且 VFP 数值字段没有小数点的会升迁为两位小数。
Jim 的修改是让用户指定他们的要求; 你可以使用它们如果你的需要与之相同,或将他们作为模板使用以便你自己修改。
创建一个更好用的WWW 搜索页向导
在 "Visual FoxPro 6 企业开发" (Prima Tech,ISBN 0-7615-1381-7)一书中,Rod Paddock 和 John Petersen 描述了如何修改WWW 搜索页向导来取消只能输出5个字段到一个网页的局限。胜于修改向导,你会希望派生它们。要这样做,用我派生生成器类的相似的方法。WWW 搜索页向导的代码在VFP 向导源目录下的WIZARDS\WZINTNET 目录中。
Tags:
作者:佚名评论内容只代表网友观点,与本站立场无关!
站长推荐
栏目导航
本类热门阅览
相关文章
- › 使用 Visual FoxPro 的Slider ...
- › 使用 Visual FoxPro 的Progres...
- › 使用 Visual FoxPro 的Calenda...
- › 使用 Visual FoxPro 的Common ...
- › 使用 Visual FoxPro 的TreeVie...
- › 使用 Visual FoxPro 的 ImageL...
- › 使用 Visual FoxPro 的 Active...
- › foxpro 结论
- › foxpro 维护源表
- › foxpro 多个本地数据
- › foxpro 机动查询和数据输入
- › foxpro 刷新(Refreshing) 离线...
