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

Windows GDI 程式設計入門:從 DC 封裝到記憶體繪圖防閃爍

     編輯:VC++

一、GDI 基礎觀念

GDI 繪圖函式皆為有狀態操作,核心在於裝置內容。取得 HDC 三大途徑:

  • BeginPaint / EndPaint:回應 WM_PAINT 專用。
  • GetWindowDC / ReleaseDC:整個視窗區域(含邊框、標題列)。
  • GetDC / ReleaseDC:僅客戶區。

MFC 封裝類別對應關係:

MFC 類別封裝對象建構/解構行為
CPaintDCBeginPaint/EndPaint建構呼叫 BeginPaint,解構呼叫 EndPaint
CWindowDCGetWindowDC/ReleaseDC建構呼叫 GetWindowDC,解構呼叫 ReleaseDC
CClientDCGetDC/ReleaseDC建構呼叫 GetDC,解構呼叫 ReleaseDC

CDC 將需 HDC 參數的 GDI 函式封裝為成員函式,HDC 成為其成員變數。

二、實作範例:自繪平面風格狀態列

繼承 CStatusBar,覆寫 OnEraseBkgnd 與 OnPaint:

  • OnEraseBkgnd:以灰色筆刷填滿背景。
  • OnPaint:逐格繪製圓角矩形、填入文字、繪製右下角調整大小圖示(六個小圓)。

關鍵技巧:SelectObject 切換筆、刷、字體,用畢必須還原原始物件,否則造成 GDI 物件洩漏。兩種還原策略:

  1. 保存舊物件指標,繪製完畢呼叫 SelectObject(pOld) 還原。
  2. 直接選入系統預備物件 GetStockObject(NULL_BRUSH),無需還原。

特例:FillRect 直接接受筆刷參數,不依賴 DC 狀態。

三、進階技巧

1. 學習捷徑

閱讀、除錯他人原始碼是最快累積 GDI 經驗的途徑。

2. 除錯技巧

  • IDE 與測試視窗分開排列,單步執行即可觀察每步繪圖效果。
  • 在 InitInstance 加入 GdiSetBatchLimit(1)(僅 _DEBUG),強制每個 GDI 呼叫即時生效,避免批次處理導致除錯時畫面不更新。

3. 記憶體繪圖防閃爍

原理:先在相容記憶體 DC 繪製完畢,再一次 BitBlt 複製到螢幕 DC。

HDC hMemDC = CreateCompatibleDC(hDestDC);
HBITMAP hBmp = CreateCompatibleBitmap(hDestDC, rc.right, rc.bottom);
HBITMAP hOldBmp = SelectObject(hMemDC, hBmp);
// ... 在 hMemDC 上繪圖 ...
BitBlt(hDestDC, rc.left, rc.top, rc.right, rc.bottom, hMemDC, 0, 0, SRCCOPY);
SelectObject(hMemDC, hOldBmp);
DeleteObject(hBmp);
DeleteDC(hMemDC);

封裝為 CMemDC 類別,利用建構/解構自動管理,除錯時可透過條件編譯切換是否使用記憶體 DC,兼顧效能與除錯便利性。

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