?? mfc教程14_ mfc工具條和狀態欄.htm
字號:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<!-- saved from url=(0042)http://www.vczx.com/tutorial/mfc/mfc13.php -->
<HTML><HEAD><TITLE>MFC教程_ MFC工具條和狀態欄</TITLE>
<META http-equiv=Content-Type content="text/html; charset=gb2312">
<META content="MSHTML 6.00.2900.3157" name=GENERATOR></HEAD>
<BODY bgColor=#ffffff>
<OL start=13>
<P align=justify>
<LI><A name=_Toc452641006></A><A name=_Toc457299135></A><B>MFC工具條和狀態欄</B>
<P></P>
<OL>
<P align=justify>
<LI><B><A name=_Toc452641007></A><A name=_Toc457299136></A>Windows控制窗口</B>
<P></P></LI></OL></LI></OL>
<P align=justify>Windows (Windows95或者以上版本)
提供了系列通用控制窗口,其中包括工具條(ToolBar)、狀態欄(StatusBar)、工具條提示窗口(ToolTip)。</P>
<P
align=justify>Windows在一個DLL加載時注冊個控制窗口的“窗口類”。例如,工具條的“窗口類”是“ToolbarWindow32”,狀態欄的“窗口類”是“msctls_statusbar32”,工具條提示窗口的“窗口類”是“tooltips_class32”。為了保證該DLL被加載,使用控制“窗口類”前,應該首先調用函數InitCommonControl。MFC在窗口注冊函數AfxDeferRegisterClass中實現了這一點。見2.2.1節MFC下窗口的注冊。</P>
<P
align=justify>創建通用控制窗口,可以使用專門的創建函數,如創建工具條的函數::CreateToolBarEx,創建狀態欄的函數::CreateStatusBarEx。也可以調用窗口創建函數::CreateWindowEx,但是需要指定預定義的“窗口類”,必要的話還要其他步驟,如使用“ToolbarWindow32”“窗口類”創建工具欄后,還需要在工具欄中添加或者插入按鈕。</P>
<P
align=justify>一般,通用控制可以指定控制窗口風格(Style)。例如,具備風格CCS_TOP,表示該控制窗口放到父窗口客戶區的頂部,具備CCS_BOTTOM,表示該控制窗口在客戶區的底部。具體的控制窗口類可以有特別的適合于自己的風格,例如,TTS_ALWAYSTIP表示只要光標落在工具欄的按鈕上,ToolTip窗口不論激活與否都會顯示出來。</P>
<P align=justify>每一控制窗口類都有自己的窗口過程來處理自己的窗口消息,實現特定的功能??刂拼翱陬惖拇翱谶^程由Windows提供。</P>
<UL>
<P align=justify>
<LI>工具條
<P></P></LI></UL>
<P
align=justify>工具條的窗口過程處理了必要的消息,提供了標準工具條的功能,例如,工具條對客戶化特征提供內在的支持,用戶可以通過一個客戶化對話框來添加、修改、刪除或者重新安排工具條按鈕。這些特征是否可以被用戶所用或者用到什么地步是可以由程序控制的。</P>
<P
align=justify>工具條的窗口過程將自動設置工具條的尺寸大小和位置,如果指定了控制窗口風格CCS_TOP或者CCS_BOTTOM,則窗口過程把工具條放到父窗口客戶區的頂部或者底部。窗口過程任何時候只要收到WM_SIZE或者TB_AUTOSIZE消息就自動地調整工具條的大小和位置。</P>
<P align=justify>工具條的按鈕被選中后,會產生一個命令消息,它的窗口過程把該消息送給父窗口的窗口過程處理。</P>
<P
align=justify>工具條中的按鈕并不以子窗口的形式出現,而是以字符或者位圖按鈕的方式顯示,每個按鈕大小相同,缺省是24*22個像素。每個按鈕都有一個索引,索引編號從0開始。每個按鈕包括如下屬性:</P>
<P align=justify>按鈕的字符串索引,位圖索引,風格,狀態,命令ID</P>
<P
align=justify>按鈕可以有兩種風格TBSTYLE_BUTTON和TBSTYLE_CHECK,前者像一個標準按鈕那樣響應用戶的按擊,后者響應每一次按擊,在按下和跳起兩種狀態之間切換。按鈕響應用戶的動作,給父窗口發送一個包含了該按鈕對應命令ID的命令消息。一般一個按鈕的命令ID對應一個菜單項。</P>
<P
align=justify>工具條維護兩個列表,分別用來存放工具條按鈕使用的字符串或者位圖,列表中的位圖或者字符串從0開始編號,編號和按鈕的索引相對應。</P>
<P align=justify>工具條可以是Dockable(泊位)或者Floatable(漂浮)的。</P>
<P
align=justify>工具條可以有TBSTYLE_TOOLTIPS風格,如果具有這種風格,則創建和管理一個Tooltip控制,這是一個小的彈出式窗口,用來顯示描述按鈕的文本,平時該窗口隱藏,當鼠標落到按鈕上面并停留約一秒后才彈出,在鼠標附近顯示。</P>
<P
align=justify>由于Tooltip窗口平時是隱藏的,所以不能接收鼠標消息來決定何時顯示本窗口。這樣,接收鼠標的窗口必須把鼠標消息送給Tooltip窗口,這是通過給Tooptip窗口發送消息TTM_RELAYEVENT來實現的。</P>
<UL>
<P align=justify>
<LI>狀態欄
<P></P></LI></UL>
<P align=justify>狀態欄類似于工具條,有自己的窗口過程,可以泊位、漂浮。不過,習慣上狀態欄都位于屏幕底部。每個狀態條分成若干格(Status
bar panes),每格從0開始編號,編號作為格的索引。每一個格,如同工具條的按鈕一樣,并不是一個Windows窗口。</P>
<OL>
<OL>
<P align=justify>
<LI><A name=_Toc452641008></A><A name=_Toc457299137></A><B>MFC的工具條和狀態欄類</B>
<P></P></LI></OL></OL>
<P
align=justify>MFC使用CToolBarCtrl、CStatusBarCtrl和CToolTipCtrl窗口類分別對工具條、狀態欄、Tooltip控制窗口進行了封裝。</P>
<P
align=justify>但是,直接使用這些類還不是很方便。MFC提供了CToolBar、CStatusBar來處理狀態欄和工具條,CToolBar、CStatusBar功能更強大,靈活。這兩個類都派生于CControlBar。</P>
<P
align=justify>在MFC下,建議這些控制條子窗口ID介于AFX_IDW_TOOLBARFIRST(0xE800)和AFX_IDW_CONTROLBAR_LAST(0Xe8FF)之間。這256個ID中,前32個又有其特殊性,用于MFC的打印預覽中。</P>
<P
align=justify>CControlBar派生于CWnd類,是控制條窗口類的基類,它派生出CToolBar、CStatusBar、CDockBar、CDialogBar、COleResizeBar類。CControlBar實現了以下功能:</P>
<UL>
<P align=justify>
<LI>和父窗口(邊框窗口)的頂部或者底部或者其他邊對齊。
<P></P>
<P align=justify></P>
<LI>可以包含子條目,這些條目或者是基于HWND的子窗口,或者是基于非HWND的條目。負責分配條目數組。
<P></P>
<P align=justify></P>
<LI>支持CBRS_TOP(缺省,控制條放在頂部),CBRS_BOTTOM(放在底部),CBRS_NOALIGN(父窗口大小變化時不重新放置控制條)等幾種控制風格。
<P></P>
<P align=justify></P>
<LI>支持派生類的實現。幾個派生類有一定的共性,或者其中兩個有一定的共性,這樣CControlBar實現的函數一部分只適用于某個派生類,一部分適用于兩個或者多個派生類,還有一部分適用于所有的派生類。所謂適用,這里指派生類直接繼承了CControlBar的實現,或者覆蓋了其實現但是建立在擴展其實現的基礎上。類似地,CControlBar的成員變量也不是為所有派生類所共同適用的。
<P></P></LI></UL>
<P
align=justify>CStatusBar和CControlBar一方面建立在CControlBar的基礎之上,另一方面以Windows的通用控制狀態欄和工具條為基礎。它們繼承了CControlBar類的特性,但是所封裝的窗口句柄是相應的Windows控制窗口的句柄,如同CFormView繼承了CSrcollView的視類特性,但是其窗口句柄是無模式對話框窗口句柄一樣。</P>
<P align=justify></P>
<P
align=justify>典型地,如果在使用AppWizard生成應用程序時,指定了要求工具條和狀態欄的支持,則在主邊框窗口的OnCreate函數中包含一段如下的代碼,用來創建工具條、狀態欄和設置一些特性。</P>
<P align=justify>//創建工具欄</P>
<P align=justify>if (!m_wndToolBar.Create(this)
||!m_wndToolBar.LoadToolBar(IDR_MAINFRAME))</P>
<P align=justify>{</P>
<DIR>
<P align=justify>TRACE0("Failed to create toolbar\n");</P>
<P align=justify>return -1; // fail to create</P></DIR>
<P align=justify>}</P>
<P align=justify>//創建狀態欄</P>
<P align=justify>if (!m_wndStatusBar.Create(this) ||</P>
<DIR>
<P align=justify>!m_wndStatusBar.SetIndicators(indicators,
sizeof(indicators)/sizeof(UINT)))</P></DIR>
<P align=justify>{</P>
<DIR>
<P align=justify>TRACE0("Failed to create status bar\n");</P>
<P align=justify>return -1; // fail to create</P></DIR>
<P align=justify>}</P>
<P align=justify></P>
<P align=justify>// TODO: Remove this if you don't want tool tips or a
resizeable toolbar</P>
<P align=justify>//對工具欄設置Tooltip特征</P>
<P align=justify>m_wndToolBar.SetBarStyle(m_wndToolBar.GetBarStyle() |</P>
<DIR>
<P align=justify>CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC);</P>
<P align=justify></P></DIR>
<P align=justify>//使得工具欄可以泊位在邊框窗口</P>
<P align=justify>// TODO: Delete these three lines if you don't want the toolbar
to</P>
<P align=justify>// be dockable</P>
<P align=justify>m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY);</P>
<P align=justify>EnableDocking(CBRS_ALIGN_ANY);</P>
<P align=justify>DockControlBar(&m_wndToolBar);</P>
<P align=justify></P>
<P
align=justify>工具條除了Tooltip,Resizeable,Dockable特性外,還可以是Floatable。應用程序可以使用CFrameWnd::SaveBarState保存邊框窗口的控制條的有關信息到INI文件或者Windows
Register庫,使用LoadBarSate從INI文件或者Register庫中讀取有關信息并恢復各個控制條的設置。</P>
<P
align=justify>下文,將討論工具條等的創建、銷毀,從中分析CControlBar和派生類的關系,討論CControlBar如何實現共性,如何支持派生類的特定要求,派生類又如何實現自己的特定需求等。</P>
<OL>
<OL>
<OL>
<P align=justify>
<LI><A name=_Toc452641009></A><A name=_Toc457299138></A><B>控制窗口的創建</B>
<P></P>
<P
align=justify>創建工具條、狀態條、對話框工具欄的方法是不同的,所以必須給每個派生類CToolBar、CStatusBar、CDialogBar設計和實現自己的窗口創建函數Create。但是,它們是也是有共性的,共性由CControlBar的PreCreateWindow處理。在窗口創建之后,各個派生類都要進行的處理(共性)由CControlBar的OnCreate完成,特別的處理通過派生類的OnNcCreate完成。</P>
<OL>
<P align=justify>
<LI><A name=_Toc457299139></A><B>PreCreateWindow</B>
<P></P>
<P align=justify>首先,討論CControlBar 類的PreCreateWindow的實現。</P>
<P align=justify>BOOL CControlBar::PreCreateWindow(CREATESTRUCT&
cs)</P>
<P align=justify>{</P>
<P align=justify>if (!CWnd::PreCreateWindow(cs))</P>
<P align=justify>return FALSE;</P>
<P align=justify></P>
<P align=justify>//修改窗口風格,強制適用clipsliblings,以防重復繪制</P>
<P align=justify>cs.style |= WS_CLIPSIBLINGS;</P>
<P align=justify></P>
<P align=justify>//default border style translation for Win4</P>
<P align=justify>//(you can turn off this translation by setting
CBRS_BORDER_3D)</P>
<P align=justify>if (afxData.bWin4 && (m_dwStyle &
CBRS_BORDER_3D) == 0)</P>
<P align=justify>{</P>
<P align=justify>DWORD dwNewStyle = 0;</P>
<P align=justify>switch (m_dwStyle &
(CBRS_BORDER_ANY|CBRS_ALIGN_ANY))</P>
<P align=justify>{</P>
<P align=justify>case CBRS_LEFT: //控制條在邊框窗口的左邊顯示</P>
<P align=justify>dwNewStyle = CBRS_BORDER_TOP|CBRS_BORDER_BOTTOM;</P>
<P align=justify>break;</P>
<P align=justify>case CBRS_TOP://控制條在邊框窗口的頂部顯示</P>
<P align=justify>dwNewStyle = CBRS_BORDER_TOP;</P>
<P align=justify>break;</P>
<P align=justify>case CBRS_RIGHT://控制條在邊框窗口的右邊顯示</P>
<P align=justify>dwNewStyle = CBRS_BORDER_TOP|CBRS_BORDER_BOTTOM;</P>
<P align=justify>break;</P>
<P align=justify>case CBRS_BOTTOM://控制條在邊框窗口的底部顯示</P>
<P align=justify>dwNewStyle = CBRS_BORDER_BOTTOM;</P>
<P align=justify>break;</P>
<P align=justify>}</P>
<P align=justify></P>
<P align=justify>// set new style if it matched one of the predefined
border types</P>
<P align=justify>if (dwNewStyle != 0)</P>
<P align=justify>{</P>
<P align=justify>m_dwStyle &= ~(CBRS_BORDER_ANY);</P>
<P align=justify>m_dwStyle |= (dwNewStyle | CBRS_BORDER_3D);</P>
<P align=justify>}</P>
<P align=justify>}</P>
<P align=justify>return TRUE;</P>
<P align=justify>}</P>
<P
align=justify>其中,afxData是一個全局變量,MFC用它來記錄系統信息,如版本信息等。這里afxData.bWin4表示Windows版本是否高于4.0。</P>
<P
align=justify>CToolBar的PreCreateWindow函數修改了窗口風格,也修改狀態欄、工具欄等的CBRS_風格。CBRS_風格的改變不會影響窗口風格。因為這些CBRS_風格被保存在成員變量m_dwStyle中。</P>
<P
align=justify>除了上述在程序中用到的影響工具條、狀態欄等顯示位置的CBRS_風格外,還有和泊位相關的CBRS_風格,CBRS_ALIGN_LEFT、CBRS_ALIGN_RIGHT、CBRS_ALIGN_BOTTOM、CBRS_ALIGN_TOP、CBRS_ALIGN_ANY,分別表示工具條可以在停泊在邊框窗口的左邊、右邊、底部、頂部或者所有這些位置;和漂浮相關的CBRS_風格CBRS_FLOAT_MULTI,表示多個工具條可以漂浮在一個微型邊框窗口中;和Tooltips相關的CBRS_風格CBRS_TOOLTIPS和CBRS_FLYBY。</P>
<P
align=justify>派生類如果沒有特別的要求,可以不覆蓋PreCreateWindow函數。CStatusBar因為有更具體和特殊的風格要求,所以它覆蓋了PreCreateWindow。CStatusBar的覆蓋實現調用了CControlBar的實現。</P>
<P
align=justify>派生類也可以在覆蓋實現中修改PreCreateWindow參數cs,改變窗口風格;修改m_dwStyle,改變CBRS_風格。</P>
<P align=justify></P>
<LI><A name=_Toc457299140></A><B>控制條的窗口創建</B>
<P></P></LI></OL></LI></OL></OL></OL>
<P
align=justify>CControlBar派生類實現了自己的窗口創建函數Create,CControlBar的PreCreateWindow被派生類的Create函數直接或者間接地調用。以CToolBar為例討論窗口創建函數和創建過程。</P>
<OL>
<P align=justify>
<LI>CToolBar的窗口創建函數Create
<P></P>
<P align=justify>Create函數實現如下:</P>
<P align=justify>BOOL CToolBar::Create(CWnd* pParentWnd, DWORD dwStyle, UINT
nID)</P>
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -