VC6中工具条的新特色
生活随笔
收集整理的這篇文章主要介紹了
VC6中工具条的新特色
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
加入時間:01-1-8 下午 09:10:32
在Visual C++ 版本6中工具條的新特色
作者: Dave Schmitt
微軟在www.microsoft.com/visualc已經推出Visual C++6.0預覽版幾個月了。正式版預計到今年年底發布。同時,預覽版顯示出版本6將包含大量的改進和提高,包括支持Internet控件,例如扁平工具條等。雖然改進的控件包與Internet無關,但它首先出現在Internet Explorer中,因此它就被取做這個名字了。事實上,官方發布的預覽版的標題是“針對Internet Explorer 4.0的Visual C++ 5.0技術預覽”。
在以前關于MFC工具條類的討論專題中,我曾答應提供一個在版本6中工具條的外觀演示。有一個很好的消息,那就是你現在用CToolBar所作的所有工作在新的版本中都是有效的,包括那些在以前的欄目中所描述的一些擴展功能。因此,你將很容易修改現存的程序以獲得象Internet Explorer和Visual Studio中那樣“酷”的界面。此外,并沒有什么壞消息。
工具條的新特色
早在版本4中,CToolBar就已被MFC庫完全實現了。一旦公用控件動態鏈接庫(命名為comctl32.dll)變得無所不在了,CToolBar就成了如今已包含在操作系統中的工具條控件的代名詞了。然而,CToolBar并沒有揭示公用工具條控件的所有能力。如今,通過CreateEx()函數,它成功了。
公用控件動態鏈接庫現在包含了至少三類風格:最初的、在Internet Explorer 3.0中加入的以及在Internet Explorer 4.0中加入的。雖然這些版本理論上是向下兼容的,但某些專業人員曾寫出一些不能在后來版本中正常運行的應用程序,這可能是這些程序采用了一些沒有公開的功能,而這些功能并沒有被包含在所有的版本中。
Visual C++程序員沒有這樣的經歷,因為在Visual C++4.0或5.0中comctl32.dll并不是一個可以再分發的組件,它在安裝Internet Explorer時被更新,因此MFC程序員無法依靠最新版本的某些功能來用于他們的程序。這就是CToolBar僅僅具有最初的DLL的有限功能的原因。CToolBar能夠實現最新的特色意味著微軟將在Visual C++6.0中包含最新的DLL并將其作為一個可以再分發的組件。
絕大多數新特色將由在調用CreateEx()和其它CToolBar成員函數時指定的新的風格標志來確定。下面是commctrl.h的一部分,它定義了TBSTYLE類標識符:
#define TBSTYLE_BUTTON ? ? ? ? ?0x0000
#define TBSTYLE_SEP ? ? ? ? ? ? 0x0001
#define TBSTYLE_CHECK ? ? ? ? ? 0x0002
#define TBSTYLE_GROUP ? ? ? ? ? 0x0004
#define TBSTYLE_CHECKGROUP ? ? ?(TBSTYLE_GROUP | TBSTYLE_CHECK)
#if (_WIN32_IE >= 0x0300)
#define TBSTYLE_DROPDOWN ? ? ? ?0x0008
#endif
#if (_WIN32_IE >= 0x0400)
#define TBSTYLE_AUTOSIZE ? ? ? ?0x0010
#define TBSTYLE_NOPREFIX ? ? ? ?0x0020
#endif
#define TBSTYLE_TOOLTIPS ? ? ? ?0x0100
#define TBSTYLE_WRAPABLE ? ? ? ?0x0200
#define TBSTYLE_ALTDRAG ? ? ? ? 0x0400
#if (_WIN32_IE >= 0x0300)
#define TBSTYLE_FLAT ? ? ? ? ? ?0x0800
#define TBSTYLE_LIST ? ? ? ? ? ?0x1000
#define TBSTYLE_CUSTOMERASE ? ? 0x2000
#endif
#if (_WIN32_IE >= 0x0400)
#define TBSTYLE_REGISTERDROP ? ?0x4000
#define TBSTYLE_TRANSPARENT ? ? 0x8000
#define TBSTYLE_EX_DRAWDDARROWS 0x00000001
#endif
你會注意到其中的一些采用了條件編譯,依賴于_WIN32_IE的值,它缺省指的是Internet Explorer 4.0(即取值為0x0400)。對于Internet Explorer 3.0(即取值為0x0300)以前的版本,大多數的TBSTYLE標識符指的是按鈕或是一組按鈕。Internet Explorer 3.0引入了扁平鈕、文本標簽、下拉列表和自定義繪制。Internet Explorer 4.0增強了下拉列表和自定義繪制功能,并且增加了支持OLE拖動目標到一個工具條。
扁平鈕和把手
在過去的18個月中我常常被問及該如何獲得象Internet Explorer和Visual Studio中的工具條一樣不使用浮雕按鈕而是用扁平鈕并且帶有便于移動和定位的把手那樣酷的界面。這些特色并不被MFC所支持,因此最簡單獲取的方法就是購買一個擴展庫。而對于Visual C++ 6.0來說卻無須多此一舉,因為它使得CToolBar類實現了對扁平鈕、把手和其它新的視覺效果的支持。
在預覽版中,AppWizard并不會自動包括這些新特色,但它們卻很容易被加入。表1顯示了AppWizard創建的主框架窗口的OnCreate()函數,表2顯示了需要做哪些修改以獲得具有扁平鈕和把手的工具條。圖1顯示了表1創建出的工具條,而圖2顯示出了表2實現的工具條。
表 1: CMainFrame::OnCreate as generated by AppWizard
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if(CMDIFrameWnd::OnCreate(lpCreateStruct) == -1)
? ?return -1;
if(!m_wndToolBar.Create(this) || !m_wndToolBar.LoadToolBar(IDR_MAINFRAME))
? ?{
? ?TRACE0("Failed to create toolbar\n");
? ?return -1; ? ? ?// fail to create
? ?}
if(!m_wndStatusBar.Create(this) ||
? ?!m_wndStatusBar.SetIndicators(indicators,
? ? ? ?sizeof(indicators
圖1
表2: Adding flat buttons and the gripper
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if(CMDIFrameWnd::OnCreate(lpCreateStruct) == -1)
? ?return -1;
if(!m_wndToolBar.CreateEx(this) || !m_wndToolBar.LoadToolBar(IDR_MAINFRAME))
? ?{
? ?TRACE0("Failed to create toolbar\n");
? ?return -1; ? ? ?// fail to create
? ?}
if(!m_wndStatusBar.Create(this) ||
? ?!m_wndStatusBar.SetIndicators(indicators,
? ? ? ?sizeof(indicators)/sizeof(UINT)))
? ?{
? ?TRACE0("Failed to create status bar\n");
? ?return -1; ? ? ?// fail to create
? ?}
// TODO: Remove this if you don't want tool tips or a resizeable toolbar
m_wndToolBar.SetBarStyle(m_wndToolBar.GetBarStyle() |
? ?CBRS_GRIPPER | CBRS_BORDER_3D | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC);
// TODO: Delete these three lines if you don't want the toolbar to
// ?be dockable
m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY);
EnableDocking(CBRS_ALIGN_ANY);
DockControlBar(&m_wndToolBar);
return 0;
}
圖2
為了作出扁平按鈕我必須使用CreateEx()來代替Create()。這個新的函數在afxext.h中聲明:
BOOL CreateEx
?(
?CWnd* pParentWnd, ? ? ? ? ? ? ? ?// parent window
?DWORD dwCtrlStyle = TBSTYLE_FLAT, ? ?// extended style
?DWORD dwStyle = ? ? ? ? ? ? ? ? // style
? ?WS_CHILD | WS_VISIBLE | CBRS_ALIGN_TOP,
?CRect rcBorders = CRect(0,0,0,0), ? ?// border rectangle
?UINT nID = AFX_IDW_TOOLBAR ? ? ? ?// identifier
?);
因為擴展風格缺省指的就是TBSTYLE_FLAT,因此我要得到扁平按鈕就只需要簡單地將AppWizard形成的代碼中的Create()改為CreateEx()即可。我將在后面實現其它的擴展風格。
為了獲得把手,我必須在調用SetBarStyle()函數時包含CBRS_GRIPPER標志,參看表2。這是CControlBar類的一個新風格,而CToolBar類是從它繼承而來的。 請注意到我也加入了CBRS_BORDER_3D標志,這是為了修正一個未知的繪制問題,該問題將會在工具條的邊緣繪制一些多余的點。這也許意味著預覽版確實有這個問題,因為一旦我將3D標志加入就立即解決了并且也似乎沒有影響到別的什么。
上面所作的兩個簡單的改變是使得一個已存程序獲得酷界面的最省力的方法。在一個程序具有了扁平鈕和把手的同時,它也不會發生不應有的其它改變。
文本標簽
Internet Explorer使得普通的工具條具有了大按鈕和取代了文本提示的文本標簽。MFC程序員可以通過SetButtonText()函數為每個按鈕設置一個文本串來獲得這種效果。雖然在Visual C++ 5.0中已包含了這個函數,但如果不使用扁平鈕風格則不會取得令人滿意的效果。
表3顯示了如何使用現有的文本提示作為按鈕的標簽,而且圖3和圖4顯示了將工具條分別定位在頂端和右邊的效果。我仍然使得文本提示有效,但你可以通過在調用SetBarStyle()時去掉CBRS_TOOLTIPS風格而使之無效。
表 3: Adding text labels
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if(CMDIFrameWnd::OnCreate(lpCreateStruct) == -1)
? ?return -1;
? ?
if(!m_wndToolBar.CreateEx(this) ||
? ?!m_wndToolBar.LoadToolBar(IDR_MAINFRAME))
? ?{
? ?TRACE0("Failed to create toolbar\n");
? ?return -1; ? ? ?// fail to create
? ?}
if(!m_wndStatusBar.Create(this) ||
? ?!m_wndStatusBar.SetIndicators(indicators,sizeof(indicators)/sizeof(UINT)))
? ?{
? ?TRACE0("Failed to create status bar\n");
? ?return -1; ? ? ?// fail to create
? ?}
// TODO: Remove this if you don't want tool tips or a resizeable toolbar
m_wndToolBar.SetBarStyle(m_wndToolBar.GetBarStyle() |
? ?CBRS_GRIPPER | CBRS_BORDER_3D | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC);
// Add text to each button
for(int i = 0; i < m_wndToolBar.GetCount(); i++)
{ UINT id = m_wndToolBar.GetItemID(i);
CString s;
if(!s.LoadString(id)) continue;
int j = s.Find(_T('\n'));
if(j < 0) continue;
s = s.Right(s.GetLength() - j - 1);
m_wndToolBar.SetButtonText(i,s); }// Adjust sizes to include text
CRect rect;
m_wndToolBar.GetItemRect(0,&rect);
m_wndToolBar.SetSizes(rect.Size(),CSize(16,15));// TODO: Delete these three lines if you don't want the toolbar to
// be dockable
m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY);
EnableDocking(CBRS_ALIGN_ANY);
DockControlBar(&m_wndToolBar);
return 0;}
圖4
為了產生按鈕標簽,一個簡單的for循環掃過所有的按鈕并且從與之相連的幫助串中提取出提示文本。在設置完每個按鈕的標簽后,就調用工具條的SetSizes()函數去重新計算工具條的外觀以便使得標簽可見。也許會有更好的方法去實現最后一步,但我還是從微軟的MFCIE范例程序中借用了這個過程,不為別的,只為它確實有效。
從很多方面來說,MFCIE都是值得仔細學習的。從本質上來說,它實際上是Internet Explorer的一個微型版本,并且它還闡述了如何使用版本6的一些新特色。你將會驚訝于在你的MFC應用程序中添加HTML瀏覽功能是如此之簡單。
在絕大多數情況下你會希望文本標簽顯示在按鈕下面(這在最初的公用控件庫中是唯一的選擇)。Internet Explorer 3.0版加入了TBSTYLE_LIST風格,該風格導致文本標簽顯示在按鈕右邊。對于在標簽旁邊顯示一個下拉列表或者按鈕被一個子窗口覆蓋時,該風格是很有用的。
下拉列表
在“工具條的變形”一文中,我演示了通過將一個組合框作為一個子窗口來在工具條上添加下拉列表的情形。該方法在版本6中仍然有效,并且當你想在工具條上顯示當前的可選擇項時它仍然是有用的。然而,有時你希望工具條包含一個可以在鼠標點擊時顯示選擇列表或菜單的按鈕。該功能現在可以通過擴展風格TBSTYLE_DROPDOWN和TBSTYLE_EX_DRAWDDARROWS實現了。
例如,假設我希望對應于“文件”菜單下“新建”的按鈕可以顯示一個我的應用程序知道如何去創建的所有文件類型的列表。表4 顯示在前面的例子中如何加入該功能,而圖5顯示該工具條。我抓取了鼠標停留在該按鈕上時的屏幕,它顯示出了按鈕和下拉箭頭之間的分隔線。
為了加入一個下拉箭頭,首先我必須在基本的工具條控件上調用SetExtendedStyle()函數,并且指定TBSTYLE_EX_DRAWDDARROWS風格。然后我必須在每一個我想要顯示下拉箭頭的按鈕上指定TBSTYLE_DROPDOWN風格。
表 4: Converting the File menu New command to a drop-down button
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if(CMDIFrameWnd::OnCreate(lpCreateStruct) == -1)
? ?return -1;
? ?
if(!m_wndToolBar.CreateEx(this) ||
? ?!m_wndToolBar.LoadToolBar(IDR_MAINFRAME))
? ?{
? ?TRACE0("Failed to create toolbar\n");
? ?return -1; ? ? ?// fail to create
? ?}
if(!m_wndStatusBar.Create(this) ||
? ?!m_wndStatusBar.SetIndicators(indicators,sizeof(indicators)/sizeof(UINT)))
? ?{
? ?TRACE0("Failed to create status bar\n");
? ?return -1; ? ? ?// fail to create
? ?}
// TODO: Remove this if you don't want tool tips or a resizeable toolbar
m_wndToolBar.SetBarStyle(m_wndToolBar.GetBarStyle() |
? ?CBRS_GRIPPER | CBRS_BORDER_3D | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC);
// Add text to each button
for(int i = 0; i
圖5
當用戶在New按鈕上點擊時,就象圖5所示一樣,基本的按鈕操作就發生了。在這個例子中命令消息導致調用CWinApp::OnFileNew()。然而,當用戶點擊下拉箭頭時,工具條就發出TBN_DROPDOWN通知消息給工具條的父窗口。我可以通過重載OnNotify()函數或者通過在消息映射中加入一個ON_NOTIFY而獲取這個消息。
表5顯示了后者的實現技術。通常我顯示一個彈出菜單或者一個列表框去響應這個通知消息。在絕大多數情況下沒有必要提供一個結果值,因為缺省值(TBDDRET_DEFAULT)顯示了我已獲取了對這個事件的控制。其它可能的結果值是TBDDRET_NODEFAULT和TBDDRET_TREATPRESSED。前者表示該事件沒有受到控制,當出現后者時,工具條就表現得好像該按鈕被點擊一樣。
表 5: Handling drop-down notifications
BEGIN_MESSAGE_MAP(CMainFrame, CMDIFrameWnd)
? ?//{{AFX_MSG_MAP(CMainFrame)
? ?ON_WM_CREATE()
? ?//}}AFX_MSG_MAP
? ?ON_NOTIFY(TBN_DROPDOWN,AFX_IDW_TOOLBAR,OnDropDown)
END_MESSAGE_MAP()
void CMainFrame::OnDropDown(NMHDR* pNotifyStruct,LRESULT* result)
{
NMTOOLBAR* pInfo = (NMTOOLBAR*)pNotifyStruct;
switch(pInfo->iItem)
? ?{
? ?case ID_FILE_NEW:
? ?TRACE0("ID_FILE_NEW drop down\n");
? ?// TODO: Display popup menu or list box
? ?break;
? ?// TODO: Add cases for other drop-down buttons
? ?}
}
熱點圖像
運行Internet Explorer 4.0并且將鼠標在工具條上劃過。就能注意到在平時每個按鈕是平淡的顏色。而當鼠標觸及到該按鈕時,他會凸出來并且顯現出鮮艷的顏色。這種視覺效果采用了工具條控件的被稱作“熱點圖像”的功能。
一般的AppWizard代碼使用工具條資源來指定其上按鍵的外觀和與每個按鍵相連接的一個命令ID。工具條資源實際上包含一個復合的位圖,該位圖在調用LoadToolBar()函數時將被轉變成一個圖像列表(參見表4)。要激活熱點圖像功能,我必須通過SetHotImageList()函數提供第二個圖像列表,就象表6所示一樣。
表 6: Using hot images
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if(CMDIFrameWnd::OnCreate(lpCreateStruct) == -1)
? ?return -1;
? ?
if(!m_wndToolBar.CreateEx(this) ||
? ?!m_wndToolBar.LoadToolBar(IDR_MAINFRAME))
? ?{
? ?TRACE0("Failed to create toolbar\n");
? ?return -1; ? ? ?// fail to create
? ?}
CImageList img;
if(!img.Create(IDB_MAINFRAME,16,0,RGB(128,128,128)))
? ?{
? ?TRACE0("Failed to load hot images\n");
? ?return -1;
? ?}
m_wndToolBar.GetToolBarCtrl().SetHotImageList(&img);
img.Detach();
if(!m_wndStatusBar.Create(this) ||
? ?!m_wndStatusBar.SetIndicators(indicators,sizeof(indicators)/sizeof(UINT)))
? ?{
? ?TRACE0("Failed to create status bar\n");
? ?return -1; ? ? ?// fail to create
? ?}
// TODO: Remove this if you don't want tool tips or a resizeable toolbar
m_wndToolBar.SetBarStyle(m_wndToolBar.GetBarStyle() |
? ?CBRS_GRIPPER | CBRS_BORDER_3D | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC);
// Add text to each button
for(int i = 0; i
圖6
圖6 顯示了熱點圖像被激活的情形。鼠標正停留在New按鈕上,它就被顯示成一個空文檔的圖形。其它的按鈕是扁平的和淡顏色的。為了生成這個改進的工具條,我將res子目錄下的toolbar.bmp拷貝為toolbar1.bmp,然后將其作為一個位圖資源插入資源中,并取其ID為IDR_MAINFRAME。 接下來我編輯IDR_MAINFRAME 工具條,用很淡的顏色(例如淡灰色)來取代它原來的顏色。最后,我加入了如表6所示的對函數SetHotImageList()的調用。
這個例子演示了在一個已存的工具條中加入熱點圖像的捷徑,但他不會改進工具條的外觀。如果你想在這一點上取得更好的效果,MFCIE的例子包含了非常好的蝕刻位圖,它演示了當你使用非常有藝術性的圖像時它能達到何等地步的視覺效果。
其它特色
前面的講解演示了你怎樣簡單地改變現存的MFC程序,以獲得扁平鈕、把手、下拉列表和熱點圖像的功能。Visual C++ 6.0還提供了幾種其它令人感興趣的工具條特色,包括自定義繪制、OLE拖入目標和使用rebar(抱歉,不知道該單詞指的是什么)容器等。這些特色將會是將來的欄目的主題。
本文引用通告地址: http://blog.csdn.net/silver/services/trackbacks/5453.aspx
在Visual C++ 版本6中工具條的新特色
作者: Dave Schmitt
微軟在www.microsoft.com/visualc已經推出Visual C++6.0預覽版幾個月了。正式版預計到今年年底發布。同時,預覽版顯示出版本6將包含大量的改進和提高,包括支持Internet控件,例如扁平工具條等。雖然改進的控件包與Internet無關,但它首先出現在Internet Explorer中,因此它就被取做這個名字了。事實上,官方發布的預覽版的標題是“針對Internet Explorer 4.0的Visual C++ 5.0技術預覽”。
在以前關于MFC工具條類的討論專題中,我曾答應提供一個在版本6中工具條的外觀演示。有一個很好的消息,那就是你現在用CToolBar所作的所有工作在新的版本中都是有效的,包括那些在以前的欄目中所描述的一些擴展功能。因此,你將很容易修改現存的程序以獲得象Internet Explorer和Visual Studio中那樣“酷”的界面。此外,并沒有什么壞消息。
工具條的新特色
早在版本4中,CToolBar就已被MFC庫完全實現了。一旦公用控件動態鏈接庫(命名為comctl32.dll)變得無所不在了,CToolBar就成了如今已包含在操作系統中的工具條控件的代名詞了。然而,CToolBar并沒有揭示公用工具條控件的所有能力。如今,通過CreateEx()函數,它成功了。
公用控件動態鏈接庫現在包含了至少三類風格:最初的、在Internet Explorer 3.0中加入的以及在Internet Explorer 4.0中加入的。雖然這些版本理論上是向下兼容的,但某些專業人員曾寫出一些不能在后來版本中正常運行的應用程序,這可能是這些程序采用了一些沒有公開的功能,而這些功能并沒有被包含在所有的版本中。
Visual C++程序員沒有這樣的經歷,因為在Visual C++4.0或5.0中comctl32.dll并不是一個可以再分發的組件,它在安裝Internet Explorer時被更新,因此MFC程序員無法依靠最新版本的某些功能來用于他們的程序。這就是CToolBar僅僅具有最初的DLL的有限功能的原因。CToolBar能夠實現最新的特色意味著微軟將在Visual C++6.0中包含最新的DLL并將其作為一個可以再分發的組件。
絕大多數新特色將由在調用CreateEx()和其它CToolBar成員函數時指定的新的風格標志來確定。下面是commctrl.h的一部分,它定義了TBSTYLE類標識符:
#define TBSTYLE_BUTTON ? ? ? ? ?0x0000
#define TBSTYLE_SEP ? ? ? ? ? ? 0x0001
#define TBSTYLE_CHECK ? ? ? ? ? 0x0002
#define TBSTYLE_GROUP ? ? ? ? ? 0x0004
#define TBSTYLE_CHECKGROUP ? ? ?(TBSTYLE_GROUP | TBSTYLE_CHECK)
#if (_WIN32_IE >= 0x0300)
#define TBSTYLE_DROPDOWN ? ? ? ?0x0008
#endif
#if (_WIN32_IE >= 0x0400)
#define TBSTYLE_AUTOSIZE ? ? ? ?0x0010
#define TBSTYLE_NOPREFIX ? ? ? ?0x0020
#endif
#define TBSTYLE_TOOLTIPS ? ? ? ?0x0100
#define TBSTYLE_WRAPABLE ? ? ? ?0x0200
#define TBSTYLE_ALTDRAG ? ? ? ? 0x0400
#if (_WIN32_IE >= 0x0300)
#define TBSTYLE_FLAT ? ? ? ? ? ?0x0800
#define TBSTYLE_LIST ? ? ? ? ? ?0x1000
#define TBSTYLE_CUSTOMERASE ? ? 0x2000
#endif
#if (_WIN32_IE >= 0x0400)
#define TBSTYLE_REGISTERDROP ? ?0x4000
#define TBSTYLE_TRANSPARENT ? ? 0x8000
#define TBSTYLE_EX_DRAWDDARROWS 0x00000001
#endif
你會注意到其中的一些采用了條件編譯,依賴于_WIN32_IE的值,它缺省指的是Internet Explorer 4.0(即取值為0x0400)。對于Internet Explorer 3.0(即取值為0x0300)以前的版本,大多數的TBSTYLE標識符指的是按鈕或是一組按鈕。Internet Explorer 3.0引入了扁平鈕、文本標簽、下拉列表和自定義繪制。Internet Explorer 4.0增強了下拉列表和自定義繪制功能,并且增加了支持OLE拖動目標到一個工具條。
扁平鈕和把手
在過去的18個月中我常常被問及該如何獲得象Internet Explorer和Visual Studio中的工具條一樣不使用浮雕按鈕而是用扁平鈕并且帶有便于移動和定位的把手那樣酷的界面。這些特色并不被MFC所支持,因此最簡單獲取的方法就是購買一個擴展庫。而對于Visual C++ 6.0來說卻無須多此一舉,因為它使得CToolBar類實現了對扁平鈕、把手和其它新的視覺效果的支持。
在預覽版中,AppWizard并不會自動包括這些新特色,但它們卻很容易被加入。表1顯示了AppWizard創建的主框架窗口的OnCreate()函數,表2顯示了需要做哪些修改以獲得具有扁平鈕和把手的工具條。圖1顯示了表1創建出的工具條,而圖2顯示出了表2實現的工具條。
表 1: CMainFrame::OnCreate as generated by AppWizard
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if(CMDIFrameWnd::OnCreate(lpCreateStruct) == -1)
? ?return -1;
if(!m_wndToolBar.Create(this) || !m_wndToolBar.LoadToolBar(IDR_MAINFRAME))
? ?{
? ?TRACE0("Failed to create toolbar\n");
? ?return -1; ? ? ?// fail to create
? ?}
if(!m_wndStatusBar.Create(this) ||
? ?!m_wndStatusBar.SetIndicators(indicators,
? ? ? ?sizeof(indicators
圖1
表2: Adding flat buttons and the gripper
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if(CMDIFrameWnd::OnCreate(lpCreateStruct) == -1)
? ?return -1;
if(!m_wndToolBar.CreateEx(this) || !m_wndToolBar.LoadToolBar(IDR_MAINFRAME))
? ?{
? ?TRACE0("Failed to create toolbar\n");
? ?return -1; ? ? ?// fail to create
? ?}
if(!m_wndStatusBar.Create(this) ||
? ?!m_wndStatusBar.SetIndicators(indicators,
? ? ? ?sizeof(indicators)/sizeof(UINT)))
? ?{
? ?TRACE0("Failed to create status bar\n");
? ?return -1; ? ? ?// fail to create
? ?}
// TODO: Remove this if you don't want tool tips or a resizeable toolbar
m_wndToolBar.SetBarStyle(m_wndToolBar.GetBarStyle() |
? ?CBRS_GRIPPER | CBRS_BORDER_3D | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC);
// TODO: Delete these three lines if you don't want the toolbar to
// ?be dockable
m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY);
EnableDocking(CBRS_ALIGN_ANY);
DockControlBar(&m_wndToolBar);
return 0;
}
圖2
為了作出扁平按鈕我必須使用CreateEx()來代替Create()。這個新的函數在afxext.h中聲明:
BOOL CreateEx
?(
?CWnd* pParentWnd, ? ? ? ? ? ? ? ?// parent window
?DWORD dwCtrlStyle = TBSTYLE_FLAT, ? ?// extended style
?DWORD dwStyle = ? ? ? ? ? ? ? ? // style
? ?WS_CHILD | WS_VISIBLE | CBRS_ALIGN_TOP,
?CRect rcBorders = CRect(0,0,0,0), ? ?// border rectangle
?UINT nID = AFX_IDW_TOOLBAR ? ? ? ?// identifier
?);
因為擴展風格缺省指的就是TBSTYLE_FLAT,因此我要得到扁平按鈕就只需要簡單地將AppWizard形成的代碼中的Create()改為CreateEx()即可。我將在后面實現其它的擴展風格。
為了獲得把手,我必須在調用SetBarStyle()函數時包含CBRS_GRIPPER標志,參看表2。這是CControlBar類的一個新風格,而CToolBar類是從它繼承而來的。 請注意到我也加入了CBRS_BORDER_3D標志,這是為了修正一個未知的繪制問題,該問題將會在工具條的邊緣繪制一些多余的點。這也許意味著預覽版確實有這個問題,因為一旦我將3D標志加入就立即解決了并且也似乎沒有影響到別的什么。
上面所作的兩個簡單的改變是使得一個已存程序獲得酷界面的最省力的方法。在一個程序具有了扁平鈕和把手的同時,它也不會發生不應有的其它改變。
文本標簽
Internet Explorer使得普通的工具條具有了大按鈕和取代了文本提示的文本標簽。MFC程序員可以通過SetButtonText()函數為每個按鈕設置一個文本串來獲得這種效果。雖然在Visual C++ 5.0中已包含了這個函數,但如果不使用扁平鈕風格則不會取得令人滿意的效果。
表3顯示了如何使用現有的文本提示作為按鈕的標簽,而且圖3和圖4顯示了將工具條分別定位在頂端和右邊的效果。我仍然使得文本提示有效,但你可以通過在調用SetBarStyle()時去掉CBRS_TOOLTIPS風格而使之無效。
表 3: Adding text labels
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if(CMDIFrameWnd::OnCreate(lpCreateStruct) == -1)
? ?return -1;
? ?
if(!m_wndToolBar.CreateEx(this) ||
? ?!m_wndToolBar.LoadToolBar(IDR_MAINFRAME))
? ?{
? ?TRACE0("Failed to create toolbar\n");
? ?return -1; ? ? ?// fail to create
? ?}
if(!m_wndStatusBar.Create(this) ||
? ?!m_wndStatusBar.SetIndicators(indicators,sizeof(indicators)/sizeof(UINT)))
? ?{
? ?TRACE0("Failed to create status bar\n");
? ?return -1; ? ? ?// fail to create
? ?}
// TODO: Remove this if you don't want tool tips or a resizeable toolbar
m_wndToolBar.SetBarStyle(m_wndToolBar.GetBarStyle() |
? ?CBRS_GRIPPER | CBRS_BORDER_3D | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC);
// Add text to each button
for(int i = 0; i < m_wndToolBar.GetCount(); i++)
{ UINT id = m_wndToolBar.GetItemID(i);
CString s;
if(!s.LoadString(id)) continue;
int j = s.Find(_T('\n'));
if(j < 0) continue;
s = s.Right(s.GetLength() - j - 1);
m_wndToolBar.SetButtonText(i,s); }// Adjust sizes to include text
CRect rect;
m_wndToolBar.GetItemRect(0,&rect);
m_wndToolBar.SetSizes(rect.Size(),CSize(16,15));// TODO: Delete these three lines if you don't want the toolbar to
// be dockable
m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY);
EnableDocking(CBRS_ALIGN_ANY);
DockControlBar(&m_wndToolBar);
return 0;}
圖4
為了產生按鈕標簽,一個簡單的for循環掃過所有的按鈕并且從與之相連的幫助串中提取出提示文本。在設置完每個按鈕的標簽后,就調用工具條的SetSizes()函數去重新計算工具條的外觀以便使得標簽可見。也許會有更好的方法去實現最后一步,但我還是從微軟的MFCIE范例程序中借用了這個過程,不為別的,只為它確實有效。
從很多方面來說,MFCIE都是值得仔細學習的。從本質上來說,它實際上是Internet Explorer的一個微型版本,并且它還闡述了如何使用版本6的一些新特色。你將會驚訝于在你的MFC應用程序中添加HTML瀏覽功能是如此之簡單。
在絕大多數情況下你會希望文本標簽顯示在按鈕下面(這在最初的公用控件庫中是唯一的選擇)。Internet Explorer 3.0版加入了TBSTYLE_LIST風格,該風格導致文本標簽顯示在按鈕右邊。對于在標簽旁邊顯示一個下拉列表或者按鈕被一個子窗口覆蓋時,該風格是很有用的。
下拉列表
在“工具條的變形”一文中,我演示了通過將一個組合框作為一個子窗口來在工具條上添加下拉列表的情形。該方法在版本6中仍然有效,并且當你想在工具條上顯示當前的可選擇項時它仍然是有用的。然而,有時你希望工具條包含一個可以在鼠標點擊時顯示選擇列表或菜單的按鈕。該功能現在可以通過擴展風格TBSTYLE_DROPDOWN和TBSTYLE_EX_DRAWDDARROWS實現了。
例如,假設我希望對應于“文件”菜單下“新建”的按鈕可以顯示一個我的應用程序知道如何去創建的所有文件類型的列表。表4 顯示在前面的例子中如何加入該功能,而圖5顯示該工具條。我抓取了鼠標停留在該按鈕上時的屏幕,它顯示出了按鈕和下拉箭頭之間的分隔線。
為了加入一個下拉箭頭,首先我必須在基本的工具條控件上調用SetExtendedStyle()函數,并且指定TBSTYLE_EX_DRAWDDARROWS風格。然后我必須在每一個我想要顯示下拉箭頭的按鈕上指定TBSTYLE_DROPDOWN風格。
表 4: Converting the File menu New command to a drop-down button
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if(CMDIFrameWnd::OnCreate(lpCreateStruct) == -1)
? ?return -1;
? ?
if(!m_wndToolBar.CreateEx(this) ||
? ?!m_wndToolBar.LoadToolBar(IDR_MAINFRAME))
? ?{
? ?TRACE0("Failed to create toolbar\n");
? ?return -1; ? ? ?// fail to create
? ?}
if(!m_wndStatusBar.Create(this) ||
? ?!m_wndStatusBar.SetIndicators(indicators,sizeof(indicators)/sizeof(UINT)))
? ?{
? ?TRACE0("Failed to create status bar\n");
? ?return -1; ? ? ?// fail to create
? ?}
// TODO: Remove this if you don't want tool tips or a resizeable toolbar
m_wndToolBar.SetBarStyle(m_wndToolBar.GetBarStyle() |
? ?CBRS_GRIPPER | CBRS_BORDER_3D | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC);
// Add text to each button
for(int i = 0; i
圖5
當用戶在New按鈕上點擊時,就象圖5所示一樣,基本的按鈕操作就發生了。在這個例子中命令消息導致調用CWinApp::OnFileNew()。然而,當用戶點擊下拉箭頭時,工具條就發出TBN_DROPDOWN通知消息給工具條的父窗口。我可以通過重載OnNotify()函數或者通過在消息映射中加入一個ON_NOTIFY而獲取這個消息。
表5顯示了后者的實現技術。通常我顯示一個彈出菜單或者一個列表框去響應這個通知消息。在絕大多數情況下沒有必要提供一個結果值,因為缺省值(TBDDRET_DEFAULT)顯示了我已獲取了對這個事件的控制。其它可能的結果值是TBDDRET_NODEFAULT和TBDDRET_TREATPRESSED。前者表示該事件沒有受到控制,當出現后者時,工具條就表現得好像該按鈕被點擊一樣。
表 5: Handling drop-down notifications
BEGIN_MESSAGE_MAP(CMainFrame, CMDIFrameWnd)
? ?//{{AFX_MSG_MAP(CMainFrame)
? ?ON_WM_CREATE()
? ?//}}AFX_MSG_MAP
? ?ON_NOTIFY(TBN_DROPDOWN,AFX_IDW_TOOLBAR,OnDropDown)
END_MESSAGE_MAP()
void CMainFrame::OnDropDown(NMHDR* pNotifyStruct,LRESULT* result)
{
NMTOOLBAR* pInfo = (NMTOOLBAR*)pNotifyStruct;
switch(pInfo->iItem)
? ?{
? ?case ID_FILE_NEW:
? ?TRACE0("ID_FILE_NEW drop down\n");
? ?// TODO: Display popup menu or list box
? ?break;
? ?// TODO: Add cases for other drop-down buttons
? ?}
}
熱點圖像
運行Internet Explorer 4.0并且將鼠標在工具條上劃過。就能注意到在平時每個按鈕是平淡的顏色。而當鼠標觸及到該按鈕時,他會凸出來并且顯現出鮮艷的顏色。這種視覺效果采用了工具條控件的被稱作“熱點圖像”的功能。
一般的AppWizard代碼使用工具條資源來指定其上按鍵的外觀和與每個按鍵相連接的一個命令ID。工具條資源實際上包含一個復合的位圖,該位圖在調用LoadToolBar()函數時將被轉變成一個圖像列表(參見表4)。要激活熱點圖像功能,我必須通過SetHotImageList()函數提供第二個圖像列表,就象表6所示一樣。
表 6: Using hot images
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if(CMDIFrameWnd::OnCreate(lpCreateStruct) == -1)
? ?return -1;
? ?
if(!m_wndToolBar.CreateEx(this) ||
? ?!m_wndToolBar.LoadToolBar(IDR_MAINFRAME))
? ?{
? ?TRACE0("Failed to create toolbar\n");
? ?return -1; ? ? ?// fail to create
? ?}
CImageList img;
if(!img.Create(IDB_MAINFRAME,16,0,RGB(128,128,128)))
? ?{
? ?TRACE0("Failed to load hot images\n");
? ?return -1;
? ?}
m_wndToolBar.GetToolBarCtrl().SetHotImageList(&img);
img.Detach();
if(!m_wndStatusBar.Create(this) ||
? ?!m_wndStatusBar.SetIndicators(indicators,sizeof(indicators)/sizeof(UINT)))
? ?{
? ?TRACE0("Failed to create status bar\n");
? ?return -1; ? ? ?// fail to create
? ?}
// TODO: Remove this if you don't want tool tips or a resizeable toolbar
m_wndToolBar.SetBarStyle(m_wndToolBar.GetBarStyle() |
? ?CBRS_GRIPPER | CBRS_BORDER_3D | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC);
// Add text to each button
for(int i = 0; i
圖6
圖6 顯示了熱點圖像被激活的情形。鼠標正停留在New按鈕上,它就被顯示成一個空文檔的圖形。其它的按鈕是扁平的和淡顏色的。為了生成這個改進的工具條,我將res子目錄下的toolbar.bmp拷貝為toolbar1.bmp,然后將其作為一個位圖資源插入資源中,并取其ID為IDR_MAINFRAME。 接下來我編輯IDR_MAINFRAME 工具條,用很淡的顏色(例如淡灰色)來取代它原來的顏色。最后,我加入了如表6所示的對函數SetHotImageList()的調用。
這個例子演示了在一個已存的工具條中加入熱點圖像的捷徑,但他不會改進工具條的外觀。如果你想在這一點上取得更好的效果,MFCIE的例子包含了非常好的蝕刻位圖,它演示了當你使用非常有藝術性的圖像時它能達到何等地步的視覺效果。
其它特色
前面的講解演示了你怎樣簡單地改變現存的MFC程序,以獲得扁平鈕、把手、下拉列表和熱點圖像的功能。Visual C++ 6.0還提供了幾種其它令人感興趣的工具條特色,包括自定義繪制、OLE拖入目標和使用rebar(抱歉,不知道該單詞指的是什么)容器等。這些特色將會是將來的欄目的主題。
本文引用通告地址: http://blog.csdn.net/silver/services/trackbacks/5453.aspx
轉載于:https://www.cnblogs.com/henryzc/archive/2005/10/25/262072.html
總結
以上是生活随笔為你收集整理的VC6中工具条的新特色的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: C# Programming Langu
- 下一篇: 使用c#调用API函数CreatePro