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

Windows GDI 設備內容(DC)完整操作指南與 MFC 封裝類詳解

     編輯:關於VC++

核心概念:什麼是設備內容?

Windows 繪圖不直接操作硬體像素,而是透過 設備內容(Device Context,DC) 這個邏輯繪圖平面。DC 是一個資料結構,封裝了 GDI 所需的所有繪圖狀態:關聯的實體裝置、筆刷、字型、對映模式、裁剪區域等。程式必須先取得 HDC,繪圖後再歸還,否則會造成資源洩漏。

三種取得/釋放 DC 的層級

1. 純 Win32 API:GetDC / ReleaseDC

// 取得整個螢幕 DC
HDC hDC = ::GetDC(NULL);
::MoveToEx(hDC, 0, 0, NULL);
::LineTo(hDC, 200, 20);
::ReleaseDC(NULL, hDC);  // 參數必須與 GetDC 配對

// 取得特定視窗客戶區 DC
HDC hDC = ::GetDC(m_hWnd);
::MoveToEx(hDC, 0, 0, NULL);
::LineTo(hDC, 200, 50);
::ReleaseDC(m_hWnd, hDC);

關鍵點:GetDC(NULL) 取得螢幕 DC,座標原點在螢幕左上角;GetDC(hWnd) 取得視窗客戶區 DC,原點在客戶區左上角。務必配對呼叫 ReleaseDC,否則 GDI 物件計數器會遞增導致系統資源耗盡。

2. MFC CWnd 封裝:GetDC / ReleaseDC


CDC* pDC = GetDC();
pDC->MoveTo(0, 0);
pDC->LineTo(200, 100);
ReleaseDC(pDC);

MFC 將 HDC 包裝為 CDC*,提供物件導向介面,自動處理座標轉換與狀態管理,程式碼更簡潔。

3. MFC 專用 DC 類別:自動建構/解構管理生命週期(最推薦)

MFC 提供三個 CDC 衍生類,建構子自動取得 DC,解構子自動釋放,彈性對應不同繪圖範圍:

類別對應範圍典型用途建構/解構對應 API
CClientDC視窗客戶區一般繪圖、回應 WM_PAINT 外的即時繪製GetDC/ReleaseDC
CWindowDC整個視窗(含非客戶區)繪製標題列、邊框、捲軸等非客戶區元素GetWindowDC/ReleaseDC
CPaintDC視窗客戶區僅限 OnPaint 內回應 WM_PAINTBeginPaint/EndPaint

實戰程式碼範例

CClientDC:繪製紅色矩形於客戶區


void CDCDemoDlg::OnCclientdc() {
    CClientDC dc(this);                    // 自動 GetDC
    CBrush brush(RGB(255,0,0));            // 紅色筆刷
    dc.FillRect(CRect(0,0,100,100), &brush); // 填滿矩形
}                                           // dc 解構自動 ReleaseDC

CWindowDC:繪製綠色粗線跨越整個視窗


void CDCDemoDlg::OnCwindowdc() {
    CWindowDC dc(this);                    // 自動 GetWindowDC
    CPen pen(PS_SOLID, 3, RGB(0,255,0));   // 3 像素實線綠筆
    CPen* pOldPen = dc.SelectObject(&pen); // 選入並保存舊筆
    dc.MoveTo(0, 0);
    dc.LineTo(200, 200);
    dc.SelectObject(pOldPen);              // 恢復舊筆
}                                           // dc 解構自動 ReleaseDC

動態配置 DC 指標(堆疊上建立衍生類物件)


void CDCDemoDlg::OnPointer() {
    CWindowDC* pDC = new CWindowDC(this);  // 堆疊配置
    pDC->MoveTo(0, 0);
    pDC->LineTo(200, 250);
    delete pDC;                            // 手動刪除觸發解構子釋放 DC
}

注意:動態配置時必須成對 new/delete,否則 DC 不會被釋放。

最佳實踐總結

  1. 優先使用 CClientDC/CWindowDC/CPaintDC:RAII 機制確保不洩漏,程式碼最簡潔。
  2. 僅在需要精確控制生命週期時 才用 CWnd::GetDC/ReleaseDC。
  3. 避免直接呼叫 Win32 API,除非在非 MFC 專案或特殊需求下。
  4. 繪圖物件(筆、刷、字型)選入 DC 後務必恢復,防止 GDI 物件洩漏。

掌握 DC 的取得與釋放機制,是 Windows 繪圖程式穩定、高效的基石。

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