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

工具列嵌入下拉式方塊完整實戰:從建立到平面風格與訊息處理

     編輯:VC 教學

Office XP 風格的工具列嵌入下拉方塊 (如縮放比例選擇) 曾風靡一時。本文手把手教你在 MFC SDI 專案中實現此效果,涵蓋:工具列預留位置、嵌入 ComboBox、解決工具列高度不足、套用第三方平面風格類 (CFlatComboBox)、處理選擇變更訊息 全流程。

效果預覽

六大步驟完整實作

1. 建立 SDI 專案並新增工具列分隔項

資源編輯器開啟工具列,新增一個按鈕 (ID: ID_TOOL_ZOOM),類型設為「分隔符」。這個位置將作為下拉方塊的容器槽位。

2. 派生專屬工具列類別 CMainToolBar : public CToolBar

在 ClassView 右鍵 Add Class,選 Generic Class。於 MainToolBar.h 宣告下拉方塊成員:

public: CComboBox m_wndZoom; // 稍後替換為 CFlatComboBox

3. 主框架替換工具列類別

MainFrm.h:#include "MainToolBar.h",將 CToolBar m_wndToolBar; 改為 CMainToolBar m_wndToolBar;。

4. OnCreate 中動態建立並嵌入下拉方塊

int index = 0;
// 找到預留的分隔項索引
while (m_wndToolBar.GetItemID(index) != ID_TOOL_ZOOM) index++;

// 設定分隔項寬度為 80 像素,取得其矩形區域
m_wndToolBar.SetButtonInfo(index, ID_TOOL_ZOOM, TBBS_SEPARATOR, 80);
CRect rect;
m_wndToolBar.GetItemRect(index, &rect);

// 微調位置與高度 (下拉清單需足夠高度)
rect.top += 2;
rect.bottom += 200; 

// 建立下拉方塊 (CBS_DROPDOWNLIST 僅允許選擇,不可編輯)
if (!m_wndZoom.Create(WS_CHILD | WS_VISIBLE | CBS_AUTOHSCROLL | CBS_DROPDOWNLIST | CBS_HASSTRINGS, 
                      rect, &m_wndToolBar, ID_TOOL_ZOOM))
    return FALSE;

m_wndZoom.ShowWindow(SW_SHOW);
// 填充縮放選項
m_wndZoom.AddString(_T("25%")); m_wndZoom.AddString(_T("50%")); 
m_wndZoom.AddString(_T("75%")); m_wndZoom.AddString(_T("100%"));
m_wndZoom.AddString(_T("125%")); m_wndZoom.AddString(_T("150%"));
m_wndZoom.AddString(_T("175%")); m_wndZoom.AddString(_T("200%"));
m_wndZoom.SetCurSel(3); // 預設 100%

5. 解決三大常見問題

問題解決方案
工具列高度不夠,下拉方塊被切掉資源編輯器中,任意工具列按鈕屬性 -> Height 設為 22 或更大
下拉方塊非平面風格,與 XP 風格工具列不搭引入 Kirk Stowell 的 CFlatComboBox (附於範例),替換 CComboBox 成員類型,含標頭檔,重新編譯即變平面
ClassWizard 找不到下拉方塊訊息,無法處理選擇事件手動在 CMainFrame 加入訊息映射與處理函數 (見下文)

6. 手動處理 CBN_SELENDOK 選擇確認訊息

MainFrm.h:afx_msg void OnSelectZoomed();
MainFrm.cpp 訊息映射:ON_CBN_SELENDOK(ID_TOOL_ZOOM, OnSelectZoomed)

void CMainFrame::OnSelectZoomed()
{
    CString strContent;
    m_wndToolBar.m_wndZoom.GetWindowText(strContent);
    AfxMessageBox(strContent); // 實際專案中執行縮放邏輯
}

作者心聲

「很久沒寫文章了,這是我出社會後寫的第一篇作文,寫得不好請多包涵!」 —— 這份樸實的分享精神,比代碼本身更珍貴。

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