MFC 預設工具列僅支援按鈕。將工具列封裝為 CMainToolBar : public CToolBar,以 CFlatComboBox m_wndZoom 為成員變數,實現物件導向封裝。
CComboBox,處理 WM_MOUSEMOVE、WM_LBUTTONDOWN、WM_LBUTTONUP、WM_TIMER、WM_PAINTFC_DRAWNORMAL(平坦)、FC_DRAWRAISED(滑鼠進入凸起)、FC_DRAWPRESSD(按下凹陷)Draw3dRect 繪製 3D 邊框模擬,覆蓋系統預設邊框OnTimer 每 10ms 檢查滑鼠位置,實現即時狀態切換// 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%
// 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); // 實際專案改為套用縮放邏輯
}
// 預留 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、主題、觸控、自動版面,無需手寫自繪邏輯。