最經在做一些用戶界面的東西,對話框上有很多按鈕和組合框,全部加起來差不多有20多個吧,界面非常凌亂,最後決定用CToolBar + CReBar來重新設計界面,爲什麼選用這個呢?一是因爲看到IE用的也是這個,二是用CReBar+透明的CToolBar可以實現漂亮的換膚效果。
1、在對話框類中添加成員變量:
CStatic m_static;
CButton m_btn;
CComboBox m_combo;
CToolBar m_toolBar;
CReBar m_reBar;
在OnInitDialog()添加如下代碼:
1、用於創建工具欄和ReBar
if (!m_reBar.Create(this))
return FALSE;
if (!m_toolBar.CreateEx(this))
return FALSE;
//TBSTYLE_TRANSPARENT是使CToolBar透明,可以顯示CReBar的背景。
//TBSTYLE_LIST用於設置按鈕文字時,文字在按鈕的右邊,默認情況下是文字在按鈕的下部
m_toolBar.ModifyStyle(0, TBSTYLE_TRANSPARENT | TBSTYLE_LIST);
m_toolBar.GetToolBarCtrl().SetExtendedStyle(TBSTYLE_EX_DRAWDDARROWS);//設置下拉箭頭樣式
m_toolBar.SetButtons(NULL, 5);//設置ToolBar 按鈕個數
m_reBar.AddBar(&m_toolBar);
2、添加按鈕:
CRect rect;
int nIndex = -1;
//添加文本
m_toolBar.SetButtonInfo(++nIndex, 0, TBSTYLE_BUTTON | BTNS_AUTOSIZE | TBSTYLE_AUTOSIZE | TBBS_DISABLED, -1);
//此處是爲了增加按鈕的寬度,可以更加自己的需要適當的調整,由於是不可見字符,因此是透明的
m_toolBar.SetButtonText(nIndex, _T(" "));
m_toolBar.GetItemRect(nIndex, &rect);
rect.top += 3;//此處是爲了讓文本垂直居中
m_static.Create(_T("工具欄"), WS_CHILD | WS_VISIBLE | SS_CENTER | SS_SIMPLE, rect, &m_toolBar);
m_static.SetFont(m_toolBar.GetFont());
//添加組合框
m_toolBar.SetButtonInfo(++nIndex, 0, TBSTYLE_SEP, 80);
m_toolBar.GetItemRect(nIndex, &rect);
rect.bottom += 100;
m_combo.Create(WS_CHILD | WS_VISIBLE | CBS_DROPDOWN, rect, &m_toolBar, 0);m_combo.SetFont(m_toolBar.GetFont());
//添加
CheckBoxm_toolBar.SetButtonInfo(++nIndex, 0,TBSTYLE_BUTTON | TBBS_DISABLED | TBSTYLE_AUTOSIZE, -1);
m_toolBar.SetButtonText(nIndex, _T(" "));
m_toolBar.GetItemRect(nIndex, &rect);
m_btn.Create(_T("你好"), WS_CHILD | WS_VISIBLE | BS_AUTOCHECKBOX, rect, &m_toolBar, 0);
m_btn.SetFont(m_toolBar.GetFont());
//添加下拉按鈕,這個-2表示不顯示按鈕位圖,但是顯示了文字,這個我通過跟蹤IE8的CToolBar按鈕得到的,微軟完全沒有說明。
//至於這個-2是怎麼來的,我會在另一個文章中說明。
m_toolBar.SetButtonInfo(++nIndex, 0, TBSTYLE_AUTOSIZE | BTNS_WHOLEDROPDOWN, -2);
m_toolBar.SetButtonText(nIndex, _T("下拉列表"));
//顯示ReBar和工具欄
CRect rcWnd;
GetClientRect(&rcWnd);
m_reBar.SetWindowPos(NULL, 0, 0, rcWnd.Width(), 24, SWP_SHOWWINDOW);//顯示CReBar
顯示效果如下:
"工具欄"是CStatic,如果要讓他透明,直接從CStatic 派生一個CStaticExt類
添加宏ON_WM_CTLCOLOR_REFLECT()和函數
HBRUSH CTransparentStatic::CtlColor(CDC *pDC, UINT nCtlColor)
{
pDC->SetBkMode(TRANSPARENT);
return (HBRUSH)::GetStockObject(NULL_BRUSH);//直接返回空畫刷,這樣就透明瞭
}
4、讓對話框能響應ON_UPDATE_COMMAND_UI消息
添加函數:
void OnKickIdle()
{
if (m_toolBar.GetSafeHwnd() && m_toolBar.IsWindowVisibile())
m_topBar.OnUpdateCmdUI((CFrameWnd *)this, FALSE);//響應工具欄按鈕更新消息
}
添加宏ON_WM_INITMENUPOPUP()和函數:
void OnInitMenuPopup(CMenu* pPopupMenu, UINT nIndex, BOOL bSysMenu)
{
CDialogEx::OnInitMenuPopup(pPopupMenu, nIndex, bSysMenu);
if (!bSysMenu && pPopupMenu)
{
CCmdUI cmdUI;
int nCount;
UINT nID;
cmdUI.m_pOther = NULL;
cmdUI.m_pMenu = pPopupMenu;
cmdUI.m_pSubMenu = NULL;
nCount = pPopupMenu->GetMenuItemCount();
cmdUI.m_nIndexMax = nCount;
for (int i = 0; i < nCount; ++i)
{
nID = pPopupMenu->GetMenuItemID(i);
if (nID == -1 || nID == 0)
continue;
cmdUI.m_nID = nID;
cmdUI.m_nIndex = i;
cmdUI.DoUpdate(this, FALSE);//菜單按鈕更新消息
}
}
}
接下來我們就可以使用ON_UPDATE_COMMAND_UI宏來添加消息響應了,這裏不再說明。
補充:通過m_reBar.GetReBarCtrl().ShowBand(1,bShow);函數來顯示或隱藏Band,界面會刷新不正常。
解決辦法:先重繪工具欄,再重繪子窗口。
m_reBar.RedrawWindow();
m_static.RedrawWindow();
m_combo.RedrawWindow();