首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> VC >> 關於VC++

MFC 列印程式設計全攻略:從文檔/視圖架構到對話框列印實戰

     編輯:關於VC++

前言:為什麼選擇 MFC 列印?

Windows SDK 風格的列印程式碼冗長且需深諳 GDI 底層流程。MFC 封裝了強大的列印框架,善用文檔/視圖架構可大幅簡化開發,支援列印預覽、多頁列印、頁首頁尾等專業功能。本文將由淺入深,從標準架構切入,再攻克「無文檔/視圖的對話框列印」這一實戰難題。

一、文檔/視圖架構下的列印機制

核心流程:CView::OnFilePrint 源碼解讀

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 物件

CPrintInfo 關鍵成員速查

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_pCallerDlg
  • CPrintView : 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 核心繪製

OnMyPrint 範例:繪製表格與圖表


void CDlgPrintDlg::OnMyPrint(WPARAM wParam, LPARAM lParam) {
    CDC* pDC = (CDC*)wParam;
    CPrintInfo* pInfo = (CPrintInfo*)lParam;
    
    int page = pInfo->m_nCurPage;
    // 依頁碼繪製對應內容:表格、曲線、影像...
    pDC->Rectangle(...);  // GDI 繪圖任意組合
}

三、已知限制與注意事項

  • 僅支援動態連結 MFC:靜態連結會導致模組狀態錯誤
  • Debug 版本較穩定:Release 下需仔細驗證記憶體管理
  • 預覽視窗的列印按鈕無效:必須在對話框另置「列印」按鈕
  • 資源釋放:CPrintFrame 需在列印結束後 delete,避免洩漏

四、實戰效果展示

列印功能對話框
圖 1:列印功能主對話框

列印預覽效果
圖 2:列印預覽單頁模式

雙頁預覽效果
圖 3:雙頁同屏預覽

印表機選擇對話框
圖 4:系統內建印表機選擇對話框(不可移除)

結語

透過虛擬文檔/視圖技法,對話框專案也能享用 MFC 完整的列印/預覽引擎。CPrintFrame / CPrintView 兩個可重用類別已封裝核心邏輯,開發者只需專注 OnMyPrint 的 GDI 繪製即可。掌握此技法,將列印開發效率提升數倍。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved