MFC 列印/預覽架構將繪圖邏輯統一在 CView::OnDraw(CDC* pDC),由框架決定 pDC 指向螢幕 DC、印表機 DC 或預覽 DC。本文深入剖析 預覽 DC 的特殊屬性 及 映射模式下的座標轉換機制。
預覽時 pDC 並非螢幕 DC,而是根據**預設印表機屬性**構造的虛擬 DC:
GetDeviceCaps(HORZSIZE)/GetDeviceCaps(VERTSIZE) 返回紙張物理尺寸 (毫米),如 A4 為 210×297。GetDeviceCaps(HORZRES)/GetDeviceCaps(VERTRES) 返回像素解析度,如 1200 DPI 下為 9921×14031。MM_LOMETRIC (0.1mm 為單位),邏輯座標系統直接對應實體紙張。建立 MemDC.CreateCompatibleDC(pDC) 時,MemDC **不繼承** pDC 的映射模式與視口/視窗設定:
| 屬性 | 預覽 DC (pDC) | MemDC (預設) |
|---|---|---|
| 映射模式 | MM_LOMETRIC | MM_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 取得參數。
SetMapMode 同步模式,再 SetViewportOrg/Ext, SetWindowOrg/Ext 同步屬性。OnDraw 僅使用邏輯座標 (如 MM_LOMETRIC),完全交由 DC 內部映射,實現真正的裝置獨立。掌握視口/視窗映射關係,是解決 MFC 列印預覽「螢幕正常、列印偏移/縮放」疑難雜症的鑰匙。