第1章 关于PFC

PFC 用户向导

主题:

这本书记述的是如何利用PowerBuilder Foundation Class (PFC)编程.

读者:

这本书给您带来的是:

  • 可以非常方便的使用 MicrosoftWindows 应用程序.

  • 叙述了PowerBuilder当件最流行的编程方法，和”Application Techniques book”一书中叙述的概念和编程技巧。

  • 如何理解SQL和如何使用DBMS。

这本书共分四部分，每部分都是为特定的PFC读者准备的。

Simaple Windows and dialog boxes

这本书阐述的窗口和对话框都是Win95界面。如果你的操作系统是UNIX 或是Macintosh，那么，你的窗口和对话框就不会和这本书匹配。

Part 1

PFC 总述:

这部分描述的是PFC和PowerBuilder的首要概念.所有的读者都有必要看一下。

第一章 关于PFC

这一章介绍的是PFC的基础，PB的首要概念，面向对象的内容，并附有一个PFC的组成图。

理解PFC：

PFC是一组PowerBulider的对象，它可以由用户自己定制，扩充。你可以象搭积木一样使用它，使程序紧密的连接起来。PFC还包括许多有用的对象，例如:debug对象。

PFC是由PowerBuilder提供的PB对象，并支持PowerScript 源代码。它使用的是先进的PowerBuilder面向对象技术，其一个特征是面向服务设计。确使你的程序占用最少的计算机资源。

PFC使用了许多先进的编码技巧，你可以使用PowerBuilder的PowerScript编译器来检查对象，实例，事件，和继承PFC父类的函数。

这本书说的是PFC的概念(PFC是什么东西和你为什么使用它)还有使用信息(如何计划.使用PFC)

为了更详细的了解PFC的对象,实例,事件,和继承PFC父类的函数,请看PFC ObjectReference 。

理解PowerBuilder：

使用PFC可以创建先进的面向对象式的PowerBuild类库。要想掌握PFC和它的面向对象特征，首先需要了解PowerBuilder和它的面向对象特征。这一节将告诉你应该熟悉PowerBuilder的基本概念。

PFC原是为建类库准备的,但并不是不让你用它创建应用程序。通过看PowerBuilder User's Guide可以完全了解的PowerBuilder的概念。

PowerBuilder类库和对象:

PFC是作为PowerBuilder Libraries(PBLS)发行的。PBLs包括你用于写程序的父类和派生类对象。在使用任何PFC对象之前，你一定要在你的应用程序库的搜索路径中把PFC类库加进去。PowerBuilder在执行程序时通过搜索路径找到程序所引用的对象。

PB标准对象 | 用途
Windows | PowerBuilder应用程序和它的用户之间的联系界面。
Menus | 用户在当前活动窗口用来搜索命令的表。
DataWindow objects | 用于接收,实时处理数据。
User objects | 由用户自己定义的对象(一次定义可以重复使用)。

User objects 有两种类型:

（一）:Visual user objects (可视化用户对象)

一个可视化用户对象是一个可以重复使用的可视化控制,或者是一批预先确定的可视化控制.PFC包括两种可视化用户对象类型.

1.标准的可视化用户对象类：

PFC提供了一套丰富的标准的可视化用户对象.每个PFC的标准的可视化用户对象都相当于一个PowerBuilder的窗口控件.这些对象包括以PFC服务预想确定完全的综合操作。 特别值得一提的是u_dw DataWindow 用户对象，这是以PFC服务来提供广泛的综合功能。

2.用户自定义的可视化用户对象

PFC也提供了用户自定义的可视化用户对象，这些对象包括一组窗口控件，并提供先进的函数用在某些特别情况。 (PFC没有使用外部用户对象和VBX用户对象，要想进 一步了解可视化用户对象，请看"PowerBuilder User's Guide")

（二）:Class user objects(非可视用户对象类)

一个非可视用户对象是一个用来实现非可视的处理时使用的控件。PFC包括两种非可视用户对象类型。

1.标准的非可视用户对象:

标准的非可视用户对象是继承 PowerBuilder内嵌的系统对象而来。PFC提供了许多标准的非可视用户对象,例如:处理事务，错误对象，和其他所有的扩展系统对象。

2.用户自定义的非可视用户对象:

用户自定义的非可视用户对象是继承 PowerBuilder非可视对象类而来，它把数据和代码进行封装。这种类型的用户对象允许你从SCRATCH定义一个对象。

PFC用Class user objects来执行它的许多服务以及提供这些服务对象的函数。它也提供？reference variables(引用变量)，何谓 rdference variables呢？即是一个对象指针。你可以用它来存取一个对象的实例变量，函数，事件。

Functions（函数）：

PowerBuilder支持全局函数和对象函数。PFC通过user_object function执行它的处理。一个函数就是执行一些处理的PowerScript语句的集合，你可以传递数据或者是什么也不传，它来返回一个值。

详细信息册参考PFC Object Reference。

Events and user events（事件和用户事件）：

PowerBuilder的Windows,user objects,contols,都有一些预先设定的事件。PFC通过定义用户事件为许多PFC 对象增加事件。事件可以接受数据和返回值。共有三种PFC 事件：

事件类型 | 触发时间
PowerBuilder预先设定的事件 | 某个动作导致操作系统调用事件
预先编好代码的用户事件 | 某个动作（例如选择一个菜单）导致PFC触发用户事件
空的用户事件（可以加入代码） | 某个动作（例如选择一个菜单）导致PFC触发用户事件
除非另有说明，本书的event都指的是这三种。

Function and events compared （函数和事件比较）

函数和事件在许多方面都是相似的：

（1）他们都可以接收数据，返回值；

（2）他们都由PowerBuilder语句构成；

（3）他们都可以被调用，触发，传递。

但他们还是有些不同的：

使用特征 | 函数 | 事件
调用一个不存在的 | 将会出现运行时错误 | TriggerEvent返回-1
覆盖父类脚本 | 直接覆盖父类脚本 | 可以扩展或者覆盖
访问 | 可以是Public、Private、Protected | 永远是Public
重载 | 可以重载 | 不可以重载

面向对象式的设计

面向对象的编程工具支持三个基本规则：inheritance（继承），encapsulation（封装），polymorphism（多态）。

如何使用PFC扩展层:

在PFC中没有类库完全适合你的需要，你可以代表性的修改PFC来满足你的程序的需要。假如没有PFC扩展层，就会出现一个问题：当PFC版本升级时，新版本的PFC恢复该这些修改，而你不得不用手工改变。

一个特别的扩展层：

PFC产生一个扩展层是通过继承所有的层实现的。所有的扩展对象都在单独的PBLS，这在PFC升级时不会影响。

内容 | 祖先层
Application and global services | PFCAPPSRV.PBL
DataWindow services | PFCDWSRVPBL
Visual and standard class user objects | PFCMAIN.PBL
Utility services | PFCUTIL.PBL
Window services | PFCWNSRV.PBL

祖先层的类库中的对象包括所有的实例变量，事件，函数；扩展层的类库中的对象是相应祖先层类库中的对象的不可修改的子类。即使是继承，也可以访问祖先的实际变量，事件和函数。

通过PowerBuilder Bowser来察看子类的对象的实际变量，事件和函数。

使用扩展层有二个优点：

  1. 你可以增加一些点，部门，还有程序逻辑。

  2. 不会影响版本升级。

旧版本对象：

PFCOLD。PBL Library包含旧的对象。如果你有一个存在的PFC程序，你有可能需要把他加在你的library list.

注意：

你要通过修改扩展层的对象来定制PFC程序。千万不要轻易修改祖先对象。你的程序中的对象要使用扩展层的对象并且继承扩展层的窗口。

迅速开始：

在用PFC编程时，程序经常需要修改，存取，以及从扩展层中继承对象。PFC装置中有一套扩展库（PFC Quickstart Libraries）。它包括扩展层的基本功能，使你的程序快速发展。

PFC命名规则：

PFC遵循以下命名规则：

Level | Name
PFC层对象 | 用前缀pfc_
扩展层对象 | 和它的祖先有同样的名字但没有前缀pfc_

例如：DataWindow selection service object的祖先是pfc_n_cst_dwsrv,扩展层的子类是

n_cst_dwsrv.Pfc_n_cst_dwsrv 包括所有服务的代码。n_cst_dwsrv 是不可修改的子类（你可以在假如程序指定的实例变量和代码。）。

PFC定义的用户事件：

PFC定义用户实践也用前缀pfc_prefix.这使得你的应用程序的用户事件和PFC 的用户事件更加容易。

PFC文档使用扩展层名字

当指定一个服务对象时，PFC文档总是用扩张层命名。例如：当论述基类窗口时这书指向w_master不是pfc_w_master.但要记住，w_master的实际变量，事件和可用函数实际上是在pfc_w_master定义的。

PFC命名习惯详细资料请看PFC Object Reference

我们不难想到：

PFC的对象继承允许你在每一层假如扩展逻辑。例如：pfc_w_sheet是从w_master继承的，w_master的实际变量，函数，你加在它的事件在它的子类窗口中都已存在。

如何加扩展层

扩展层通过PFC升级类有效的实现应用程序内部的重用和单个程序的重用。但是，在大部门或者是多部门合作时，一定要考虑好扩展的标准，方法，注意部门的规则和商业规律。

如果你是在一个组织里使用PFC，你要考虑创建一个新层（包括这个组织的所有的变量函数，事件）。应用程序还是使用PFC扩展库的对象，可是调用实例变量，事件，函数的祖先变了。

PFC构成：

PFC是由以下构成的：

  • 一套PBLS

  • 一个数据库

  • Quickstart PBLS

  • 实例代码

  • 一个简单的应用程序

Localized PFC(局部化的PFC)

局部化的PFC 将会在PFC新版本公布后升级。

The PFC PBLs

PFC是分布在PBLS包含的祖先对象和PBLS扩展层包含的对象。每个祖先对象扩张层包含提供以下服务的对象

Libraries | Contents
PFCAPSRV.PBL PFEAPSRV.PBL | 应用程序管理器，应用程序服务对象和全局服务对象。
PFCMAIN.PBL PFEMAIN.PBL | 标准可视化用户对象，自定义可视化用户对象，标准用户对象类。
PFCUTIL.PBL PFEUTIL.PBL | 有用的对象和服务。
PFCWNSRV.PBL PFEWNSRV.PBL | 窗口服务，包括用户对象和有用的窗口。
PFCOLC.PBL | 旧的用户对象。（基层和扩展层的对象）

使用library画笔：

使用library画笔来看到PFC中所有对象

PFC 数据库

PFC装载了pfc.db本地数据库。这个数据库包括以下几个表：

Table | Usage
Messages | 错误信息服务。
Security_apps | 安全服务。
Security_groupings | 安全服务。
Security_info | 安全服务。
Security_template | 安全服务。
Security_users | 安全服务。

PFC本地数据库是由开发者预先设定的，如果你要使用错误信息服务和安全服务一定要在你的数据库中复制指定的表。连接”Deploying database tables”

The PFC Quickstart PBLs

使用PFC Quickstart libraries用来是程序配置和运行迅速。他们包括经过挑选的PFC扩展层对象的保护子集。

做一个PFC Quickstart libraries备份，你就有了后援了。

The PFC code example

使用它是为了了解PFC的对象和服务。学习如何编码并且实现PFC的基本功能。The PFC Quickstart有广泛的参照和使用资料。

The PFC sample application

使用PEAT可以看到PFC的例子是如何进行工程预算和跟踪系统的。


第三部分 PFC 深入编程

概要：

这一部分解释了如何使用PFC与PFC的SERVICE进行编程。

这一部分是为应用程序开发人员而写的。

  1. PFC编程基础

概要：

这一章阐述了 PFC 编程的基本技巧，同时也告诉了你如何开始运用 PFC 编写应用程序。

设置应用程序管理器

首先建立一个PFC应用程序的第一步就是配置应用程序以及建立应用程序管理器--n_cst_appmanager。应用程序管理器将替代原来的应用程序对象。原来在应用程序对象中编写的脚本将全部改写在应用程序管理器中。应用程序管理器中同时还通过实例变量、函数来维护应用程序的属性。其中有框架窗口、应用程序与用户的INI文件或注册键以及帮助文件等。

注意：

使用分开的物理文件

每个独立的应用程序都必须拥有自己独立的一套文件。你不可以共享父类文件，也就是那些以PFC开头的文件。这是由PFC的内部继承关系而决定的。

例如，假设应用程序1与应用程序2都拥有它们自己的一套扩展的PFC库文件，但是它们共享父类文件（PFC库文件）。这时应用程序1在自己的PFE（PFC扩展库）的w_master中增加了一个函数名为of_SetData。这样这个函数将在w_master的所有子类中都有效，这些子类是pfc_w_main，pfc_w_frame，pfc_w_sheet 等。而这些对象恰恰在这两个应用程序共享的父类文件（PFC库文件）中。这样当应用程序2重新生成应用程序时（regenerate）由于应用程序2的PFE文件中没有of_SetData函数。这样w_master的所有子类中的关于of_SetData函数的指针都将被删除。这样当应用程序1运行时将会导致运行时错误与编译错误。

具体步骤

  1. 打开应用程序画笔。

  1. 定义库文件列表。

    2. PFCAPSRV.PBL

    PFCDWSRV.PBL

    PFCMAIN.PBL

    PFCUTIL.PBL

    PFCWNSRV.PBL

    PFEAPSRV.PBL

    PFEDWSRV.PBL

    PFEMAIN.PBL

    PFEUTIL.PBL

    PFEWNSRC.PBL

    PFCOLD.PBL（如果你的应用程序是使用老版本的PFC库那么请增加该文件到库列表中）

  3. 在应用程序画笔中打开脚本画笔，定义n_cst_appmanager类型的全局变量gnv_app。

    4. n_cst_appmanger gnv_app

    这个变量名必须是gnv_app，因为PFC的对象、函数、事件都需要这个n_cst_appmanager或它的子类的全局变量—gnv_app。

  4. 增加如下代码到应用程序对象的OPEN事件中。它的用途是创建n_cst_appmanager、调用pfc_Open事件。

    5. gnv_app = Create n_cst_appmanager

    gnv_app.Event pfc_Open(commandline)

  5. 增加如下代码到应用程序对象的CLOSE事件中。

    6. gnv_app.Event pfc_Close()

    Destroy gnv_app

  6. 增加如下代码到应用程序对象的SystemError事件中。调用pfc_SystemError事件。

    7. gnv_app.Event pfc_SystemError()

  7. 关闭应用程序画笔，保存所作的修改。

  8. 打开用户自定义对象画笔。在PFEAPSRV.PBL中找到n_cst_appmanager并打开，或者是它的子类。

  9. 在n_cst_appmanager的构造事件（Constructor Event）中调用它的函数来初始化关于软件版本号、公司、和INI文件的实例变量。

  10. 在 n_cst_appmanager的pfc_Open事件中打开你所想要的应用程序Service 。

    11. 你所想打开的Service 调用函数

    Application preference of_SetAppPreference

    DataWindow caching of_SetDWCache

    Error of_SetError

    Most recently used object of_SetMRU

    Transaction registration of_SetSecurity

    Debug of_SetDebug

  11. 在pfc_Open事件中增加打开你的初始窗口的代码，例如框架窗口（Frame Window）或者调用显示快闪窗口的of_Splash（）函数。

  12. （可选）增加代码到pfc_PreAbout，pfc_PreLogonDlg，pfc_PreSplash事件中，用于定制关于对话框（About box）、登录对话框（Logon box）、快闪窗口（splash screen）。

  13. （可选）增加代码到pfc_idle，pfc_ConnectionBegin，pfc_ConnectionEnd事件中。

    • 在应用程序对象的idle事件中调用pfc_idle事件。

    • 在应用程序对象的ConnectionBegin事件中调用pfc_ConnectionBegin事件。

    • 在应用程序对象的 ConnectionEnd事件中调用pfc_ConnectionEnd事件。

14. 保存n_cst_appmanager

如何显示快闪窗口

非常简单，只需在pfc_Open事件中，在打开第一个窗口的代码之前写上如下代码：

this.of_Splash（1）

Open（w_tut_frame）（根据不同的应用程序有不同的变化！）

如何显示登录窗口

  1. 在框架窗口的Open事件中调用of_LogonDlg函数：

    2. Integer li_return

    li_return = gnv_app.of_LogonDlg( )

    IF li_return = 1 THEN

    this.SetMicroHelp("Logon successful")

    ELSE

    MessageBox("Logon", "Logon failed")

    Close(this)

    End If

    Of_LogonDlg函数将显示w_logon对话框，同时还会提示输入用户名、密码，当用户点击OK按钮时还会触发n_cst_appmanager的pfc_Logon事件。

    同样，你也可以在n_cst_appmanager的pfc_Open事件中的打开框架窗口之后立即调用Of_LogonDlg函数。但是绝对不要在Of_Splash之后立即调用Of_LogonDlg 。

  2. 在n_cst_appmanager的pfc_logon事件中编写登录到数据库的代码。这个例子假设有一个INI文件，它包含了所有的需要登录到数据库的信息，除了用户名、密码以外。同时还假设你已将SQLCA的默认类型改为n_tr（PFC制定的书屋对象类型）。

Integer li_returnString ls_inifile, ls_userid, ls_password

ls_inifile = gnv_app.of_GetAppIniFile()

IF SQLCA.of_Init(ls_inifile,"Database") = -1 THEN

Return -1

END IF

// as_userid and as_password are arguments

// to the pfc_Logon event

SQLCA.of_SetUser(as_userid, as_password)

IF SQLCA.of_Connect() = -1 THEN

Return -1

ELSE

gnv_app.of_SetUserID(as_userid)

Return 1

End If

建立应用程序

建立一个MDI应用程序

使用w_frame，w_sheet窗口作为你的框架窗口与表单窗口的父类。在w_sheet窗口中增加你的应用程序中所有表单窗口需要的事件、实例变量、函数。

你必须为每一个表单窗口定义菜单。

具体步骤：

  1. 为应用程序在w_frame窗口中作特定的修改。最好是建立一个w_frame窗口的子类，然后再修改这子类。

  2. （可选）在w_sheet中增加实例变量、函数、用户自定义事件。

  3. 建立继承w_sheet的表单窗口。

  4. 建立一个框架窗口（frame window）用的菜单，通常是选用w_frame 。

  5. 为框架窗口指定相应的框架窗口菜单。

  6. 建立表单窗口的菜单

  7. 为表单窗口（sheet window）指定相应的表单菜单。

  8. 在n_cst_appmanager的pfc_Open事件中加入打开框架窗口的代码。

  9. （可选）在必要时候，开启框架窗口Service 。

  • 调用w_frame的of_SetStatusBar函数开启状态条Service 。

  • 调用w_frame的of_SetSheetManager函数开启表单管理Service 。

在MDI应用程序中打开表单窗口：

  1. 在菜单项的Clicked事件中编写有关打开表单窗口的脚本。你需要将表单窗口的名称以字符串的形式传递给Message.StringParm，然后以pfc_Open为参数调用of_SendMessage函数：

    2. n_cst_menu lnv_menu

    Message.StringParm = "w_products"

    lnv_menu.of_SendMessage(this,”pfc_Open”)

  2. 在w_frame的pfc_Open事件中访问Message.StringParm，打开指定的表单窗口。

String ls_sheet

w_sheet lw_sheet

ls_sheet = Message.StringParm

OpenSheet（lw_sheet, ls_sheet, this, 0, Layered!）

建立一个SDI应用程序

在使用PFC建立SDI应用程序中，你将使用w_main窗口作为你的所有main类型窗口的父类。为了使得你的事件、函数、实例变量能够在所有的窗口中都有效，只需将它们加到w_main中。

如果你的窗口需要菜单，那么你必须为每一个窗口定义菜单。

具体步骤

  1. 继承w_main窗口，建立一个main类型窗口，最为主窗口。最好是直接修改w_main窗口。

  2. 建立一个主菜单。

  3. 根据需要建立其他的菜单与窗口。

  4. 在n_cst_appmanager的pfc_Open事件中编写打开主窗口的脚本。

PFC编程过程中的函数使用方法

几乎所有的PFC函数都是对象级函数。这就意味着你必须定义POWERBUILDER对象后才可以使用函数。经过PB封装后的函数使你很轻易的看到哪个函数属于哪个对象。

PFC使用Set/Get/Is 命名规则来控制实例变量。

    • of_Set函数允许你为实例变量赋值

    • of_Get函数允许你获得一个非布尔类型的变量的值

    • of_Is函数允许你确定一个布尔类型变量的真与假

其他类型实例变量的访问规则

PFC定义变量时同时指定为公共类型（public）,那么你将可以随意直接访问。

另外，有些变量由于只是在内部使用，因此不能通过函数进行访问。

除了Set/Get/Is命名规则以外，PFC在为某一Service定义入口参数时使用Register/UnRegister规则。例如，你可以调用u_calculator对象的of_Register函数来定义Datawindow的那个列使用下拉日历。

Object qualificationPFC uses access levels (public, private, protected) to control your access to functions designed for 内部自动调用 use.

When you call these functions from outside the object, use dot notation to qualify the function name. Qualify the function name with the reference variable used to create the object (in some cases you qualify the function name with the actual object name).

调用PFC对象函数

  1. 确认对象是已否被创建

    2. PowerBuilder在当窗口打开的时候会建立窗口、菜单和可视的用户对象。你

    要使用函数of_Setservicename来建立大部分的不可视的用户对象。例如，下面u_dw的对象函数创建了排序Service（n_cst_dwsrv_sort user object），并且在u_dw’s中的实例变量inv_sort中保留它的引用。通常这些代码都在Datawindow的构造事件中：

    this.of_SetSort（True）

    自动实例化对象

    某些PFC对象利用了Powerbuilder提供的自动实例化功能。这些对象没有Set函数。PowerBuilder会在它们声明的时候自动实例化它们。

  2. 在应用程序中调用适当的对象函数

这个例子展示了排序Service将利用DataWindow的列名、排序已显示值、

实现当用户点击后排序。同时可以在菜单栏上显示下拉对话框。

this.inv_sort.of_SetColumnNameSource(this.inv_sort.HEADER) this.inv_sort.of_SetUseDisplay(TRUE) this.inv_sort.of_SetColumnHeader(TRUE)

this.inv_sort.of_SetStyle(this.inv_sort.DRAGDROP)

函数重载PFC使用函数重载提供了一个丰富的、富有弹性的编程接口。它通过两种方法实现函数重载。

  • 多种语法 多个函数具有不同的参数类型、不同的参数顺序。这使得PFC的函数可以处理多种数据类型的参数。

  • 随意的参数数目 许多函数拥有一个具有相同数据类型、相同顺序、参数数目可以变化的参数。它同时还允许PFC为常用的参数提供默认值。

只用于内部处理所重载的函数

除了公有类型的重载函数以外，PFC通常还有一个保护类型的版本，一般都是用来进行内部调用的。例如，n_cst_dwsrv_report中的of_Addline函数有4个公有类型的版本、一个保护类型的版本。这个保护类型的版本是供其他4个调用的。虽然有些时候可以调用这些保护类型的版本，但是他们纯粹是为了内部调用而设计的。

关于PFC事件的编程

PFC包括了预代码的事件、用于实现PFC Service的用户自定义事件。还有一些空的事件，你可以在其中为你的应用程序加入特定的代码，或者执行一些特定的任务。所有的事件都是公有的，你可以直接访问它们。

“预代码事件”与其他的用户自定义事件

预代码事件指的是那些已经在PFC层对象中编号代码的事件。PFC拥有许多具有一定功能的“预代码事件”。这意味着如果你开启了一个Service ，PFC的对象发现该Service已开启了，那么这些“预代码事件”将会执行其中的代码。

例如：u_dw的Clicked事件就是一个“预代码事件”，它会自动调用那些开启的Service函数。你可以扩展这些事件，但是不可以覆盖它们。

空的用户自定义事件

PFC定义了许多空的用户自定义事件。你可以在其中为你的应用程序写入特定的代码。许多这种事件都是通过菜单而触发的。另外一些则是应用程序代码触发的。

例如：

在u_dw中有一个用户自定义事件pfc_Retrieve ，你可以在其中加入检索数据的代码。

Return this.Retrieve（）

有关更多的关于PFC事件的内容请参考PFC Object Reference

PFC中的事件是如何起作用的

PFC是采用如下的方式调用Services中的事件的

    1. 当用户触发某个对象的某个事件时，PFC将会调用相应的Service 的自定义事件，同时传递相应的参数。例如：u_dw的clicked事件会调用n_cst_dwsrv_sort的pfc_Clicked事件，同时传递X坐标、Y坐标、DW对象（这些其实也是DW的Clicked事件的参数）。

    2. 这些Services的事件同时还有可能调用其他对象函数。例如，n_cst_dwsrv_sort的pfc_Clicked事件中还调用了n_cst_dwsrv_sort的函数。

尽管你可以直接调用PFC的对象函数，但是调用相应的事件显得更简单，因为这些事件中已经包括了错误检测代码。

关于事件触发前的一些处理

PFC有一种自定义事件名是Prename 。这意味着这些事件是发生在事件 name 之前的事件。我们把它叫做 pre_event 。你可以随意在 pre_event 中增加代码用于扩充相应的事件处理能力。这些 pre_event 有：

pfc_PreAbout

pfc_PreClose

pfc_PreLogonDlg

pfc_PreOpen

pfc_PrePageSetupDlg

pfc_PrePrintDlg

pfc_PreRestoreRow

pfc_PreSplash

pfc_PreToolbar

pfc_PreUpdate

通常，这些事件中都有一个已经自动实例化了的用户对象的引用变量。这个对象的属性可以影响这个事件的运行。你可以修改这个用户对象的属性，从而达到改变事件的运行或扩展事件的运行效果。有些时候你还需要修改一些其他的对象。例如，当你需要控制About对话框中的一个附加控件的显示效果时，你需要：

    1. 扩展用户对象n_cst_aboutattrib ，在其中增加一个用于在w_about中代表显示效果的实例变量（一个 user ID）。

    2. 在w_about中增加控件（sle_userid）

    3. 在w_about的Open事件中编写代码，将user ID的值放入单行编辑框中（sle_userid）

      4. sle_userid.text = inv_aboutattrib.is_userid

    4. 在n_cst_appmanager的pfc_PreAbout事件中编写初始化代码：

inv_aboutattrib.is_userid = this.of_GetUserID（）

然后当你需要显示w_about时，调用应用程序管理器的of_About函数即可。

如何使用属性对象

PFC提供了许多专门的属性用户对象。这些用户对象有如下特征：

  • 包含公有性质的实例变量

  • 自动实例化

  • 名称以 attrib 结尾

  • 通常用于向PFC的pre_event传递信息，例如pfc_PreAbout

  • 可扩展，你可以在其中自己定义其他的实例变量。

因为，你有可能会扩展这些对象。因此，PFC使用对象而不使用对象。

同样你还可以定义对象函数，做到更随意的控制这些对象。

这些属性对象有：

属性对象 | 有关的 | 用法
n_cst_aboutattrib | Pfc_Pre_About（n_cst_appmanager） | 调用n_cst_appmanager的of_About函数打开about对话框
n_cst_calculatorattrib | Constructor（u_calculator） | 内部自动调用
n_cst_dirattrib | File service object | 内部自动调用
N_cst_dwobjectattrib | Of_Describe（n_cst_dssrv与n_cst_dwsrv） | 函数Of_Describe返回DataWindow中的对象属性。
n_cst_dwproperyattrib | DataWindow Properties objects | 内部自动调用
n_cst_errorattrib | Error message service | 用于传递显示内容到w_message窗口
n_cst_filterattrib | DataWindow filter service | 用于传递信息到filter对话框
n_cst_findattrib | DataWindow find service | 传递信息到Find对话框
n_cst_itemattrib | PFC ListBox, PictureListBox, and TreeView | 内部自动调用
n_cst_linkageattr b | DataWindow linkage service | 内部自动调用
n_cst_logonattrib | Pfc_PreLogonDlg (n_cst_appman ger) | 调用n_cst_appmanager的of_LogonDlg函数打开w_logon窗口
n_cst_mruattrib | MRU service | 用于窗体的pfc_MRUProcess和pfc_PreMRUSave事件
n_cst_restoreroattrib | DataWindow row manager service | 内部自动调用
n_cst_returnattrib | DataWindow filter and sort services | 内部自动调用
n_cst_selectionattrib | Selection service | Populated with arguments to the n_cst_selection of_Open function
n_cst_sortattrib | DataWindow sort service | 用于传递信息到Sort对话框
n_cst_splashattrib | Pfc_PreSplash event (n_cst_appman ger) | 调用n_cst_appmanager的of_Splash函数打开w_splash 。
n_cst_sqlattrib | SQL service | 该属性对象中含有SQL语句的部分内容。
n_cst_textstyleattrib | PFC RichTextEdit control | 用于设置和获取text属性（黑体、斜体等）。
n_cst_toolbarattrib | Pfc_PreToolbars event (w_frame) | 调用w_frame的pfc_Toolbars事件打开w_toolbars 。
n_cst_zoomattrib | DataWindow print preview service | 内部自动调用

PFC的常量

许多PFC对象都包含了常量。使用常量使得程序更加易读。例如：下面两段代码同样是设置Datawindow的linkage风格，但是第二段则显得更加容易理解：

// 1 = Filter linkage style.

dw_emp.inv_linkage.of_SetStyle(1)

// FILTER 作为一个常量

dw_emp.inv_linkage.of_SetStyle (dw_emp.inv_linkage.FILTER)

约定：PFC的所有常量都采用大写。

消息路由

消息路由器可以用于任何一个对象与窗体之间的通讯。不过，大部分时候都是用于菜单与窗体之间的消息传递。它提供了一种查找算法用于确定哪个对象来接收消息。

使用消息路由时：

  • 你菜单中的代码只需要知道代用哪个事件，你无须知道当前的窗口时哪个，或者与其相关的对象名称。

  • 你的窗口无须维护用户事件，只需简单调用DataWindow的事件即可。从而减少了窗口需要维护的事件数量。

Message = user event

经过消息路由传递的消息实际上就是用户事件名。窗口、控件收到这些消息后就会调用相应的事件。

内置的debug消息

消息路由机制还提供了内置的debug

函数of_SendMessage的工作流程

当用户选择菜单项时，Clicked事件中的代码便以欲触发的用户事件名为参数（字符串的形式）调用of_SendMessage函数。Of_SendMessage调用n_cst_menu的of_SendMessage函数，n_cst_menu的of_SendMessage将会调用窗体的pfc_MessageRouter事件，pfc_MessageRouter事件将会调用你所要触发的用户事件（即在Clicked中传递字符串参数）。

在MDI与SDI应用程序中，函数Of_SendMessage调用pfc_MessageRouter时将有所不同。如图：

pfc_MessageRouter的工作流程

如图：

菜单与窗口之间的消息传递

消息路由是菜单与窗口之间的通讯桥梁。你不可以通过按钮来触发pfc_MessageRouter事件。因为，消息路由会调用GetFocus函数判断当前控件。这样当你按下按钮时，按钮便成了当前控件。

PFC中的事务对象

PowerBuilder的强大功能之一就是可以快速便利的访问多种数据库。PowerBuilder使用事务对象（Transaction Object）作为PowerBuilder与Database之间的桥梁。SQLCA就是一个默认的事务对象。

用户自定义对象n_tr

PFC中有一个n_tr对象。它是标准事务对象的子类。其中设有实例变量、用户自定义事件、函数，主要用于扩充与数据库的通讯能力。

N_tr提供了一套标准函数用于连接、切断、提交、回滚等数据库操作。使用这些函数代替原有的数据库语句。例如使用of_Connect代替CONNECT语句。

两处地方使用n_tr

  • 替代sqlca：在应用程序的属性对话框中将SQLCA的默认数据类型设为n_tr 。

  • 附加的事务对象：当你需要访问多个数据库时，你可以再定义一个事务对象。

如果你使用了多个事务对象，你可以使用事务对象的registration service ，做到一次提交全部已打开的事务对象，一次回滚所有已打开的事务对象。

将SQLCA设置为n_tr类型

  1. 打开应用程序画笔

  4. 显示属性窗口，选中Variable页

  5. 在SQLCA框中输入n_tr

  6. 点击OK

使用n_tr

  1. 如果你不使用SQLCA ，而是使用其他的事务对象。

    2. 下面的例子假设itr_security是n_tr的实例变量

    itr_security = CREATE n_tr

  2. 初始化实例变量ib_autorollback 。这个变量的作用是当事务对象正处于连接状态时应用程序被关闭了或者是该事务对象被删除了的时候，该事务对象应该如何操作

    3. itr_security.of_SetAutoRollback（FALSE）

    关于初始化ib_autorollback的扩展

    你可以在n_tr的构造事件中初始化ib_autorollback 。

  3. 使用n_tr的of_Init函数初始化事务对象的属性

    4. Integer li_return

    String ls_inifile

    ls_inifile = gnv_app.of_GetAppIniFile()

    IF SQLCA.of_Init(ls_inifile,"Database") = -1 THEN

    MessageBox("Database","Error initializing from " + ls_inifile)

    HALT CLOSE

    End if

  4. 调用of_Connect进行数据库连接

    5. IF SQLCA.of_Connect() = -1 THEN

    MessageBox("Database","Unable to connect using " + ls_inifile)

    HALT CLOSE

    ELSE

    gnv_app.of_GetFrame().SetMicroHelp("Connection complete")

    End if

  5. 调用n_tr的成员函数

调用父类的函数、事件

在扩充父类的函数和事件时，你有可能需要先调用父类的函数或事件，然后再依据返回值进行下面的处理。这对那些具有返回值前缀是PFC的事件特别有意义。你在执行子类的代码前必须先确认父类的代码是否执行成功。

覆盖父类的函数

为了扩展父类的代码，获取父类的返回值。你必须覆盖父类的代码，然后显示的调用父类的函数或事件。

采用如下的语法格式调用父类的事件，同时传递参数、获取返回值：

Result = Super :: Event eventname（arguments叄©

采用如下的语法格式调用父类的函数，同时传递参数、获取返回值：

result = Super :: Function functionname（arguments叄©

下面的例子则覆盖了u_dw的pfc_Update事件。当父类的事件处理成功时，子类将信息纪录到日志中。

Integer li_return

// Call ancestor event, passing

// descendant's arguments.

li_return = Super::Event pfc_Update(ab_accepttext, ab_resetflag)

IF li_return = 1 THEN

// ue_WriteLog is a user-defined event.

li_return = this.Event ue_WriteLog

END IF

Return li_return

在应用程序中增加联机帮助

联机帮助是应用程序中非常重要的一部分。PFC提供了许多函数、事件使得你可以方便的将联机帮助添加到你的应用程序中。

相关信息：有关PFC的帮助对话框请参考“Deploying PFC dialog box HELP” 。

  1. 使用n_cst_appmanager的of_SetHelpFile函数设置帮助文件。通常在构造事件中：

this.of_SetHelpFile（“c:\eis\eisapp.hlp”）

  2. pfc_PreOpen是为窗口设置帮助主题的最好的地方

    3. Long ll_helpid

    Ll_helpid = 1020 //1020是一个帮助主题的ID

    Ia_helptypeid = ll_helpid

    采用这种方式你可以为用户选中的窗口提供详细的帮助。你可以将ia_helptypeid设置成长整形（此时PFC把它解释成帮助主题的ID），或者是字符串（此时PFC将它解释成关键字）。

  3. （可选）如果你没有使用PFC的m_master的子类。那么，在你的HELP菜单项中调用窗体的pfc_Help事件。因为，pfc_Help定义在窗口w_master中，所以所有的PFC窗口都具有事件。

  4. 对于对话框，则在其中的HELP按钮的Clicked事件中编写：

Parent.Event pfc_Help（）

PFC自动处理窗口级别的帮助

当你从m_master的子类的菜单中选择Help->Help时，消息路由机制会自动的调用当前活动的窗口的pfc_help事件。

PFC的升级

PFC在发布PowerBuilder的升级版本时同时也包括了PFC的升级文件。如何升级PFC，请按如下规则：

  • PFC的各层（PFC层、PFE层、中间层等）没有任何被修改时：你可以直接安装新的PBLs覆盖原有的PBLs 。

注意：每次升级PFC时都保留一份原有的文件备份

  • 如果你修改了PFC中的某一层：你必须保证你所作的修改不会被覆盖！请按如下的步骤进行：

将PFC升级到最新版本

  1. 将所有扩展层的PBL文件移到一个不会被安装过程覆盖的目录中。

    2. 说明：你不应该对PFC的最基类（以PFC为前缀的对象）作任何修改，这里假设你没有对PFC的最基类作任何修改

  2. 确定你当前的PFC的版本号。你可以在Readme.txt文件中查看，或者在pfc_n_cst_debug的实例变量中查看。版本号的格式：主版本号.次版本号.修正号

  3. 执行安装程序，将PFC安装口的PBL文件放到PFC所在的目录中，覆盖原有的PFC最基类的PBLS ，即以PFC开头的库文件。

  9. 合并已存在的扩展对象与新安装的扩展对象。首先详细阅读Readme.txt中说明的新扩展对象清单。然后按照一下的两种方法合并对象：

  • 将新的对象COPY到你的扩展PBLS中。

  • 将已经存在的对象COPY到新的扩展PBLS中。

  10. 启动PowerBuilder

  11. （可选）必要的时候调整一下应用程序的库列表

  12. 打开库画笔，从新编译一边所有的对象。


第四章 PFC的服务

概要：

这一章主要介绍了什么是PFC的Services ，以及如何使用它们。

  1. 应用程序服务

PFC提供了以下各种应用程序Services ：

DataWindow caching

Debugging

Error

Application preference

Most recently uesed object

Security

Transaction registration

你必须通过n_cst_appmanager（应用程序管理器）来控制这些Services （这些Services实际上是应用程序管理器的是数据成员）。应用程序管理器（application manager）通过调用成员函数来开启与关闭Services 。由于它们在应用程序管理器的范围内有效。而应用管理器是全局变量，因此你可以在你的应用程序的任何地方是使用应用程序Services 。

  1. DataWindow caching service

概要：

Datawindow caching service为Datawindow提供了数据缓冲。它将数据保存在内存中，从而减少了程序访问数据库的频率，加快了程序的执行速度。Datawindow caching service支持如下的数据源：

    • Datawindow对象，它的数据可以来自于数据库表也可以来自存储过程。

    • SQL语句

    • Datawindow控件

    • DataStore对象

    • 数组中的数据

    • 文件

PFC使用Powerbuilder的Datastore来实现Datawindow caching service 。它对应的对象是n_cst_dwcache 。

PFC的代码实际只在父类对象中

这本书讲述的都是扩展类的对象，就像n_cst_dwcache 。而实际上PFC的代码全在父类的对象中（pfc_n_cst_dwcache）。

使用方法

使用DataWindow caching 可以将数据库访问频率降到最低，可以加快程序运行速度。

  • 开启DataWindow caching

    • 调用n_cst_appmanager的of_SetDWCache函数

gnv_app.of_SetDWCache（TRUE）

  • 使用Datawindow caching ：

    1. 调用of_Register函数进行数据缓存，同时依据不同的数据提供相应的参数。

    • 缓存Datawindow对象从数据库中检索出的数据时：你需要传递标识符（identifier）、事务对象、Datawindow对象名、其他参数（如果存在的话）。

    • 缓存SQL语句从数据库中检索出的数据时：你需要传递标识符（indentifier）、事务对象、SQL语句。

    • 将数据缓存到数组中：传递标识符（identifier）、Datawindow对象名、数据。

    • 缓存DataWindow控件中的数据：传递标识符（identifier）、Datawindow控件。

    • 缓存DataStore中的数据：传递标识符（identifier）、DataStore对象。

    • 缓存文件中的数据：传递标识符（identifier）、文件名。

    1. 你可以使用函数of_IsRegistered（参数是对象本身），确定DataWindow对象是否已经在caching service中注册了。

    2. 调用函数of_GetRegistered函数访问已经缓存的数据。

      3. Gnv_app.inv_dwcache.of_GetRegistered（”d_emplist”，ids_datastore）

      Ids_datastore.ShareData（dw_emplist）

    3. 调用函数of_Refresh检索已经缓存数据的DataWindow 。

    4. 调用函数of_UnRegister函数停止数据缓存服务。

    5. （可选）调用n_cst_appmanager的of_SetDWCache函数关闭DataWindow caching service 。

gnv_app.of_SetDWCache（FALSE）

通常你没必要显示的关闭DataWindow caching service 。PFC在删除对象n_cst_dwcache时会自动的关闭它。

  1. Debugging service

概要：

Debugging service 在应用程序遇到错误时会自动显示错误信息。PFC的消息路由当发现需要调用的事件不存在时便会使用Debugging service显示出错信息。

重要说明：PFC debugging service 只是一个开发工具。在用户的应用程序中不要开启它。

使用方法

使用debugging service 可以帮助你在PFC的开发过程中解决问题。

  1. 调用n_cst_appmanager的of_SetDebug函数开启Debugging service 。

    2. gnv_app.of_SetDebug（TRUE）

  2. PFC的对象首先检测应用程序的debugging状态，然后在适当的情况下显示错误信息。

  3. （可选）调用n_cst_appmanager的 of_SetDebug函数关闭Debugging service 。

gnv_app.of_SetDebug（FALSE）

多数情况下，你不需要显示的关闭Debugging service 。

关于PFC提供的两个工具（SQL Spy 和DataWindow Property）的使用请参考第七章“PFC Utilities”。

  1. Application preference service

概要：

你可以利用Application preference service保存、恢复应用程序、用户的信息到INI文件或WINDOWS的注册表中。保存和恢复应用程序设置有如下两个好处：

    • 延续性：保存应用程序的设置可以使得用户在下次使用软件时可以看到他上次关闭软件的样子。也就是说用户不必每次使用软件时都重新设置他的软件环境。

    • 容易维护：你可以无须更改n_cst_appmanager的代码的情况下更新应用程序的设置。

PFC通过用户自定义对象n_cst_apppreference提供Application preference service 。

这个Service保存应用程序的如下信息：

用户键（User key）

MicroHelp

Help File

Version

Logo bitmap

Copyright notice

DDETimeOut property

DisplayName property

DWMessage Title property

MicrohelpDefault property

RightToLeft property

ToolbarFrameTitle property

ToolbarPopMenuText property

ToolbarSheetTitle property

ToolbarUserControl property

Application preference service 同时保存如下的用户信息

ToolbarText property

ToolbarTips property

User ID

保存、恢复设置

Application perference service 在应用程序开启的时候会自动恢复应用程序在关闭时保存的设置。这些信息可以保存到注册表中（只限于Windows95和Windows NT）或者INI文件中。你可以按照如下说明：

    • 保存到注册表中：调用函数of_SetUserKey ，指定你需要保存的键。

    • 保存到INI文件中：调用函数of_SetUserINIFile ，指定用于保存信息的INI文件名。

使用步骤：

  1. 调用n_cst_appmanager的of_SetAppPref函数开启Application preference service 。

    2. gnv_app.of_SetAppPref（TURE）

  2. 依据不同的执行平台采用不同的方式保存应用程序信息。下面的例子就是在应用程序的构造事件中保存应用程序的信息。同时假设你已经在n_cst_appmanager中建立好了应用程序信息键、用户信息键、应用程序INI文件、用户INI文件。

    3. IF this.of_IsRegistryAvailable() THEN

    this.inv_apppref.of_SetAppKey(this.of_GetAppKey()) this.inv_apppref.of_SetUserKey(this.of_GetUserKey())

    ELSE

    this.inv_apppref.of_SetAppINIFile(this.of_GetAppINIFile()) this.inv_apppref.of_SetUserINIFile(this.of_GetUserINIFile())

    END IF

  3. 调用函数of_SetRestoreApp和of_SetRestoreUser函数设置需要保存信息的类型：

this.inv_apppref.of_SetRestoreApp(TRUE)

this.inv_apppref.of_SetRestoreUser(TURE)

  1. Most recentily used object service

概要

你可以使用Most recentily used object service（最近使用对象Service）将最经使用的对象、表单列在文件菜单下。默认情况下只允许显示5个最经使用对象。但是，你可以改变这个数量。

PFC 通过n_cst_mru用户自定义对象提供MRU Service（Most recentily uesd object service）。

MRU Service在应用程序启动时会自动的将应用程序关闭时保存的最经使用过的对象信息加载到应用程序中。这些信息可以保存到注册表或者INI文件中。你可以通过如下的方式：

    • 保存到注册表中：调用函数of_SetUserKey函数确定要保存到注册表中的MRU信息。

    • 保存到INI文件中：调用函数of_SetUserINIFile函数指定用于保存MRU信息的INI文件。

你必须还要额外编写代码：

为了使用MRU Service ，你必须在你想启用MRU Service的窗口的两个事件中编写代码。

    • pfc_MRUProcess ：在窗口开启时加载MRU信息。

    • pfc_PreMRUSave ：在窗口关闭时保存MRU信息。

与PFC菜单的结合

PFC的m_master菜单的FILE菜单包括了五个MRU菜单项，你还可以自己添加。

如果你的应用程序没有使用PFC的菜单，那么请以m_master为模板建立你自己的MRU菜单项。

使用MRU Service步骤

  1. 调用n_cst_appmanager中的of_SetMRU函数开启MRU Service 。

    2. gnv_app.of_SetMRU（TRUE）

  2. 调用n_cst_appmanager的函数of_SetUserKey（尽适用于WIN95与WINNT）或of_SetUserINIFile函数（使用于所有的平台）确定需要保留的信息。下面的例子假设你已经为n_cst_appmanager建立好了的用户键（保存到注册表）或者INI文件（保存到INI文件）。下面的代码位于应用程序管理器（n_cst_appmanager）的构造事件。

IF this.of_IsRegistryAvailable() THEN

this.inv_mru.of_SetUserKey(this.of_GetUserKey())

ELSE

this.inv_mru.of_SetUserINIFile(this.of_GetUserINIFile())

END IF

3. Register IDs with the MRU service by calling the n_cst_mru of_Register function. An ID is the identifier that the window will use to retrieve information out of the MRU service. This is an example of code you can add to the pfc_PreOpen event of the MDI frame window:

IF IsValid(gnv_app.inv_mru) THEN gnv_app.inv_mru.of_Register("myapp") END IF

4. Extend the pfc_MRUProcess event in each window that uses exclusive processing, adding code to open the sheet passing the necessary arguments (be sure to add similar code to the frame window if you want to specify exclusive items on the frame menu):

Window lw_frame, lw_window n_cst_menu lnv_menu n_cst_mruattrib lnv_mruattrib // Check parameters. IF IsNull(ai_row) THEN Return -1 END IF IF NOT IsValid(gnv_app.inv_mru) THEN Return -1 END IF // Retrieve row from DataStore. gnv_app.inv_mru.of_GetItem & (ai_row, lnv_mruattrib) // Get the MDI frame, if necessary. lnv_menu.of_GetMDIFrame(this.menuid, lw_frame) OpenSheet(lw_window, & lnv_mruattrib.is_classname, lw_frame) Return 1

Performing other actions in the pfc_MRUProcess eventTo see other types of processing you can perform in the pfc_MRUProcess event, see the comments in the pfc_w_master pfc_MRUProcess event.5Extend the pfc_PreMRUSave event in each window that uses the MRU service. In this event, populate the n_cst_mruattrib object with the id, classname, key, item, and MicroHelp to be saved:

anv_mruattrib.is_id = "myapp" anv_mruattrib.is_classname = this.ClassName() anv_mruattrib.is_menuitemname = this.Title anv_mruattrib.is_menuitemkey = this.ClassName() anv_mruattrib.is_menuitemmhelp = & "Opens " + this.Title Return 1 6Extend the pfc_MRURestore event in each window that uses the MRU service. In this event, set the ID of the information you want to display on the menu:

If IsValid(gnv_app.inv_mru) Then Return gnv_app.inv_mru.of_Restore("myapp", This) End If

  1. Error message service

概要

Error Message service提供了许多用于显示、纪录应用程序的错误信息。你既可以显示PowerBuilder提供的标准的Message对话框，也可以显示PFC的W_Message对话框。两种显示效果都具有如下的功能：

  • 消息日志：将消息纪录到文件中，支持多种平台。PFC会自动的将严重级别大于某个值的消息纪录到文件中。

  • 支持MAPI：通过Email发出错误警告。PFC会自动将严重级别大于某个值的消息作为邮件发出。

  • 消息数据库：通过已经定义好的形式（可以是数据库或文件）来存取消息。定义好了消息格式，使得消息有一种标准的形式、消息的重复减到最少、容易查询。

  • 参数替代：消息可以具有参数，这样它会依据程序运行而变化。

  • 不显示，直接纪录：消息可以不显示直接纪录到日志中。

  • 注释与打印：用户可以打印消息，甚至可以增加注释。对消息日志用于邮件时非常有用的。

  • 自动关闭：w_message过了数秒后会自动关闭。

W_message 位图

如果你使用w_message ，位图在运行时必须有效。

用法

Error service可以处理应用程序所有的错误信息。如果你打算将错误信息保存到数据库中，你可以使用PFC.DB中关于消息的几个表，或使用消息管道将它传到你的数据库中。

使用Messages表

大多数情况下，你应该将Messages表复制到你的数据库中。这个表已经包含了PFC的错误信息格式。

使用步骤：

  1. 调用n_cst_appmanager的of_SetError函数开启error message service（创建n_cst_error实例），下面的代码位于n_cst_appmanager的pfc_Open事件：

    2. this.of_SetError（TRUE）

  2. 定义错误消息的源：

    • 如果消息源是文件，调用如下函数：

this.inv_error.of_SetPredefinedSource(“c:\eisapp\eiserr.txt”)

    • 如果消息源是数据库，调用如下函数：

this.inv_error.of_SetPredefinedSource （itr_error）

消息源：当你使用文件作为消息源时，文件中必须包括PFC.DB中Messages表中的所有数据。同时列必须由TAB键隔开。

PFC uses predefined messages in certain situations. If you enable the error message service and receive message display errors, make sure the error message source has been established correctly. Additional user-defined messages must conform to the format of the messages table (also used by the d_definedmessages DataWindow object).

    • （可选）设置日志文件名（调用函数of_SetLogFile参数为空字符串可以不进行日志纪录）：

this.inv_error.of_SetLogFile（”C:\pb6\errlog.txt”）

    • （可选）设置用户ID（用于日志文件）：

this.inv_error.of_SetUser（this.of_GetUserID（））

    • （可选）设置什么类型的消息需要自动纪录：

this.inv_error.of_SetNotifySeverity（5）

this.inv_error.of_SetLogSeverity（4）

    • （可选）如果你的应用程序使用了错误自动通告功能。你需要设置当前用户的Email、密码。还可以设置其他的Email用户与密码。下面的例子展示了如何设置Email ID与Password 。

this.inv_error.of_SetNotifyConnection(ims_mailsess) this.inv_error.of_SetNotifyWho(is_autonotify)

说明：以上的代码都可以在n_cst_appmanager的pfc_Open事件中。

    • 在应用程序的错误检测中，使用函数of_Message显示对话框。同时你还可以将它纪录到日志中。函数of_Message可以使用数据库中的消息，也可以动态的指定消息。下面的例子就是使用数据库中的消息：

gnv_app.inv_error.of_Message（”EIS0210”）

使用参数表（只限于已定义的消息）

    1. 在消息表中定义如下的数据。%运行时将被替换：

      2. EIS1030 Unable to find the file % in %

    2. 定义一个参数数组：

      3. String ls_parms[]

      ls_parms[1] = “Logfile.txt”

      ls_parm[2] = “c:\windows\system”

    3. 调用of_Message ，传递参数：

gnv_app.inv_error.of_Message（”EIS1030”，ls_parms）

PFC在显示消息时使用数组中的第一个元素替换第一个% ，第二元素替换第二个% 。

  1. Security service

概要

PFC的安全机制可以处理许多你的应用程序安全性问题。它包括应用程序管理员组件、安全对象（security object）n_cst_security 。

用法：在使用Security service时，你必须要定义用户组与用户，然后分别与窗口、菜单、用户对象、控件相关联，然后再编写代码。

使用步骤：

    1. 定义用户、用户组。参考第七章”PFC Utilities”

      2. 为你的窗口控件、菜单、用户对象、其他控件定义安全属性。参考第七章”PFC Utitities”

    2. 调用n_cst_appmanager的of_SetSecurity函数创建安全对象

      3. this.of_SetSecurity（TRUE）

    3. 为安全对象建立一个事务对象。

      4. Itr_sec = Create n_tr

      Connect using itr_sec；

    4. 调用函数of_InitSecurity初始化安全对象。

      5. This.inv_security.of_InitSecurity（itr_sec.”EISAPP”，gnv_app.of_GetUserID（），”DEFAULT”）

    5. 以上的代码全部在n_cst_appmanager的pfc_Open事件中编写。

    6. 应用程序关闭时，断开事务对象的连接、删除事务对象。以下的例子在n_cst_appmanager的pfc_Close事件中。

      7. Disconnect using itr_sec;

      Destroy itr_sec

    7. 在你需要使用安全对象的窗口的Open事件或pfc_PreOpen事件中调用函数of_SetSecurity（）

IF NOT gnv_app.inv_security.of_SetSecurity(this) THEN

MessageBox("Security","Unable to set security")

Close(this)

End if

说明：你可以在其他对象（Datawindow、可视用户对象、菜单，所有你想实现安全机制的对象）。

  1. Transaction registration service

概要

Transaction registration service可以追踪你的应用程序中的事务对象的使用过程。这个服务只对基于n_tr的对象有效。PFC使用n_cst_trregistration对象实现Transaction registration service 。

用法

当应用程序中使用多个事务对象时，你应该使用Transaction registration service跟踪所有的事务对象。当你的应用程序关闭时，该对象将会自动删除所有已注册的事务对象。使用n_tr的函数of_SetAutoRollback设置ib_autorollback的值。如果ib_SetAutoRollback的值为False ，则事务对象关闭时将会自动提交。如果ib_SetAutoRollback的值为True ，则事务对象关闭时会自动回滚。

启动 Transaction registration service

    • 调用n_cst_appmanager的of_SetTrRegistration函数

gnv_app.of_SetTrRegistration（True）

当应用程序关闭时，应用程序会自动删除 Trasaction registration service 。

注册事务对象：

    • 调用n_cst_trregistration的of_Register函数

gnv_app.inv_trregistration.of_Register（SQLCA）

控制当事务对象正处于连接时被删除时的行为

    • 调用n_tr的of_SetAutoRollback函数

SQLCA.of_SetAutoRollback（True）

如果你设置为True ，同时该对象正处于连接状态，当它被删除时Service会回滚该事务。如果你设置为False ，Service回提交该事务。尽管如此，你应该显示的提交或回滚、断开连接。

  1. Datawindow服务

概要

大部分的PowerBuilder的应用程序都大量的使用了Datawindow控件。PFC因此提供了功能强大的Datawindow Services 。大部分的Service使用时只需一点代码或者根本不需要编码。PFC的Datawindow Servies实际上都是由一个公共的父类对象（不可视用户自定义对象）继承而来。这个父类对象包括了许多Service的函数、事件、实例变量。同时么每个Datawindow Service还有自己的函数、事件、实例变量。

访问Datawindow Services

为了使用DataWindow Services，你应该建立基于u_dw的Datawindow对象。U_dw对象包括：

  • 用于开启、关闭Datawindow Services的函数。

  • 用于调用各种Services的函数、事件、实例变量的引用变量。

  • 调用Datawindow Service的函数、事件的Precoded事件、用户事件

  • 可供你编写代码的空事件

在你的应用程序中所有的DataWindow控件都必须是u_dw的子类。

开启DataWindow Services

只开启Datawindow控件需要的Servie ，这样才能将应用程序的负荷将到最小。以下表格列出了所有的Datawindow Service ，以及对应的对象。

DataWindow Service | 对应的对象
Datawindow service的基类 | n_cst_dwsrv
Dropdown search service | n_cst_dwsrv_dropdownsearch
Filters service | n_cst_dwsrv_filter
Find andreplace service | n_cst_dwsrv_find
Linkage service | n_cst_dwsrv_linkage
Multitable update service | n_cst_dwsrv_multitable
Print preview service | n_cst_dwsrv_printpreview
DataWindow property service | n_cst_dwsrv_property
Querymode service | n_cst_dwsrv_querymode
Reporting service | n_cst_dwsrv_report
Required column service | n_cst_dwsrv_reqcolumn
DataWindow resize service | n_cst_dwsrv_resize
Row management service | n_cst_dwsrv_rowmanager
Row selection service | n_cst_dwsrv_rowselection
Sort service | n_cst_dwsrv_sort

  1. DataWindow Services 的父类

概要

DataWindow Services的父类包括了所有DataWindow Services需要的Instance变量、事件、函数。PFC使用n_cst_dwsrv实现DataWindow Services的父类。

DataStore Service：DataStore Service的对象是n_cst_dssrv

用法

你可以使用这些Service实现如下功能

  • 获取、设置DataWindow信息

  • 修改、获取DataWindow脚本函数

  • 默认DataWindow service

父类函数在子类中有效

因为n_cst_dwsrv是所有DataWindow services的父类，因此所有在n_cst_dwsrv的函数在它的子类中都有效。

开启Basic DataWindow service

  • 调用u_dw的of_SetBase函数

dw_emplist.of_SetBase（TRUE）

当Datawindow被删除时u_dw会自动删除该Service 。

访问DataWindow

  • 调用n_cst_dwsrv中的函数

函数 | 调用
of_Describe | 访问DataWindow的属性、列。
Of_GetHeaderName | 确定某一列的列名
Of_GetHeight | 确定某一列的高度
Of_GetObject | 依据对象名访问DataWindow中的对象
Of_GetWidth | 确定某一列的宽度
Of_GetItem Of_GetItemAny | 获取DataWindow中某一列的数据（任何类型数据）。

给DataWindow设置数据

  • 调用n_cst_dwsrv中如下函数：

函数 | 调用
of_Modify | 修改DataWindow属性、列。
Of_SetItem | 设置、修改DataWindow的数据（任何数据类型）。

刷新DataWindow中所有的下拉DataWindow：

  • 调用函数of_PopulateDDDWs

Integer li_return

li_return = dw_emplist.inv_base.of_PopulateDDDWs()

gnv_app.of_GetFrame().SetMicroHelp(String(li_return) + " DDDW columns

refreshed")

访问DataWindow service的默认值：

  • 调用如下的函数

函数

调用说明

of_GetColumnDisplayName

确定DataWindow中某一列的显示名。

Of_GetColumnNameStyle

确定当DataWindow需要显示列时那些列需要显示

Of_GetDefaultHeaderSuffix

确定DataWindow列名的默认后缀。

Of_GetDisplayItem

Of_GetDisplayUnits

确定关闭时显示的消息

Of_SetColumnDisplayNameStyle

确定当DataWindow Service需要显示列时显示的信息

  • DataWindow列名

  • Database列名

  • DataWindow列标题名

Of_SetDefaultHeaderSuffix

设置默认的DataWindow列标题的后缀

Of_SetDisplayItem

Of_SetDisplayUnits

设置关闭时显示的信息

  1. Dropdown DataWindow search service

概要

PFC下拉DataWindow seach service提供了一个当用户敲入一个字母后自动滚到该字母开头的数据项上。它对应的对象是n_cst_dwsrv_dropdownsearch 。

使用方法

开启Dropdown DataWindow search service

  1. 调用u_dw的of_SetDropDownSearch函数

this.of_SetDropDownSearch（TRUE）

U_dw被删除时会自动删除这些Service 。

  2. 在DataWindow控件的EditChanged事件中调用n_cst_dropdownsearch的pfc_EditChanged事件：

this.inv_dropdownsearch.event pfc_EditChanged(row,dwo,data)

  3. 在DataWindow控件的ItemFocusChanged事件中调用n_cst_dwsrv_dropdownsearch的pfc_ItemFocusChanged事件

this.inv_dropdownsearch.Event pfc_ItemFocusChanged(row,dwo)

  4. 调用函数of_AddColumn为DataWindow的列启用DropDown DataWindow search service 。

this.inv_dropdownsearch.of_AddColumn(“dept_id”)

  1. Filter service

概要

PFC的Filter service提供了一个非常简单易用的过滤功能。它对应的对象是n_cst_dwsrv_filter 。

使用说明

Filter service自动的显示过滤对话框。你所要作的只是开启Service、指定过滤类型。你可以选择三种过滤对话框。

  • PowerBuilder标准对话框

  • 两种PFC提供的对话框

  • w_filtersimple 下拉Listbox界面。

  • w_filterextended Tabbed界面。

开启Filter service

  • 调用u_dw的of_SetFilter函数，设置事务对象，指定过滤对话框使用DataWindow的列标题：

dw_emp.of_SetFilter(TRUE)

dw_emp.of_SetTransObject(SQLCA)

dw_emp.inv_filter.of_SetColumnDisplayNameStyle(dw_emp.inv_filter.HEADER)

u_dw在被删除时会自动删除该Service 。

设置过滤风格：

  • 调用函数of_SetStyle，指定对话框风格：

dw_emplist.inv_filter.of_SetStyle(dw_emp.inv_filter.SIMPLE)

显示过滤对话框：

  • 调用事件pfc_FilterDlg事件：

dw_emplist.inv_filter.event pfc_FilterDlg()

你无须显示的调用该事件。大多数情况下，用户通过选择View>Filter菜单显示过滤对话框。

  1. Find and replace service

概要

PFC的Find and replace service使得你可以在你的应用程序中加入查找与替换功能。它对应的对象是n_cst_dwsrv_find 。

使用说明

你可以使用该服务为DataWindow提供查找与替换的功能。可以显示w_find窗口或w_replace窗口。如果用户在m_master菜单的子类中选择了Edit>Find或Edit>Replace时该服务将自动显示w_find或m_master窗口。

开启Find service

  • 调用u_dw的of_SetFind函数：

dw_emplist.of_SetFind(TRUE)

U_dw被删除时将自动删除该服务

显示w_find对话框：

  • 调用u_dw的pfc_FindDlg事件

dw_Emplist.Event pfc_FindDlg()

你无须显示的调用该事件。用户选择Edit>Find时会自动显示w_find对话框。

显示w_replace对话框：

  • 调用u_dw的pfc_ReplaceDlg事件：

dw_emplist.Event pfc_ReplaceDlg()

你无须显示的调用该事件。用户选择Edit>replace时会自动显示w_replace对话框。

  1. Linkage service

概要

PFC的linkage service帮助你实现主/从窗口合作处理。

Linkage service包括如下功能：

  • Linkage style（连接风格）：控制从窗口的DataWindow检索数据、过滤数据、滚动到特定行。

  • Update style（更新风格）：控制Linkage service更新DataWindows的方式（top-down, bottom-up, top-down then bottom-up, bottom-up then top-down, or a developer-specified custom update）

  • 数据发生变化时的提醒窗口：当主数据发生变化，从数据即将丢失时，该选项可以显示一个提醒窗口。

  • 删除数据时的提醒窗口：当用户删除数据时可以显示提醒窗口

  • Cascading key changes：当用户改变主纪录时，Linkage service会自动修改从纪录

  • 删除风格：当你删除主纪录时，该选项可以设成删除从纪录、不理会从纪录。

  • 更新扩展：允许你将其他的控件也作为默认数据保存过程。

使用说明

你可以使用Linkage service处理各种DataWindow中的合作。尽管如此，大部分时候都是用于处理主/从关系的DataWindow 。

开启Linkage service：

  • 调用u_dw的of_SetLinkage函数：

dw_emplist.of_SetLinkage（TRUE）

u_dw自动删除所有Service 。

使用Linkage service实现主/从处理：

  1. 在主从DataWindow中同时开启Linkage service：

    2. dw_master.of_SetLinkage（TRUE）

    dw_detail.of_SetLinkage（TRUE）

  2. 分别为主从DataWindow设置事务对象：

    3. dw_master.inv_linkage.of_SetTransObject（SQLCA）

    dw_detail.inv_linkage.of_SetTransObject（SQLCA）

  3. 将从DataWindow连接到主DataWindow中：

    4. dw_detail.inv_linkage.of_SetMaster（dw_master）

  4. 调用函数of_Register注册关联列：

    5. dw_dwtail.inv_linkage.of_Register（”emp_id”,”emp_id”）

  5. （可选）(Optional) Specify that the service updates DataWindows from the bottom of the linkage chain on up (the default is to update top down):

    6. dw_detail.inv_linkage.of_SetUpdateStyle(dw_detail.inv_linkage.BOTTOMUP)

  6. 调用函数of_SetStyle建立当主数据改变时从数据的动作。

    7. 下面的例子说明了当主数据改变时从数据检索数据：

    dw_detail.inv_linkage.of_SetStyle（dw_detail.inv_linkage.RETRIEVE）

  7. 调用主DataWindow的of_Retrieve函数：

    8. IF dw_master.of_Retrieve（）= -1 特Then

    MessageBox（”Error”,”Retrieve error”）

    Else

    Dw_Master.SetFocus（）

    End if

    你可以将以上的代码全部写在一个事件中。

  8. 在主DataWindow的pfc_Retrieve事件中添加检索数据的代码：

Return this.Retrieve（）

检索数据：如果Linkage service刷新了从数据。你只需要编写代码检索主DataWindow。如果你打开了filter和scroll选项，你必须在从DataWindow中编写检索数据函数。

数据改变时的提醒窗口（尽限于retrieval风格）

  1. 在从DataWindow中调用of_SetUpdateOnRowChange函数：

dw_detail.inv_linkage.of_SetUpdateOnRowChange(TRUE)

  2. 在从Datawindow中调用of_SetConfirmOnRowChange函数

dw_detail.inv_linkage.of_SetConfirmOnRowChange(TRUE)

数据删除时的提醒窗口

  1. 在从DataWindow中调用of_SetUpdateOnRowChange函数：

dw_detail.inv_linkage.of_SetUpdateOnRowChange（TRUE）

  2. 在从DataWindow中调用of_SetConfirmOnDelete函数

dw_detail.inv_linkage.of_SetConfirmOnDelete（TRUE）

开启casacding key

  • 在所有关联的DataWindow中调用of_SetSyncOnKeyChange函数

dw_master.inv_linkage.of_SetSyncOnKeyChange（TRUE）

dw_detail.inv_linkage.of_SetSyncOnKeyChange（TRUE）

设置删除风格：

  • 在主DataWindow中调用函数of_SetDeleteStyle

dw_master.inv_linkage.of_SetDeleteStyle（dw_cust.inv_linkage.DISCARD_ROWS）

启用更新扩展：

  • 为其他需要添加到默认保存过程中的控件调用函数of_SetOtherSaveObjects

PowerObject lpo_objs[ ]

// This example adds the lv_salesinfo ListView

// to the save process.

lpo_objs[1] = lv_salesinfo

dw_master.inv_linkage.of_SetOtherSaveObjects(lpo_objs)

  1. Multitable update service

PFC的多表更新服务（Multitable update service）使得你的DataWindow可以轻松更新多表。它对应的对象是n_cst_dwsrv_multitable 。

DataStore services

该服务同样适用于DataStore ，对应的对象是n_cst_dssrv_multitable 。

使用说明：

当你需要更新的数据涉及到多个表时就需要使用该服务。当你调用w_master的pfc_Save事件时。PFC会更新所有的表。

开启多表更新服务:

  • 调用函数u_dw的函数of_SetMultiTable：

dw_emplist.of_SetMultiTable（TRUE）

u_dw会自动删除所有的服务

指定需要更新的表：

  • 调用函数of_Register设定需要更新的表：

String ls_projcols[] = {“proj_id”}

String ls_taskcols[] = {“proj_id”,”task_id”}

Dw_project.inv_multitable.of_Register(“project”,ls_projcols)

Dw_project.inv_multitable.of_Register(“task”,ls_taskcols)

（可选）更新包含多表数据的DataWindow

  • 调用w_master的函数pfc_Save事件

Integer li_return

Li_return = w_sheet.Event pfc_Save()

…

  1. Print preview service

概要

PFC的打印预览服务使你的DataWindow可以具备打印预览的功能：

  • 打印预览

  • 第一页、下一页、上一页、最后一页

  • 放大、缩小

菜单m_master的子类会自动访问这些功能。它对应的对象是n_cst_dwsrv_printpreview 。

该服务对DataStore同样有效，它对应的对象是n_cst_dssrv_printpreview 。

使用说明

该服务使得你的应用程序具备了打印预览的功能。用户选择File>Print Preview菜单项便进入预览模式。

开启打印预览模式：

  • 调用u_dw的of_SetPrintPreview函数：

dw_emplist.of_SetPrintPreview（TRUE）

u_dw自动会删除所有的服务。

  1. DataWindow properties service：

概要

DataWindow属性服务允许你显示DataWindow的属性窗口。还可以

  • 开启、关闭其他的DataWiindow服务

  • 察看某个服务的PFC语法

  • 交互式的访问、修改DataWindow的属性，具体如下：

DataWindow buffers

Row and column status

Statistics

Properties of all objects on the DataWindow object

详情察看”DataWindow Properties window”

使用说明：

开启DataWindow属性服务（DataWindoe Properties service）

  1. 调用函数of_SetProperty：

    2. dw_emplist.of_SetProperty（TRUE）

    U_dw会自动的删除所有的Service 。

  2. 当DataWindow出现时，右击，选择DataWindow属性：

  1. Query mode service

概要

PFC的查询模式使得你可以轻松的在你的应用程序中加入查询模式。它也可以帮助你懂得如何使用、理解查询模式。在查询模式中，用户可以点击右键，在弹出式菜单中选择显示的列、操作符、数据。它对应的对象是n_cst_dwsrv_querymode 。

使用说明

你可以使用PFC的Query service实现如下功能：

  • 开始、中止查询模式

  • 选择某列

  • 将查询结果保存到文件中，调用以前的查询结果。

开启查询模式服务

  • 调用u_dw的of_SetQuerymode函数

dw_emplist.of_SetQuerymode（TRUE）

u_dw会自动删除所有的Service 。

进入查询模式：

  • 调用函数of_SetEnabled，参数为TRUE

dw_emplist.inv_querymode.of_SetEnabled（TRUE）

结束查询模式：

  • 调用函数of_SetEnabled，参数为FALSE

dw_emplist.inv_querymode.of_SetEnabled（FALSE）

设定查询列：

  • 调用函数of_SetQueryCols，参数为需要查询的列数组：

String ls_cols[]

Ls_cols[1] = “emp_dept_id”

Ls_cols[2] = “emp_id”

Dw_emplist.inv_querymode.of_SetQueryCols(ls_cols)

当你调用函数of_SetEnabled ，查询模式服务会保护为被选择的列。

将查询保存到文件中：

  1. 调用函数of_SetEnabled（TRUE）开始查询模式。

  2. 许用户设定查询条件。

  3. 调用函数of_Save

该函数会出现一个对话框提示用户输入用于保存数据的文件名。

从文件中加载查询：

  • 调用函数of_Load

该函数出现一个对话框提示用户输入用于加载的文件名。

  1. Reporting service

概要

PFC的报表服务增强了DataWindow的显示、打印功能。该服务中的许多函数既可以修改DataWindow中的对象也可以获得DataWindow中的修改语法，并为你的修改语句所用。If you code more than two consecutive report service functions, consider returning the Modify syntax, concatenating the strings and issuing the Modify function from within your own code 。

DataWindow必须使用PBUs或者pixels

使用该Service，DataWindow必须使用PBUs或者pixels作为度量单位。它不允许使用英尺、公分（It does not work with DataWindows that use thousandths of an inch or thousandths of a centimeter as the DataWindow Unit）。它对应的对象是n_cst_dwsrv_report 。

该服务同样适用于数据存储（DataStore），对应的对象是n_cst_dssrv_report 。

使用说明

你可以使用该服务实现如下功能：

  • 给DataWindow增加一项

  • 建立复合报表。操纵起来就像使用一个报表一样。

  • 格式化与打印

  • 设置背景、颜色、边框

  • 放大、缩小

On Macintosh：函数of_AddComputer、of_AddText、of_GetTextSizePos函数不可用。

开启报表服务：

  • 调用函数of_SetReport

dw_emplist.of_SetReport（TRUE）

U_dw会自动删除所有的service 。

给DataWindow增加一项：

  • 调用n_cst_dwsrv_report中的如下函数

函数 用途

of_AddCompute 增加一个计算列

of_AddLine 增加一行

of_AddPicture 增加一幅图片

of_AddText 增加字符

建立符合报表：

  1. 调用函数of_CreateComposite，传递需要复合的DataWindow信息：

    2. String ls_dws[ ], ls_trailfooter[ ]

    String ls_slide[ ]

    String ls_return

    Integer li_return

    Boolean lb_vertical

    Border lbo_border[ ]

    lb_vertical = TRUE

    ls_dws[1] = "d_employee"

    ls_dws[2] = "d_benefits"

    ls_trailfooter[1] = "No"

    ls_trailfooter[2] = "Yes"

    ls_slide[1] = "AllAbove"

    ls_slide[2] = "AllAbove"

    lbo_border[1] = Lowered!

    lbo_border[2] = Lowered!

    li_Return = dw_composite.inv_report.of_CreateComposite(ls_dws, lb_vertical, ls_trailfooter, ls_slide, lbo_border)

    IF li_Return = 1 THEN

    dw_composite.SetTransObject(SQLCA)

    dw_composite.Event pfc_Retrieve( )

    END IF

  2. 打印与显示复合报表

dw_composite.inv_report.of_PrintReport（TRUE，FALSE）

打印输出Datawindow：

  • 调用函数of_PrintReport。

设置默认值、颜色、边框：

调用n_cst_dwsrv_report中的如下函数

函数 用途

of_SetDefaultBackColor 修改DataWindow的默认值

of_SetDefaultBorder

of_SetDefaultCharset

of_SetDefaultColor

of_SetDefaultFontFace

of_SetDefaultFontSize

of_SetBorder 修改一个或多个DataWindow中的对象的边框

of_SetColor 修改一个或多个DataWindow中的对象的颜色、背景色

控制DataWindow的大小：

  • 调用函数of_SetRelativeZoom

缩放与当前的显示有关：函数Of_SetRelativeZoom的参数是当前大小的百分数。例如DataWindow当前显示的大小是正常的80%，此时你调用函数of_SetRelativeZoom（５０），当前大小即变为40% 。

  1. Required column service

概要

PFC的非空列服务（Required column service）可以处理那些必须要输入数据的列。它使得你非常容易的处理那些输入不完整的数据。该服务只适用于那些具有nilisnull属性的列。例如，EditMasks不具备该属性，因此非空列服务不适用于Edit Mask 。

它对应的对象是n_cst_dwsrv_reqcolumn 。

使用说明

DataWindow非空列的处理会与GUI界面的应用程序产生冲突。非空列服务可以将对非空列的处理留到用户输入数据完毕后处理。该服务允许你设置哪些列是非空列。

非空列的检测:当你调用Window的pfc_Save事件时它会自动的进行非空列的检测。

开启非空列服务

  • 调用函数of_SetReqColumn

dw_emplist.of_SetReqColumn（TRUE）

U_dw会自动删除所有的服务

放弃某些列的非空处理：

  • 调用函数of_RegisterSkipColumn指定哪列需要保留PowerBuilder标准的非空列处理：

dw_Emplist.inv_reqcolumn.of_RegisterSkipColumn（”dept_id”）

  1. Row management service

概要

PFC的Row management service允许你插入、删除数据。同时还提供了恢复被删除的数据功能。它对应的对象是n_cst_dwsrv_rowmanager 。

使用说明：

该服务有如下作用：

  • 在DataWindow的最后加上一行空记录

  • 在两行数据之间插入一行记录

  • 删除一条或多条记录

  • 显示一个对话框用于允许你恢复已删除的记录。

开启行管理服务（Row Management service）

  • 调用函数of_SetRowManager：

dw_Emplist.of_SetRowManager（TRUE）

在DataWindow的末尾增加一条记录：

  • 调用事件pfc_AddRow：

Long ll_return

ll_return = dw_emplist.inv_rowmanager.Event pfc_AddRow()

IF ll_return = -1 THEN

MessageBox("Error", "Error adding empty row")

END IF

当用户从弹出式菜单m_dw中选择Add时，PFC会自动的调用该事件。

在两记录之间插入数据：

  • 调用事件pfc_InsertRow

下面的例子在当前行中插入数据：

Long ll_return

ll_return = dw_emplist.inv_rowmanager.Event pfc_InsertRow()

IF ll_return = -1 THEN

MessageBox("Error", "Insert error")

END IF

当用户在弹出式菜单m_dw中选择Insert时，PFC会自动的调用该事件。

删除数据：

  • 调用函数pfc_DeleteRow事件

下面的例子删除当前行或选择的行：

Long ll_return

ll_return = dw_emplist.inv_rowmanager.pfc_DeleteRow()

IF ll_return = -1 THEN

MessageBox("Error", "Deletion error")

END IF

当用户选择弹出式菜单m_dw的Delete时，PFC会自动调用该事件。为了实现多选供功能使用行选择服务（row selection service。

恢复已删除的数据：

  • 调用事件pfc_RestoreRow

该事件调用　of_UnDelete，同时出现一个对话框给用户用于用户选择需要恢复的记录。

  1. Row selection service

概要

PFC的行选择服务（Row selection serviec）允许你在DataWindow中实现单个、多个、扩展的选择能力。它对应的对象是n_cst_dwsrv_rowselection 。

使用说明：

行选择服务自动处理的所有的行选择处理。所有你需要作的只是开启该服务、指定你所想要的风格

  • 单行选择：当你的DataWindow只允许实现单行选择是请采用此风格。

  • 多行选择：允许你的用户一次选择多条记录。这些记录可以是连贯的也可以是非连贯的。当使用多行选择风格时，程序运行时，用户单击后会触发row’s 选择状态。该特性与listbox的多项选择相似。

  • 扩展的选择：你可以使用键盘与鼠标共同实现选择操作，SHIFT+Click，CTRL+Click 。

同样该风格也相似与listbox的扩展选择。

开启行选择服务:

  • 调用u_dw的函数of_SetRowSelect（TRUE）

U_dw会自动删除所有的服务。

设定行选择风格：

  • 调用函数of_SetStyle ，指定你想设定的行选择风格：

dw_emplist.inv_rowselect.of_SetStyle（dw_emplist.inv_rowselect.EXTENDED）

  1. DataWindow resize service

概要

PFC的resize服务使得用户在改变窗口大小时自动的改变DataWindow中的列的大小。它对应的对象是n_cst_dwsrv_resize 。

使用说明：

你可以使用resize服务使得你的DataWindow中的列自动的随着Window的大小变化而变化。

特别说明：你不可以在Composite或者RichTextEdit风格的Datawindow中使用Resize服务。

开启DataWindow的Resize服务：

  1. 调用u_dw的of_SetResize函数、设置事务对象、依据列标题指定排序对话框：

    2. dw_emp.of_SetResize（TRUE）

    u_dw会自动删除所有的服务。

  2. （可选）调用函数of_SetOrigSize设置DataWindow控件的原始大小。当你在MDI窗口下打开一表单（Sheet）时可以使用该函数替代枚举变量Original!：

    3. this.inv_resize.of_SetOrigSize(this.width,this.height)

  3. （可选）调用函数of_SetMinSize设定DataWindow的最小大小。

    4. This.inv_resize.of_SetMinSize（this.width – 50 , this.height - 100）

  4. 调用函数of_Register设定哪些列需要Resize、如何Resize ：

    5. this.inv_resize.of_Register("emp_fname",0,0,50,50)

    this.inv_resize.of_Register("emp_lname",100, 0, 50, 50)

  5. 开启Window resize service，注册DataWindow控件

    6. this.of_SetResize（TRUE）

    this.inv_resize.of_Register（dw_1,0,0,100,100）

  6. （可选）调用函数of_UnRegister函数将某一列从列表中删除，即取消对某一列的resize service 。

  1. Sort service

概要

PFC的Sort服务使得你轻易的在你的DataWindow中增加了排序的功能。它对应的对象是n_cst_dwsrv_sort 。

使用说明

该服务会自动的显示排序对话框。所有你需要作的只是开启服务，指定你所想的排序风格。你有四种风格选择。

  • PowerBuilder标准排序风格

  • 拖拉风格（w_sortdragdrop）

  • 多列选择风格（w_sortmulti）

  • 单列选择风格（pfc_w_sortsingle）

开启排序服务

  • 调用函数of_SetSort开启服务，同时指定排序对话框使用列标题：
    dw_emp.of_SetSort（TRUE）

dw_emp.inv_sort.of_SetColumnDisplayNameStyle（dw_emp.inv_sort.HEADER）

u_dw会自动删除所有的服务

指定PFC的排序服务只对显示的数据进行排序还是对所有的数据进行排序：

  • 调用函数of_SetUseDisplay

dw_emp.inv_sort.of_SetUseDisplay（TRUE）

指定排序风格：

  • 调用函数of_SetStyle指定排序风格：

dw_emp.inv_sort.of_SetStyle（dw_emp.inv_sort.DRAGDROP）

显示排序对话框：

  • 调用事件pfc_SortDlg

dw_emplist.Event pfc_SortDlg（）

通常你没必要显示的调用该事件，当用户选择View>Sort（菜单m_master的后代）时会自动的打开排序窗口。

  1. 窗口服务

为了使用窗口服务，你的窗口必须继承w_master或者它的后代：

w_child

w_frame

w_main

w_popup

w_response

w_sheet

w_master包含：

    • 用于开启、关闭窗口服务的函数

    • 各个用户自定义对象的引用变量。

    • 用于执行窗口服务的已编号代码的事件

    • 空用户事件

关于继承：当你继承窗口是一定要继承w_prefix开头的窗口，不要继承pfc_prefix开头的窗口。Pfc_prefix开头的对象是用于升级PFC的。

以下表格列出了各种窗口服务以及对应的变量：

窗口服务 实现对象

Basic window n_cst_winsrv以及函数、用户事件

Preference service n_cst_winsrv_preference

Sheet managerment service n_cst_winsrv_sheetmanager

Status bar service n_cst_winsrv_statubar

  1. Basic window services

概要

PFC的窗口中有：

  • 窗口函数

  • 预代码事件、用户事件

  • 空用户事件

这些函数、事件对你的应用程序中的所有窗口都有效。如果你使用PFC的标准可视控件、m_master的后代菜单，那么PFC回自动完成它们的连接。

自动的关闭询问处理：PFC的所有窗口都会自动处理带有DataWindow的关闭询问处理。当用户在保存对话框中选择YES是，PFC会自动的将Datawindow的所有修改都保存。如果你需要作特定的保存处理，你可以覆盖CloseQuery事件。或者将变量ib_disableclosequery值设为True 。

使用说明：

基本窗口服务具有如下功能：

  • 消息路由、菜单集成

  • 由PFC菜单触发的空用户事件

  • 工具栏，只限于w_frame

  • 自动保存处理

关于PFC窗口类型的资料请参考 PFC Object Reference 。

在菜单项的脚本中使用消息路由：

  • 调用菜单函数of_SendMessage ，以用户事件为参数：

of_SendMessage（”pfc_CheckStatus”）

该函数会将请求传递给n_cst_menu的of_SendMessage函数，然后n_cst_menu的of_SendMessage函数会将请求传递给当前窗口的pfc_MessageRoute事件，然后目标事件才会被调用。

在非菜单函数或事件中使用消息路由：

  • 调用活动窗口的pfc_MessageRouter事件，传递需要调用的事件：

this.Event pfc_MessageRouter（”pfc_CheckStatus”）

事件pfc_MessageRouter将请求传递给当前窗口，然后目标事件便会触发。

PFC的菜单使用菜单函数of_SendMessage调用窗口中的用户事件。

使用空用户事件：

  • 为了某种目的在PFC的用户事件中添加代码。下面的例子说明了当你需要显示一个PageSetup对话框时，你可以在pfc_PageSetup事件中编写代码：

Integer li_return

li_return = idw_active.Event pfc_PageSetup()

IF li_return > 0 THEN

li_return = idw_active.Event pfc_PrintImmediate()

END IF

在PFC Object Reference中有关于该事件的其他必须代码的说明。

显示用于控制工具栏的窗口

  • 调用框架窗口的pfc_ToolBars事件：

gnv_app.of_GetFrame().Event pfc_Toolbars()

当用选择m_master的后代菜单的Tools>Customize时，PFC会自动调用该事件。

保存对数据库的修改：

  • 调用窗口的pfc_Save事件：

Integer li_return

Li_return = this.Event pfc_Save（）

当用户选择m_master的后代菜单的File>Save时，PFC会自动的调用该用户事件。同样对于w_master的后代窗口的CloseQuery事件当用户在提示保存窗口中选择Yes时也会调用pfc_Save事件。

将窗口定位在屏幕中间：

  1. 开启基本窗口服务：

    2. this.of_SetBase（True）

  2. 调用n_cst_winsrv的of_Center函数：

this.inv_base.of_Center（）

  1. Preference service

概要

选项服务提供了允许用户保存、恢复用户窗口设置，或者是关于注册表、INI文件。选项服务可以保存：

  • 大小

  • 位置

  • 工具栏设置

它对应的对象是n_cst_winsrv_preference 。

使用说明：

使用该服务保存、恢复窗口设置：

自动运行：如果你的w_master后代窗口开启了该服务，所有的操作将会自动执行。

开启窗口选项服务：

  • 调用w_master的of_SetPreference函数。该函数对所有的PFC窗口都有效。因为w_master时所有PFC窗口的祖先。

PFC会自动的删除所有的服务。

指定特定的窗口选项需要恢复，调用如下的几个函数：

  • 根据需要调用如下的几个函数：

of_SetToolbarItemOrder

of_SetToolbarItemSpace

of_SetToolbarItemVisible

of_SetToolbars

of_SetToolbarTitles

of_SetWindow

  1. Sheet management service

概要

PFC的表单管理服务提供了一个供MDI应用程序管理多个表单的功能。当你启用该功能时，PFC会在WINDOW的菜单中增加如下几项：

  • 最小化所有的窗口

  • 恢复排列图表操作

它对应的对象是n_cst_winsrv_sheetmanager 。

使用说明：

使用该服务管理MDI应用程序中的多个表单。

开启表单管理服务：

  • 调用w_frame的of_SetSheetManager函数，该函数对w_frame的所有后代窗口都有效：

this.of_SetSheetManager（TRUE）

PFC回自动删除所有的服务。

访问表单：

  • 根据需要如下的函数：

of_GetSheetCount

of_GetSheets

of_GetSheetsByClass

of_GetSheetsByTitle

  1. Status bar service

PFC的状态栏服务可以在MDI父窗口的右下角状态栏处显示时间、内存信息。该服务提供的其他服务还有：

  • GDI、可用内存监视器

  • 支持进度条

  • 显示开发人员的文本

有关进度条的详细说明请参考”Using the progress bar control”

PFC的状态条服务对应的对象是n_cst_winsrv_statusbar用户自定义对象，它实际上是使用了一个窗口（w_statusbar）显示信息。

你可以调用n_cst_winsrv_statusbar的函数来控制显示的项。

在Macintosh和UNIX操作系统上：该服务不适用于这两种操作系统。

使用说明：

使用该服务在MDI父窗口中显示状态条信息。如果需要，你可以使用w_statusbar的函数修改显示的内容。

开启状态条服务：

  1. 调用w_frame的of_SetStatusBar函数。该函数适用于所有w_frame的后代窗口。

    2. This.of_SetStatusBar（TRUE）

    PFC会自动删除所有的服务。

  2. 在w_frame的pfc_PreOpen事件中调用n_cst_winsrv_statusbar的函数指定需要在状态栏中显示的信息。各信息显示的从做到右顺序与其相关的函数的调用顺序相同。例如，下面例子内存信息显示在日期信息的左边：

this.inv_statusbar.of_SetMem（TRUE）

this.inv_statusbar.of_SetTimer（TRUE）

3. 适当的时候调用n_cst_winsrv_statusbar的函数

  1. 菜单服务

概要

PFC的菜单服务提供了菜单与菜单、菜单与窗体之间的通信功能。通时还有获取MDI父窗口、工具栏的信息的函数。你可以在菜单的脚本中时该服务提供的函数。它对应的对象是的n_cst_menu 。

使用说明：

你可以在非PFC的菜单中使用该服务访问框架窗口（Frame window）、与窗口通信。

开启菜单服务：

  • 定义类型为n_cst_menu的变量：

n_cst_menu lnv_menu

该变量可以是菜单级的实例变量或者是菜单脚本中局部变量。你无须调用Create或Destroy语句，因为PFC已经将该对象定义为autoinstantiate（自动实例）。

使用消息路由：

  • 在菜单的脚本中调用of_SendMessage函数：
          n_cst_menu lnv_menu

Message.StringParm = “w_emplist”

Lvn_menu.of_SendMessage（This, “pfc_Open”）

访问MDI父窗口：

  • 在菜单脚本中调用函数of_GetMDIFrame访问MDI父窗口

n_cst_menu lnv_menu

w_frame lw_frame

// This is an alternative to of_SendMessage.

lnv_menu.of_GetMDIFrame(this, lw_frame)

Message.StringParm = "w_emplist"

lw_frame.Event pfc_Open()

  1. Resize服务

概要

PFC的resize服务提供了当用户改变窗口的大小、Tab页的大小时可以自动移动控件、改变控件大小的函数。该服务允许你当窗口、Tab页大小改变时控制其中的控件的移动、大小变化等。它对应的对象是n_cst_resize 。

你可以使用n_cst_dwsrv_resize对象实现DataWindow的resize服务。

使用说明：

使用该服务控制窗口的大小变化。

开启Resize服务：

  • 调用w_master、u_tab、u_tabpg的of_SetResize函数：

this.of_SetResize（TRUE）

PFC会自动的删除所有的服务。

注册需要resize的控件：

  • 调用函数of_Register指定控件应该如何相应窗口、Tab页的resize 。注册时需要说明当发生resize时应该移动多少，大小变化的比例是多少。下面的例子使得DataWindow控件向下、向右扩展。

This.inv_resize.of_Register（dw_emplist, 0, 100, 100, 100）

设置Resize的下限：

  • 调用函数of_SetMinSize设置大小的下限。你可以将该代码放在窗体的Open事件中指定下限小于当前大小一点。

Integer li_return

Li_return = this.inv_resize.of_SetMinSize（this.width – 200, this.height - 150）

在带有表单的MDI应用程序中使用resize服务：

  • 采用如下方法之一：

    • 以表单原大小打开：

OpenSheet（w_emp, “w_emplist”, w_frame, 0, Original!）

    • 如果你使用其他的枚举变量。那么在控件进行resize服务的注册之间调用函数of_SetOrigSize 。调用函数of_SetOrigSize时传递工作空间的宽度、高度为参数。

This.inv_resize.of_SetOrigSize（1200, 1000）

  1. 转换服务

概要

PFC的转换服务提供了数据类型转换函数。例如，你可以使用函数of_Boolean将整形或者字符串转换成布尔类型。它对应的对象是n_cst_conversion 。n_cst_conversion是自动实例的，因此，它不需要Create、Destroy语句。

使用说明：

你可以使用该服务实现下列转换

原数据类型 目标数据类型

Integer or String Boolean

Boolean、ToolbarAlignment、SQLPreviewType String

Boolean Integer

String ToolbarAlignment

Button String

Icon String

String SQLPreviewType

如果你想查看详细的说明请查看 PFC Object Reference 中的n_cst_conversion对象。

声明n_cst_conversion变量

定义n_cst_conversion成全局、实例或者局部变量。

使用说明 变量类型

贯穿整个应用程序 全局变量或者n_cst_appmanager的事例变量

针对一个对象 对象的事例变量

针对一段脚本 局部变量

开启转换服务：

  • 定义类型为n_cst_conversion的变量

n_cst_conversion inv_conversion

因为n_cst_conversion是自动实例化，因此不需要使用Create或者Destroy语句。

调用转换服务的函数：

  • 调用函数

下面的例子假设inv_conversion是实例变量：

String ls_checked

Ls_checked = inv_conversion.of_String（cbx_confirmed.Enabled）

MessageBox（”Conversion”,”CheckBox is: ” + ls_Checked）

  1. 日期/时间服务

概要

PFC的日期/时间提供了许多用于计算日期、时间的函数。例如，你可以使用of_SecondsAfter函数计算两个时间之间的秒数。它对应的对象是n_cst_datatime 。对象n_cst_datatime对象是自动实例化，因此你无须使用Create或Destroy语句。

使用说明：

你可以使用日期/时间服务进行有关日期/时间的计算。该服务提供了以下函数：

  • 将Julian日期转换成Gregorian日期

  • 将秒数转换成小时

  • 将秒数转换成天数

  • 将Gregorian日期转换成Julian日期

  • 计算两日期之间的年数

  • 计算两日期之间的月份

  • 计算两日期之间的周数

  • 计算两日期之间的秒数

  • 计算两日期之间的毫秒

  • 判断日期是否有效

  • 判断某日是否是平日（非周日）。原文：Determine if a date falls on a weekday

  • 判断某日是否是周末

  • Halt processing until a specified date/time

你可以将n_cst_datetime定义成全局变量、实例变量、局部变量。

日期/时间函数使用说明 变量类型

贯穿整个应用程序 全局变量或者n_cst_appmanager的实例变量

针对一个对象 该对象的实例变量

针对一段代码 局部变量

开启日期/时间服务：

  • 定义类型为n_cst_datetime的变量

n_cst_datetime inv_datetime

类型n_cst_datetime是自动实例化的，因此无须使用Create或Destroy语句

调用日期/时间服务的函数：

  • 直接调用函数

下面的例子假设inv_datetime是实例变量

Long ll_seconds,ll_days

Ll_seconds = Long（sle_seconds.Text）

Ll_days = inv_datetime.of_Days（ll_seconds）

MessageBox（”Date/Time”，String（ll_seconds）+ “ seconds is equal to ” + String（ll_days） + “ days。“）

  1. 文件服务

概要

PFC的文件服务使得你的应用程序可以具备文件管理器功能。例如，你可以使用of_FileRename函数改变文件名称。文件服务支持多种操作系统，针对各种操作系统该服务会自动的调用相应的外部函数。它对应的对象是n_cst_filesrv 。

使用说明：

通过文件服务你可以使用如下操作：

  • Assembling a concatenated filename 。

  • 建立、删除目录。

  • 读、写、重命名、复制文件。适用于大于32765字节的文件。

  • 访问文件信息，包括日期、时间。

  • 在一个目录下创建、排序文件。

你可以将n_cst_filesrv定义成全局、实例、局部变量。

使用情况 变量类型

贯穿整个应用程序 全局变量或者n_cst_appmanager的实例变量

针对一个对象 对象的实例变量

针对一段代码 局部变量

由于PFC会根据特定的平台创建n_cst_filesrv的子类。因此它没有使用PB的自动实例化功能。你必须显示的调用Destroy语句删除该对象。

开启文件服务：

  1. 定义类型为n_cst_filesve的变量

n_cst_filesrv inv_filesrv

  2. 调用全局函数f_set_filesrv：

f_SetFilesrv（inv_filesrv,TRUE）

该函数会自动的建立对象inv_filesrv 。

  3. 使用完毕后删除对象

Destroy inv_filesrv

调用文件服务的函数：

  • 直接调用函数

该例子调用函数of_FileRead访问文件信息。该例子假设inv_filesrv是实例变量：

Integer li_return

String ls_file[]

li_return = inv_filesrv.of_FileRead(sle_filename.text, ls_file)

CHOOSE CASE li_return

CASE –1

MessageBox("Error", "Error accessing file")

CASE ELSE

// File processing goes here

END CHOOSE

删除该服务：

  • 使用DESTROY语句

DESTROY inv_filesrv

  1. INI文件服务

概要

PFC的INI文件服务提供了许多读、写INI文件的函数。它对应的对象是n_cst_inifile。

使用说明：

你可以使用INI文件做到如下：

  • 检索INI文件中的所有键

  • 检索INI文件中的所有段

  • 删除INI文件中的所有行

  • 删除INI文件中一行

  • 删除INI文件中一段

你可以同时使用ProfileInt、ProfileString、SetProfileString访问INI文件。INI文件服务对大小写不敏感。

开启INI文件服务：

  • 定义类型为n_cst_inifile的变量：

n_cst_inifile inv_ini_handler

该类型属于自动实例化，因此你无须调用Create与Destroy 。

使用INI文件服务：

  • 调用n_cst_inifile的对象函数：

String ls_keys[]

Integer li_count, li_size

Li_size = inv_ini_handler.of_GetKeys（gnv_app.of_GetAppINIFile（），“CustApp”，ls_keys）

Lb_keys.Reset（）

For li_count = 1 to li_size

Lb_keys.AddItem（ls_keys[li_count]）

Next

  1. 数字服务

概要

PFC的数字服务提供的函数使得你可以处理二进制数。例如，你可以使用of_GetBit函数判断一位是开还是关。

使用说明：

你可以使用数字服务中的函数做到：

  • 判断一位是开还是关

  • 将十进制转换成二进制

  • 将二进制转换成十进制

与Window SDK共同使用该对象：Windows SDK中许多函数都使用位返回值。因此你需要使用函数of_GetBit 。

你可以将n_cst_numerical定义成全局、实例、局部变量。

使用说明 变量类型

贯穿整个应用程序 全局变量或者n_cst_appmanager的实例变量

针对一个对象 对象的实例的变量

针对一段脚本 局部变量

开启数字服务：

  • 定义类型为n_cst_numerical的变量

n_cst_numerical inv_numerical

类型n_cst_numerical自动实例化，你无须使用Create或者Destroy语句。

调用数字服务（numerical service）函数：

  • 直接调用函数

下面的例子假设inv_numerical是实例变量：

Long ll_base10

String ls_binary

Ll_base10 = Long（sle_base10.text）

Ls_binary = inv_numerical.of_Binary（ll_base10）

MessageBox("Numerical", String(ll_base10) + " base 10 is equal to " + String(ll_base10) + " base 10 is equal to " + ls_binary + " in binary.")

  1. 平台服务

概要

PFC的平台服务提供的函数使到你的应用程序可以使用特定平台的函数。你可以使用该服务实现支持多平台的应用程序，而无须在你的应用程序中加入有关平台检测的代码。例如，你可以调用函数of_GetFreeMemory确定现在所剩的内存大小。平台服务此时便会依据不同的平台调用相应的外部函数而完成工作。该服务对应的对象是n_cst_platform以及不同平台的相应的子类。

打印与页面设置对话框：PFC的平台服务会根据不同的平台作相应的调整。

使用说明：

平台服务提供的函数有：

  • 确定可用内存空间

  • 确定可用资源空间

  • 确定某一字符串的高度、宽度，单位是PBUs

你可以将n_cst_platform定义成全局变量、实例变量、局部变量

使用说明 变量说明

贯穿整个应用程序 全局变量、n_cst_appmanager的实例变量

针对一个变量 对象的实例变量

针对一段代码 局部变量

平台服务没有使用自动实例化功能，因此你必须显示的删除n_cst_platform 。

在Macintosh上：在Macintosh上函数of_GetTextSize无法使用。

开启平台服务：

  1. 定义类型n_cst_platform的变量：

n_cst_platform inv_platform

  2. 调用f_SetPlatform全局函数

f_SetPlatform（inv_platform，TRUE）

函数f_SetPlatform会自动建立该对象。

调用平台服务函数：

  • 直接调用函数

下面的例子调用函数of_GetFreememory在状态栏处显示可用内存的大小。

Long ll_free_monery

ll_free_memory = inv_platform.of_GetFreeMemory（）

gnv_app.of_GetFrame（）. SetMicroHelp（”Free memory：” + String（ll_free_memory））

删除服务

  • 调用 Destroy 语句

Destroy inv_platform

  1. 选择服务

概要

PFC提供了一个用于显示 w_selection 对话框的函数。当用户选择OK时该函数返回选中行的一列或者多列的值。它对应的对象是 n_cst_selection 。

使用说明：

你可以使用 of_Open 函数打开一个供用户选择数据的对话框，然后在由应用程序处理。

共有三种版本的 of_Open 函数，每个函数的 w_selection显示信息都不一样：

  • 检索、显示 DataWindow 中的所有数据

  • 显示一部分数据。原文：W_selection displays a passed set of rows

  • 显示已保存的一部分数据。原文：W_selection displays rows that have been saved as part of the passed DataWindow object

你可以将 n_cst_selection定义成全局变量、实例变量、局部变量

说明 变量类型

贯穿整个应用程序 全局变量或者 n_cst_appmanager 的实例变量。

针对一个变量 实例变量

针对一段代码 局部变量

开启选择服务：

  • 定义类型为 n_cst_selection 变量

n_cst_selection inv_selection

因为对象 n_cst_selection是自动实例化的，因此你无需调用Create 或者Destroy 语句。

使用选择服务：

  1. 定义供of_Open使用的变量

    2. n_cst_selection lnv_selection

    Any la_selected[]

    String ls_columsp[

    Integer li_count

  2. 设定需要返回值的列

    3. ls_columns[1] = "emp_id"

    ls_columns[2] = "emp_lname"

    ls_columns[3] = "emp_fname"

  3. 调用函数of_Open显示w_selection窗口。该版本的of_Open将显示DataWindow中的所有数据。

  4. 访问返回的值

FOR li_count = 1 to UpperBound(la_selected)

lb_selected.AddItem (String(la_selected[li_count]))

NEXT

  1. SQL语法分析服务

概要

PFC的SQL语法分析服务提供的函数可以让你分析你的SQL语句。他对应的对象是n_cst_sql 。

使用说明：

你可以使用SQL语法分析服务做到：

  • 由他的部分组件建立SQL语句。原文：Build a SQL statement from its component parts

  • 分析组件中的SQL语句

你可以将n_cst_sql定义成全局变量、实例变量、局部变量

说明 变量类型

贯穿整个应用程序 全局变量或n_cst_appmanager的实例变量

针对一个对象 对象的实例变量

针对一段代码 局部变量

开启SQL语法分析服务：

  • 定义类型为n_cst_sql的变量

n_cst_sql inv_sql

由于n_cst_sql是自动实例化的，因此你无需使用Create或者Destroy语句

To build a SQL statement from its component parts:

  • 调用of_Assemble函数

String ls_sql

n_cst_sqlattrib lnv_sqlattrib[]

lnv_sqlattrib[1].s_verb = sle_verb.text

lnv_sqlattrib[1].s_tables = sle_tables.text

lnv_sqlattrib[1].s_columns = sle_columns.text

lnv_sqlattrib[1].s_values = sle_values.text

lnv_sqlattrib[1].s_where = sle_where.text

lnv_sqlattrib[1].s_order = sle_order.text

lnv_sqlattrib[1].s_group = sle_group.text

lnv_sqlattrib[1].s_having = sle_having.text

ls_sql = inv_sql.of_Assemble(lstr_sql)

MessageBox("SQL", ls_sql)

To parse a SQL statement into its component parts:

  • 调用函数of_Parse

String ls_sql

Integer li_return

n_cst_sqlattrib lnv_sqlattrib[ ]

li_return = inv_sql.of_Parse(mle_sql.text, lnv_sqlattrib)

IF li_return > 0 THEN

sle_verb.text= lnv_sqlattrib[1].s_verb

sle_tables.text = lnv_sqlattrib[1].s_tables

sle_columns.text = lnv_sqlattrib[1].s_columns

sle_values.text = lnv_sqlattrib[1].s_values

sle_where.text = lnv_sqlattrib[1].s_where

sle_order.text = lnv_sqlattrib[1].s_order

sle_group.text = lnv_sqlattrib[1].s_group

sle_having.text= lnv_sqlattrib[1].s_having

END IF

  1. 字符串处理服务

概要

PFC的字符串服务提供的函数可以处理字符串。他对应的对象是n_cst_string。

使用说明：

你可以使用字符串服务做到：

  • 将具有定界符的字符串分割成数组。

  • 将数组转换成具有定界符的字符串。

  • 判断字符串的大小写，是否按字母排序、是否按数字、字母排序

  • 通用替代。原文：Global replacing

  • 计算字符串中数字出现的次数

  • 将字符串中的非字母除去

  • 判断一字符串是否是表达式

  • 将所有的字母都变成首字母大写

你可以将n_cst_string定义成全局变量、实例变量、局部变量

使用说明 变量类型

贯穿整个应用程序 全局变量或者n_cst_appmanager的实例变量

针对一个对象 对象的实例变量

针对一段代码 局部变量

开启字符串服务：

  • 定义类型为n_cst_string的变量：

n_cst_string inv_string

由于对象n_cst_string是自动实例化的，因此你无需调用Create或者Destroy语句

调用字符串处理函数：

  • 直接调用函数

这段代码来自n_cst_dwsrv_report的of_AddText函数。他调用函数of_ParseRoArray as_text字符串转换成一个数组，其中lnv_string是局部变量

n_cst_string lnv_string

Integer li_newlines

String ls_line[ ]

...

li_newlines = lnv_string.of_ParseToArray (as_text, "~r~n", ls_line)

  1. 元类服务

概要

元类服务的函数提供了其他对象中的函数、事件、变量的信息。他对应的对象是n_cst_metaclass 。

使用说明：

元类服务最有用也是最常用的就是在调用对象函数、事件之前先判断它们是否存在。

使用元类服务：

  1. 定义类型为n_cst_metaclass的变量：

    2. boolean lb_defined

    n_cst_metaclass lnv_metaclass

    classdefinition lcd_obj

    String ls_args[ ]

    Integer li_rc

    由于对象n_cst_metaclass是自动实例化的，因此你无需使用Create或者Destroy函数。

  2. 调用n_cst_metaclass函数

lcd_obj = FindClassDefinition("w_sheet")

lb_defined = lnv_metaclass.of_isFunctionDefined(lcd_obj,"of_Validation", ls_args)

If lb_defined Then

// Qualify with instance of w_sheet descendant.

li_rc = w_sheet.Function Dynamic of_Validation ()

If li_rc < 0 Then

Return -1

End If

  1. 工作逻辑单元服务

概要

工作逻辑单元提供了具有自动保存数据功能的对象（简称自更新对象）。一个具有自动保存数据功能的对象实际上是提供了一整套函数接口（self-updating object API）供n_cst_luw对象执行保存操作时调用。这些函数再调用那些需要保存数据的对象的事件。工作逻辑单元服务自动的调用这些函数，并且作为默认保存操作的一部分。PFC有好几个具有自动保存数据功能的对象，它们是：

U_dw

N_ds

U_lvs

U_tab

U_tvs

U_base

W_master

查看这些对象的API的执行结果即可证实。

默认情况下，w_master的pfc_Save会使用工作逻辑单元保存所有具有自动保存数据功能的对象。详细情况查看”Using the pfc_Save process”

自更新对象的实现：

工作逻辑单元更新所有的可更新的自更新对象。

注意：大部分的自更新对象默认情况下是不可更新的。为了确保向后兼容性，u_dw是唯一的默认可更新的。

下面是所有的自更新对象的对外接口（API）

函数 | 用途
of_AcceptText | 调用pfc_AcceptText事件，该事件再调用AcceptText函数
of_UpdatesPending | 调用pfc_UpdatesPending事件，该事件会判断该对象是否已经保存数据了。
of_Validation | 调用pfc_Validation事件，该事件会对数据进行有效性检验。
of_UpdatePrep | 调用pfc_UpdatePrep事件，该事件将会准备好那些将要更新的对象。
of_Update | 调用事件pfc_Update，该事件会更新数据库。
of_PostUpdate | 调用事件pfc_PostUpdate，该事件将会异步的执行更新操作。

你可以使用Browser查看这些函数、事件的信息。

编写你自己的自更新对象：

要编写自己的自更新对象只需调用上述的函数和必须使用一组引用类型数组指向你的对象作为n_cst_luw中的某些函数的参数。

扩展保存操作

默认情况下，w_master的pfc_Save会保存其中的所有被修改的DataWindow。你可以按如下扩展该操作：

  • 其他的自更新对象：你可以在对象的构造事件中调用函数of_SetUpdateable将其他的自更新对象设置成可更新的。下面的代码来自u_lvs。

this.of_SetUpdateable（TRUE）

  • 现在，工作逻辑单元将会将保存u_lvs的数据操作作为默认的保存操作

  • DataStore：你可以将一个或多个DataStore通过调用函数of_SetUpdateObjects列为需要更新的对象：

PowerObject lpo_objs[]

Integer li_count

lpo_objs = this.control

li_count = UpperBound（lpo_objs）

li_count ++

lpo_objs[li_count] = ids_data

this.of_SetUpdateObjects（lpo_objs）

    • 附加的窗口：你可以调用w_master的of_SetUpdateObjects将一个或者多个窗口列为需要更新的对象。

PowerObject lpo_objs[ ]

Integer li_count

lpo_objs = this.control

li_count = UpperBound(lpo_objs)

li_count++

// Update w_other as well as this window

lpo_objs[li_count] = w_other

this.of_SetUpdateObjects(lpo_objs)


第五章 使用PFC的可视控件

  1. 使用标准可视控件

  1. 基本功能的使用

  2. 高级功能的使用

DataWindow u_dw 的使用

多数的PowerBuilder程序都大量的使用了DataWindow控件。DataWindow 用户自定义控件 u_dw 有大量丰富的内容：

  • 用于开启和关闭DataWindow服务的函数。

  • 用于设置事务对象的函数。

  • 关于DataWindow、下拉DataWindow检索数据的事件。

  • 用于控制DataWindow更新数据的事件。

  • 用于控制DataWindow打印的事件。

与PFC菜单的结合：

下面讨论的大部分事件都会由PFC m_master菜单或者它的子类菜单自动调用。例如，当你选择 File-〉Save 时，PFC 将会调用 pfc_Save 事件。

开启 DataWindow 服务

PFC 提供了大量的DataWindow服务。它会很容易的增强你的应用程序的功能。大部分的服务只需要一点代码甚至不需要代码。

  • 开始使用DataWindow服务

    1. 将 u_dw 可视控件放入窗口中。

    2. 确定那个 DataWindow 服务将要用在该 DataWindow 控件中。

    3. 使用函数 u_dw 的函数 of_Setservicename 开启相应的服务（下面的代

      4. 码位于 DataWindow 控件的 Constructor 事件中。）：

      this.of_SetRowSelect(TRUE)

      this.of_SetRowManager(TRUE)

      this.of_SetSort(TRUE)

    4. 为 DataWindow 建立事务对象：

this.of_SetTransObject(SQLCA)

    1. 调用其他的初始化函数（下面的例子设置了行选择风格、排序对话框风格、开启了列头排序服务）：

      2. this.inv_rowselect.of_SetStyle(this.inv_rowselect.EXTENDED)

      this.inv_sort.of_SetStyle(this.inv_sort.DRAGDROP)

      this.inv_sort.of_SetColumnHeader(TRUE)

    2. 根据不同的需要调用 DataWindow 服务的事件、函数等。大多数情况下，你不需要另外为服务编写代码就可以获得服务提供的好处。下面的例子调用 pfc_SortDlg 显示排序窗口：

dw_list.Event pfc_SortDlg（）

  1. 使用自定义可视控件


第6章　使用PFC窗口和菜单

关于本章　本章解释如何使用 PFC窗口和菜单.

使用 PFC窗口

PFC提供了一个基类祖先窗口(w_master)并为每种标准窗口类型提供了祖先窗口.

每个这样的窗口都继承自w_master:

PFC窗口包含实例变量、事件和提供高级功能并可与其它PFC对象通信的函数。

窗口的基本用法

开发应用程序,典型地:

创建基类和继承的窗口

启动窗口服务

从菜单选项中打开窗口

使用PFC窗口进行开发

当你开始一个应用程序的开发,你应考察需要的功能以决定哪一个实例变量、事件以及函数应归入祖先窗口.

你定义特定应用程序祖先的不同行为取决于你的扩充策略:

策略

方法

创建中间扩展层　应用程序的祖先窗口使用PFC扩展层窗口.

例如,在 w_master定义共用的扩展和在 w_sheet定义工作表窗口扩展.

于是你的应用程序窗口从PFC扩展层窗口继承

典型地，因为在MDI应用程序中仅有一个框架窗口,你可以修改和使用w_frame代替继承的窗口

使用存在的PFC扩展层　你可以通过继承PFC扩展层窗口来创建一组应用程序的祖先窗口.

应用程序窗口于是继承自应用程序专有的祖先窗口　通过继承w_frame来创建框架窗口

启动窗口服务

PFC提供各种窗口服务是你能用来加入产品化应用程序特性.

许多这样的服务要求极少甚至不须编码.

窗口服务有:

基本窗口服务

偏好服务

状态栏服务 (限于框架窗口)

工作表管理服务 (限于框架窗口)

调整大小服务 (也适合属性页、属性页页面以及自定义的可视用户对象)

使用窗口服务:

1为窗口确定适当的窗口服务.

2使用of_Setservicename函数启动适当的窗口服务(本例子从窗口的 pfc_PreOpen事件启动偏好和调整大小服务):

this.of_SetPreference(TRUE)

this.of_SetResize(TRUE)

3按需要调用其它函数以初始化服务 (本例子为菜单项和工具栏启动偏好服务并为DataWindow务和两个按钮提供启动调整大小服务):

this.inv_preference.of_SetMenuItems(TRUE) this.inv_preference.of_SetToolbars(TRUE)

this.inv_resize.of_Register &

(dw_emplist,0,0,100,100) this.inv_resize.of_Register &

(cb_ok,0,100,0,0)

this.inv_resize.of_Register &

(cb_cancel,0,100,0,0)

参阅　有关每种窗口服务的具体用法,参见 "窗口服务" .

开启PFC窗口

在许多应用程序,用户通过选择菜单项打开窗口.

你能使用PFC消息路由器帮助以可变的和固定的方法处理本过程.

参阅　参见 "消息路由器" .

从菜单项打开PFC窗口:

1在该菜单项,将Message.StringParm设为窗口名并调用菜单服务of_SendMessage函数:

n_cst_menu lnv_menu Message.StringParm = "w_emplist"

lnv_menu.of_SendMessage(this, "pfc_Open")

2在框架窗口的 pfc_Open事件,添加代码到存取消息对象并打开请求的窗口:

String ls_window

w_sheet lw_sheet

ls_window = Message.StringParm

OpenSheet(lw_sheet, ls_window,this, 4,Original!)

其他选项 打开 PFC窗口的其它 方法.

这些包含直接从菜单选项打开窗口,扩充消息对象以包含传递的参数,以及通过定义框架窗口的附加用户事件打开窗口.

使用响应式窗口

典型地，你使用 w_response ( PFC响应式窗口)创建显示并收集数据、设置或参数选择的响应式窗口。

w_response的另一个用途　你还能使用 w_response创建响应式窗口以取代 MessageBox.

但是通常最好使用 w_message对话框 (出错信息服务部分).

W_response包含三个处理用户动作的用户事件，你可以在其中添加代码:

事件　使用它　更多信息

pfc_Apply　处理窗口内容,保持窗口打开　当前许多的应用程序包含Apply按钮来执行本功能

pfc_Cancel　忽略窗口内容并关闭窗口　你从赋与Cancel特性的按钮调用本事件

pfc_Default　处理窗口内容并关闭窗口　你从赋与Default特性的按钮调用本事件

使用w_response事件:

1创建一个继承自w_response的窗口.

2添加控件以处理显示和用户输入.

使用PFC标准可视用户对象　你能使用同PFC一起使用PowerBuilder窗口控件.

但是最好使用继承自PFC标准可视用户对象 (u_dw, u_lb, u_sle, u_cb,等等)的控件.

3添加代码支持这些控件.

例如,添加代码到窗口的pfc_PreOpen事件，存取在 INI文件值以显示在SingleLineEdit控件上.

4按需要在pfc_Apply、pfc_Cancel和pfc_Default事件中添加代码。.

例如, 可以在pfc_Default事件中保存窗口内容到INI文件并关闭窗口:

ls_String ls_temp ls_temp = trim(sle_base.Text)

SetProfileString("eisapp.ini",&

"Files","base",ls_temp)

ls_temp=trim(sle_x1.Text)

SetProfileString("eisapp.ini",&

"Files","extra1",ls_temp) ls_temp = trim(sle_x2.Text)

SetProfileString("eisapp.ini",&

"Files", "extra2", ls_temp)

Close(this)

5添加按钮以触发相应事件.

例如,OK按钮应调用 pfc_Default事件:

parent.Event pfc_Default()

使用 pfc_Apply

到最大化 reusability,把处理放置于pfc_Apply内和调用 pfc_Apply从 pfc_Default.

使用 pfc_Save过程

w_master pfc_Save事件为窗口中所有PFC和非PFC的 DataWindows自动确认并保存改动.

因为 pfc_Save调用许多其它事件, 保存大多数工作到工作服务的逻辑单元，你应该将它看作一个过程而不是作为一个单一的事件.

工作服务的逻辑单元　pfc_Save使用你通过调用of_SetLogicalUnitOfWork函数启动的工作服务逻辑单元,.

如果你启动工作服务的逻辑单元, w_master按需要自动启动它.

虽然有许多方法保存数据,最好使用 pfc_Save事件保存改动.

除了简单地调用w_master pfc_Save事件和检查返回值之外,你能通过定制和扩充被pfc_Save过程调用的事件来对更新过程进行完全控制.

你能:

为其它自更新对象保存改动(包括n_ds DataStore、u_tvs TreeView和u_lvs Listview)

为其它控件保存改动

控制哪个对象被更新和指定它们被更新的顺序

为其它窗口的对象保存改动

自更新对象 PFC将更新机能与某些对象结合，称作自更新对象 .

你当调用 w_master pfc_Save事件,它自动更新窗口中的所有自更新对象.

所有 DataWindows都是自更新的.

你必须为n_ds、u_lvs、u_tab和u_tvs明确地启动自更新功能.

并且你能为任何可视的或非可视的控件添加自更新功能.

参阅　有关自更新对象的详细信息,参见 "工作服务的逻辑部件" .

pfc_Save过程

本是 w_master pfc_Save过程:

Pfc_Save事件

这些是 pfc_Save过程中的事件:

事件　用途　注解

pfc_AcceptText　为窗口中的所有自更新对象执行 AcceptText功能　被w_master of_AcceptText函数调用

pfc_UpdatesPending　确定哪一个自更新对象有未决的更新　被w_master of_UpdatesPending函数调用

pfc_Validation　在所有包含未决更新的自更新对象上执行合法性检验　被of_Validation函数调用　为非PFC DataWindows，编写一个返回值类型为Integer或Long的用户事件ue_validation，大于或等于0表示成功

pfc_UpdatePrep　空的用户事件，你可以随意添加准备更新的处理代码　如果窗口本身是自更新对象则扩充本事件

pfc_PreUpdate　空的事件，你可以添加附加的合法性检验代码　返回 1为成功;

返回别的值则终止 pfc_Save过程

pfc_BeginTran　空的事件，如果你的 DBMS需要，你可以添加代码开始数据库事务。　返回 1为成功;

返回别的值则终止 pfc_Save过程

pfc_Update　为所有有改动的自更新对象执行数据库更新　你能扩充本事件更新非自更新控件

返回 1为成功;

返回 -1为失败.

如果返回 -1,同样通过调用 of_SetDBErrorMsg函数产生一个出错信息.

pfc_DBError事件将显示本信息

pfc_EndTran　空的事件，你用来添加提交或回滚数据库事务的代码　提交或回滚基于传递的参数　虽然你能在其它 地方使用COMMIT和ROLLBACK语句，但最好在此处使用它们

pfc_DBError　若有更新失败的话,本事件显示有关信息　如果Error服务被启动,本事件调用 of_Message函数;

否则,它调用 PowerScript MessageBox函数 　 PFC延迟显示出错信息 (相对于pfc_Update)以便你能在显示出错消息框前在 pfc_EndTran事件中回滚改动

pfc_PostUpdate　为所有已更新对象复位更新标志,如下　如果你扩充了pfc_Save处理以更新其它控件,扩充本事件复位更新标志

Pfc_Save返回值

Pfc_Save返回如下值 :

返回值含义注解

1成功

0没有未决的更新

-1 AcceptText错误 pfc_Save过程中断

-2错误在 pfc_UpdatesPending pfc_Save过程中断

-3合法性错误 pfc_Save过程中断

-4错误在 pfc_PreUpdate pfc_Save过程中断

-5错误在 pfc_BeginTran pfc_Save过程中断

-6错误在 pfc_Update 　pfc_EndTran和 pfc_DBError事件完成;

pfc_PostUpdate未被执行

-7错误在 pfc_EndTran pfc_PostUpdate未被执行

-8错误在 pfc_PostUpdate

-9错误在 pfc_UpdatePrep pfc_Save过程中断

添加代码扩充 pfc_Save事件

你能定制和扩充 pfc_Save过程.

例如,你能:

添加代码到 pfc_EndTran事件以提交或回滚事务

创建ue_Validation用户事件并编写代码，以在非PFC DataWindows执行合法性检验

扩充 pfc_Save过程以包含其它类型的窗口控件

添加代码到 pfc_EndTran事件:

加代码到 pfc_EndTran事件，检验ai_update_results参数并按需要为每个可以被更新事务对象提交或回滚改动:

Integer li_return IF ai_update_results = 1 THEN

li_return = SQLCA.of_Commit()

ELSE

li_return = SQLCA.of_Rollback()

END IF

IF li_return = 0 THEN

Return 1

ELSE

Return -1

END IF

启动自更新对象

默认的, DataWindows是唯一可更新的自更新对象

所有其它 (n_ds、u_lvs、u_tvs、u_tab,以及任何用户自定义的可视用户对象)是不可更新的，必须被显式地启动.

启动自更新对象:

1调用自更新对象的 of_SetUpdatable函数:

ids_data.of_SetUpdateable(TRUE) lv_1.of_SetUpdateable(TRUE) tv_1.of_SetUpdateable(TRUE)

2 (仅DataStores)添加 n_ds-based DataStore到将被更新的控件的列表中:

PowerObject lpo_objs[] Integer li_count // this = window

lpo_objs = this.control

li_count = UpperBound(lpo_objs)

lpo_objs[li_count + 1] = ids_data

this.of_SetUpdateObjects(lpo_objs)

启动一个单次更新

PFC允许你指定一组控件并一次更新它们.

执行一个单次更新:

1指定被更新的控件:

PowerObject lpo_objs[ ]

Integer li_return

lpo_objs[1] = lv_1

lpo_objs[2] = dw_1

lv_1.of_SetUpdateable(TRUE)

2通过调用 pfc_SaveObjects事件执行单次保存:

// this = window

li_return = this.Event

pfc_SaveObjects(lpo_objs)

// Check for return codes 1 to -8 ...

使用PFC菜单

PFC通过函数、菜单项以及在m_master事件中的代码来实现菜单服务.

M_master包含:

调用消息路由器的函数

通过使用消息路由器执行所需功能的菜单项

从扩充层菜单继承　当使用菜单时,总是从m_前缀的菜单继承(不从pfc_前缀的菜单继承).

当你升级 PFC版本时Pfc_前缀对象受改动的影响.

两个菜单继承策略

你能使用PFC的菜单或写你自己的.

使用PFC菜单

你的应用程序能使用 PFC菜单作为它的菜单的基础.

在大多数情况下,你使用m_master作为你的应用程序工作表窗口菜单的祖先并使用m_frame作为框架菜单.

你添加所有应用程序的工具栏项和菜单项到 m_master.

让工作表菜从 m_master单继承,并且按需要的启动和禁止菜单项.

在 m_frame按需要禁止工具栏项和菜单项.

创建你的自己菜单

选择性的,你能实现和m_master分开的你自己的定制菜单.

如果你这样做,考虑使用菜单服务 of_SendMessage菜单函数实现 PFC消息路由器功能.

扩充 PFC菜单

如果你使用 PFC菜单,你将需要修改它们或它们的子孙提供应用程序特定的处理.

当你添加新工具栏项和菜单项, PFC使用 PowerBuilder Shift Over/Down归因于控件在哪里菜单项被地方:

在本菜单 PowerBuilder插入新项

菜单栏位于工具和窗口

文件菜单在删除上方

编辑菜单在更新上方连接

查看菜单在标尺上方

工具菜单在定制上方工具栏

窗口菜单在撤消下面

帮助菜单在关于上方

为信息为完成有关信息 Shift高于/往下特性,看见 PowerBuilder使用手册 .

创造你的自己菜单

PFC菜单提供菜单项覆盖最事件在 PFC控件.

你的应用程序可能更多专用的要求那辩护创造菜单从头做起为使用和你的 PFC窗口.

创造菜单

使用菜单画板创建你的菜单.

加仅仅项必需的为你的应用程序,定义快捷键,加速键,并且工具栏位图作为需要.

创造扩充级如果你是对象管理人创造菜单为使用通过多重的开发者和应用程序,考虑创造祖先菜单 (和 PowerScript和 PFC代码)并且空的扩充级菜单为使用通过 d

通话窗口

取决于你的需要,你能使用或者你的自己菜单-窗口通信方法或 PFC消息路由器.

当使用消息路由器,它最好到使用菜单服务 of_SendMessage函数到调用事件在窗口.

每个菜单选项调用 of_SendMessage,通过事件的名字到调用.

例如,单击事件为编辑>剪切菜单选项调用 of_SendMessage如下:

n_cst_menu lnv_menu

lnv_menu.of_SendMessage(this, "pfc_Cut")

有二菜单项那要求专用的注意:

文件>退出调用应用程序管理器 pfc_Exit事件:

gnv_app.Event pfc_Exit()

MRU菜单项 (文件菜单)在调用前复制菜单选项正文到 Message.StringParm of_SendMessage:

n_cst_menu lnv_menu

Message.StringParm = this.Text

lnv_menu.of_SendMessage(this, "pfc_MRUClicked")

复制和粘贴你能保存时间通过复制和粘贴菜单选项手写体从 pfc_m_master.

启动地址项在窗口菜单

当窗口工作表管理器服务被启动, PFC菜单自动启动和禁止窗口菜单项作为适当的.

如果你在使用工作表管理器服务和想要那机能在你的菜单,复制代码从 pfc_m_master窗口菜单项选定的事件.

使用标准的菜单选项

M_master包含菜单项那调用用户事件在对应窗口.

使用菜单项如下:

如果菜单选项不适用于窗口制作它看不见的.

如果菜单选项应用到窗口评论 PowerScript代码在对应用户事件为联合的窗口, DataWindow,或可视的控件.

每 m_master菜单项触发某一个事件.

某些这样的用户事件空的;

你必须加适当的 PowerScript代码执行应用程序-专用的处理.

为信息如需要更多信息在 PFC用户事件,看见 PFC对象引用 .

文件菜单

菜单选项事件触发对象(s)包含用户事件

新建 pfc_New w_master

打开 pfc_Open u_rte, w_master

结束 pfc_Close w_master

保存 pfc_Save u_rte, w_master

保存为 pfc_SaveAs u_rte, w_master

打印 pfc_Print u_dw, u_rte, w_master

打印预览 pfc_PrintPreview u_dw, u_rte

页面设置 pfc_PageSetup u_dw, w_master

打印立即 pfc_PrintImmediate u_dw, u_rte, w_master

删除空的菜单选项加你的拥有事件或函数

属性空的菜单选项加你的拥有事件或函数

退出 pfc_exit N_cst_appmanager

编辑菜单

菜单选项事件触发对象(s)包含用户事件

撤消 pfc_Undo U_dw, u_em, u_mle, u_rte,并且 u_sle

剪切 pfc_Cut U_ddlb, u_ddplb, u_dw, u_em, u_mle, u_oc, u_rte,并且 u_sle

复制 pfc_Copy U_ddlb, u_ddplb, u_dw, u_em, u_mle, u_oc, u_rte,并且 u_sle

粘贴 pfc_Paste U_ddlb, u_ddplb, u_dw, u_em, u_mle, u_oc, u_rte,并且 u_sle

选择性粘贴 pfc_PasteSpecial U_oc

清除 pfc_Clear U_ddlb, u_ddplb, u_dw, u_em, u_mle, u_oc, u_rte,并且 u_sle

全部选定 pfc_SelectAll U_ddlb, u_ddplb, u_dw, u_em, u_mle, u_rte,并且 u_sle

查找 pfc_Find DlgU_dw和 u_rte

替换 pfc_ReplaceDlg U_dw和 u_rte

更新连接 pfc_UpdateLinks U_oc

对象>编辑 pfc_EditObject U_oc

对象>打开 pfc_OpenObject U_oc

查看菜单

菜单选项动作对象包含用户事件

标尺 pfc_Ruler U_dw和 u_rte

大图标空的菜单选项.

加逻辑到 u_lvs切换到大图标查看

小图标空的菜单选项加逻辑到 u_lvs切换到小的图标查看;

调用从本菜单选项

表格空的菜单选项加逻辑到 u_lvs切换到表格查看;

调用从本菜单选项

详细空的菜单选项加逻辑到 u_lvs切换到详述查看;

调用从本菜单选项

重排图标>通过空的菜单选项加逻辑到 u_lvs重排图标通过一些公用属性;

调用从本菜单选项

重排图标>自动排列空的菜单选项加逻辑到 u_lvs重排图标;

调用从本菜单选项

第一 pfc_FirstPage U_dw和 u_rte

下一个 pfc_NextPage U_dw和 u_rte

在pfc_PreviousPage之前 U_dw和 u_rte

上一 pfc_LastPage U_dw和 u_rte

分类 pfc_SortDlg U_dw

过滤器 pfc_FilterDlg U_dw

缩放 pfc_Zoom U_dw

插入菜单

菜单选项事件触发对象(s)包含用户事件

文件 pfc_InsertFile U_rte

PICT格式标准 pfc_InsertPicture U_rte

对象 pfc_InsertObject U_oc

工具菜单

菜单选项事件触发对象(s)包含用户事件

定制工具栏 pfc_Toolbars W_frame

窗口菜单

菜单选项动作对象包含用户事件

串联 pfc_Cascade W_frame

水平平铺 pfc_TileHorizontal W_frame

垂直排列 pfc_TileVertical W_frame

层 pfc_Layer W_frame

全部最小化窗口 pfc_MinimizeAll W_frame

撤消 pfc_UndoArrange W_frame

帮助菜单

菜单选项事件触发对象(s)包含用户事件

帮助主题 pfc_Help W_master

关于 of_About N_cst_appmanager

使用弹出菜单

PFC也提供弹出菜单为使用通过你的应用程序和 PFC服务:

弹出菜单它当显示如何禁止扩充容量

M_edit显示你按当右翼-鼠标器按钮高于下列之一可编辑的可视的控件:

U_ddlb U_ddplb U_em U_mle U_rte U_sle禁止本机能,放 ib_rmbmenu例子变量错误在控件的构造函数 eventYou能扩充 m_edit加应用程序-专用的右鼠标器按钮机能

M_dw显示你按当右翼 u_dw的鼠标器按钮 -基本 DataWindow禁止本机能,放 ib_rmbmenu例子变量错误在 u_dw构造函数事件你能扩充 m_dw加应用程序-专用的右

M_oc显示你按当右翼 u_oc的鼠标器按钮 -基本 OLE容器禁止本机能,放 ib_rmbmenu例子变量错误在 u_oc构造函数事件你能扩充 m_oc加应用程序-专用的装备

M_lvs显示你按当右翼 u_lvs的鼠标器按钮 -基本 ListView禁止本机能,放 ib_rmbmenu例子变量错误在 u_lvs构造函数事件你能扩充 m_lvs加应用程序-专用的righ

M_tvs显示你按当右翼 u_tvs的鼠标器按钮 -基本 TreeView禁止本机能,放 ib_rmbmenu例子变量错误在 u_tvs构造函数事件你能扩充 m_tvs加应用程序-专用的righ


第7章 PFC工具

关于本章

本章描述PFC工具和如何使用它们。

DataWindow属性窗口

DataWindow属性窗口允许你:

  • 选择允许和禁止 DataWindow服务

  • 查看选定服务的PFC语法

  • 交互式地访问和修改 DataWindow属性,包括:

DataWindow缓冲区

行和列状态

统计

DataWindow对象中所有对象的属性

DataWindow属性窗口属性页

DataWindow属性窗口有三个属性页:

  • Services 显示 DataWindow的服务列表。

选择一项服务并按需要点击Enable或Disable。点击Properties以显示当前选定服务的信息:

  • Buffers　点击鼠标器右键显示弹出菜单，允许你对行进行如下操作:

  • Status flags　按需要改变DataWindow状态标志。

单选框Assist Status Change允许你执行两状态变化成为一步:

服务对话框属性页

每个服务显示它拥有的一套属性页以显示它的属性。本例子显示排序服务的属性页：

  • General　显示选定服务的有关信息：

Syntax　显示用于选定服务的PFC语法：

用法

使用DataWindow属性窗口调试和测试你的应用程序和 DataWindow服务的用途。

显示DataWindow属性窗口：

1　由调用u_dw of_SetProperty函数允许DataWindow属性服务：

this.of_SetProperty(TRUE)

2　当显示DataWindow后，右击并选择 DataWindow Properties，以显示出DataWindow属性窗口。

SQL间谍

SQL间谍工具自动为DataWindows和EXEC IMMEDIATE语句捕获并保存SQL。

你能使用 SQL间谍显示和随意地修改 DataWindow的 SQL语句，并把本地SQL记入日志。

修改 SQL　如果你在使用 ODBC数据源,你必须将连接字符串中的DisableBind置为1。

SQL间谍将SQL语句记入日志文件，你能随意地在弹出窗口中显示。

用法

使用SQL间谍,你可以调用函数以启动间谍工具,指定日志文件,和控制 w_sqlspy窗口的显示。

你还能调用函数到将本地 SQL记入日志。

虽然你能从应用程序以内的任何地方调用SQL间谍功能，但一般说来，你应该在应用程序管理器的pfc_Open事件中初始化SQL间谍。

启动SQL间谍：

1　通过调用 n_cst_appmanager of_SetDebug函数启动调试服务：

this.of_SetDebug(TRUE)

2通过调用 n_cst_debug of_SetSQLSpy函数启动 SQL间谍:

this.inv_debug.of_SetSQLSpy(TRUE)

3 (可选项)通过调用 n_cst_sqlspy of_SetLogFile函数指定日志文件:

this.inv_debug.inv_sqlspy.of_SetLogFile &

("c:\PB6\adk\pfc\appdbug.log")

显示 w_sqlspy弹出窗口:

调用 n_cst_sqlspy of_OpenSQLSpy函数:

gnv_app.inv_debug.inv_sqlspy.of_OpenSQLSpy(TRUE)

w_sqlspy弹出窗口显示日志文件中最近记载的项目：

在DataWindow提交到数据库以前w_sqlspyinspect对话框允许你查看和随意地修改SQL语句。

显示 w_sqlspyinspect对话框:

调用 n_cst_sqlspy of_SetBatchMode(FALSE)函数:

gnv_app.inv_debug.inv_sqlspy.of_SetBatchMode &

(FALSE)

使用 对话框w_sqlspyinspect:

1更新数据库、插入、删除或修改行。对话框w_sqlinspect显示:

2检查SQL语句,随意修改数值。

3单击适当的命令按钮:

Step　更新当前的行并显示将被更新的下一行的信息

Resume　更新当前的行并更新所有剩余的行;

禁止SQL间谍检查功能

Cancel　不更新当前的行并显示将被更新的下一行

Cancel All　不更新所有剩余的行

手动地将SQL语句记入日志 :

使用n_cst_sqlspy of_SQLSyntax函数,把将被记入日志的 SQL语句传递给它：

String ls_sql ls_sql = "SELECT * FROM employee;"

gnv_app.inv_debug.inv_sqlspy.of_SQLSyntax &

("Native SQL", String(Now()) + ": " + &

String(Today()) + ": " + ls_sql)

安全性

PFC提供需要在应用程序中进行少量编码的数据库驱动的安全系统。

它允许你在安全数据库中记载如下信息：

窗口控制

DataWindow列

用户对象

菜单项

然后创建用户和组的真值表，控制这些项的访问权限。

在执行时，PFC按安全数据库中的记载选择允许、禁止或隐藏被保护的项。

PFC安全系统包括:

安全管理工具　允许你定义用户、组、被保护的项和用户访问权限。

安全扫描器　扫描用户自定义对象以搜所有集能被保护的项目的信息。

安全数据库包含有关用户、组、被保护的项目和用户对那些被保护项的访问权限的信息。

以本地数据库交付　PFC提供一个本地数据库以保存安全性信息。

无论如何，当你实施安全性时，你将想使用服务器数据库。

由异常提供安全性

PFC安全特性由异常提供。

默认地，安全系统使用对象的当前设置。

这意味着PFC仅修改安全数据库中明确指定的设置。

过程

安全管理工具是PowerBuilder应用程序，你用来：

定义用户和组

运行安全性扫描器

为对象和控件定义安全性

关联用户和组与对象和控件

在你的应用程序中，添加如下代码以实现安全性：

对象　添加代码

应用程序管理器　调用 n_cst_appmanager of_SetSecurity函数以启动安全性服务，n_cst_security

应用程序管理器或框架窗口　建立事务对象,连接到安全性数据库,并且调用 n_cst_security of_InitSecurity函数

of_InitSecurity函数允许你为用户设置缺省组。

如果用户没有设定为其它组，安全系统将使用缺省组。

要求安全性的窗口　在窗口Open事件中调用 of_SetSecurity函数

如需要有关在应用程序中实现安全性的更多信息，参看 "在应用程序中实现安全性" 。

定义用户和组

概述

要使用 PFC安全性,你必须定义用户和组。

用户可以是零个或多个组的成员;

用户设置总是优先于组设置。

用法

你使用安全管理工具定义用户和组，并关联用户和组。

运行安全管理工具

运行安全管理工具,启动 PowerBuilder,打开应用程序画板,在 pfc\security目录选择 PFCSECAD.PBL,将 PFC PBLs加到库列表,并运行应用程序。

如果连接到 PFC.DB数据库出现问题,检查 PFCSECAD.INI文件和你的工作站的 ODBC设置。

如果你已将PFC安全性表从PFC.DB移动到其它的数据库,你必须更新PFCSECAD.INI文件的Database段以使用正确的数据库连接参数。

定义用户:

1从菜单栏选择File>User/Groups。

User/Groups管理窗口显示：

2在Users列右击并选择Add Item。

Add User对话框显示:

3输入用户名和描述。

用户名必须符合应用程序在执行时能存取的用户ID。

4单击OK。

5按需要继续添加用户。

6从菜单栏File>Save。

定义组:

1在Groups列右击并选择Add Group。Add Group对话框显示：

2输入组名、描述和优先权。

零是最高的优先权;

无论如何,用户设置优先于组设置。

3单击OK。

4按需要继续添加组。

5从菜单栏选择File>Save。

关联用户和组:

拖放用户到组上。

从组中删除用户:

1在用户上右击并选择Delete Item。从组中删除用户对话框显示。

2单击OK。

3从菜单栏选择File>Save。

修改先前定义的用户或组:

1在项目上右击并选择Edit Item。编辑用户或编辑组对话框显示。

2按需要修改信息。

3单击OK。

4从菜单栏选择File>Save。

运行安全性扫描器

安全性扫描器在应用程序中检查所有窗口、数据窗口、菜单以及用户对象。

它保存如下信息到PFC数据库:

窗口

窗口控件

对于DataWindow控件，有关关联在DataWindow对象上的列信息

菜单项

用户对象和属性页控件;

收集有关定义在用户对象或属性页上所有控件的信息

用法

你能从PowerBuilder运行安全性扫描器或者创建安全性扫描器可执行版本并从安全管理工具中运行它。

从 PowerBuilder运行安全性扫描器:

1启动 PowerBuilder。

2打开应用程序画板。

3选择 PFCSECSC.PBL并选定pfcsecurity_scanner应用程序。

4运行应用程序。

如果在连接时遇到困难　如果连接到PFC.DB数据库出现问题,检查 PFCSECAD.INI文件和你的工作站的 ODBC设定。

创建安全性扫描器的可执行版本:

1复制 PFCAPSRV.PBL文件到安全性目录。

2打开应用程序画板。

3打开PFCSECSC.PBL并选择 pfcsecurity_scanner应用程序。

4关闭应用程序画板。

5打开 Project 画板。

6指定可执行文件名 (PFCSECSC.EXE)及资源文件名 (PFCSECSC.PBR)。

7从菜单栏选择 Design>Build Project。

单独的可执行文件　因为扫描器应用程序会复位它的库搜索路径,安全性扫描器必须被创建为没有PBDs的单独可执行文件。

8编译过程完成后,关闭Project画板。

9使可执行文件能被找到：

Windows 95和Windows NT　添加pfcsecsc.exe文件的目录 到AUTOEXEC.BAT的PATH语句中。

并确保路径中包含PowerBuilder执行时DLLs的目录 (如 PBVM60.DLL)

Windows 95和Windows NT

为 pfcsecsc.exe在HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\Current Version\App Paths添加项目。

本项目必须包含关键字Path(字符串)，值为包含 PowerBuilder运行时DLLs的目录

UNIX　将pfcsecsc.exe的目录添加到PATH环境变量中。

同时确保LD_LIBRARY_PATH环境变量包含 PowerBuilder执行时DLLs的目录。

从内部安全管理工具运行安全性扫描器:

1从菜单栏选择File>Scan Application。

选择应用程序对话框显示出定义在pb.ini文件Application段中的应用程序列表:

2选择被扫描的应用程序并单击Select。选择被扫描的对象对话框显示:

3按CTRL+单击或SHIFT+单击选择被扫描的对象。

选择对象 为了使安全性数据库最小,不要选择你不准备实施安全性的对象。

4单击Scan。

5当扫描完成,单击Exit。

定制启动了安全性的控件：

1从安全管理工具菜单栏中选择File>Templates。模板管理窗口显示出来:

2在你刚才扫描应用程序上双击。

一个窗口列表显示出来。

3在窗口之一上双击 。

一个控件列表显示出来:

4按需要修改描述。

在本窗口修改描述能在将用户和组与窗口、窗口控件以及菜单项关联起来时使一切显得更清楚明了。

5在你不准备实施安全性的项目上右击并选择Delete以删除该项。

删除没必要的项以减少安全性数据库的大小,从而提高性能。

6完成后,从菜单栏选择File>Save。

7在实施安全性的所有对象上继续本过程。

为用户和组定义安全性规则

运行扫描器记录了对象和控件并选择性地删除了不需要安全性的项目之后,你可以通过关联用户和组与对象和控件定义安全性规则。

用法

对于每个用户和组,你可以允许或禁止他们访问窗口控件、 DataWindow列、用户对象以及有关被保护的对象的菜单项。

用户可以属于零个或多个组。

用户设置总是优先于组设置。

如果没有用户设置,那么具有最高优先权的组设置将被使用 (0是最高优先权)。

为用户或组定义安全性规则:

1从菜单栏选择File>Users/Objects。

用户/对象管理窗口显示:

2点击用户下拉列表框并选择一个将要设置安全性的用户。

3双击包含被保护对象的应用程序。

4选择所有的单选按钮 (如果它尚未被选定)。

你现在已准备好去设置安全性项目了。

5对于被保护的项,使用状态下拉列表框指定Enable、Disabled、Invisible(不要设为不改变对象设置)。

6完成后,从菜单栏选择File>Save。

7继续设置该对象直到所有用户和组都设定完毕。

8继续设定其它对象。

在应用程序中实现安全性

一旦你定义了安全性数据库,那么在你的应用程序中启动安全性服务。

用法

在你的应用程序中启动安全性服务包括:

启动安全性服务

建立与包含安全性表的数据库的连接并与安全性服务进行通讯

在适当的窗口启动安全性服务

为应用程序启动安全性服务:

调用 n_cst_appmanager of_SetSecurity函数:

gnv_app.of_SetSecurity(TRUE)

建立与包含安全性表的数据库的连接并与安全性服务进行通讯:

1创建事务对象并连接到数据库 (本例子假定了一个自定义 n_cst_appmanager子孙的实例变量itr_security):

gnv_app.itr_security = CREATE n_tr

gnv_app.itr_security.of_Init &

(gnv_app.of_GetAppINIFile(), "Security")

gnv_app.itr_security.of_Connect()

安全性表布置　最小化你的应用程序与数据库的连接数目,把安全性表放置于应用程序数据库内。

2调用 n_cst_security of_InitSecurity函数:

Integer li_return

li_return = &

gnv_app.inv_security.of_InitSecurity &

(gnv_app.itr_security, "EISAPP", &

gnv_app.of_GetUserID(), "Default")

为窗口启动安全性:

在窗口的Open或 pfc_PreOpen事件中调用 n_cst_security of_SetSecurity函数:

gnv_app.inv_security.of_SetSecurity(this)

维护安全性数据库

PFC安全系统的表发布在本地数据库PFC.DB中。

PFC安全性表有:

Security_apps

Security_groups

Security_info

Security_template

Security_users

你能使用本地数据库 PFC.DB定义用户和组、扫描对象，并且定义存取权限。

无论如何,在发布应用程序前你将需要移动这些表到服务器数据库中。

PFC安全系统和安全性数据库为易于移动到服务器数据库作了设计:

所有数据库通过DataWindows与PFC安全性进行交互(没有嵌入SQL)

PFC安全系统强迫使用手动的级联删除

用法

将PFC安全性表移动至服务器数据库，为应用程序的所有用户启动安全性。

移动PFC安全性表至服务器数据库:

1使用数据管道画板移动表定义和数据到服务器数据库。

尽可能地保留表和列名。

2使用 DataWindow画板访问 PFC安全性 DataWindow。

注意下列情况:

保留 DataWindow的列的顺序和 DataWindow列名。

如果必要的话,使用选择画板更改联合的数据库表或列的名字以匹配那些在服务器数据库上的表或列。

记得不要更改 DataWindow的列名。

3在你的应用程序中,正确地为包含安全性表的服务器数据库设定事务对象。

库扩展器

你可以使用PFC库扩展器自动创建和设定位于二个已有层次(PFC祖先层和PFC扩展层)的中间扩展层。

例如,你可以使用库扩展器给PFC创建包含所有你公司扩展库的中间扩展层:

加入公司和部们的中间扩展层使得应用程序程序员能充分利用扩展层。

用法

库扩展器安装在 PFC工具目录。

参阅　完整的用法,请参见“库扩展器在线帮助”。

移植助手

移植助手扫描 PowerBuilder库 (PBLs)并且突出显示废弃的函数和事件。

废弃的函数和事件仍然工作在 PowerBuilder的当前的版本但是不可以工作于今后的版本。

如果你打算保正应用程序将来的运行,最好使用当前的语法和事件。

用法

移植助手被安装在 PowerBuilder目录。

参阅　完整的用法,参见“移植助手在线帮助”。


第8章 发布 PFC应用程序

关于本章

本段说明PFC应用程序发布的有关事项。

选择发布策略

你使用PFC建立产品化的应用程序。

和所有产品化的应用程序一样,发布PFC应用程序需要小心地规划和实施。

你的目标

你的发布策略必须提供用户工作站执行PFC应用程序所需要的全部文件：

应用程序可执行文件(EXE)

应用程序 PBDs或 DLLs (如果不使用单个EXE文件)

PFC PBDs或 DLLs (如果不使用单个 EXE文件)

PFC DLLs

你的应用程序使用的其它文件和项目（ActiveX控件、注册表项、INI文件、位图等等）

PowerBuilder执行模块（可能已经被安装在用户工作站上）

数据库客户端软件（可能已经被安装在用户工作站上）

四个发布选项

PFC应用程序与其它PowerBuilder应用程序一样具有四个发布选项。

在选择发布策略前你需要考虑每个选项的优缺点在哪儿：

实际文件发行

如果你的应用程序应用Pcode PBDs或已编译的DLLs，它们通常需要为每份发布的PFC应用程序做成一个文件集。

这是因为内部存在从高级扩充对象往下延伸的相互依赖关系，比如 w_master、n_cst_dwsrv、n_cst_winsrv和n_cst_dssrv。

参阅　“设置应用程序管理器”。.

使用公用的实际文件集

如果发布的应用程序没有改变PFC祖先层或PFC扩充层，应用程序能共享PBD或DLL文件。

所以为了便于维护和升级，最好为发布的应用程序提供提供一套PBD和DLL文件集。

使用PFC DLLs

如果你的应用程序提供打印能力或明确地使用文件或系统服务,你将需要发布一个或多个PFC DLLs：

每个平台专用模块：

平台模块(s)使用 32-位 Windows PFCCOM32.DLL 16-位 Windows PFCCOMM.DLL PFCFILSRV.DLL Macintosh PFCMACPLATFORMSRV.LIB UNIX不平台-专用的模块用 PBR文件 PFC运和六 PBR文件:

使用PBR文件

PFC包括六个PBR文件：

一个当位图放置于EXE文件内时被使用

另五个当发布PBDs或DLLs被使用，这些文件如下：

Deployment方法 PBR文件(s)使用什么发生你展开当和 PBR什么发生你展开当 没有 PBR把位图放置于单 EXE内 Pfc.pbr(This PBR包含动态的 conversion数据变换窗户参考)位图和 dynamically referen

发布数据库表

PFC包括数据库PFC.DB。

表引用

虽然没有PFC服务直接引用PFC.DB，但有几个最初包括在PFC.DB中的服务需要引用表：

PFC服务表参考出错信息服务 (n_cst_error)消息安全性服务 (n_cst_security) Security_appsSecurity_groupingsSecurity_infoSecurity_templateSecurity_users做什么最小化数据库的数 connectio

做什么

为了使你的应用程序与数据库PFC.DB的连接数最少，通常最好将这些表移动到应用程序数据库.

无论如何,你的应用程序发布策略必须为用户使用者提供应用程序必需的对所有数据库表的访问。

这包含安装客户软件、更新INI文件、更新注册表项等等，以及其它在应用程序技术中讨论数据库发布数据库发布考虑概要在。

发布 PFC对话框帮助 PFC包含 PFCDLG.HLP文件,哪一个包含在线帮助为 PFC对话箱.

如果你的应用程序使用 PFC对话箱 (比如 w_find, w_replace,并且 w_sortdragdrop)你应该展开 PFCDLG.HLP如此用户使用者将有对话框帮助.

PFC也包含 PFCDLG.RTF,哪一个包含原文为 PFC对话框帮助.

如果你的应用程序制作 PFC的专用的使用对话箱,你能修改这文件和 recompile帮助文件.

16-位 Windows deployment如果你是发布应用程序在 16-位 Windows,重命令 PFCDLG16.HLP到 PFCDLG.HLP和展开这文件.