WS_EX_TRANSPARENT 或 OnCtlColor 返回空畫刷)。SetWindowText 後新舊文字重疊。透明背景意味著控件不擦除背景,WM_PAINT 時若不手動清除客戶區,舊像素將保留。標準 Edit 控件內部繪製邏輯假設背景會被擦除,透明模式下該假設失效。
void CMyEdit::OnPaint() {
CPaintDC dc(this);
CRect rect;
GetClientRect(&rect);
// 1. 用窗口背景色填充,模擬擦除背景
CBrush brush(GetSysColor(COLOR_WINDOW));
dc.FillRect(&rect, &brush);
// 2. 調用默認繪製邏輯
Default(); // 或 CEdit::OnPaint()
}
BOOL CMyEdit::OnEraseBkgnd(CDC* pDC) {
CRect rect;
GetClientRect(&rect);
CBrush brush(GetSysColor(COLOR_WINDOW));
pDC->FillRect(&rect, &brush);
return TRUE; // 標記已處理,系統不再發送 WM_PAINT 擦除背景
}
HBRUSH CMyEdit::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor) {
HBRUSH hbr = CEdit::OnCtlColor(pDC, pWnd, nCtlColor);
pDC->SetBkMode(OPAQUE); // 不透明模式
pDC->SetBkColor(GetSysColor(COLOR_WINDOW)); // 設置背景色
return hbr;
}
| 誤區 | 後果 | 正確做法 |
|---|---|---|
| 只設置 WS_EX_TRANSPARENT | 背景不擦除,文字殘留 | 必須配合 OnPaint/OnEraseBkgnd 手動清除 |
| OnPaint 中未調用 Default() | 文字不顯示 | 清除背景後必須調用 Default() 繪製文本 |
| 使用 GetBkColor() 獲取背景色 | 透明模式下返回無效值 | 用 GetSysColor(COLOR_WINDOW) 或父窗口背景色 |
MFC 透明控件的核心矛盾在於系統默認擦除背景與透明屬性衝突。解決之道是接管擦除背景責任:在 OnEraseBkgnd 或 OnPaint 首行用正確背景色填充客戶區,再讓默認繪製流程跑通。