PFC入门
數(shù)據(jù)庫快速開發(fā)工具 PowerBuilder 從5.0版本開始提供了一套基礎(chǔ)類庫PFC(PowerBuilder Foundation Class),使得應用程序的開發(fā)速度又提高了一大步。由于PFC使用的不是很廣泛,許多開發(fā)者對此還不是很了解。下面就我使用的過程中所得到的心得與遇到的問題,整理出來與大家共享與探討。各位覺得有不合適的地方,希望批評指正。
PFC的幫助對各個獨立服務(wù)、事件或者函數(shù)有一些實例代碼,但是對于整體的使用幾乎沒有很全面地介紹。因此,我寫這些東西,作為PFC幫助的一個輔助材料,大部分是在PFC幫助上沒有的內(nèi)容,是我使用PFC的過程中的總結(jié)與歸納。
PFC入門
首先,介紹一下如何創(chuàng)建一個簡單的PFC應用程序。
構(gòu)造一個簡單的PFC程序框架
使用PFC,我們得先學會使用PFC構(gòu)造一個簡單的應用程序。我們可以根據(jù)PFC幫助提供的模式來構(gòu)造我們的應用程序框架(參見PFC幫助的Overview 中的 For a quick start項),也可以查看PFC例程(Peat、Example等)仿造構(gòu)造我們的應用程序。下面簡單的陳述一下我通常使用PFC構(gòu)造應用程序的步驟:
設(shè)置n_mdl_app的相關(guān)事件的代碼,可參見PFC例程的程序代碼;
- 在Additional Properties中,更改Variable Types 頁中的3個變量(SQLCA->n_tr; Error->n_err; Message->n_msg)(參考PFC例程Peat)
- 根據(jù)需要更改默認字體的類型及大小(由于我們開發(fā)的都是中文界面的應用程序,所有字體更改為“宋體 9pt”),根據(jù)需要更改應用程序的圖標;
- 根據(jù)需要更改其他的屬性,比如:DisplayName, MicroHelpDefault, 等等;
- 另外,我還需要更改應用對象的SystemError事件的代碼,我使用的是逄新利編寫的一個錯誤陷阱模塊。
好了,到此為止,一個PFC應用程序框架就完成了。試著運行一下,可以看到框架窗口的運行狀態(tài)。
添加一個工作區(qū)窗口
應用程序框架窗口實現(xiàn)出來了,為了能夠工作,我們還得有工作區(qū)窗口(Sheet)。
首相,隨便創(chuàng)建一個Grid型的數(shù)據(jù)窗口對象,保存為d_demo1。然后從w_sheet窗口繼承出來一個窗口對象,然后在這個窗口中放置一個用戶對象u_dw(數(shù)據(jù)窗口的基礎(chǔ)祖先對象)。該數(shù)據(jù)窗口控件的數(shù)據(jù)對象為剛才創(chuàng)建的數(shù)據(jù)窗口對象d_demo1。
在窗口的Open事件中編寫如下代碼:
// 開啟Resize服務(wù)
this.of_SetResize(True)
//設(shè)置Resize服務(wù)的原始大小
this.inv_Resize.of_SetOrigsize( dw_Demo.Width + dw_Demo.X * 2, dw_Demo.Height + dw_Demo.Y * 2 )
//注冊要實施Resize服務(wù)的控件及方法
this.inv_Resize.of_Register(dw_Demo,this.inv_Resize.SCALERIGHTBOTTOM)
//異步觸發(fā)事件,利用消息路由發(fā)送消息。該消息是要檢索數(shù)據(jù)
this.Event Post pfc_MessageRouter('pfc_Retrieve')
在數(shù)據(jù)窗口控件的Constructor事件中編寫如下代碼:
this.of_SetTransObject(SQLCA)??????? // 設(shè)置事物對象
this.of_SetBase(True)??????? // 開啟數(shù)據(jù)窗口基本服務(wù)
this.of_SetPrintPreView(True)??????? // 打印預覽服務(wù)
this.of_SetRowManager(True)??????? // 行管理服務(wù)
this.of_SetRowSelect(True)??????? // 行選擇服務(wù)
this.of_SetFind(True)??????? // 查找服務(wù)
this.of_SetSort(True)??????? // 排序服務(wù)
this.of_SetFilter(True)??????? // 篩選服務(wù)
this.inv_RowSelect.of_SetStyle(this.inv_RowSelect.EXTENDED)??????? // 設(shè)置行選擇服務(wù)為高級選擇模式,支持Ctrl & Shift鍵
this.inv_Sort.of_SetStyle(this.inv_Sort.DROPDOWNLISTBOX)??????? // 設(shè)置排序服務(wù)的對話框樣式
this.inv_Filter.of_SetStyle(this.inv_Filter.SIMPLE)??????? // 設(shè)置篩選服務(wù)的對話框樣式
this.inv_Sort.of_SetColumnDisplayNameStyle(this.inv_Sort.HEADER)??????? // 設(shè)置排序服務(wù)的顯示內(nèi)容
this.inv_Filter.of_SetColumnDisplayNameStyle(this.inv_Filter.HEADER)??????? // 設(shè)置篩選服務(wù)的顯示內(nèi)容
在數(shù)據(jù)窗口控件的pfc_Retrieve事件中編寫如下代碼:
Return this.Retrieve()
如果該窗口需要保存數(shù)據(jù),在窗口的pfc_EndTrans事件中編寫如下代碼:
Integer li_TransRtn
If ai_Update_Results = 1 Then
?? // 如果更新數(shù)據(jù)庫成功, 則提交事務(wù)
?? li_TransRtn = SQLCA.Of_Commit()
Else
?? // 否則, 回滾事務(wù),并提示信息
?? li_TransRtn = SQLCA.Of_Rollback()
?? of_Messagebox('Update DB Failed','提示','數(shù)據(jù)保存失敗。',Exclamation!,OK!,1)
End If
// 返回該事件發(fā)生的情況 SUCCESS & FAILURE 是w_master的實例變量
If li_TransRtn = 0 Then
?? Return SUCCESS
Else
?? Return FAILURE
End If
如果該窗口的數(shù)據(jù)不需要保存,則要將數(shù)據(jù)窗口控件的ib_UpdateAble屬性選擇為False,這樣在更改了數(shù)據(jù)以后,關(guān)閉窗口是不會提示類似于“數(shù)據(jù)以更改,是否保存”等的信息了。
將該窗口命名保存為w_Demo1。
在應用程序的主菜單上添加一個項目,編寫該項目的Clicked事件代碼為:
Message.StringParm = 'w_demo'
of_SendMessage('pfc_open')
好了,運行應用程序,看一下運行的效果吧。你可以查看以下的效果:
- 使用鼠標右鍵單擊數(shù)據(jù)窗口,查看數(shù)據(jù)窗口的右鍵菜單;
- 刪除一條數(shù)據(jù),然后右鍵單擊數(shù)據(jù)窗口,選擇“Restore”項,看一看恢復刪除的功能;
- 點擊窗口菜單上的“Sort”、“Filter”、“Print Preview”,“Find”,“Replace”等菜單項,查看數(shù)據(jù)窗口的“排序”、“篩選”、“打印預覽”,“查找”,“替換”等的功能;
- 點擊菜單[View]的[First/Prior/Next/Last]等菜單項,查看數(shù)據(jù)窗口的翻頁功能;
- 修改部分數(shù)據(jù),關(guān)閉窗口,查看提示保存的對話框
以上的這些功能,使用PFC的時候,簡單到只需設(shè)置某項屬性或者編寫一句開啟某項服務(wù)的語句即可實現(xiàn)。如果你想對某項服務(wù)提出更高的要求,比如排序服務(wù),你想更改服務(wù)的模式由默認的PB拖放排序方式改為下拉列表框方式,還需要一行命令來更改服務(wù)的方式。
完善并增加更多的功能
如果您想增加更多的更強大的功能,比如閃屏,登錄窗口等等。下面就簡單的介紹一下增加這些功能的簡單的方法。順便介紹一下我們可也在這些事件中添加的代碼和開啟的服務(wù)。涉及到的有關(guān)的具體問題會在以后慢慢的了解到。
通過查看PFC例程Peat的代碼,我們知道可以在“應用程序管理器”對象(gnv_App的對象)的Contructor事件中初始化版本、公司、INI文件等的信息(實例變量值,這些值大多可以在屬性窗口中設(shè)置),可以在“應用程序管理器”對象的pfc_Open事件中開啟需要的應用程序服務(wù),這些服務(wù)包括:應用程序選項服務(wù)、數(shù)據(jù)窗口緩存服務(wù)、錯誤信息服務(wù)、調(diào)試服務(wù)、安全服務(wù)、事務(wù)注冊服務(wù)、最近使用對象服務(wù)等等。
其次,我們可以在該對象的pfc_PreAbout,pfc_PreSplash,pfc_PreLogonDlg事件中添加代碼來定制“關(guān)于”、“登錄”以及閃屏對話框的顯示。在這三個事件中各有一個參考型的參數(shù),這些參數(shù)是相應的屬性對象實例,開發(fā)人員可以改變這些對象的屬性,來達到控制對話框顯示信息目的。如果不更改,將按照默認的樣式現(xiàn)實。
如果需要,“應用程序管理器”對象的pfc_Idle,pfc_ConnectionBegin、pfc_ConnectionEnd事件中編寫代碼,并在應用的相應事件中觸發(fā)這些事件。
如果需要顯示登錄窗口,需要完成以下步驟:
- 在框架窗口的Open事件中調(diào)用of_LogonDlg()函數(shù):
Integer??????? li_Rtn
//調(diào)用函數(shù)打開登錄對話框
li_Rtn??????? = gnv_App.of_LogonDlg()
If li_Rtn = 1 Then?? this.SetMicroHelp('Logon Successful')
Else?? If li_Rtn = -1 Then
????? MessageBox('Logon','Logon Failure' + String(li_Rtn))
?? End If
?? //Close(this)
?? Halt Close
End If
- 在“應用程序管理器”對象的pfc_Logon事件中添加代碼來處理用戶的登錄。例如可以是如下的代碼:
Integer??????? li_Rtn
String??????? ls_IniFile
ls_IniFile??????? = this.of_GetAppIniFile()
If SQLCA.of_Init(ls_IniFile,"DataBase") = -1 Then
?? li_Rtn??????? = FAILURE
End If
//as_UserID & as_Password為傳遞給事件的參數(shù)
SQLCA.of_SetUser(as_UserID,as_Password)
If SQLCA.of_Connect() = -1 Then
?? li_Rtn??????? = FAILURE
Else
?? gnv_App.of_SetUserID(as_UserID)
?? li_Rtn??????? = SUCCESS
End If
Return??????? li_Rtn
其實,在我們大多開發(fā)的應用程序中,登錄窗口檢驗的是我們存放在數(shù)據(jù)庫中的用戶列表,而不是登錄數(shù)據(jù)庫的用戶身份驗證。開發(fā)人員可根據(jù)需要自行更改。
另外,我們可以開啟框架窗口的狀態(tài)條服務(wù)和工作區(qū)窗口(Sheet)管理服務(wù)。要開啟這兩個服務(wù),我們只需在框架窗口的Open事件中編寫相應的代碼。不過,PFC的狀態(tài)條實在是差強人意。
消息路由器
CSDN上曾有網(wǎng)友提問要知道PFC消息路由器的機制問題,下面我從《PowerBuilder 基礎(chǔ)類庫技術(shù)詳解》一書摘抄一節(jié)介紹消息路由器的部分。
PFC使用消息路由器來處理菜單和窗口之間的通信。這種定制的消息傳送機制內(nèi)至于所有PFC菜單和窗口中。
雖然消息路由器可以用于任何對象與一個窗口的通信,但是他通常用來將消息從菜單傳遞給窗口。消息路由器根據(jù)一種定制的搜索算法來決定接受該消息的對象。
使用消息路由器有以下優(yōu)點:
- 菜單的腳本只需要知道要調(diào)用的用戶事件,而不必知道當前窗口或相關(guān)控件的名稱;
- 窗口不必保留那些只是簡單地調(diào)用數(shù)據(jù)窗口的用戶事件。這樣,窗口所保留的用戶事件的數(shù)目就減少了。
消息路由器函數(shù)傳遞的消息實際上就是一個字符串,該字符串包含窗口或窗口的控件要激活的用戶事件的名稱。消息路由器包括內(nèi)置的調(diào)試信息,從而可以提供錯誤信息。
當用戶選中一個菜單項時,該菜單項的Clicked事件調(diào)用該菜單的of_SendMessage函數(shù),并傳遞要調(diào)用的用戶事件的名稱。 of_SendMessage函數(shù)調(diào)用n_cst_menu的of_SendMessage函數(shù),該函數(shù)調(diào)用窗口的pfc_MessageRouter事件,該事件再調(diào)用制定的用戶事件。
根據(jù)應用程序是MDI程序還是SDI程序,of_SendMessage調(diào)用的pfc_MessageRouter用戶事件的方式有所不同,如圖:
pfc_MessageRouter用戶事件調(diào)用窗口、當前控件以及最近即獲得數(shù)據(jù)窗口中傳遞的用戶事件,如圖:
消息路由器提供一種菜單和窗口之間的通信機制。除了數(shù)據(jù)窗口中的命令按鈕之外,沒有按鈕能夠調(diào)用pfc_MwssageRouter事件。這是因為詳細函數(shù)調(diào)用GetFocus事件來的到當前的控件,而實際上點中一個命令按鈕之后,當前的控件就是該命令按鈕本身。
以上內(nèi)容摘自《PowerBuilder 基礎(chǔ)類庫技術(shù)詳解》,電子工業(yè)出版社出版,王梅君 等編著。
該書是 劉紅巖 主編的《PowerBuilder 7.0 與 Sybase Internet 技術(shù)叢書》系列中的一員。
源文檔 <http://dev.csdn.net/article/12/12674.shtm>
總結(jié)
- 上一篇: python wxpy_【微信辅助】吃鸡
- 下一篇: the 95th-percentile