VC++技術內幕(第四版)筆記(第13章)

第十三章:工具欄和狀態欄

1,工具欄是CToolBar類一個對象,狀態欄是CStatusBar類的對象.CToolBar類和CStatusBar類均由CControlBar類派生.CControlBar類則由CWnd類派生.
CControlBar類所支持的控制欄窗口位於主框架窗口內,並且這些控制欄窗口能夠隨着主框架窗口的尺寸改變或移動自動調整自己的尺寸與位置.
控制欄對象的構造與析構以及窗口的創建都是由應用程序框架來管理的,其嚮導產生的代碼位於框架頭文件和代碼文件中.

2,工具欄的按鈕被按下是會象菜單或加速鍵一樣,發送相應的命令消息(該命令消息會象菜單命令一樣進行傳遞.原因:工具欄對象以及狀態欄對象都與主框架窗口聯繫.).
更新命令UI消息控制函數一方面可以用來更新工具欄中的按鈕的狀態,另一方面可以用來修改工具欄中的按鈕圖形.
整個工具欄只有一個位圖,每一個按鈕在其中佔一個高15像素寬16像素的位圖片.
注意:不要直接編輯工具欄位圖,而是應該使用DeveloperStudio的特定工具欄編輯工具進行編輯.

3,更新命令消息控件函數主要是用來對菜單項進行禁止和複選的,但也可以作用於工具欄按鈕.
1)CCmdUI::Enable
virtual void Enable( BOOL bOn = TRUE );
//bOn: TRUE to enable the item, FALSE to disable it.
//Call this member function to enable or disable the user-interface item for this command.
2)CCmdUI::SetCheck
virtual void SetCheck( int nCheck = 1 );
//nCheck: Specifies the check state to set. If 0, unchecks; if 1, checks; and if 2, sets indeterminate.
//Call this member function to set the user-interface item for this command to the appropriate check state. This member function works for menu items and toolbar buttons. The indeterminate state applies only to toolbar buttons.

4,當某菜單項所在的彈出式菜單彈出時候,對該菜單項進行處理的更新命令UI消息控制函數纔會被調用.
工具欄總是處於顯示狀態,對它進行處理的更新命令UI控制函數是在應用程序的空狀態處理過程中被調用的.
當同一個更新命令UI控制函數既需要對某菜單項處理,又需要對某工具欄按鈕進行處理,則在空狀態處理過程及當該菜單項所在的彈出式菜單彈出時候,該控制函數都會被調用.

5,創建工具提示:
把提示文本加在菜單提示的後面,前面加一個換行符.如在Prompt:打印活動文檔/n打印

6,幾個重要函數
1)CWnd::GetParentFrame 
CFrameWnd* GetParentFrame( ) const;
//Return Value:A pointer to a frame window if successful; otherwise NULL.
//Call this member function to retrieve the parent frame window. The member function searches up the parent chain until a CFrameWnd (or derived class) object is found.
//MDI中得到的是MDI子框架窗口.
2)AfxGetApp 
CWinApp* AfxGetApp( );
//Return Value:A pointer to the single CWinApp object for the application.
//The pointer returned by this function can be used to access application information such as the main message-dispatch code or the topmost window.
通過應用程序獲得主框架窗口指針:(單文檔和多文檔程序均適用)
 CMainFrame* pFrame=(CMainFrame*)AfxGetApp()->m_pMainWnd;
 CToolBar* pToolBar=&pFrame->m_wndToolBar;
注:在SDI程序中,當視圖的OnCreate函數被調用時候,m_pMainWnd還沒有被設置,這時候可通過CWnd::GetParentFrame來獲取主框架窗口指針.
說明:
在MDI程序中AppWizard嚮導自動生成了對m_pMainWain的賦值代碼.而在SDI中,框架是在視圖的創建的過程中對m_pMainWain的賦值代碼的.


7,工具欄編輯器的使用:用鼠標選中某按鈕,然後按DEL鍵可以擦除該按鈕的像素;如果想刪掉某個按鈕,只需要把它拖出工具欄即可.

8,工具欄的停靠:
在CMainFrame::OnCreate函數中可以看到如下代碼,該代碼允許工具欄在框架窗口任何邊筐處停靠:
m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY);
EnableDocking(CBRS_ALIGN_ANY);
DockControlBar(&m_wndToolBar);
說明:
1)CControlBar::EnableDocking
//Call this function to enable a control bar to be docked. The sides specified must match one of the sides enabled for docking in the destination frame window, or the control bar cannot be docked to that frame window.
2)CFrameWnd::EnableDocking
//Call this function to enable dockable control bars in a frame window. By default, control bars will be docked to a side of the frame window in the following order: top, bottom, left, right.
3)CFrameWnd::DockControlBar
//Causes a control bar to be docked to the frame window. The control bar will be docked to one of the sides of the frame window specified in the calls to both CControlBar::EnableDocking and CFrameWnd::EnableDocking. The side chosen is determined by nDockBarID.

9,狀態欄既不接受用戶輸入也不產生命令消息,它的作用就是在程序的控制下在窗格(pane)中顯示一些文本.
狀態欄支持兩種類型文本窗格(信息行窗格 和 狀態指示器窗格).
注:爲實現在狀態欄中顯示一些應用程序的特殊數據,必須先禁止標準狀態欄顯示菜單提示及鍵盤狀態.(具體方法?)
1)AppWizard在MainFrm.cpp文件中產生的靜態數組indicators是用以定義狀態欄的.
static UINT indicators[] =
{
 ID_SEPARATOR,           // status line indicator
 ID_INDICATOR_CAPS, //以下均爲串資源ID
 ID_INDICATOR_NUM,
 ID_INDICATOR_SCRL,
};
2)CStatusBar::SetIndicators//根據indicators[]數組內容對狀態欄進行設置.
BOOL SetIndicators( const UINT* lpIDArray, int nIDCount );
//Sets each indicator’s ID to the value specified by the corresponding element(對應元素) of the array lpIDArray, loads the string resource specified by each ID, and sets the indicator’s text to the string.
//SetIndicators在應用程序的派生框架類中被調用.在CMainFrame::OnCreate函數中可以看見.
3)信息行窗格所顯示的是儲蓄動態提供的字符串.
對信息行的設置:首先訪問狀態欄對象,然後再用從0開始的索引參數來調用CStatusBar::SetPaneText函數設置.
如:
 CMainFrame* pFrame=(CMainFrame*)AfxGetApp()->m_pMainWnd;
 CStatusBar* pStatus=&pFrame->m_wndStatusBar;
 pStatus->SetPaneText(0,"message line for first pane");
4)狀態指示器窗格總是與一個字符串相連,該字符串是由字符串資源來提供的(在string table裏設置),它是否被顯示完全取決於相應的更新命令UI控制函數.
指示器是由一個字符串資源ID來標識的,該ID也被用來傳遞更新命令UI消息.
afx_msg void CMainFrame::OnUpdateKeyCapsLock(CCmdUI *pCmdUI);
ON_UPDATE_COMMAND_UI(ID_INDICATOR_CAPS,OnUpdateKeyCapsLock)
void CMainFrame::OnUpdateKeyCapsLock(CCmdUI *pCmdUI)
{
 pCmdUI->Enable(::GetKeyState(VK_CAPITAL)&1);
}
說明:
狀態欄的更新命令UI消息控制函數是在空閒處理階段被調用的.(推測:調用的時候傳入CCmdUI指針).
5)狀態指示器窗格的長度即爲相應字符串資源的長度.


10,獲取狀態欄的控制.
1)用於鍵盤狀態指示器的更新命令UI控制函數被嵌入在主框架窗口類中,它們與資源字符串ID(indicators[]中定義的串資源ID)相聯.
2)狀態欄實際上有一個子窗口(即status line indicator),其默認ID在CMainFrm::OnCreate函數中的CStatusBar::Create函數中設置爲AFX_IDW_STATUS_BAR.改變這個ID可以實現禁止框架在0號窗格中顯示菜單提示.
具體實現如下:
將CMainFrm::OnCreate函數中的CStatusBar::Create函數由m_wndStatusBar.Create(this)改成m_wndStatusBar.Create( this,WS_CHILD | WS_VISIBLE | CBRS_BOTTOM, ID_MY_STATUS_BAR(自定義的ID)).


11,注意,左右鼠標按鈕跟鍵盤上的鍵一樣有虛鍵碼,可以通過GetKeyState函數獲取。

強烈建議自己動手實現書中兩個事例,尤其是第二個了,自己做了就明白這章講的是什麼個回事了.

///////////////////
//////////////////

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