void CTestView::OnDraw(CDC* pDC) {
CRect rect; GetClientRect(&rect);
CBrush brush(RGB(255,0,0));
pDC->FillRect(&rect, &brush); // 每次重繪都會先擦除再填 → 閃爍
}
MFC 繪圖流程:WM_ERASEBKGND → 系統用類別註冊時的 hbrBackground 擦除 → OnDraw 繪製內容。在 OnDraw 重填背景會導致「擦白→填紅」雙重繪製,產生閃爍。
COLORREF m_viewBkColor 並提供 Get/Set,支援序列化ON_WM_ERASEBKGND()BOOL CTestView::OnEraseBkgnd(CDC* pDC) {
CRect rect; pDC->GetClipBox(&rect); // 僅取得需更新區域
CBrush brush(GetDocument()->GetViewBkColor());
pDC->FillRect(&rect, &brush);
return TRUE; // 告訴系統已處理擦除,不再預設動作
}
void CTestView::OnChangeViewBkColor() {
CColorDialog dlg;
if(dlg.DoModal() == IDOK) {
GetDocument()->SetViewBkColor(dlg.GetColor());
InvalidateRect(NULL); // 觸發重繪
}
}
CTestDialog dlg;
dlg.SetWindowText(_T("新標題")); // 失效:視窗尚未建立
dlg.DoModal();
DoModal 內部才建立視窗物件,建構函數返回時視窗不存在;DoModal 返回後視窗已銷毀。
CString m_strCaption 公有成員CTestDialog dlg;
dlg.m_strCaption = _T("動態標題");
dlg.DoModal();
OnInitDialog:BOOL CTestDialog::OnInitDialog() {
CDialog::OnInitDialog();
if(!m_strCaption.IsEmpty()) SetWindowText(m_strCaption);
return TRUE;
}
兩個技巧本質相同:在正確的生命週期階段執行正確的代碼。MFC 框架預定義了大量虛擬函數與訊息映射入口,掌握調用時序(建構 → Create/DoModal → OnInitDialog/OnCreate → WM_ERASEBKGND → OnDraw → 銷毀)是寫出高效、穩定程式的關鍵。