MFC 對話方塊/視圖中修改 CStatic (StaticText) 字體顏色/字型時,文字背景出現灰白條紋/邊框殘留,與對話方塊背景不融合。

OnCtlColor 返回的 HBRUSH 決定控件背景繪製方式NULL 或父類筆刷,導致文字區域使用系統預設背景色 (通常灰白)
class CMyDialog : public CDialogEx {
// ...
protected:
CFont m_customFont; // 自定義字體
CBrush m_bgBrush; // 背景筆刷 (關鍵)
COLORREF m_textColor; // 文字顏色
COLORREF m_bgColor; // 背景顏色
};
BOOL CMyDialog::OnInitDialog() {
CDialogEx::OnInitDialog();
// 1. 設定目標顏色 (與對話方塊背景一致)
m_textColor = RGB(0, 0, 255); // 藍色文字
m_bgColor = GetSysColor(COLOR_BTNFACE); // 系統按鈕面板色 (典型灰白)
// 或指定確切色值:m_bgColor = RGB(240, 240, 240);
// 2. 建立字體
m_customFont.CreatePointFont(100, _T("微軟正黑體")); // 10 點大小
// 或 LOGFONT 精細控制
// 3. 建立背景筆刷 (核心步驟!)
m_bgBrush.CreateSolidBrush(m_bgColor);
// 4. 關聯控件變數 (若使用 DDX_Control)
// m_staticCtrl.SubclassDlgItem(IDC_STATIC_INFO, this);
return TRUE;
}
HBRUSH CMyDialog::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor) {
HBRUSH hbr = CDialogEx::OnCtlColor(pDC, pWnd, nCtlColor); // 必須調用基類
// 針對特定 Static 控件
if (pWnd->GetDlgCtrlID() == IDC_STATIC_INFO) {
// 1. 設定文字顏色
pDC->SetTextColor(m_textColor);
// 2. 設定文字背景模式:透明 (關鍵!)
pDC->SetBkMode(TRANSPARENT);
// 3. 選入自定義字體
pDC->SelectObject(&m_font);
// 4. 返回自定義背景筆刷
return m_bgBrush;
}
return hbr;
}
| 設置 | 作用 | 錯誤後果 |
|---|---|---|
SetBkMode(TRANSPARENT) | 文字背景透明,由筆刷填充 | 文字周圍出現不透明矩形框 |
CreateSolidBrush(bgColor) | 實體筆刷填充控件背景 | 背景色與對話框不一致 |
SelectObject(&font) | 應用自定義字體 | 字體不生效 |
返回 m_bgBrush | 告訴系統用此筆刷繪製背景 | 使用預設筆刷 |
void CMyDialog::SetStaticColor(COLORREF textColor, COLORREF bgColor) {
m_textColor = textColor;
m_bgColor = bgColor;
// 重建筆刷
if (m_bgBrush.GetSafeHandle()) m_bgBrush.DeleteObject();
m_bgBrush.CreateSolidBrush(m_bgColor);
// 觸發重繪
CWnd* pStatic = GetDlgItem(IDC_STATIC_INFO);
if (pStatic) pStatic->Invalidate(TRUE); // TRUE = 擦除背景
}
// 1. 控件屬性設定 Owner Draw (固定)
// 2. 重寫 DrawItem
void CMyDialog::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct) {
if (lpDrawItemStruct->CtlID == IDC_STATIC_INFO) {
CDC dc;
dc.Attach(lpDrawItemStruct->hDC);
CRect rect = lpDrawItemStruct->rcItem;
// 填充背景
dc.FillSolidRect(rect, m_bgColor);
// 設定文字屬性
dc.SetTextColor(m_textColor);
dc.SetBkMode(TRANSPARENT);
CFont* pOldFont = dc.SelectObject(&m_customFont);
// 繪製文字
CString text;
GetDlgItemText(IDC_STATIC_INFO, text);
dc.DrawText(text, rect, DT_LEFT | DT_VCENTER | DT_SINGLELINE);
dc.SelectObject(pOldFont);
dc.Detach();
return;
}
CDialogEx::DrawItem(lpDrawItemStruct);
}
CBrush/CFont 自動管理)GetSysColor(COLOR_BTNFACE) 或 GetSysColor(COLOR_WINDOW) 適應主題切換CreatePointFont 返回 BOOL,失敗時 GetSafeHandle() 為 NULL修正前:

修正後:
