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

動態真彩工具列進階實現:ReBar + 圖示熱態切換 + 自訂背景圖

     編輯:VC 教學

作者分享專案實戰中提煉的「動態真彩工具列」模組,特色在於:基於 ReBar 控制項 (支援背景圖、捲動)、圖示支援冷/熱態切換、按鈕尺寸/文字/圖示全動態建立、扁平化風格。適合需要高度客製化工具列介面的專案。

效果展示

核心實現步驟 (於 CMainFrame)

1. 成員變數宣告

CReBar m_wndReBar; // ReBar 容器,取代傳統工具列直接停靠

2. 核心建立函數 CreateExToolBar()

BOOL CMainFrame::CreateExToolBar()
{
    CImageList img;
    CString str;

    // 建立 ReBar
    if (!m_wndReBar.Create(this)) return FALSE;

    // 建立工具列 (扁平、工具提示、飛越、動態尺寸)
    if (!m_wndToolBar.CreateEx(this, TBSTYLE_FLAT, 
        WS_CHILD | WS_VISIBLE | CBRS_TOP | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC))
        return FALSE;

    // 設定按鈕寬度範圍
    m_wndToolBar.GetToolBarCtrl().SetButtonWidth(40, 80);

    // ===== 熱態圖像列表 (滑鼠經過) =====
    img.Create(22, 22, ILC_COLOR8 | ILC_MASK, 2, 2);
    img.SetBkColor(::GetSysColor(COLOR_BTNFACE));
    img.Add(AfxGetApp()->LoadIcon(IDI_ICON_MSG_GETBUTTON)); // 0: 收信
    // ... 省略其他圖示 Add ...
    m_wndToolBar.GetToolBarCtrl().SetHotImageList(&img);
    img.Detach(); // 所有權轉移

    // ===== 冷態圖像列表 (一般) =====
    img.Create(19, 19, ILC_COLOR8 | ILC_MASK, 2, 2);
    img.SetBkColor(::GetSysColor(COLOR_BTNFACE));
    img.Add(AfxGetApp()->LoadIcon(IDI_ICON_MSG_GETBUTTON)); // 0: 收信
    img.Add(AfxGetApp()->LoadIcon(IDI_ICON_MSG_WRITEMSGBTN)); // 1: 寫信
    // ... 省略其他圖示 Add ...
    m_wndToolBar.GetToolBarCtrl().SetImageList(&img);
    img.Detach();

    // 調整風格:扁平、工具提示、透明背景、核取方塊風格
    m_wndToolBar.ModifyStyle(0, TBSTYLE_FLAT | CBRS_TOOLTIPS | TBSTYLE_TRANSPARENT | TBBS_CHECKBOX);

    // 動態設定按鈕資訊 (ID、圖示索引、文字)
    m_wndToolBar.SetButtons(NULL, 21); // 配置 21 個按鈕位置
    m_wndToolBar.SetButtonInfo(0, IDC_WRITEMSG, TBSTYLE_BUTTON, 1);
    m_wndToolBar.SetButtonText(0, _T("寫信"));
    // ... 省略其他按鈕設定 ...

    // 計算按鈕實際大小並設定工具列尺寸
    CRect rectToolBar;
    m_wndToolBar.GetItemRect(0, &rectToolBar);
    m_wndToolBar.SetSizes(rectToolBar.Size(), CSize(20, 20));

    // 加入 ReBar
    m_wndReBar.AddBar(&m_wndToolBar);

    // ===== 進階:為 ReBar 頻帶設定背景位圖 =====
    REBARBANDINFO rbbi = { sizeof(REBARBANDINFO) };
    rbbi.fMask = RBBIM_CHILDSIZE | RBBIM_IDEALSIZE | RBBIM_SIZE | RBBIM_BACKGROUND;
    rbbi.cxMinChild = rectToolBar.Width();
    rbbi.cyMinChild = rectToolBar.Height();
    rbbi.hbmBack = LoadBitmap(::AfxGetInstanceHandle(), MAKEINTRESOURCE(IDB_TOOLBARBKMAP)); // 背景圖資源
    rbbi.cx = rbbi.cxIdeal = rectToolBar.Width() * 10;
    m_wndReBar.GetReBarCtrl().SetBandInfo(0, &rbbi);

    return TRUE;
}

3. OnCreate 中調用並清除舊代碼

if (!this->CreateExToolBar()) return -1;
// 刪除原有工具列建立、浮動相關代碼

關鍵技術亮點

  • ReBar 容器化: 取代傳統 DockControlBar,支援工具列內嵌背景圖、斷行捲動、混合編輯框/下拉框等子控制項。
  • 冷/熱態分離載入: 分別建立不同尺寸 (19x19 vs 22x22) 的圖像列表,熱態圖示通常稍大、更飽和,視覺回饋明顯。
  • 圖示資源管理: 統一使用 AfxGetApp()->LoadIcon 載入圖示資源,CImageList::Add(HICON) 自動處理透明遮罩。
  • 動態按鈕配置: SetButtons(NULL, nCount) 預留位置,SetButtonInfo/SetButtonText 逐一配置,極靈活。
  • 背景圖技巧: REBARBANDINFO::hbmBack + RBBIM_BACKGROUND 旗標,賦予工具列獨特材質感。

作者提醒

  • 每個按鈕的 ID、訊息處理需手動添加 (類別精靈不支援動態建立的按鈕)。
  • 範例代碼省略了重複的圖示 Add 與按鈕設定,完整版請下載附件。

這套方案展現了 MFC 進階 UI 開發的實戰智慧,適合作為專案通用工具列基礎模組延伸開發。

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