首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計疑難解答

MFC SelectObject 返回 NULL:CDC 指針未初始化導致繪圖失敗

     編輯:程式設計疑難解答

錯誤代碼

CDC *m_pDC; // 僅聲明,未初始化!
COLORREF ColorValue = RGB(255,255,255);
CRect rect(50,50,200,200);
CBrush newBrush;
newBrush.CreateSolidBrush(ColorValue);
CBrush *oldBrush = m_pDC->SelectObject(&newBrush); // 此處崩潰/返回 NULL
m_pDC->Rectangle(rect);
m_pDC->SelectObject(oldBrush);

核心問題

CDC *m_pDC; 只是一個野指針,未指向任何有效的設備上下文對象。調用 m_pDC->SelectObject 即為未定義行為(通常崩潰或返回 NULL)。

正確獲取 CDC 指針的場景

1. 視圖類 OnDraw 中

void CMyView::OnDraw(CDC* pDC) {
    // pDC 由框架傳入,有效
    CBrush brush(RGB(255,0,0));
    CBrush* pOld = pDC->SelectObject(&brush);
    pDC->Rectangle(10,10,100,100);
    pDC->SelectObject(pOld);
}

2. 對話框/窗口客戶區繪圖

// 在 WM_PAINT 或 OnPaint 中
CPaintDC dc(this); // 構造函數自動 BeginPaint
CBrush brush(RGB(0,255,0));
CBrush* pOld = dc.SelectObject(&brush);
dc.Ellipse(20,20,120,120);
dc.SelectObject(pOld); // 析構函數自動 EndPaint

3. 內存設備上下文(雙緩衝)


CDC memDC;
memDC.CreateCompatibleDC(pDC); // pDC 為目標 DC
CBitmap bmp;
bmp.CreateCompatibleBitmap(pDC, width, height);
CBitmap* pOldBmp = memDC.SelectObject(&bmp);

// 在 memDC 上繪圖...
memDC.SelectObject(pOldBmp);
pDC->BitBlt(0,0,width,height,&memDC,0,0,SRCCOPY);

GDI 物件選入/選出鐵律

  1. 選入自定義物件前,必須保存舊物件指針:CGdiObject* pOld = pDC->SelectObject(&newObj);
  2. 繪圖結束後,必須選回舊物件:pDC->SelectObject(pOld);
  3. 自定義物件 (CBrush, CPen, CFont...) 必須在 DC 釋放前銷毀:通常作為局部變量,離開作用域自動析構。
  4. 不要選入股票物件:GetStockObject 返回的物件無需/不可選出。

總結

CDC *m_pDC; 未初始化是導致 SelectObject 失敗的直接原因。MFC 繪圖必須在有效的 CDC 對象上進行,來源通常是框架傳遞的 OnDraw(CDC*) 參數、CPaintDC、CClientDC 或兼容 DC。牢記 GDI 物件選入選出配對,避免資源洩漏與繪圖異常。

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