CPrintDialog 封裝了 Windows 列印常用流程:選擇印表機、設定頁數範圍、取得列印 DC(GetPrinterDC)、啟動/結束列印作業(StartDoc/EndDoc)、分頁控制(StartPage/EndPage)。關鍵在於將繪圖邏輯集中於 OnDraw 或自訂 OnPrint,由架構自動處理分頁座標轉換。
void CMyView::OnFilePrint() {
// 1. 建立列印對話框,隱藏頁碼輸入
CPrintDialog dlg(FALSE, PD_ALLPAGES | PD_NOPAGENUMS | PD_HIDEPRINTTOFILE, this);
if (dlg.DoModal() != IDOK) return;
// 2. 取得印表機 DC
HDC hDC = dlg.GetPrinterDC();
if (!hDC) return;
// 3. 文件資訊
DOCINFO di = { sizeof(DOCINFO), _T("我的文件"), NULL, NULL, 0 };
// 4. 開始列印作業
if (StartDoc(hDC, &di) <= 0) { DeleteDC(hDC); return; }
// 5. 逐頁列印
for (int page = 1; page <= totalPages; ++page) {
if (StartPage(hDC) <= 0) break;
// 繪圖區域以裝置座標為單位,建議使用 MM_TWIPS 或 MM_LOMETRIC
// 這裡直接呼叫視圖的 OnDraw,自動處理縮放與分頁
OnDraw(CDC::FromHandle(hDC));
if (EndPage(hDC) <= 0) break;
}
// 6. 結束並清理
EndDoc(hDC);
DeleteDC(hDC);
}
OnPrepareDC 依 m_nCurPage 計算可列印區域,配合 SetMapMode 實現 WYSIWYG。OnDraw,只需在列印時調整對應比例(SetViewportOrg/Ext)。CPreviewView 內部同樣呼叫 OnDraw,無需額外代碼。StartDoc/StartPage/EndPage 均需檢查回傳值,失敗時呼叫 AbortDoc 並 DeleteDC。DeleteDC 導致 GDI 物件洩漏。掌握 CPrintDialog + OnDraw 共用架構,即可用最少代碼實現專業級列印/預覽功能,關鍵在於座標映射與分頁控制的正確處理。