IE 經典介面特徵:扁平工具列 (滑鼠懸停凸起)、熱點圖示/冷態圖示切換、按鈕文字提示、下拉箭頭按鈕、整合位址下拉方塊。MFC 透過 CReBar、CToolBar、CImageList、CComboBox 即可完整複刻。本文解析 CMainFrame::OnCreate 核心實作碼。
CReBar m_wndReBar:容器,管理工具列與位址列條帶。CToolBar m_wndToolBar:主工具列,支援扁平、熱點圖示、下拉按鈕。CImageList m_imgHot, m_imgCold:熱點/冷態圖示清單 (22x22, 256 色)。CComboBox m_wndAddress:位址列,CBS_DROPDOWN 模式。
if (!m_wndReBar.Create(this)) return -1;
if (!m_wndToolBar.CreateEx(this)) return -1;
// CreateEx 才能套用 TBSTYLE_FLAT 等新風格
m_wndToolBar.GetToolBarCtrl().SetButtonWidth(50, 150); // 按鈕寬度範圍
m_wndToolBar.GetToolBarCtrl().SetExtendedStyle(TBSTYLE_EX_DRAWDDARROWS); // 支援下拉箭頭
// 熱點圖示 (滑鼠懸停)
m_imgHot.Create(IDB_HOTTOOLBAR, 22, 0, RGB(255,0,255));
m_wndToolBar.GetToolBarCtrl().SetHotImageList(&m_imgHot);
m_imgHot.Detach();
// 冷態圖示 (正常)
m_imgCold.Create(IDB_COLDTOOLBAR, 22, 0, RGB(255,0,255));
m_wndToolBar.GetToolBarCtrl().SetImageList(&m_imgCold);
m_imgCold.Detach();
m_wndToolBar.ModifyStyle(0, TBSTYLE_FLAT | TBSTYLE_TRANSPARENT);
// CToolBar::Create/CreateEx 不直接支援 TBSTYLE_FLAT,必須事後 ModifyStyle
m_wndToolBar.SetButtons(NULL, 9); // 9 個按鈕
CString str;
for (int i = 0; i < 9; i++)
{
UINT nID = ID_BUTTON0 + i;
UINT nStyle = TBSTYLE_BUTTON;
if (i == 6 || i == 8) nStyle |= TBSTYLE_DROPDOWN; // 第 7、9 個按鈕帶下拉箭頭
m_wndToolBar.SetButtonInfo(i, nID, nStyle, i); // 圖示索引 = 按鈕索引
str.LoadString(IDS_BUTTON0 + i);
m_wndToolBar.SetButtonText(i, str); // 文字提示
}
CRect rcBtn;
m_wndToolBar.GetItemRect(0, &rcBtn);
m_wndToolBar.SetSizes(rcBtn.Size(), CSize(30,20)); // 按鈕大小、圖示大小
if (!m_wndAddress.Create(CBS_DROPDOWN | WS_CHILD, CRect(0,0,200,120), this, AFX_IDW_TOOLBAR + 1))
return -1;
m_wndReBar.AddBar(&m_wndToolBar);
str.LoadString(IDS_ADDRESS);
m_wndReBar.AddBar(&m_wndAddress, str, NULL, RBBS_FIXEDBMP | RBBS_BREAK); // 換行
REBARBANDINFO rbbi = { sizeof(rbbi) };
rbbi.fMask = RBBIM_CHILDSIZE | RBBIM_IDEALSIZE | RBBIM_SIZE;
rbbi.cxMinChild = rcBtn.Width();
rbbi.cyMinChild = rcBtn.Height();
rbbi.cx = rbbi.cxIdeal = rcBtn.Width() * 9;
m_wndReBar.GetReBarCtrl().SetBandInfo(0, &rbbi); // 工具列條帶
rbbi.cxMinChild = 0;
CRect rcAddr; m_wndAddress.GetEditCtrl()->GetWindowRect(&rcAddr);
rbbi.cyMinChild = rcAddr.Height() + 10;
rbbi.cxIdeal = 200;
m_wndReBar.GetReBarCtrl().SetBandInfo(2, &rbbi); // 位址列條帶 (索引 2 因換行)
if (!m_wndStatusBar.Create(this) || !m_wndStatusBar.SetIndicators(indicators, ...))
return -1;
| 技術 | 關鍵 API/旗標 | 說明 |
|---|---|---|
| 扁平工具列 | ModifyStyle(0, TBSTYLE_FLAT) | 繞過 CToolBar 封裝限制,直接設定視窗風格。 |
| 熱點/冷態圖示 | SetHotImageList/SetImageList | 系統自動在懸停/正常狀態切換圖示清單。 |
| 下拉箭頭按鈕 | TBSTYLE_DROPDOWN + TBSTYLE_EX_DRAWDDARROWS | 按鈕右側顯示小三角,點擊發送 TBN_DROPDOWN 通知。 |
| 按鈕文字 | SetButtonText | 工具列按鈕顯示文字 (需配合 SetSizes 寬度)。 |
| ReBar 版面配置 | AddBar + SetBandInfo | 彈性管理多條帶 (工具列、位址列、自訂控制項) 大小與換行。 |