Windows SDK 風格的列印程式碼冗長且需深諳 GDI 底層流程。MFC 封裝了強大的列印框架,善用文檔/視圖架構可大幅簡化開發,支援列印預覽、多頁列印、頁首頁尾等專業功能。本文將由淺入深,從標準架構切入,再攻克「無文檔/視圖的對話框列印」這一實戰難題。
void CView::OnFilePrint() {
CPrintInfo printInfo;
CPrintDialog dlg(FALSE);
if (OnPreparePrinting(&printInfo)) { // 1. 初始化列印資訊(虛函數)
if (dlg.DoModal() != IDOK) return; // 2. 顯示列印對話框
}
OnBeginPrinting(&dcPrint, &printInfo); // 3. 列印開始(虛函數)
OnPrepareDC(&dcPrint, &printInfo); // 4. 頁面準備(虛函數)
OnPrint(&dcPrint, &printInfo); // 5. 核心繪製(虛函數)
OnEndPrinting(&dcPrint, &printInfo); // 6. 收尾清理(虛函數)
}
| 函數 | 職責 | 典型用途 |
|---|---|---|
OnBeginPrinting | 列印作業啟動 | 設定總頁數 pInfo->SetMaxPage(n)、建立字體/筆刷等資源 |
OnPrint | 單頁繪製核心 | 依 pInfo->m_nCurPage 繪製對應頁面內容、頁首頁尾 |
OnEndPrinting | 列印作業結束 | 釋放 OnBeginPrinting 中配置的 GDI 物件 |
m_nCurPage // 當前列印頁碼(1-based)
m_nNumPreviewPages // 預覽頁數
m_rectDraw // 可列印區域矩形(裝置座標)
m_bPreview // 是否處於預覽模式
m_strPageDesc // 頁碼顯示格式字串
ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView::OnFilePrintPreview)
預覽與列印共用 OnPrint,零成本複用。
對話框專案缺乏 CView,但可動態建立「隱形框架視窗 + 虛擬視圖」借用 MFC 列印引擎。
CPrintFrame : public CFrameWnd — 隱形框架視窗,持有對話框指標 m_pCallerDlgCPrintView : public CView — 虛擬視圖,重寫 OnPrint 轉發 WM_MY_PRINT 給對話框void CDlgPrintDlg::OnPrint() {
CPrintFrame* pFrame = new CPrintFrame;
pFrame->m_pCallerDlg = this;
pFrame->Create(NULL, _T("列印"), WS_OVERLAPPEDWINDOW, CRect(0,0,0,0));
pFrame->m_pView->OnMyPrint(); // 觸發列印
}
void CDlgPrintDlg::OnPrintPreview() {
CPrintFrame* pFrame = new CPrintFrame;
pFrame->m_pCallerDlg = this;
pFrame->Create(NULL, _T("列印預覽"), WS_OVERLAPPEDWINDOW, CRect(0,0,0,0));
pFrame->m_pView->OnMyPrintPreview(); // 觸發預覽
}
ON_MESSAGE(WM_BEGIN_PRINTING, OnBeginPrinting) // 對應 OnBeginPrinting
ON_MESSAGE(WM_END_PRINTING, OnEndPrinting) // 對應 OnEndPrinting
ON_MESSAGE(WM_MY_PRINT, OnMyPrint) // 對應 OnPrint 核心繪製
void CDlgPrintDlg::OnMyPrint(WPARAM wParam, LPARAM lParam) {
CDC* pDC = (CDC*)wParam;
CPrintInfo* pInfo = (CPrintInfo*)lParam;
int page = pInfo->m_nCurPage;
// 依頁碼繪製對應內容:表格、曲線、影像...
pDC->Rectangle(...); // GDI 繪圖任意組合
}
CPrintFrame 需在列印結束後 delete,避免洩漏
圖 1:列印功能主對話框
圖 2:列印預覽單頁模式
圖 3:雙頁同屏預覽
圖 4:系統內建印表機選擇對話框(不可移除)
透過虛擬文檔/視圖技法,對話框專案也能享用 MFC 完整的列印/預覽引擎。CPrintFrame / CPrintView 兩個可重用類別已封裝核心邏輯,開發者只需專注 OnMyPrint 的 GDI 繪製即可。掌握此技法,將列印開發效率提升數倍。