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

MFC 自繪 Edit 控件文字殘留問題:透明背景下的重繪機制解析

     編輯:程式設計綜合問答

問題現象

  • Edit 控件設置透明背景(WS_EX_TRANSPARENT 或 OnCtlColor 返回空畫刷)。
  • SetWindowText 後新舊文字重疊。
  • 按退格鍵刪除,舊文字未清除,新輸入文字重疊。

根本原因

透明背景意味著控件不擦除背景,WM_PAINT 時若不手動清除客戶區,舊像素將保留。標準 Edit 控件內部繪製邏輯假設背景會被擦除,透明模式下該假設失效。

解決方案

方案一:重寫 OnPaint,手動清除後調用默認繪製(推薦)

void CMyEdit::OnPaint() {
    CPaintDC dc(this);
    CRect rect;
    GetClientRect(&rect);
    // 1. 用窗口背景色填充,模擬擦除背景
    CBrush brush(GetSysColor(COLOR_WINDOW));
    dc.FillRect(&rect, &brush);
    // 2. 調用默認繪製邏輯
    Default(); // 或 CEdit::OnPaint()
}

方案二:攔截 WM_ERASEBKGND,返回 TRUE 並手動擦除


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 首行用正確背景色填充客戶區,再讓默認繪製流程跑通。

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