PFC是什么?
Powerbuilder Foundation Class
PFC就是Sybase公司给我们做好的混凝土预制件(即扩展的对象),我们可以拿来用,这些对象具有新的功能,使我们在开发过程中事半功倍。
样例在以下环境通过:
1. 服务器: Windows 2000 Server
2. 客户端: Windows 2000 Professtion
3. 网络: 100兆以太网
4. 数据库系统: MS SQL Server 2000
5. 数据库: pubs
6. 工具: Powerbuilder 8.0.3 9704
7. 联接: 直接联接
安装PFC:
如果没有安装PFC,则要自定义安装
(图 1)
![PFC 图解 - limindo - 风雨无阻](http://img691.ph.126.net/NQd_mjOzHHrIJSJkrsGcsA==/2832201215663971252.bmp)
![PFC 图解 - limindo - 风雨无阻](http://img389.ph.126.net/EvvT-3zbrXFCMHjhbf1Y7g==/1052997887875778581.jpg)
(图2)
如图1,图2的高亮度选择,将PFC安装到系统中。
![PFC 图解 - limindo - 风雨无阻](http://img694.ph.126.net/srZZImdzrGkrqqx73T48Vg==/2861756088218498395.jpg)
(图3)
这样将会在系统的安装路径下面看到PFC文件夹。如图3
在PFC文件夹里面有11个.pbl文件,我们将用到其中的10个文件,pfcapp.pbl不用。
如表一
pfcapsrv.pbl |
|
|
pfcdwsrv.pbl |
|
|
pfcmain.pbl |
|
|
pfcutil.pbl |
|
|
pfcwnsrv.pbl |
|
|
pfepsrv.pbl |
|
|
pfedwsrv.pbl |
|
|
pfemain.pbl |
|
|
pfeutil.pbl |
|
|
pfewnsrv.pbl |
|
|
为了使用方便,可以将这10个文件拷贝到待开发的程序文件夹下面。例如:D:\study
其中的5个PFC开头的文件是PFC的基础层类库,而PFE开头的5个文件是PFC的扩展层,PFE文件在使用中不是必需的,但是考虑到今后的升级,强烈建议使用PFE文件,如果需要对PFC进行扩展或对属性进行修改,也要在PFE文件库中进行。
搭建PFC应用程序框架:
![PFC 图解 - limindo - 风雨无阻](http://img.ph.126.net/woLIV8vWQ-LsJ_7w3XRgkg==/3365877771507265740.jpg)
(图4)
我们从一个实际应用开始详细的介绍PFC程序的开发,首先我们建立一个工作空间(workspace),名字叫study。如图4
![PFC 图解 - limindo - 风雨无阻](http://img846.ph.126.net/WhWrgoTi_pYdJdcrKSf2kw==/752382612749753832.jpg)
(图5)
建立一个目标名为study,选中第二项,即模板项。如图5
![PFC 图解 - limindo - 风雨无阻](http://img618.ph.126.net/7wdECfv8ytPlWEnmSY27AA==/1695605259707204258.jpg)
(图6)
![PFC 图解 - limindo - 风雨无阻](http://img237.ph.126.net/_hhy0638h0NcWquplcdBHg==/1375568211186696651.jpg)
(图7)
![PFC 图解 - limindo - 风雨无阻](http://img238.ph.126.net/oHkoS3-6fBR3uqtl8dRdMw==/2226185590806245481.jpg)
(图8)
![PFC 图解 - limindo - 风雨无阻](http://img762.ph.126.net/Qa9gsHL8Qsi_07ZG2fEQiw==/4938478466388649960.jpg)
(图9)
这里是关键,一定要选择第三项。如图9
![PFC 图解 - limindo - 风雨无阻](http://img624.ph.126.net/uC6SOZPyE-NP3eDHcM202g==/3016004375456621409.jpg)
(图10)
将PFC的10个类库加进去。
![PFC 图解 - limindo - 风雨无阻](http://img851.ph.126.net/g0vl4NloKaITMHxMYHMO9w==/586030901512566571.jpg)
(图11)
![PFC 图解 - limindo - 风雨无阻](http://img846.ph.126.net/vDtr-aWbDIL3LBhUJq2H3A==/745345738331614620.jpg)
(图12)
![PFC 图解 - limindo - 风雨无阻](http://img611.ph.126.net/w0qneCkPTIl0wTTjMI8gMQ==/1920785241075422938.jpg)
(图13)
PFC的基本框架就搭建起来了,这里就是我们PFC的家。如图13
但是这只是一个框架,还不能运行,我们还要做一些工作才可以。
![PFC 图解 - limindo - 风雨无阻](http://img838.ph.126.net/pApg75_DE3aiQpCDu-Z6Uw==/1787366102114613759.jpg)
(图14)
![PFC 图解 - limindo - 风雨无阻](http://img764.ph.126.net/KTZ4hsgh7t69brUQZ9tyFQ==/2972657229042560847.jpg)
(图15)
从pfemain.pbl库文件中继承窗口名字叫w_frame_app,继承对象为w_frame,(也可以直接使用w_frame窗口),如图14、图15
![PFC 图解 - limindo - 风雨无阻](http://img161.ph.126.net/XpYZmg4AxZHxxV9gaQThRw==/1444811055457839897.jpg)
(图16)
![PFC 图解 - limindo - 风雨无阻](http://img615.ph.126.net/pyb0S_oLV66LIGZtVj2wPw==/1931199815213827429.jpg)
(图17)
从pfeapsrv.pbl库文件中继承用户对象名字叫u_cst_appmanager,继承对象为n_cst_appmanager,(也可以直接使用n_cst_appmanager),并且在u_cst_appmanager的pfc_open事件中添加脚本:
open(w_frame_app)
如图16、图17
![PFC 图解 - limindo - 风雨无阻](http://img.ph.126.net/4By6d3ad24RJOkA50KqSLQ==/3396277068992049146.jpg)
(图18)
![PFC 图解 - limindo - 风雨无阻](http://img1.ph.126.net/9MOmbzwnuAS7paDMsaXCEA==/3189955911063949826.jpg)
(图19)
打开应用程序对象,将全局变量定义中的n_cst_appmanager改为u_cst_appmanager。
将open事件中脚本的n_cst_appmanager改为:
u_cst_appmanager
如图19
![PFC 图解 - limindo - 风雨无阻](http://img852.ph.126.net/U8_4_apzz0bbnkxjBlcfSA==/598415800487901432.jpg)
(图20)
这个时候,程序就可以运行了。如图20
![PFC 图解 - limindo - 风雨无阻](http://img96.ph.126.net/LtSedI0Qax78wQ9UfUUtRQ==/728457239729301951.jpg)
(图21)
![PFC 图解 - limindo - 风雨无阻](http://img.ph.126.net/op6XVLHFiw_75pmcZRUArw==/3369818421181132888.jpg)
(图22)
好像标题栏缺少点什么?不要着急,u_cst_appmanager对象的constructor事件中写脚本:
iapp_object.DisplayName="PFC 应用程序"
引号里面的内容,各位自便。iapp_object.DisplayName是应用对象(application)的一个属性,PFC在运行的时将这个属性带进窗口的title属性。如图21、图22
![PFC 图解 - limindo - 风雨无阻](http://img846.ph.126.net/PsSzGk-nMnIXbipIebzU-g==/746190163261885151.jpg)
(图23)
从pfemain.pbl库文件中继承窗口对象名字叫w_sheet_authors,继承对象为w_sheet,(也可以直接使用w_sheet)。如图23
![PFC 图解 - limindo - 风雨无阻](http://img842.ph.126.net/2Qof1ICTbMN8Et2y3p7csg==/1865616145640431690.jpg)
(图24)
![PFC 图解 - limindo - 风雨无阻](http://img165.ph.126.net/NgxGSokveDdM2KwI_ntIfQ==/2261088487918785028.jpg)
(图25)
使用我们自己的菜单,从pfewnsrv.pbl库文件中继承菜单对象名字叫m_frame_app,继承对象为m_frame,(也可以直接使用m_frame)。在菜单的基本数据项的clicked事件下写脚本:
message.stringparm = 'w_sheet_authors'
of_sendmessage('pfc_open')
如图24、图25
![PFC 图解 - limindo - 风雨无阻](http://img849.ph.126.net/-lORXHJ912Dazhakaaa5Tw==/564075853329204242.jpg)
(图26)
将窗口w_frame_app的菜单指定为m_frame_app。在窗口的pfc_open事件下面写脚本:
string ls_sheet
w_sheet lw_sheet
ls_sheet = message.stringparm
opensheet(lw_sheet,ls_sheet,this,0,original!)
如图26
![PFC 图解 - limindo - 风雨无阻](http://img853.ph.126.net/6O6D-UmdWdvCf-HJOWe_3w==/609956274533047418.jpg)
(图27)
运行后的结果。如图27
到此为止,我们开始近距离接触PFC了。脚本:
message.stringparm = 'w_sheet_authors'
of_sendmessage('pfc_open')
就是利用了PFC的消息路由器将菜单m_frame_app的指令传给了窗口w_frame_app,在传递过程中指明了一个字符串和一个事件,例子中就是传递了w_sheet_authors字符串,指明调用w_frame_app窗口的pfc_open事件。
如果所调用的事件没有参数,则直接使用of_sendmessage('事件名')
数据库联接:
![PFC 图解 - limindo - 风雨无阻](http://img.ph.126.net/wbmF0vqcQmlqGjzo_JaLwg==/3374884970761923306.jpg)
(图28)
PFC有个登录窗口,在pfe_apsrv.pbl库中,名为w_logon,我们在u_cst_appmanager的pfc_open事件添加脚本:
if of_logonDLG() <> 1 then halt close
这时候我们运行程序,就会弹出登录对话框。但是这个对话框只能接收用户提供的登录名和口令,更多的连接信息要在要在u_cst_appmanager的pfc_logon事件中完成。
![PFC 图解 - limindo - 风雨无阻](http://img306.ph.126.net/bVxOvRcZ21weUr7OBGGURQ==/3856207180936597768.jpg)
(图29)
我们在u_cst_appmanager的pfc_logon事件中添加脚本:
integer li_rc
SQLCA.DBMS = "MSS Microsoft SQL Server"
SQLCA.Database = "pubs"
SQLCA.LogPass = as_password
SQLCA.ServerName = "127.0.0.1"
SQLCA.LogId = as_userid
SQLCA.AutoCommit = False
SQLCA.DBParm = ""
li_rc = SQLCA.of_connect()
if li_rc = 0 then return 1
return li_rc
如图29
这样就可以连接到数据库上了。
![PFC 图解 - limindo - 风雨无阻](http://img847.ph.126.net/yUUBizXD2MZmmdeZXPIkOg==/763078661864714707.jpg)
(图30)
其中登录窗口w_logon有个ii_logonattempts实例变量,缺省值为1。我们可以更改变量ii_logonattempts的值,来确定错误登录次数。如图30
![PFC 图解 - limindo - 风雨无阻](http://img540.ph.126.net/ZhqvSfhKRjNewxFHPAZefA==/2689211927494836040.jpg)
(图31)
但是这样后有一些不足,就是联接信息不能更改,所以我们要引入ini文件或注册表来更改和保存保存联接信息。在u_cst_appmanager的is_userinifile变量里面指定ini文件,要确保当前目录下有一个setup.ini文件,名字一定要保持一致(不一定是setup.ini)。如图31
pfc默认的是在注册表中取联接信息并在联接成功后将连接信息写回到注册表中。下面是u_cst_appmanager的of_logondlg函数关于写回联接信息的脚本(是pfc的脚本,不是我们要添加的脚本):
lnv_logonattrib = message.powerobjectparm
if Len (lnv_logonattrib.is_userid) > 0 then
if of_IsRegistryAvailable() then
RegistrySet (is_userkey + "\logon", "userid", lnv_logonattrib.is_userid)
else
SetProfileString (is_userinifile, "logon", "userid", lnv_logonattrib.is_userid)
end if
of_SetUserID (lnv_logonattrib.is_userid)
end if
return lnv_logonattrib.ii_rc
其中is_userinifile就是我们指定的ini文件名。
我们在这里主要介绍以ini文件的方式读取和保存联接信息的方法。
![PFC 图解 - limindo - 风雨无阻](http://img128.ph.126.net/LTgDeRJhSG1Ss9ONKEEQ9w==/1617073741204307046.jpg)
(图32)
在u_cst_appmanager的of_isregistryavaliable函数下面添加脚本:
Return False
如图32
因为pfc应用在windows操作系统环境中是使用注册表来读取和保存信息,Return False脚本将应用改为使用ini文件来读取和保存信息。
![PFC 图解 - limindo - 风雨无阻](http://img540.ph.126.net/sw4uk6LdPz6UivodDbh8lA==/110056715895095058.jpg)
(图33)
在setup.ini文件里面添加脚本:
[logon]
DBMS = "MSS Microsoft SQL Server"
Database = "pubs"
UserID = sa
LogPass =
ServerName = "127.0.0.1"
AutoCommit = False
DBParm = ""
如图33
![PFC 图解 - limindo - 风雨无阻](http://img245.ph.126.net/e3FEUVUCL8w1EBlORVgMnw==/1385701310348320675.jpg)
(图34)
我们将u_cst_appmanager的pfc_logon事件脚本替换成下面的脚本:
integer li_rc
SQLCA.DBMS = ProfileString (is_userinifile, "logon","DBMS", "")
SQLCA.Database = ProfileString (is_userinifile, "logon","Database", "")
SQLCA.ServerName = ProfileString (is_userinifile, "logon","ServerName", "")
SQLCA.DBParm = ProfileString (is_userinifile, "logon","DBParm", "")
SQLCA.LogId = as_userid
SQLCA.LogPass = as_password
SQLCA.AutoCommit = false
li_rc = SQLCA.of_connect()
if li_rc = 0 then return 1
return li_rc
如图34
这样我们就可以通过更改setup.ini文件来实现不同的连接。
![PFC 图解 - limindo - 风雨无阻](http://img161.ph.126.net/KYTBPX0eTG9pua1ppjrW5A==/1440870405783459854.jpg)
(图35)
如果要用注册表读取或保存信息,则要在is_userkey变量指明注册表项。如图35
需要特别说明的是,u_cst_appmanager的pfc_prelogondlg事件在setup.ini文件中或在用户指定的注册表项中未能得到userid时,则会调用API函数在操作系统注册表中读取操作系统的登录名。