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

MFC 列印預覽深度解析:映射模式、座標轉換與裝置獨立性原理

     編輯:關於VC++

MFC 列印/預覽架構將繪圖邏輯統一在 CView::OnDraw(CDC* pDC),由框架決定 pDC 指向螢幕 DC、印表機 DC 或預覽 DC。本文深入剖析 預覽 DC 的特殊屬性 及 映射模式下的座標轉換機制。

預覽 DC 的「偽裝」特性

預覽時 pDC 並非螢幕 DC,而是根據**預設印表機屬性**構造的虛擬 DC:

  • 呼叫 GetDeviceCaps(HORZSIZE)/GetDeviceCaps(VERTSIZE) 返回紙張物理尺寸 (毫米),如 A4 為 210×297。
  • 呼叫 GetDeviceCaps(HORZRES)/GetDeviceCaps(VERTRES) 返回像素解析度,如 1200 DPI 下為 9921×14031。
  • 此 DC 的映射模式常設為 MM_LOMETRIC (0.1mm 為單位),邏輯座標系統直接對應實體紙張。

記憶體 DC (MemDC) 與預覽 DC 的差異

建立 MemDC.CreateCompatibleDC(pDC) 時,MemDC **不繼承** pDC 的映射模式與視口/視窗設定:

屬性預覽 DC (pDC)MemDC (預設)
映射模式MM_LOMETRICMM_TEXT (像素)
視口原點/範圍(0,0) / 9921×-14031 像素(0,0) / 1024×-768 (螢幕解析度)
視窗原點/範圍(0,0) / 2100×2970 (0.1mm)(0,0) / 3200×2400 (0.1mm)

因此 同一邏輯座標在兩個 DC 上 DPtoLP/LPtoDP 結果完全不同。

映射模式數學本質:視口 ↔ 視窗線性映射

MFC 維護兩個矩形區域:

  • 視窗:邏輯繪圖區,單位由映射模式決定。
  • 視口:實體輸出區 (螢幕/紙張/記憶體),單位永遠是像素。

座標轉換公式 (LPtoDP):

xVp = (xWin - xWinOrg) * cxVp / cxWin + xVpOrg
yVp = (yWin - yWinOrg) * cyVp / cyWin + yVpOrg

DPtoLP 為反運算。CDC 提供 GetWindowOrg/Ext, GetViewportOrg/Ext 取得參數。

實戰啟示

  1. 預覽時勿直接用 MemDC 做座標換算,需先 SetMapMode 同步模式,再 SetViewportOrg/Ext, SetWindowOrg/Ext 同步屬性。
  2. 列印/預覽/螢幕統一繪圖:在 OnDraw 僅使用邏輯座標 (如 MM_LOMETRIC),完全交由 DC 內部映射,實現真正的裝置獨立。
  3. 自繪控件列印:若控件自行管理 MemDC 雙緩衝,列印前必須將 MemDC 映射屬性與目標 DC 對齊,否則輸出位置/大小錯誤。

掌握視口/視窗映射關係,是解決 MFC 列印預覽「螢幕正常、列印偏移/縮放」疑難雜症的鑰匙。

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