MFC 預設列印架構建立在 Document/View 模型上,若專案採用對話框架構 (Dialog-based) 則無法直接使用。本文提供一套獨立的列印預覽/列印方案,僅需兩個 CDialog 衍生類別 (CPreParent、CPreView) 即可在對話框專案中實現完整列印功能,支援多頁、捲動、縮放、跳頁、直接列印。
static void DrawInfo(CDC&, PRNINFO&) 繪製單頁內容,框架負責分頁邏輯與預覽迴圈。
typedef struct {
int nMaxLine; // ListCtrl 總行數
int nCountPage; // 總頁數 (框架計算)
int nCurPage; // 目前頁碼
BOOL IsPrint; // FALSE=預覽, TRUE=列印
HWND hWnd; // 呼叫視窗句柄
HWND hListView; // ListCtrl 句柄
TCHAR szTag[256]; // 附加資料
int nTag;
LPVOID lpVoid; // 自訂指標
} PRNINFO, *PPRNINFO;
void CXJWH::OnPrint() {
if (m_List.GetItemCount() <= 0) return;
PRNINFO info = {0};
info.hListView = m_List.m_hWnd;
info.hWnd = m_hWnd;
info.IsPrint = FALSE; // 預覽模式
info.nCurPage = 1;
info.nMaxLine = m_List.GetItemCount();
CPreParent dlg;
dlg.SetCallBackFun(DrawInfo, info); // 設定繪製回呼
dlg.DoModal(); // 顯示預覽對話框
}
// 靜態繪製回呼:從 ListCtrl 讀取資料繪製單頁
static void DrawInfo(CDC& dc, PRNINFO& info) {
// 計算每頁行數、欄位寬度、標題列...
// 迴圈呼叫 dc.TextOut / dc.Rectangle 繪製表格
// 使用 info.nCurPage 決定繼續資料範圍
}
BitBlt 輸出螢幕,避免閃爍。WM_MOUSEWHEEL、OnLButtonDown/Move/Up 實現頁面上下左右拖曳。VK_PRIOR/NEXT/HOME/END 對應首/尾頁、上/下頁。info.IsPrint = TRUE,建立 CPrintDialog、DOCINFO,呼叫 StartDoc/StartPage/EndPage/EndDoc 逐頁列印。| 按鈕 | 功能 |
|---|---|
| 首頁 | nCurPage=1, 重繪 |
| 上頁 | nCurPage--, 重繪 |
| 跳頁 | 彈出輸入對話框設定 nCurPage |
| 下頁 | nCurPage++, 重繪 |
| 末頁 | nCurPage=nCountPage, 重繪 |
| 結束 | EndDialog(IDCANCEL) |
| 列印 | 切換 IsPrint=TRUE 進入列印流程 |
這套方案只需複製 CPreParent、CPreView 兩個類別與資源,即可為任何 MFC 對話框專案加入專業級列印預覽/列印功能,避免了為了列印而強制引入 Doc/View 架構的複雜度。