將舊有 PowerBuilder 考勤系統移植至 VC++,核心在於重寫 PB 特有的 DataWindow (資料視窗) 功能:IDE 設計版面 → 執行時轉換為報表/列表/單據,支援資料庫連結、動態列印、預覽。本文介紹自製核心類別庫架構與使用方式。
| 類別 | 職責 | 關鍵基類/技術 |
|---|---|---|
ADOxxxx | 資料庫存取封裝 | ADO 智慧指標 |
CPreGraphic | 繪圖/文字輸出 | GDI / DrawText |
CPrePrint | 列印控制 | CPrintDialog, DOCINFO |
CDataWin | 核心:視窗轉報表/列表 | 繼承 CWnd, 列舉子控制項 |
CDlgDoc | 單據/單頁文檔 | 簡單頁面列印 |
CListDoc | 多筆記錄列表 | 分頁、群組、統計 |
CProgressCtrl (隱藏) 作為分隔線,將版面切為四區:**頁首、表身、表尾、頁尾**。Init() 列舉所有子控制項,記錄位置、類型、ID、Caption,並隱藏原控制項。= 開頭 (如 =EmpName) → 對應資料庫欄位。CDataCell 結構陣列 (類似 Grid),每儲存格對應一個控制項資訊。Open(SQL) 開啟記錄集,UpdateRecord() 逐筆填充 Cell 資料。
OnPaint() → OnPageStart()
→ OnCellStart(pCell) [N次] → 繪製內容 → OnCellEnd(pCell)
→ OnPageEnd()
衍生類別可覆寫 OnCellStart/End 自訂繪製 (如條件式顏色)。
BOOL CDataWin::Init() {
InitGraphic(); // 建立 CPreGraphic
ResetAll(); // 重設變數
InitBase(); // 修改視窗風格、初始化紙張設定
EnumControl(); // 列舉子視窗
if (!Init4Control()) return FALSE; // 解析控制項結構
InitConnect(); // 連結資料庫 (ADO)
Open(m_strDefSQL); // 執行預設 SQL
UpdateRecord(); // 載入資料
ShowWindow(SW_SHOW);
return TRUE;
}
class CMyView : public CView {
CDataWin m_dlg;
// ...
void OnInitialUpdate() {
CView::OnInitialUpdate();
m_dlg.Create(IDD_DATAWIN_TEMPLATE, this); // 以對話方塊範本建立
m_dlg.Init();
// m_dlg.SetDoubleRam(TRUE); // 雙緩衝減少閃爍
// m_dlg.SetPrintView(FALSE); // 是否模擬列印預覽
CRect rect; GetClientRect(&rect);
rect.DeflateRect(10, 50, 10, 50);
m_dlg.MoveWindow(rect, FALSE);
m_dlg.ShowWindow(SW_SHOW);
}
void OnFilePrint() {
m_dlg.OnPrint(_T("考勤月報表")); // 列印/預覽
}
}
class CDlgWkInput : public CFormView {
CDlgDoc m_Doc;
// ...
void OnInitialUpdate() {
m_Doc.Init(&m_Page1); // m_Page1 為對話方塊範本資源 ID
m_Doc.SetConnection(m_pConnection);
}
void OnSave() {
m_Doc.Save(); // 寫入資料庫
}
void OnRetrieve() {
CString sql = _T("SELECT * FROM kv_staff_mr");
m_Doc.Retrieve(sql); // 查詢並填充控制項
}
}
CDataCell 內容。SetDoubleRam(TRUE) 啟用記憶體 DC 離屏渲染,消除閃爍。SetPrintView(TRUE) 以螢幕 DC 模擬印表機 DC,所見即所得。