在 MIS 系統中,遠端資料庫存取常透過 Modem 連線。為節省通訊費用與時間,常採用本地暫存再批量傳送的策略。本文深入探討以「客戶/伺服器」模式直接提交資料的方案,並利用 Delphi/C++Builder 的 TBatchMove 元件搭配 BDE 回呼機制,實現進度顯示與使用者中斷功能。
TBatchMove 可大幅減少網路負擔、提升速度,但缺乏進度顯示與中斷控制。BDE 提供的「回呼機制」可彌補此缺口:長時間操作(如大量資料複製)期間,BDE 會定期呼叫開發者自訂的回呼函式,傳遞進度資訊。
CBRType __stdcall ApiCallBackFun(...))。DbiRegisterCallBack 註冊回呼函式,指定觸發條件(如 cbGENPROGRESS)。BatchMove1->Execute())。註冊回呼函式:
int rst = DbiRegisterCallBack(
NULL, // 適用所有 BDE 任務
cbGENPROGRESS, // 觸發條件:長操作進度
NULL, // 無額外資料
sizeof(CBPROGRESSDesc),
&aCBBuf, // 緩衝區位址
ApiCallBackFun // 回呼函式位址
);
回呼函式處理進度顯示與中斷邏輯:
CBRType __stdcall ApiCallBackFun(CBType ecbType, int iClientData, void *pCbInfo) {
if (ecbType == cbGENPROGRESS) {
CBPROGRESSDesc* pDesc = (CBPROGRESSDesc*)pCbInfo;
if (pDesc->iPercentDone < 0) {
// 解析 szMsg 如 "RecordsCopied:125"
AnsiString str = pDesc->szMsg;
int pos = str.AnsiPos(":") + 1;
int copied = StrToInt(str.SubString(pos, 100));
Form1->Label2->Caption = str.SubString(pos, 100);
Form1->ProgressBar1->Position = (copied / Form1->TransNum) * 100;
} else {
Form1->ProgressBar1->Position = pDesc->iPercentDone;
}
Form1->ProgressBar1->Update();
// 處理訊息佇列,避免介面凍結
MSG msg;
while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return isContinue ? cbrCONTINUE : cbrABORT;
}
return cbrCONTINUE;
}
透過 PeekMessage 處理訊息佇列,讓使用者得以在長時間傳輸中點擊「停止」按鈕,設定全域旗標 isContinue 控制是否中斷。
本文原理同樣適用於 Delphi,僅語法略有差異。掌握 BDE 回呼機制,可構建更友善、可控的遠端資料同步功能。