錯誤嘗試
- `PreCreateWindow` 註冊窗口類別刷子:僅影響**窗口類別預設背景**,`CView` 的 `OnDraw` 會在 `CPaintDC` 上繪圖,**不會自動擦除背景**。
- `OnEraseBkgnd` 手動 `PatBlt`:`CView` 預設 `OnEraseBkgnd` 回傳 `FALSE` (不擦除),若回傳 `TRUE` 並繪製,**會與 `OnDraw` 產生閃爍**,且列印/預覽時行為不同。
正確做法:在 OnDraw 開頭填充背景
void CMyView::OnDraw(CDC* pDC) {
CMyDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
if (!pDoc) return;
// 1. 取得客戶區矩形
CRect rect;
GetClientRect(&rect);
// 2. 填充背景色 (例如黑色)
CBrush brush(RGB(0, 0, 0)); // 或 GetSysColor(COLOR_WINDOW)
pDC->FillRect(&rect, &brush);
// 或 pDC->FillSolidRect(&rect, RGB(0,0,0));
// 3. 繼續原有繪圖邏輯
// pDC->TextOut(...); pDC->LineTo(...); ...
}
進階:雙重緩衝防止閃爍
void CMyView::OnDraw(CDC* pDC) {
CRect rect; GetClientRect(&rect);
CMemDC memDC(pDC, &rect); // MFC 提供的記憶體 DC 包裝類 (VC6 起內建)
CDC* pMemDC = &memDC;
// 背景
pMemDC->FillSolidRect(&rect, RGB(0,0,0));
// 繪圖...
pMemDC->TextOut(10, 10, _T("Hello"));
// CMemDC 解構時自動 BitBlt 到螢幕 DC,零閃爍
}
關鍵點
- `OnDraw` **每次重繪都會被呼叫**,在開頭填充背景即可保證顏色正確。
- **不要** 在 `OnEraseBkgnd` 做複雜繪圖,回傳 `FALSE` 讓 `OnDraw` 全權處理。
- 列印/預覽時 `OnDraw` 也會被呼叫 (傳入列印 DC),背景填充邏輯同樣生效 (可依 `pDC->IsPrinting()` 調整)。