當前位置:編程學習大全網 - 源碼下載 - delphi 怎麽用數組來記錄每壹步棋,來實現記錄遊戲和悔棋

delphi 怎麽用數組來記錄每壹步棋,來實現記錄遊戲和悔棋

為Delphi提供Pack和Undelete功能

本文針對Delphi3和Delphi4

對於C++Builder同樣也適用,在數據庫引擎BDE4.0、4.5、5.0中經過測試。

Delphi目前已經是國內常見的數據庫編程工具,它在各方面表現不錯,在支持大型多層數據庫結構的同時也完全支持本地數據庫的支持。對於本地數據庫中Delphi對FoxPro2.5b的支持也不錯,我曾經對VB、FoxPro2.5b、Delphi的數據庫操作速度進行比較,發現除了啟動速度較慢外,其它各項Delphi均排在首位。而且Delphi幾乎支持所有原先FoxPro所擁有的功能,對於有壹定編程經驗的人來說,Delphi成了編寫數據庫軟件的壹把利器,因而Delphi迅速流行起來,我幾年前甚至利用Delphi 1.0和匯編配合制作了工業控制系統的實時前後臺軟件。

但是在我長期使用Delphi編程的過程中發現它也有不如人意的地方,特別是在本地數據庫FoxPro方面,它居然不支持十分有用的Pack和Undelete功能。對於數據庫來說,因為是壹個順序存儲文件,在刪除部分記錄是壹般采用了軟刪除技術,也就是說將要刪除的記錄標記已刪除的標記,但並不立即從物理上刪除這些記錄。這樣做可以避免僅僅刪除壹條記錄就要將整個數據庫重新寫入存儲器,提高了讀寫的效率。但是如果數據庫長期不對已經被標記為刪除的記錄進行整理和真實刪除,數據庫就會越來越大,其中無用的數據所占的比率越來越大,使得數據庫的讀寫效率迅速下降,而且造成查詢速度的減慢。在編寫FoxPro數據庫時有個規律,如果數據進出數據庫頻繁,也就是說不斷刪除舊的數據,加入新的數據的情況下每次在關閉數據庫的時候或打開數據庫的時候先做壹次Pack,對數據庫進行整理,將軟刪除的記錄真正從數據庫中刪除。但是在Delphi的各個版本中數據庫控件均未提供Pack的功能,這使得用Delphi編寫的數據庫軟件如果使用本地數據庫的形式,數據庫的大小增長很快,即使刪除了大量記錄,數據庫的大小沒有任何改變。以前我的做法是在使用這類數據庫軟件壹段時間後利用FoxPro打開數據庫進行Pack

但是這樣做要求客戶端擁有FoxPro,而且經常這麼做也很繁。於是我開始查找有關資料,為什麼Delphi無法使用pack功能?

經過再三查找,我找到壹些資料,說明如何對數據庫進行pack了,在將其改編後在Delphi中使用通過。下面是其中的核心程序。

BDE API Call:

DBIResult DBIFN DbiPackTable (hDb

hCursor

pszTableName

[

pszDriverType]

bRegenIdxs);

在數據庫引擎的底層函數調用中,我找到了這個函數,這個函數據說可以對FoxPro的數據庫進行Pack

其中hDb是數據庫的句柄,可以由Table.Handle獲得;hCursor是數據表(Table)關聯的遊標,如果為NULL則數據表依賴於pszTableName和pszDriverType這兩個傳輸決定數據庫的來源;bRegenIdxs決定是否關聯外接的索引文件尤其是MDX多索引文件。

具體的操作函數如下:

procedure PackTable(Table: TTable);

var

Props: CURProps;

hDb: hDBIDb;

begin

if not Table.Active then

raise EDatabaseError.Create('Table必需已經打開');

if not Table.Exclusive then

raise EDatabaseError.Create('Table必需以獨占方式打開');

Check(DbiGetCursorProps(Table.Handle

Props));

if (Props.szTableType = szDBASE) then

Check(DbiPackTable(Table.DBHandle

Table.Handle

nil

szDBASE

True))

else

raise EDatabaseError.Create('Table必需是dBASE或FoxPro類型');

Table.Open;

end;

特別對這段源碼說明壹下,這段源碼部分改編自C,已經在上面提到過的環境中測試通過,需要註意的是,數據表必需以獨占方式打開,簡單的說,就是在設計時將數據表關閉(屬性Active=False),在運行時才打開數據表(form_onCreate時Table.Open),這樣才能保證數據表在獨占方式下被打開。DbiGetCursorProps()是壹個讀取數據表的屬性的底層函數調用,返回了大部分通用的數據表屬性。Check()函數可以簡單的處理數據庫的出錯提示和異常處理,如果出現函數調用錯誤會自動顯示出錯信息。

說了pack那麼與之對應的Undelete也就更要解釋了,同樣我找到了將軟刪除的數據恢復的函數,不過這個函數隱藏的更深,連C代碼都沒有,所以以下的代碼完全由我自己摸索出來,僅在上面說到的環境中測試通過。

首先介紹壹下相應的底層函數調用:

DBIResult DBIFN DbiUndeleteRecord (hCursor);

這個函數僅有的參數就是關聯的數據表的遊標,您可以在BDE.int的文件中找到它的聲明,但是具體的使用說明含糊不清,到底是恢復當前被刪記錄還是將數據表內所有被軟刪除的記錄全部恢復?由於缺少相應的代碼分析,我參照FoxPro的經驗進行了多次實驗,在十幾種方案的對比下得出了結論,這條函數調用僅僅恢復當前的被軟刪除的記錄。因此必需首先將數據表的遊標移動到被刪除的記錄上,然後調用這條函數,才會有所反應。要知道在默認的情況下,數據庫控件是不會將遊標移動到被刪除的記錄上的,所以必需首先將數據表的讀寫屬性修改,打開軟刪除的屬性,使得遍歷數據表時可以訪問到被標記為刪除的記錄。下面是壹段實現將數據表中所有被軟刪除的記錄恢復的源代碼。其它形式的反刪除可以參照這段代碼。

procedure Ttablepro.undelete;

var

CProps: CurProps;

rslt: DBIResult;

bm:TBookmark;

rp:pRECProps;

begin

Check(DbiGetCursorProps(self.Handle

CProps));//取得數據表的屬性

if (StrIComp(CProps.szTableType

szDBASE) 0) then//如果不是Dbase或Foxpro則退出

raise EDBEngineError.Create(DBIERR_NOTSUPPORTED);

rslt:=DbiValidateProp(hDBIObj(self.Handle)

curSOFTDELETEON

True);

//可否設置軟刪除?

if (rslt = DBIERR_NONE) then

Check(DbiSetProp(hDBIObj(self.Handle)

curSOFTDELETEON

Longint(true)));

//設置為可以軟刪除

Check(DbiGetCursorProps(self.Handle

CProps));

//更新數據表的屬性

if (CProps.bDeletedOn = False) then

raise EDatabaseError.Create('軟刪除沒有設置!');

//取得當前的記錄位置

bm:=self.GetBookmark;

//將遊標移動到第壹個記錄以前!Not Table.First!

Check(DbiSetTobegin(self.handle));

//不斷移動,直到到數據表的最後記錄

while (DBIGETNEXTRECORD(self.handle

dbinolock

nil

nil)=DBIERR_NONE) do

begin

//請關閉Delphi的異常響應,以便執行下面的語句!

try

check(DbiUndeleteRecord(self.Handle));

except

//Do somthing here !

end;

end;

//取回原先記錄的位置,重新定位

self.GotoBookmark(bm);

self.FreeBookmark(bm);

self.Refresh;

end;

(註:如果可以,請在刊登時刪去“Self.refresh”壹行,對於原理的介紹無需此行,僅在我的控件的屬性中需要,以上代碼來自我制作的Delphi控件TTablePro)

在這段代碼中已經有了詳細的解釋,應該可以比較容易的了解undelete的技巧了。當然如果能夠不必與源代碼打交道是最好的,因此我制作了壹個Delphi的控件TtablePro在Table的基礎上增加了兩個方法PackTable和Undelete;包含了上面介紹的功能。您可以到我的主頁免費下載試用,測試版可以免費使用無限制。

如果這篇文章有何問題請與我聯絡修改。謝謝。另外我可以提供防止應用程序重復加載的技術文章,同樣可以提供相應我制作的免費控件。在任務欄顯示圖標並直接與彈出式菜單的關聯的控件與完整技術資料,還可以實現動態圖標,目前的免費控件僅支持與指定的菜單關聯,就像dataset與datasource壹樣。我可以提供不少我制作的控件的實現技巧、技術的文章。另外我可以提供圍棋自動提子的算法和技巧的文章,代碼來自我制作的自由軟件-圍棋打譜軟件2.0b

我的聯絡地址:Email:mailto:weiwu@kali.com.cn

我的主頁:http://202.96.217.5/~web 169和上海熱線的Vip均可直接訪問!目前部分控件尚未上載,不過有些我制作的控件可以在其它國內外的Delphi站點看到。

目前我的研究方向是網上的圍棋對弈軟件、企業決策軟件、SQL生成器封裝得更好的DirectX5控件(改編自DelphiX

我的改編版本是目前唯壹支持Delphi4的)

  • 上一篇:請大師算算男性1986年2月5日(陰歷)早5.30出生的人命如何,請詳細,甚謝!!
  • 下一篇:洛克人zero3OZ5.0金手指
  • copyright 2024編程學習大全網