上一節(jié)中雞啄米講了工具欄的創(chuàng)建、??颗c使用,本節(jié)來講解狀態(tài)欄的知識。
狀態(tài)欄簡介
狀態(tài)欄相信大家在很多窗口中都能見到,它總是用來顯示各種狀態(tài)。狀態(tài)欄實際上也是一個窗口,一般分為幾個窗格,每個窗格分別用來顯示不同的信息和狀態(tài)等,如菜單項和工具欄按鈕的提示信息。
用MFC向?qū)傻膯挝臋n或多文檔程序都會自動創(chuàng)建狀態(tài)欄,大家可以運(yùn)行下VS2010/MFC編程入門之三十四(菜單:VS2010菜單資源詳解)中創(chuàng)建的Example34程序,在結(jié)果界面中可以看到窗口底部有個狀態(tài)欄,該狀態(tài)欄被分為了幾個窗格,分別用來顯示菜單項和工具欄按鈕的提示信息及Caps Lock、Num Lock、Scroll Lock鍵的狀態(tài)。
當(dāng)然,我們可以自定義狀態(tài)欄,加入新的提示信息或指示器。
CStatusBar類
MFC為狀態(tài)欄提供了CStatusBar類,封裝了狀態(tài)欄的屬性和操作。
下面是CStatusBar類幾個主要的成員函數(shù):
virtual BOOL Create(CWnd* pParentWnd, DWORD dwStyle = WS_CHILD | WS_VISIBLE | CBRS_BOTTOM, UINT nID = AFX_IDW_STATUS_BAR);
創(chuàng)建一個狀態(tài)欄。參數(shù)pParentWnd為狀態(tài)欄父窗口的指針,參數(shù)dwStyle為狀態(tài)欄的風(fēng)格,除了標(biāo)準(zhǔn)的Windows風(fēng)格外,它還支持:
CBRS_TOP:位于框架窗口的頂部。
CBRS_BOTTOM:位于框架窗口的底部。
CBRS_NOALIGN:父窗口大小改變時狀態(tài)欄不會被重新定位。
參數(shù)nID指定狀態(tài)欄的ID。
BOOL SetIndicators(const UINT* lpIDArray, int nIDCount);
為每個指示器設(shè)置顯示文本,具體來說,就是用lpIDArray數(shù)組中的對應(yīng)元素為每個指示器設(shè)置一個ID,然后加載每個ID代表的字符串,設(shè)置為這些指示器的顯示文本。參數(shù)lpIDArray為指向一個ID數(shù)組的指針,參數(shù)nIDCount為lpIDArray數(shù)組的元素個數(shù)。
UINT GetItemID(int nIndex) const;
獲取由nIndex指定的指示器的ID。參數(shù)nIndex為要獲取ID的指示器索引。
CString GetPaneText(int nIndex) const;
獲取狀態(tài)欄窗格中顯示的文本。參數(shù)nIndex為要獲取文本的窗格的索引。返回值為包含窗格文本的CString對象。
BOOL SetPaneText(int nIndex, LPCTSTR lpszNewText, BOOL bUpdate = TRUE);
設(shè)置狀態(tài)欄窗格的顯示文本。參數(shù)nIndex為要設(shè)置文本的窗格的索引,參數(shù)lpszNewText為指向新的窗格文本的指針,參數(shù)bUpdate表示是否設(shè)置后立即更新顯示。如果設(shè)置成功則返回TRUE,否則返回FALSE。
狀態(tài)欄的創(chuàng)建
在Example34程序中,我們在CMainFrame類中看到,創(chuàng)建狀態(tài)欄時使用的是CMFCStatusBar類對象。CMFCStatusBar類是自VS2008以來提供的狀態(tài)欄類,用法與CStatusBar類相似,甚至很多成員函數(shù)也類似,但它的功能更加豐富。關(guān)于CMFCStatusBar類的成員函數(shù)可以查閱MSDN了解。
雞啄米下面就以Example34程序的CMFCStatusBar類對象為例,來講講狀態(tài)欄的創(chuàng)建步驟:
1. 構(gòu)造一個CMFCStatusBar類的對象。
在MainFrm.h文件中,為CMainFrame類定義了一個成員對象:CMFCStatusBar m_wndStatusBar;。
2. 調(diào)用CMFCStatusBar::Create函數(shù)來創(chuàng)建狀態(tài)欄窗口。
在CMainFrame::OnCreate函數(shù)的實現(xiàn)中,我們可以找到CMFCStatusBar::Create函數(shù)的調(diào)用:
- if (!m_wndStatusBar.Create(this))
- {
- TRACE0("Failed to create status bar\n");
- return -1; // fail to create
- }
3. 調(diào)用CMFCStatusBar::SetIndicators函數(shù)為狀態(tài)欄劃分窗格,并為每個指示器設(shè)置顯示文本。
CMFCStatusBar::SetIndicators函數(shù)需要一個ID數(shù)組的參數(shù),在MainFrm.cpp中,如下定義了一個窗格ID的數(shù)組:
- static UINT indicators[] =
- {
- ID_SEPARATOR, // status line indicator
- ID_INDICATOR_CAPS,
- ID_INDICATOR_NUM,
- ID_INDICATOR_SCRL,
- };
indicators數(shù)組定義了狀態(tài)欄窗格的劃分信息。第一個元素一般為ID_SEPARATOR,對應(yīng)的窗格用來顯示命令提示信息,上面數(shù)組中的后三項為指示器文本的字符串ID,可以根據(jù)這些ID在String Table字符串資源中找到相應(yīng)的字符串,查找方法是,在Resource View資源視圖中,打開String Table字符串資源,可以看到有ID、Value和Caption三列,在ID列中找到需要的ID,對應(yīng)的Caption列文本就是要查找的字符串。ID_INDICATOR_CAPS、ID_INDICATOR_NUM和ID_INDICATOR_SCRL對應(yīng)的字符串分別是CAP、NUM、SCRL,對應(yīng)的三個窗格分別為Caps Lock指示器、Num Lock指示器和Scroll Lock指示器。
定義了指示器數(shù)組就可以使用CMFCStatusBar::SetIndicators函數(shù)為狀態(tài)欄劃分窗格了,依然是在CMainFrame::OnCreate函數(shù)中調(diào)用:
- m_wndStatusBar.SetIndicators(indicators, sizeof(indicators)/sizeof(UINT));
這樣狀態(tài)欄就創(chuàng)建完成了,之后我們可以通過CMFCStatusBar::SetPaneText設(shè)置窗格的文本。
狀態(tài)欄應(yīng)用實例
雞啄米看到網(wǎng)上有很多人在問,怎樣在狀態(tài)欄添加一個時間窗格,用來顯示系統(tǒng)時間,本節(jié)就給出這樣一個實例。此實例依然是在Example34的基礎(chǔ)上進(jìn)行修改的。步驟如下:
1. 在Resource View資源視圖中打開String Table字符串資源,然后在最后一行的下一個空白行中,或者任意處點(diǎn)右鍵選擇“New String”,添加一個新的字符串資源,ID為ID_INDICATOR_TIME,Value設(shè)為一個不與任何其他字符串資源重復(fù)的整數(shù)值,Caption設(shè)為"00:00:00",這是為了給時間的顯示預(yù)留空間,因為狀態(tài)欄會根據(jù)字符串的長度為相應(yīng)的窗格確定缺省寬度。
2. 在indicators數(shù)組的第一個元素ID_INDICATOR_SCRL后插入ID_INDICATOR_TIME。
- static UINT indicators[] =
- {
- ID_SEPARATOR, // status line indicator
- ID_INDICATOR_CAPS,
- ID_INDICATOR_NUM,
- ID_INDICATOR_SCRL,
- ID_INDICATOR_TIME
- };
3. 要實時顯示系統(tǒng)時間,就需要使用一個定時器,每秒鐘更新一次時間顯示。在CMainFrame::OnCreate函數(shù)中開啟定時器,代碼如下:
- int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
- {
- if (CFrameWndEx::OnCreate(lpCreateStruct) == -1)
- return -1;
- ......略
- // 啟動定時器,定時器ID為1,定時時間為1000ms,即1s
- SetTimer(1, 1000, NULL);
- return 0;
- }
4. 在Class View類視圖中找到CMainFrame類,右鍵選擇“Properties”,然后在顯示出來的屬性頁中,點(diǎn)工具欄上的Messages按鈕,即顯示出消息列表,找到WM_TIMER消息,添加其消息處理函數(shù)void CMainFrame::OnTimer(UINT_PTR nIDEvent),并修改此函數(shù)實現(xiàn)如下:
- void CMainFrame::OnTimer(UINT_PTR nIDEvent)
- {
- // TODO: Add your message handler code here and/or call default
- CString strTime;
- // 獲取系統(tǒng)當(dāng)前時間,并保存到curTime
- CTime curTime = CTime::GetCurrentTime();
- // 格式化curTime,將字符串保存到strTime
- strTime = curTime.Format(_T("%H:%M:%S"));
- // 在狀態(tài)欄的時間窗格中顯示系統(tǒng)時間字符串
- m_wndStatusBar.SetPaneText(4, strTime);
- CFrameWndEx::OnTimer(nIDEvent);
- }
5. 運(yùn)行程序,我們看到狀態(tài)欄的最后一個窗格中能夠?qū)崟r顯示系統(tǒng)時間,如下圖:

狀態(tài)欄的內(nèi)容就講這些,其實還是比較簡單的。雞啄米歡迎大家常來此學(xué)習(xí)。