微軟在2004年歲末發(fā)布最新版Visual Foxpro 9.0,這則消息讓我們回想起曾經(jīng)風(fēng)光無(wú)限的Foxpro,現(xiàn)在它已經(jīng)被Java、Delphi、VB等眾多明星遮掩了光芒,有人認(rèn)為如果不是誕生在豪門(mén)微軟,它肯定已經(jīng)消失。但了解Visual Foxpro的都知道,Visual Foxpro的卓越性能是無(wú)法代替的。
新版Visual Foxpro 9.0在Foxpro社區(qū)引起了轟動(dòng),新版中將包含一個(gè)更快的本地?cái)?shù)據(jù)引擎,支持更多的數(shù)據(jù)類(lèi)型,SQL語(yǔ)句執(zhí)行中有更大的一致性,一個(gè)完全重新設(shè)計(jì)的可擴(kuò)展報(bào)表編寫(xiě)器,以及一系列效率和功能增強(qiáng)特性。
在Visual FoxPro 9.0的報(bào)表系統(tǒng)出現(xiàn)了難以置信的改進(jìn)。在本文中,我只討論幾個(gè)新增功能中的一個(gè)——擴(kuò)展運(yùn)行時(shí)報(bào)表引擎(runtime reporting engine)的能力。
Visual FoxPro小組在處理運(yùn)行時(shí)改進(jìn)工作時(shí)一直緊記著幾個(gè)目標(biāo),包括: 處理打印和預(yù)覽之外的多種報(bào)表輸出
使用GDI+進(jìn)行報(bào)表輸出。這會(huì)帶來(lái)很多顯著的改進(jìn),例如精確地顯示、圖像和字體的平滑調(diào)整,以及一些附加的能力(例如文本旋轉(zhuǎn))
提供一個(gè)更加靈活和可擴(kuò)展的報(bào)表系統(tǒng)
你可以同時(shí)訪問(wèn)舊的和新的報(bào)表引擎,因此你可以根據(jù)需要選擇在哪種引擎下運(yùn)行報(bào)表。但是一旦你看到新的報(bào)表引擎的優(yōu)點(diǎn),你就再也不希望使用舊式報(bào)表了。
報(bào)表系統(tǒng)的架構(gòu)
Visual FoxPro 9以前版本中的報(bào)表系統(tǒng)類(lèi)似于單片電路:它處理所有細(xì)節(jié)信息,只有少量的例外(用戶(hù)定義的函數(shù)、報(bào)表帶條的OnEntry和OnExit表達(dá)式等等),在報(bào)表運(yùn)行的時(shí)候,你是不能與它交互操作的。
新的報(bào)表引擎把報(bào)表的功能分成了兩部分:現(xiàn)在的報(bào)表引擎只處理數(shù)據(jù)和對(duì)象定位;一種新對(duì)象(報(bào)表監(jiān)聽(tīng)器)處理顯示和輸出的事務(wù)。由于報(bào)表監(jiān)聽(tīng)器是類(lèi)(class),因此我們現(xiàn)在可以使用以前夢(mèng)寐以求的方式與報(bào)表進(jìn)程交互操作。
新的報(bào)表語(yǔ)法
Visual FoxPro 9支持使用舊的報(bào)表引擎運(yùn)行報(bào)表;你可以像以前一樣使用REPORT命令(盡管你可以使用新命令重載REPORT的行為)。為了得到新式的報(bào)表行為,必須使用REPORT命令的OBJECT子句。OBJECT子句支持兩種使用方法:指定報(bào)表監(jiān)聽(tīng)器和指定報(bào)表樣式。微軟把它歸納為對(duì)象輔助(object-assisted)報(bào)表。
報(bào)表監(jiān)聽(tīng)器是提供新式報(bào)表行為的對(duì)象。報(bào)表監(jiān)聽(tīng)器是基于Visual FoxPro 9的新的基礎(chǔ)類(lèi)ReportListener的。為了讓Visual FoxPro 9使用報(bào)表指定的監(jiān)聽(tīng)器,需要實(shí)例化監(jiān)聽(tīng)器類(lèi),并在REPORT命令的OBJECT子句中指出該對(duì)象的名稱(chēng)。下面是一個(gè)例子:
loListener = createobject('MyReportListener')
report form MyReport object loListener
如果不希望手動(dòng)實(shí)例化監(jiān)聽(tīng)器,可以通過(guò)指定報(bào)表類(lèi)型讓Visual FoxPro自動(dòng)為你完成實(shí)例化過(guò)程,例如:
report form MyReport object type 1
已經(jīng)定義好的類(lèi)型有: 0——從打印機(jī)輸出
1——預(yù)覽
2——某個(gè)時(shí)刻的頁(yè)面信息模式,但不會(huì)輸出到打印機(jī)
3——所有頁(yè)面模式,但不會(huì)調(diào)用預(yù)覽窗口
4——XML輸出
5——HTML輸出
當(dāng)然我們還可以使用其它的用戶(hù)自定義類(lèi)型。
使用這種方式運(yùn)行報(bào)表的時(shí)候,將調(diào)用新的_REPORTOUTPUT系統(tǒng)變量(默認(rèn)情況下它位于Visual FoxPro主目錄的ReportOutput.APP中)中指定的應(yīng)用程序來(lái)決定指定該類(lèi)型使用哪種監(jiān)聽(tīng)器類(lèi)來(lái)實(shí)例化。它是通過(guò)查看APP中內(nèi)建的監(jiān)聽(tīng)器注冊(cè)表(盡管你可以指定它使用一個(gè)外部表)中的監(jiān)聽(tīng)器類(lèi)型來(lái)實(shí)現(xiàn)的。如果它找到了需要的類(lèi),它就實(shí)例化該類(lèi)并傳遞該監(jiān)聽(tīng)器對(duì)象的一個(gè)引用到報(bào)表引擎中。因此,在REPORT命令中使用OBJECT TYPE 某種類(lèi)型的效果與下面的代碼的效果是相同的:
loListener = .NULL.
do (_ReportOutput) with SomeType, loListener
report form MyReport object loListener
報(bào)表監(jiān)聽(tīng)器
在報(bào)表運(yùn)行的過(guò)程中,伴隨著報(bào)表事件的發(fā)生,Visual FoxPro把這些事件暴露給基于ReportListener基類(lèi)的對(duì)象。Visual FoxPro幫助文件記錄了ReportListener的屬性、事件和方法(PEMs),但是在本文中我只討論其中最有用的一些。
表1列舉了ReportListener類(lèi)的最常使用的一些屬性。
表1:ReportListener類(lèi)的一些有用屬性
屬性
描述
CurrentDataSession
報(bào)表數(shù)據(jù)的數(shù)據(jù)對(duì)話(huà)ID
FRXDataSession
FRX游標(biāo)的數(shù)據(jù)對(duì)話(huà)ID
GDIPlusGraphics
用于顯示的GDI+繪圖對(duì)象句柄
ListenerType
監(jiān)聽(tīng)器生成的報(bào)表輸出類(lèi)型。默認(rèn)值是-1(無(wú)輸出),你應(yīng)該把它改成符合需要的值。它的值與REPORT 命令的OBJECT TYPE 子句中規(guī)定的值是相同的。
OutputPageCount
被顯示的頁(yè)面的數(shù)量
QuietMode
如果它的值為.T. (默認(rèn)值是 .F.) 就支持進(jìn)度信息
表2顯示了經(jīng)常使用的ReportListener的事件和方法。
表2:ReportListener的一些有用的事件和方法
事件/方法
描述
LoadReport
在FRX被載入和打印機(jī)假脫機(jī)操作被打開(kāi)前調(diào)用
UnloadReport
在報(bào)表運(yùn)行之后調(diào)用
BeforeReport
在FRX被載入但是報(bào)表運(yùn)行前調(diào)用
AfterReport
報(bào)表運(yùn)行后調(diào)用
BeforeBand
處理某個(gè)報(bào)表?xiàng)l帶前調(diào)用
AfterBand
處理某個(gè)報(bào)表?xiàng)l帶后調(diào)用
EvaluateContents
顯示某個(gè)字段前調(diào)用
Render
顯示對(duì)象的時(shí)候調(diào)用
OutputPage
向特定的設(shè)備輸出指定顯示的頁(yè)面
新版Visual Foxpro 9.0在Foxpro社區(qū)引起了轟動(dòng),新版中將包含一個(gè)更快的本地?cái)?shù)據(jù)引擎,支持更多的數(shù)據(jù)類(lèi)型,SQL語(yǔ)句執(zhí)行中有更大的一致性,一個(gè)完全重新設(shè)計(jì)的可擴(kuò)展報(bào)表編寫(xiě)器,以及一系列效率和功能增強(qiáng)特性。
在Visual FoxPro 9.0的報(bào)表系統(tǒng)出現(xiàn)了難以置信的改進(jìn)。在本文中,我只討論幾個(gè)新增功能中的一個(gè)——擴(kuò)展運(yùn)行時(shí)報(bào)表引擎(runtime reporting engine)的能力。
Visual FoxPro小組在處理運(yùn)行時(shí)改進(jìn)工作時(shí)一直緊記著幾個(gè)目標(biāo),包括: 處理打印和預(yù)覽之外的多種報(bào)表輸出
使用GDI+進(jìn)行報(bào)表輸出。這會(huì)帶來(lái)很多顯著的改進(jìn),例如精確地顯示、圖像和字體的平滑調(diào)整,以及一些附加的能力(例如文本旋轉(zhuǎn))
提供一個(gè)更加靈活和可擴(kuò)展的報(bào)表系統(tǒng)
你可以同時(shí)訪問(wèn)舊的和新的報(bào)表引擎,因此你可以根據(jù)需要選擇在哪種引擎下運(yùn)行報(bào)表。但是一旦你看到新的報(bào)表引擎的優(yōu)點(diǎn),你就再也不希望使用舊式報(bào)表了。
報(bào)表系統(tǒng)的架構(gòu)
Visual FoxPro 9以前版本中的報(bào)表系統(tǒng)類(lèi)似于單片電路:它處理所有細(xì)節(jié)信息,只有少量的例外(用戶(hù)定義的函數(shù)、報(bào)表帶條的OnEntry和OnExit表達(dá)式等等),在報(bào)表運(yùn)行的時(shí)候,你是不能與它交互操作的。
新的報(bào)表引擎把報(bào)表的功能分成了兩部分:現(xiàn)在的報(bào)表引擎只處理數(shù)據(jù)和對(duì)象定位;一種新對(duì)象(報(bào)表監(jiān)聽(tīng)器)處理顯示和輸出的事務(wù)。由于報(bào)表監(jiān)聽(tīng)器是類(lèi)(class),因此我們現(xiàn)在可以使用以前夢(mèng)寐以求的方式與報(bào)表進(jìn)程交互操作。
新的報(bào)表語(yǔ)法
Visual FoxPro 9支持使用舊的報(bào)表引擎運(yùn)行報(bào)表;你可以像以前一樣使用REPORT命令(盡管你可以使用新命令重載REPORT的行為)。為了得到新式的報(bào)表行為,必須使用REPORT命令的OBJECT子句。OBJECT子句支持兩種使用方法:指定報(bào)表監(jiān)聽(tīng)器和指定報(bào)表樣式。微軟把它歸納為對(duì)象輔助(object-assisted)報(bào)表。
報(bào)表監(jiān)聽(tīng)器是提供新式報(bào)表行為的對(duì)象。報(bào)表監(jiān)聽(tīng)器是基于Visual FoxPro 9的新的基礎(chǔ)類(lèi)ReportListener的。為了讓Visual FoxPro 9使用報(bào)表指定的監(jiān)聽(tīng)器,需要實(shí)例化監(jiān)聽(tīng)器類(lèi),并在REPORT命令的OBJECT子句中指出該對(duì)象的名稱(chēng)。下面是一個(gè)例子:
loListener = createobject('MyReportListener')
report form MyReport object loListener
如果不希望手動(dòng)實(shí)例化監(jiān)聽(tīng)器,可以通過(guò)指定報(bào)表類(lèi)型讓Visual FoxPro自動(dòng)為你完成實(shí)例化過(guò)程,例如:
report form MyReport object type 1
已經(jīng)定義好的類(lèi)型有: 0——從打印機(jī)輸出
1——預(yù)覽
2——某個(gè)時(shí)刻的頁(yè)面信息模式,但不會(huì)輸出到打印機(jī)
3——所有頁(yè)面模式,但不會(huì)調(diào)用預(yù)覽窗口
4——XML輸出
5——HTML輸出
當(dāng)然我們還可以使用其它的用戶(hù)自定義類(lèi)型。
使用這種方式運(yùn)行報(bào)表的時(shí)候,將調(diào)用新的_REPORTOUTPUT系統(tǒng)變量(默認(rèn)情況下它位于Visual FoxPro主目錄的ReportOutput.APP中)中指定的應(yīng)用程序來(lái)決定指定該類(lèi)型使用哪種監(jiān)聽(tīng)器類(lèi)來(lái)實(shí)例化。它是通過(guò)查看APP中內(nèi)建的監(jiān)聽(tīng)器注冊(cè)表(盡管你可以指定它使用一個(gè)外部表)中的監(jiān)聽(tīng)器類(lèi)型來(lái)實(shí)現(xiàn)的。如果它找到了需要的類(lèi),它就實(shí)例化該類(lèi)并傳遞該監(jiān)聽(tīng)器對(duì)象的一個(gè)引用到報(bào)表引擎中。因此,在REPORT命令中使用OBJECT TYPE 某種類(lèi)型的效果與下面的代碼的效果是相同的:
loListener = .NULL.
do (_ReportOutput) with SomeType, loListener
report form MyReport object loListener
報(bào)表監(jiān)聽(tīng)器
在報(bào)表運(yùn)行的過(guò)程中,伴隨著報(bào)表事件的發(fā)生,Visual FoxPro把這些事件暴露給基于ReportListener基類(lèi)的對(duì)象。Visual FoxPro幫助文件記錄了ReportListener的屬性、事件和方法(PEMs),但是在本文中我只討論其中最有用的一些。
表1列舉了ReportListener類(lèi)的最常使用的一些屬性。
表1:ReportListener類(lèi)的一些有用屬性
屬性
描述
CurrentDataSession
報(bào)表數(shù)據(jù)的數(shù)據(jù)對(duì)話(huà)ID
FRXDataSession
FRX游標(biāo)的數(shù)據(jù)對(duì)話(huà)ID
GDIPlusGraphics
用于顯示的GDI+繪圖對(duì)象句柄
ListenerType
監(jiān)聽(tīng)器生成的報(bào)表輸出類(lèi)型。默認(rèn)值是-1(無(wú)輸出),你應(yīng)該把它改成符合需要的值。它的值與REPORT 命令的OBJECT TYPE 子句中規(guī)定的值是相同的。
OutputPageCount
被顯示的頁(yè)面的數(shù)量
QuietMode
如果它的值為.T. (默認(rèn)值是 .F.) 就支持進(jìn)度信息
表2顯示了經(jīng)常使用的ReportListener的事件和方法。
表2:ReportListener的一些有用的事件和方法
事件/方法
描述
LoadReport
在FRX被載入和打印機(jī)假脫機(jī)操作被打開(kāi)前調(diào)用
UnloadReport
在報(bào)表運(yùn)行之后調(diào)用
BeforeReport
在FRX被載入但是報(bào)表運(yùn)行前調(diào)用
AfterReport
報(bào)表運(yùn)行后調(diào)用
BeforeBand
處理某個(gè)報(bào)表?xiàng)l帶前調(diào)用
AfterBand
處理某個(gè)報(bào)表?xiàng)l帶后調(diào)用
EvaluateContents
顯示某個(gè)字段前調(diào)用
Render
顯示對(duì)象的時(shí)候調(diào)用
OutputPage
向特定的設(shè)備輸出指定顯示的頁(yè)面