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

VC++ 工具列嵌入扁平化 ComboBox 完整實作:Office 2000 風格打造

     編輯:VC 教學

設計概念:工具列即類別,控制項為成員

MFC 預設工具列僅支援按鈕。將工具列封裝為 CMainToolBar : public CToolBar,以 CFlatComboBox m_wndZoom 為成員變數,實現物件導向封裝。

CFlatComboBox:自繪扁平化下拉框

  • 繼承 CComboBox,處理 WM_MOUSEMOVE、WM_LBUTTONDOWN、WM_LBUTTONUP、WM_TIMER、WM_PAINT
  • 三種視覺狀態:FC_DRAWNORMAL(平坦)、FC_DRAWRAISED(滑鼠進入凸起)、FC_DRAWPRESSD(按下凹陷)
  • 利用 Draw3dRect 繪製 3D 邊框模擬,覆蓋系統預設邊框
  • OnTimer 每 10ms 檢查滑鼠位置,實現即時狀態切換

動態建立 ComboBox 於工具列

// CMainFrame::OnCreate 中
int index = 0;
RECT rect;
// 1. 找到預留的空白按鈕 (IDC_COMBOX)
while (m_wndToolBar.GetItemID(index) != IDC_COMBOX) index++;

// 2. 設定按鈕寬度為分隔符,保留空間
m_wndToolBar.SetButtonInfo(index, IDC_COMBOX, TBBS_SEPARATOR, 80);
m_wndToolBar.GetItemRect(index, &rect);

// 3. 調整矩形:上移 2px,下方展開 200px 供下拉清單
rect.top += 2;
rect.bottom += 200;

// 4. 建立 ComboBox (CBS_DROPDOWNLIST 禁止輸入)
if (!m_wndToolBar.m_wndZoom.Create(
        WS_CHILD | WS_VISIBLE | CBS_AUTOHSCROLL | CBS_DROPDOWNLIST | CBS_HASSTRINGS,
        rect, &m_wndToolBar, IDC_COMBOX))
    return FALSE;

m_wndToolBar.m_wndZoom.ShowWindow(SW_SHOW);

// 5. 填入縮放選項
m_wndToolBar.m_wndZoom.AddString(_T("25%"));
m_wndToolBar.m_wndZoom.AddString(_T("50%"));
// ... 至 200%
m_wndToolBar.m_wndZoom.SetCurSel(3); // 預設 100%

手動加入訊息對應(ClassWizard 無法處理動態建立控制項)

// MainFrm.h
afx_msg void OnSelectZoomed();

// MainFrm.cpp
BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
    ON_WM_CREATE()
    ON_CBN_SELENDOK(IDC_COMBOX, OnSelectZoomed)
END_MESSAGE_MAP()

void CMainFrame::OnSelectZoomed()
{
    CString str;
    m_wndToolBar.m_wndZoom.GetWindowText(str);
    AfxMessageBox(str); // 實際專案改為套用縮放邏輯
}

擴充:同樣手法加入 Edit Control

// 預留 IDC_EDIT 空白按鈕
m_wndToolBar.SetButtonInfo(9, IDC_EDIT, TBBS_SEPARATOR, 160);
m_wndToolBar.GetItemRect(9, &rect);
m_wndToolBar.m_wndEdit.Create(WS_VISIBLE | WS_TABSTOP, rect, &m_wndToolBar, IDC_EDIT);

關鍵技術總結

技術點說明
資源編輯器預留空白按鈕以 TBBS_SEPARATOR 樣式佔位,不顯示圖片
SetButtonInfo 寬度設定決定控制項在工具列的寬度
GetItemRect 取得座標將工具列座標轉為控制項建立所需的 client rect
動態 Create 控制項父視窗指定為工具列,ID 與資源按鈕一致
手寫訊息對應ON_CBN_SELENDOK / ON_CBN_EDITCHANGE 等

現代化建議

VC6 時代技術若移植至 VS2019+,建議改用 CMFCToolBar + CMFCToolBarComboBoxButton 內建支援,支援高 DPI、主題、觸控、自動版面,無需手寫自繪邏輯。

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