总结以前的失败教训,这次我根本就不看源代码,避免“见树不见林”的感觉。我从Online Help开始着,先阅读PFC的相关介绍,形成对PFC架构的雏形概念。
PFC其实分2大层,pfc层是源代码所在地,是Sybase发布的不允许用户修改的基础层;pfe是扩展层,所有对象都从pfc层继承过来,里面没有任何代码。基于这种情况,Sybase强烈要求用户不要修改pfc层的任何代码,因为Sybase升级PFC时,再次修改新版pfc就是一件高代价高风险的操作;PFC架构决定了程序员必须修改pfc代码,因此只能修改pfe层,pfc的升级对pfe的修改没有任何影响。
今天,我抓住要点,从Sybase提供的简单例子切入PFC的学习。效果出来了,我马上意识到n_cst_appmanager的重要性,于是我连夜看了这个object的帮助文档。成果如下:
应用程序不直接修改n_cst_appmanager,而是继承这个对象(以下讲的n_cst_appmanager函数、事件指的是它的后代,以n_cst_appmain为例子)。应用程序开始方法如下:(先不考虑完整性,目的是抓住重点)
(1)在Application的open事件加入标准代码,不需要理会以下代码的作用。
gnv_app = create n_cst_appmain
gnv_app.Event pfc_open(commandline)
只需要理会一点:应用程序需要n_cst_appmanager(这里是n_cst_appmain)管理本应用的外部属性(版权、INI文件路径、Logo等信息),这些属性会在splash窗口和About窗口等地方显示。
(2)先撇开INI、Logo等次要信息,我们需要立即运行应用。n_cst_appmain被创建之后,PFC自动调用该object的pfc_open事件。这里就是所有程序开始的地方,类似没有PFC情况下在Application的open事件写代码。
(3)是时候要为应用运行写代码了,首先要创建一个窗口,不用New,而是Inherit一个框架窗口w_frame。使用PFC框架编程基本上都是继承创建的。我们不需要写任何代码,直接保存命名为w_app_frame。然后在n_cst_appmain的pfc_open事件直接写入: open(w_app_frame)
(4)保存所有对象运行应用。。。。一切就这样开始了!!!!
应用是运行了,也正常关闭,但下一步就不会用了,所以只能依靠Online Help。首先我瞄准了n_cst_appmanager,对这个object的Attribute、Function、Event、Instance Variable进行通编浏览。心得如下:
(1)n_cst_appmanager的祖先是pfc_n_base,原来它是PFC所有custom class user object的祖先类。细节先不管,知道就行。
(2)阅读它的Instance Variable。在OO领域,核心就在Data,大部分Function是围绕这些Variable展开的。所以看Instance Variable就可以大概明白这个Object的用途。内容很多,什么n_cst_apppreference、n_cst_error、n_cst_security、w_frame等!!打住,不要陷入细节。粗略看了各变量描述,大致明白n_cst_appmanager只是一个容器,里面藏着N个服务对象的“指针”,包括本应用的环境属性。到此为止!!!
(3)阅读它的Function。果然我猜对了,大部分是Get和Set函数,不需要理会。关注以下特别函数:
of_About: 显示About窗口的。(这个窗口在哪里,逻辑怎样等细节,不需要理会)。里面提到应用主窗口(w_app_frame,幸好从w_frame继承过来)的菜单Help->About使用这个函数。操作一次果然如此,潜意识要我打开窗口w_about观摩庐山真面目。一打开其实也没有什么,只是有一种灵感突然闪了出来:里面的信息(版权、Logo、版本等)是否与n_cst_appmanagere的Instance Variable相关联。在n_cst_appmain的Constructor事件加入以下代码:
of_SetCopyright("Hello copyright")
of_SetVersion("Hello version")
重新运行应用,打开Help->About,果然在About窗口出现了以上设定的信息。(到现在还不知道About窗口在哪!)
of_Splash:Displays the w_splash window for the specified number of seconds. 根据例程,我在n_cst_appmain的pfc_open事件该为如下代码:
of_Splash(1)
open(w_app_frame)
重新运行应用,在w_app_frame之前出现的一个Splash窗口,时长大概1秒,里面包含了之前设定的版权、版本信息。真是一脉相连。(到现在还不知道Splash窗口在哪!)
--- 困了累了,不喝红牛,还是睡觉吧。
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/damsonli/archive/2006/11/30/1421743.aspx
回忆了昨天的PFC学习过程,发现在最后的阶段关于of_about、of_splash的研究,感觉有点偏离方向了,这不重要的东西干嘛花时间看它呢?今天决定要纠正。
继续昨天的自学历程。
n_cst_appmanager最后一个Function是很重要的,决心深入研究。它就是
of_logonDlg:Displays the w_logon dialog box and then calls the pfc_Logon event, allowing you to log the user on to the database.
“登陆”是企业软件所必需的功能,涉及权限分配问题。在这里,我不想把Database关联起来,只想掌握处理机制。
通常of_logonDlg是在n_cst_appmanager的事件pfc_open被调用,代码如下:
choose case this.of_LogonDlg()
case SUCCESS // 1
// 登陆成功
case NO_ACTION //0
// 用户点击cancel按钮
case else // -1
// 用户不存在或者密码错误
end choose
of_splash(1)
open(w_app_frame)
弹出w_logon窗口(不知道什么东西,反正是让用户输入用户名和密码),用户点击OK或者Cancel按钮之后,PFC触发nst_appmanager的事件pfc_logon,真正的登陆逻辑就在这个事件里编写了。
接下来应该是对数据库连接进行学习了,以MSSQL为例子。幸好以前有累积,我马上把注意力集中到n_tr这个object。
n_tr: Transaction object for use with all PFC applications. You can use this object as is, or create DBMS- or application-specific descendants that include customized or extended functionality.
N_tr includes integration with the SQL Spy debugging service.
从理解上,n_tr是对诸如commit;rollback;connect等statement进行了封装,并加强了事务管理。因为它的祖先类是Transaction,与SQLCA一样。本质上,n_tr的实例变量用于替换默认全局事务变量SQLCA.(如果对Transaction不熟悉,请参考Online Help)。
注意一点,使用n_tr不用担心disconnect问题,n_tr的destructor事件会自动释放资源,类似JAVA的垃圾回收,具体描述如下:If the instance is still connected to a database, this event commits or rolls back the transaction, depending on the ib_autorollback instance variable. It then disconnects the transaction. This event's functionality is meant to ensure efficient use of system resources. However, it's best to commit, rollback, and disconnect explicitly using this object's of_Commit, of_Rollback, and of_Disconnect functions.
接下来阅读本object的函数,比较多,看起来有点晕!所以我决定找一个例子看。最好的方法是使用Debug。
以下是增加一个MSS数据库连接的做法(前提是MSS数据库已经配置正确)
第一步:n_tr被实例化为一个Global变量,替换SQLCA。代码加入Global Variable 列表:
/* Application Manager */
n_cst_appmanager gnv_app
// The main window
w_app_frame gw_frame
// Application Transaction
n_tr gn_sqlca
第二步:在n_cst_appmanager实例的constructor事件加入ini文件注册,代码如下(粗体是新增内容)
this.of_SetVersion("Hello version")
this.of_SetCopyright("Hello copyright")
this.of_SetFrame(w_app_frame)
this.of_SetAppIniFile("d:\damson\programs\pfc_test\genapp.ini")
第三步:genapp.ini文件如下(注意,数据项名称必须与Transaction的属性名相同,不区分大小写)
[Database]
BMS=MSS
ServerName=(local)
Database=tsecure
LogID=tsecure
LogPassword=tsecure
AutoCommit=False
DBParm =
第四步:在n_cst_appmanager实例的pfc_open事件进行数据库连接,代码修改如下:
Long ll_return // Return value of a function or others
gn_sqlca = create n_tr // Do no warry about Destory
ll_return = gn_sqlca.of_init ( gnv_app.of_getAppIniFile(), "Database" )
if ll_return <> SUCCESS then
Messagebox("error","Error to initial sqlca!")
this.Event pfc_exit()
end if
ll_return = gn_sqlca.of_connect()
if ll_return <> 0 then
Messagebox("error","Error to connect db!")
this.Event pfc_exit()
end if
choose case this.of_LogonDlg()
case SUCCESS // 1
// 登陆成功
case NO_ACTION //0
// 用户点击cancel按钮
case else // -1
// 用户不存在或者密码错误
end choose
of_splash(1)
open(w_app_frame)
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/damsonli/archive/2006/12/04/1429209.aspx