---恢復內容開始---
首先CToolBarCtrl類內部維護了三個重要的數據結構:一個圖像列表,一個字符串列表,一個TBBUTTON結構體的列表。
知道了這一點,下面的理解起來就輕松了。慢慢來:
用CToolBarCtrl類為對話框創建工具欄的一般步驟:
1、准備一張工具欄的位圖(有兩種方法加載位圖,一種是為工具欄中每一個按鈕關聯一張位圖,第二種是加載一整張位圖,這張位圖中有所有工具欄按鈕的圖像,然后設定每個按鈕圖像的大小,這樣系統就可以把一整張位圖按像素分成多張位圖,本文采用第二種方法)
2、在資源視圖中的String Table中加入工具欄中每個按鈕對應的字符串,如:
3、添加一個MFC類,命名為CStandardBar,基類為CToolBarCtrl類。
4、在CStandardBar類中添加成員變量:
int m_nButtonCount; //工具欄按鈕的數量
TBBUTTON *m_pTBButtons; //工具欄按鈕
5、在CStandardBar類中重載基類CToolBarCtrl類中的Create函數,如下:(先給出代碼然后再解釋)
1 BOOL CStandardBar::Create(DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID) 2 { 3 // TODO: 在此添加專用代碼和/或調用基類 4 5 BOOL bRect=CToolBarCtrl::Create(dwStyle, rect, pParentWnd, nID);//一定要先掉用create函數用於 6 //Creates a toolbar control and attaches it to a CToolBarCtrl object. 7 8 9 10 m_nButtonCount = IDSTR_OUT - IDSTR_XSDJ + 1; //計算得到工具欄按鈕的個數 11 12 13 //CToolBarCtrl::SetBitmapSize(CSize(32,32)); 14 SetBitmapSize( CSize(32,32) ); //設置工具欄中位圖的大小,會根據這個大小分割導入的位圖 15 16 17 18 19 VERIFY(AddBitmap(m_nButtonCount,IDR_STANDARDBAR) != -1);//添加位圖 20 21 22 23 m_pTBButtons = new TBBUTTON[m_nButtonCount]; //創建工具欄的按鈕 24 25 26 27 28 for (int nIndex = 0; nIndex < m_nButtonCount; nIndex++) 29 { 30 CString string; 31 string.LoadString(nIndex + IDSTR_XSDJ); //從字符串表中加載字符 32 33 // Add second '\0' 34 35 36 //向工具條的字符串列表添加字符串 37 int nStringLength = string.GetLength() + 2; 38 TCHAR * pString = string.GetBufferSetLength(nStringLength); 39 40 //The last string must be terminated with two null characters. 41 pString[nStringLength-2] = 0; 42 pString[nStringLength-1] = 0; 43 44 45 VERIFY((m_pTBButtons[nIndex].iString = AddStrings(pString)) != -1);//向工具條的字符串列表添加字符串 46 47 string.ReleaseBuffer(); 48 49 50 m_pTBButtons[nIndex].fsState =TBSTATE_ENABLED; 51 m_pTBButtons[nIndex].fsStyle =TBSTYLE_FLAT; 52 m_pTBButtons[nIndex].dwData = 0; 53 m_pTBButtons[nIndex].iBitmap = nIndex; 54 m_pTBButtons[nIndex].iString =nIndex; 55 m_pTBButtons[nIndex].idCommand = nIndex + IDSTR_XSDJ; 56 } 57 58 59 60 m_pTBButtons[m_nButtonCount-1].idCommand=IDCANCEL; 61 62 //添加按鈕 63 64 65 //分隔按鈕 66 TBBUTTON sepButton; 67 sepButton.idCommand = 0; 68 sepButton.fsStyle = TBSTYLE_SEP; 69 sepButton.fsState = TBSTATE_ENABLED; 70 sepButton.iString = 0; 71 sepButton.iBitmap = 0; 72 sepButton.dwData = 0; 73 74 for (int nIndex = 0; nIndex < m_nButtonCount; nIndex++) 75 { 76 //添加按鈕 77 VERIFY(AddButtons(1,&m_pTBButtons[nIndex])); 78 if (!((nIndex +1) % 3)) 79 { 80 VERIFY(AddButtons(1,&sepButton));//添加分隔按鈕 81 } 82 } 83 //this->SetStyle(TBSTYLE_FLAT|CCS_TOP); 84 85 return bRect; 86 }
在重寫的函數中:
(1)要調用基類CToolBarCtrl類的Create函數,用於創建一個CToolBarCtrl類的對象並且綁定工具欄。
(2)計算出工具欄中按鈕的數量m_nButtonCount,在以后的代碼中要使用它。
(3)設置每個按鈕對應的位圖的大小:SetBitmapSize( CSize(32,32) ); 然后加載整張位圖:
AddBitmap(m_nButtonCount,IDR_STANDARDBAR)。之所以要設置每個按鈕對應的位圖的大小是因為只有這樣,MFC的底層才知道怎樣去分割那一整張位圖,我的那個位圖的長勢288像素,工具欄中有9個按鈕,288/9=32,所以設置為(32,32).
(4)創建TBBUTTON數組,在循環中給每個元素賦值。這里仔細說一下:
TBBUTTON的定義:
其中那些以字符i開頭的iBitmap,iString都是一個序號,什么序號(索引)呢?一開始我們就說過,CToolBarCtrl類中維護了三個重要的數據結構,而iBitmap和iString就是圖像列表和字符串列表中元素的索引。這個索引怎么產生的能?我們每調用一次AddBitmap(AddStrings)函數,對應的索引就會加一。正是因為這種機制,按鈕和字符串以及位圖才會關聯對應起來。idCommand是按鈕對應的ID.
(5)用AddButtons往工具欄中添加按鈕。(代碼中還添加了分割條)
6、在對話框類中添加CStandardBar類的對象:
CStandardBar m_StandardBar;
7、在OnCreate或者OninitDialog函數中調用重寫的Create函數和調整大小的函數。如:
m_StandardBar.Create( WS_VISIBLE | WS_CHILD |WS_BORDER|TBSTYLE_WRAPABLE | CCS_TOP,CRect(0,0,0,0),this, IDR_STANDARDBAR); m_StandardBar.AutoSize();
這樣對話框中的工具欄就建立了,最后給一張效果圖;
---恢復內容結束---