CObject → CDC。封裝 Win32 HDC,提供 C++ 介面呼叫 GDI 函數。OnDraw(CDC* pDC) 程式碼可用於螢幕、列印預覽、實際列印,只需傳入不同 CDC 衍生物件。CPaintDC:BeginPaint/EndPaint 自動管理,用於 WM_PAINT。CClientDC:GetDC/ReleaseDC 客戶區,座標原點 (0,0) 為客戶區左上角。CWindowDC:整個視窗(含標題列、邊框),座標原點為視窗左上角。void CMyView::OnLButtonDown(UINT nFlags, CPoint point)
{
CRect rect;
CClientDC dc(this); // 建構時 GetDC,解構時自動 ReleaseDC
dc.GetClipBox(&rect); // 取得裁剪矩形
} // dc 离开作用域,自動釋放
void CMyView::OnLButtonDown(UINT nFlags, CPoint point)
{
CRect rect;
CDC* pDC = GetDC(); // 取得 DC 指標
pDC->GetClipBox(&rect);
ReleaseDC(pDC); // 必須手動釋放,否則洩漏
}
所有 GDI 物件繼承自 CGdiObject(抽象基類),主要衍生類:
| 類別 | 對應 GDI 物件 | 用途 |
|---|---|---|
CPen | 筆 (HPEN) | 畫線、框線,可設顏色、寬度、樣式(實/虛/點線) |
CBrush | 刷 (HBRUSH) | 填充區域,純色、斜紋、位圖樣式 |
CFont | 字體 (HFONT) | 文字繪製,字型、大小、屬性 |
CBitmap | 位圖 (HBITMAP) | 影像儲存、繪製、建立樣式刷 |
CPalette | 調色板 (HPALETTE) | 256 色模式下色彩映射管理 |
CRgn | 區域 (HRGN) | 非矩形裁剪、點擊測試、填充區域 |
void CMyView::OnDraw(CDC* pDC)
{
// 1. 建立 GDI 物件(堆疊變數)
CPen pen(PS_SOLID, 2, RGB(255,0,0)); // 紅色實線,寬 2
CBrush brush(RGB(0,255,0)); // 綠色實心刷
// 2. 選入 DC,保存舊物件
CPen* pOldPen = pDC->SelectObject(&pen);
CBrush* pOldBrush = pDC->SelectObject(&brush);
// 3. 繪製
pDC->Rectangle(CRect(10,10,100,100)); // 使用當前筆畫框、刷填充
// 4. 還原舊物件(關鍵!)
pDC->SelectObject(pOldPen);
pDC->SelectObject(pOldBrush);
// pen, brush 离开作用域自動 DeleteObject
}
系統預建立常用 GDI 物件,透過 GetStockObject 取得,不可刪除:
BLACK_PEN, WHITE_PEN, NULL_PENWHITE_BRUSH, BLACK_BRUSH, GRAY_BRUSH, DKGRAY_BRUSH, LTGRAY_BRUSH, HOLLOW_BRUSH (同 NULL_BRUSH)SYSTEM_FONT, DEFAULT_GUI_FONT, ANSI_VAR_FONT, ANSI_FIXED_FONTpDC->SelectStockObject(DKGRAY_BRUSH); // 直接選入標準深灰刷
SetMapMode(MM_TEXT/MM_TWIPS/...)SetViewportOrg/Ext, SetWindowOrg/ExtSelectClipRgn, IntersectClipRectSetBkMode(OPAQUE/TRANSPARENT)SetTextColor, SetBkColorCPen, CBrush 等 → 自動清理。new 建立 → 必須 delete,且先從 DC 取出 (SelectObject(pOld))。SelectObject 選入新物件 → 必須保存舊物件指標 → 繪製完還原。GetStockObject) → 僅選入,絕不可刪除。理解 CDC 虛擬化、GDI 物件選入/還原流程與記憶體管理,是 MFC 繪圖程式穩定、高效的基石。