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

MFC 進度條顏色設定:自繪取代過時 PBM_SETBARCOLOR

     編輯:程式設計綜合問答

舊代碼使用 ::SendMessage(m_progress.GetSafeHwnd(), PBM_SETBARCOLOR, 0, RGB(255,0,255)) 設定進度條顏色,但在啟用 Visual Styles (XP 以上) 時無效。現代 MFC 應採用 自繪 (Owner Draw) 方式,完整掌控進度條外觀。

為何 PBM_SETBARCOLOR 失效

  • 該訊息屬於 Common Control 早期版本 (v5.x),僅在「傳統主題」下生效。
  • 啟用 InitCommonControlsEx 或 Manifest 宣告 Visual Styles 後,系統使用主題繪製引擎,忽略 PBM_SETBARCOLOR。

自繪實作步驟

  1. 進度條屬性設定 Owner Draw (資源編輯器勾選 Owner Draw Fixed 或代碼 ModifyStyle(0, PBS_OWNERDRAW))。
  2. 對話框類別處理 WM_DRAWITEM 訊息 (或 OnDrawItem)。
  3. 在 OnDrawItem 中繪製背景、進度塊、文字。

代碼範例

void CMyDialog::OnDrawItem(int nIDCtl, LPDRAWITEMSTRUCT lpDrawItemStruct) {
    if (nIDCtl != IDC_PROGRESS1) {
        CDialogEx::OnDrawItem(nIDCtl, lpDrawItemStruct);
        return;
    }

    CDC* pDC = CDC::FromHandle(lpDrawItemStruct->hDC);
    CRect rect = lpDrawItemStruct->rcItem;
    int progress = m_progress.GetPos(); // 0-100
    int max = 100; // 或 GetRangeMax()

    // 1. 繪製背景
    pDC->FillSolidRect(rect, RGB(240, 240, 240));
    pDC->Draw3dRect(rect, RGB(180,180,180), RGB(255,255,255));

    // 2. 計算進度區域
    CRect barRect = rect;
    barRect.DeflateRect(2, 2); // 內縮邊框
    barRect.right = barRect.left + (barRect.Width() * progress / max);

    // 3. 繪製漸層進度條 (自訂顏色)
    COLORREF startColor = RGB(0, 120, 215);  // 藍
    COLORREF endColor   = RGB(0, 80, 180);
    for (int x = barRect.left; x < barRect.right; x++) {
        double ratio = (double)(x - barRect.left) / barRect.Width();
        int r = (int)(GetRValue(startColor) + ratio * (GetRValue(endColor) - GetRValue(startColor)));
        int g = (int)(GetGValue(startColor) + ratio * (GetGValue(endColor) - GetGValue(startColor)));
        int b = (int)(GetBValue(startColor) + ratio * (GetBValue(endColor) - GetBValue(startColor)));
        pDC->FillSolidRect(x, barRect.top, 1, barRect.Height(), RGB(r,g,b));
    }

    // 4. 繪製百分比文字
    CString str;
    str.Format(_T("%d%%"), progress);
    pDC->SetBkMode(TRANSPARENT);
    pDC->SetTextColor(RGB(0,0,0));
    pDC->DrawText(str, rect, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
}

進階技巧

  • 雙緩衝:使用 CMemDC 減少閃爍。
  • 主題感知:呼叫 IsAppThemed() 判斷是否啟用主題,決定是否自繪。
  • 動畫效果:在 OnTimer 中漸變 progress 並 Invalidate()。

總結

放棄 PBM_SETBARCOLOR,改用 PBS_OWNERDRAW + OnDrawItem,不僅相容所有 Windows 版本,還能實現漸層、圓角、動畫等豐富視覺效果。

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