首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> VC >> VC 教學

VC++ 變更對話框與視圖類別背景色:四種方法比較與適用場景

     編輯:VC 教學

前言

MFC 對話框(CDialog)與視圖(CView)預設使用系統 3D 面板色。本文比較四種變更背景色的方法,分析優缺點與適用場景。

方法一:CWinApp::SetDialogBkColor(全域)


BOOL CMyApp::InitInstance()
{
    SetDialogBkColor(RGB(192,192,192), RGB(0,0,0)); // 背景、文字
    return TRUE;
}
  • 影響**所有**對話框與視圖。
  • 無法針對單一視窗設定;不支援圖片。

方法二:WM_CTLCOLOR (OnCtlColor) — 推薦用於對話框


// 標頭
protected:
    CBrush m_brushBg;

// OnInitDialog
m_brushBg.CreateSolidBrush(RGB(0,255,0)); // 綠色

// 訊息對應
ON_WM_CTLCOLOR()

// 實作
HBRUSH CMyDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
    HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);
    if (nCtlColor == CTLCOLOR_DLG) {
        pDC->SetBkMode(TRANSPARENT);
        return m_brushBg;
    }
    return hbr;
}
  • 針對單一對話框;可分別設定控制項(編輯框、靜態文字)顏色。
  • 需成員變數持有 CBrush 避免重建/洩漏。
  • **無法用於 CView**(視圖類別不接收 WM_CTLCOLOR)。

方法三:WM_PAINT (OnPaint) 直接繪製


void CMyView::OnPaint()
{
    CPaintDC dc(this);
    CRect rc; GetClientRect(&rc);
    dc.FillSolidRect(rc, RGB(0,255,0));
}
  • 簡單直接,對話框/視圖皆適用。
  • **缺點**:會覆蓋子控制項背景,導致編輯框、按鈕出現白框;需額外處理 WM_ERASEBKGND 返回 TRUE 才完整。

方法四:WM_ERASEBKGND (OnEraseBkgnd) 繪製


BOOL CMyView::OnEraseBkgnd(CDC* pDC)
{
    CRect rc; GetClientRect(&rc);
    CBrush brush(RGB(0,0,0)); // 黑色
    CBrush* pOld = pDC->SelectObject(&brush);
    pDC->Rectangle(&rc);
    pDC->SelectObject(pOld);
    return TRUE; // 阻止系統預設擦除
}
  • 在背景擦除階段繪製,效率較 OnPaint 高。
  • 同樣會影響子控制項;若需共存需子控制項設 WS_EX_TRANSPARENT。

比較總結表

方法適用對象支援圖片子控制項影響推薦場景
SetDialogBkColorDialog/View否無全專案統一色系
OnCtlColorDialog否可分別控制單一對話框純色
OnPaintDialog/View是(可自行繪圖)會覆蓋簡單測試/漸層/圖形
OnEraseBkgndDialog/View是會覆蓋圖片背景/雙緩衝

進階:視圖類別使用 OnEraseBkgnd + 雙緩衝繪製圖片背景


BOOL CMyView::OnEraseBkgnd(CDC* pDC)
{
    CRect rc; GetClientRect(&rc);
    CDC memDC; memDC.CreateCompatibleDC(pDC);
    CBitmap bmp; bmp.CreateCompatibleBitmap(pDC, rc.Width(), rc.Height());
    CBitmap* pOld = memDC.SelectObject(&bmp);

    // 載入資源位圖並拉伸繪製到 memDC
    CBitmap bg; bg.LoadBitmap(IDB_BG);
    CDC bgDC; bgDC.CreateCompatibleDC(&memDC);
    CBitmap* pOldBg = bgDC.SelectObject(&bg);
    BITMAP bm; bg.GetBitmap(&bm);
    memDC.StretchBlt(0,0,rc.Width(),rc.Height(), &bgDC,0,0,bm.bmWidth,bm.bmHeight,SRCCOPY);
    bgDC.SelectObject(pOldBg);

    pDC->BitBlt(0,0,rc.Width(),rc.Height(), &memDC,0,0,SRCCOPY);
    memDC.SelectObject(pOld);
    return TRUE;
}
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved