发信人: lofe ()感激生活(), 信区: BorlandDev
标 题: .利用BDE的回调函数提供当前的操作状态
发信站: 哈工大紫丁香 (Mon Sep 4 16:16:39 2000), 转信
This TI demonstrates using a BDE DbiCallBack function
to drive a progress bar during a lengthy batch move
operation under Delphi 2.01.
Additional documentation on BDE function calls can be found
in the file BDE32.HLP (located in the directory where the
32 bit IDAPI is installed).
When you install a callback function to the BDE, the BDE
will "call back" to a function in your application, letting
your application know when certain events take place, and in
some cases, allow your application to return information
back to the BDE.
The BDE defines several callback types that may be installed:
during large batch operations.
requests a response from the caller.
This TI details installing a cbGENPROGRESS callback to drive
a progress bar in your application.
To do this, first call the DbiGetCallBack() function to retrieve
the handle to any callback that might already be installed
(and it's parameters), and save this information to a data
structure. Then install your callback, replacing any previous
callback installed.
You will need to pass a pointer the data structure containing
the information to the previously installed callback to the BDE
when you install your callback, so when your callback function
is executed, you can call the original callback
(if one is installed).
The BDE will call back to your application every so often,
reporting either a text message containing the number of records
it has processed or how far the batch move has progressed,
expressed as an integer percentage. Your callback should be able
to deal with either of these situations. If the percentage field
of the callback structure is greater than -1, then the percentage
is correct and you are free to update your progress bar. If the
percentage reported is less than zero, the callback has received
a text message in the szTMsg field containing a message that
includes the number of records processed. In this case, you will
need to parse the text message and convert the remaining string
to an integer, then calculate the percentage done and update
the progress bar.
Finally, when your batch move is complete, you will need to
un-register your callback, and reinstall the previous callback
function (if it exists).
The following code example is based on a form containing two tables,
a batch move component, a progress bar, and a button.
----- Code Follows ---------
unit Testbc1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, Grids, DBGrids, DB, DBTables, ComCtrls;
type
TForm1 = class(TForm)
Table1: TTable;
BatchMove1: TBatchMove;
Table2: TTable;
Button1: TButton;
ProgressBar1: TProgressBar;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
uses Bde; {Dbi Types and Procs are located here}
{$R *.DFM}
{data structure type to save previous callback info}
type TDbiCbInfo = record
ecbType : CBType;
iClientData : longint;
DataBuffLn : word;
DataBuff : pCBPROGRESSDesc;
DbiCbFn : pointer;
end;
type PDbiCbInfo = ^TDbiCbInfo;
{Our callback function}
function DbiCbFn(ecbType : CBType;
iClientData : Longint;
CbInfo : pointer): CBRType stdcall;
var
s : string;
begin
{Check to see if the callback type is what we expect}
if ecbType = cbGENPROGRESS then begin
{if iPercentDone is less that zero then extract the number}
{of records processed from szMsg parameter}
if pCBPROGRESSDesc(cbInfo).iPercentDone < 0 then begin
s := pCBPROGRESSDesc(cbInfo).szMsg;
Delete(s, 1, Pos(': ', s) + 1);
{Calculate percentage done and set the progress bar}
Form1.ProgressBar1.Position :=
Round((StrToInt(s) / Form1.Table1.RecordCount) * 100);
end else
begin
{Set the progress bar}
Form1.ProgressBar1.Position :=
pCBPROGRESSDesc(cbInfo).iPercentDone;
end;
end;
{was there a previous callback registered}
{if so - call it and return}
if PDbiCbInfo(iClientData)^.DbiCbFn <> nil then
DbiCbFn :=
pfDBICallBack(PDbiCbInfo(iClientData)^.DbiCbFn)
(ecbType,
PDbiCbInfo(iClientData)^.iClientData,
cbInfo) else
DbiCbFn := cbrCONTINUE;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
CbDataBuff: CBPROGRESSDesc; {DBi Structure}
OldDbiCbInfo : TDbiCbInfo; {data structure to save previous
callback info}
begin
{Make sure the table we are moving from is open}
Table1.Open;
{make sure the table we are batch moving to is closed}
Table2.Close;
{get info about any installed callback}
DbiGetCallBack(Table2.Handle,
cbGENPROGRESS,
@OldDbiCbInfo.iClientData,
@OldDbiCbInfo.DataBuffLn,
@OldDbiCbInfo.DataBuff,
pfDBICallBack(OldDbiCbInfo.DbiCbFn));
{register our callback}
DbiRegisterCallBack(Table2.Handle,
cbGENPROGRESS,
longint(@OldDbiCbInfo),
SizeOf(cbDataBuff),
@cbDataBuff,
@DbiCbFn);
Form1.ProgressBar1.Position := 0;
BatchMove1.Execute;
{if a previous callback exists - reinstall it else}
{unregister our callback}
if OldDbiCbInfo.DbiCbFn <> nil then
DbiRegisterCallBack(Table2.Handle,
cbGENPROGRESS,
OldDbiCbInfo.iClientData,
OldDbiCbInfo.DataBuffLn,
OldDbiCbInfo.DataBuff,
OldDbiCbInfo.DbiCbFn) else
DbiRegisterCallBack(Table2.Handle,
cbGENPROGRESS,
longint(@OldDbiCbInfo),
SizeOf(cbDataBuff),
@cbDataBuff,
nil);
{lets show our success!}
Table2.Open;
end;
end.
--
※ 修改:.haojs 于 Sep 4 16:11:15 修改本文.[FROM: bbs.hit.edu.cn]
--
※ 转寄:.武汉白云黄鹤站 bbs.whnet.edu.cn.[FROM: bbs.hit.edu.cn]
--
☆ 来源:.哈工大紫丁香 bbs.hit.edu.cn.[FROM: haojs.bbs@bbs.whnet.]
Powered by KBS BBS 2.0 (http://dev.kcn.cn)
页面执行时间:3.370毫秒