CDialog上使用CToolBar+CReBar

最經在做一些用戶界面的東西,對話框上有很多按鈕和組合框,全部加起來差不多有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();

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章