在 VC++ 開發 MDI 應用程式時,自訂主視窗用戶端區域(MDI Client Window)的背景是常見需求。雖然網路上流傳多種技巧,但 VC 6.0/5.0 的 MSDN Library 已提供標準解決方案。本文介紹基於 WM_ERASEBKGND 訊息處理的正規做法,並詳細說明子類別化 MDI 用戶端視窗的步驟。
Windows 透過處理 WM_ERASEBKGND 訊息實現背景重繪。標準做法:建立畫筆、選入裝置內容、取得裁剪矩形、使用 PatBlt 填滿背景、還原畫筆。
BOOL CMyView::OnEraseBkgnd(CDC* pDC) {
CBrush backBrush(RGB(255, 128, 128)); // 自訂背景色
CBrush* pOldBrush = pDC->SelectObject(&backBrush);
CRect rect; pDC->GetClipBox(&rect);
pDC->PatBlt(rect.left, rect.top, rect.Width(), rect.Height(), PATCOPY);
pDC->SelectObject(pOldBrush);
return TRUE; // 表示已處理背景擦除
}
MDI 主視窗的用戶端區域是獨立的子視窗(MDIClient 類別),需先將其子類別化,再處理其 WM_ERASEBKGND。
CWnd 的類別,命名為 CNewClientWndCMainFrame 中新增 CNewClientWnd m_wndNewClient 成員變數CMainFrame::OnCreate 中,呼叫基類 OnCreate 後,子類別化 MDI 用戶端視窗:if (!m_wndNewClient.SubclassWindow(m_hWndMDIClient)) {
TRACE("Failed to subclass MDI client window\n");
return -1;
}
注意: m_hWndMDIClient 是 CMDIFrameWnd 的 protected 成員,MSDN 說明中可查得,但在 ClassWizard 成員變數列表中不會顯示。
CNewClientWnd 中處理 WM_ERASEBKGND,套用上述標準背景繪製程式碼即可自訂 MDI 背景。CBitmap 載入圖片實現圖片背景OnEraseBkgnd 中繪製漸層、圖案等複雜效果WM_SIZE 動態調整背景繪製範圍