轉自:http://www.jizhuomi.com/software/217.html
上一節教程講了工具欄資源及CToolBar類,本節繼續講解工具欄的相關知識,主要內容包括工具欄的創建、停靠與使用。
工具欄的使用
上一節提到過,一般情況下工具欄中的按鈕在菜單欄中都有對應的菜單項,兩者實現的功能相同,要想實現這種效果,只需要將工具欄按鈕的ID與對應的菜單欄中菜單項的ID設置為相同值即可。
在實際使用工具欄時,除了前面講的資源編輯外,其他使用與菜單類似。例如,對COMMAND消息和UPDATE_COMMAND_UI消息,可以像VS2010/MFC編程入門之三十五(菜單:菜單及CMenu類的使用)中的菜單應用實例那樣為工具欄按鈕添加消息處理函數。
如果工具欄按鈕對應的菜單項已經添加了消息處理函數,那么就不必再為它添加了,因為它的ID與菜單項相同,所以會調用同樣的消息處理函數。這樣點擊工具欄按鈕與點擊相應菜單項執行相同的功能,在菜單項為選中、激活或禁用等狀態時,工具欄按鈕會有一樣的狀態。
工具欄的創建
大家在第三十四講創建的Example34工程的CMainFrame類中看到,它創建工具欄所使用的類並不是常用的CToolBar類,而是CMFCToolBar類。CMFCToolBar類是自VS2008以來MFC提供的類,它與CToolBar類有些類似,但功能更豐富。這里要注意,CMFCToolBar類與CToolBar類並沒有任何派生關系。
這里以CMFCToolBar類來講講工具欄的創建步驟:
1. 創建工具欄資源。
2. 構造CMFCToolBar類的對象。
3. 調用CMFCToolBar類的Create或CreateEx成員函數創建工具欄。
4. 調用LoadToolBar成員函數加載工具欄資源。
大家可以對應着看看Example34的CMainFrame類自動生成的代碼中創建工具欄的過程。
工具欄IDR_MAINFRAME的資源已經自動創建好。在MainFrm.h文件對CMainFrame類的聲明中,定義了CMFCToolBar類的對象作為成員對象:CMFCToolBar m_wndToolBar;。然后在CMainFrame::OnCreate函數的實現中可以看到工具欄的創建以及加載工具欄資源的代碼,如下:
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct) { if (CFrameWndEx::OnCreate(lpCreateStruct) == -1) return -1; ......略 // 調用CreateEx函數創建工具欄,並調用LoadToolBar函數加載工具欄資源 if (!m_wndToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP | CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) || !m_wndToolBar.LoadToolBar(theApp.m_bHiColorIcons ? IDR_MAINFRAME_256 : IDR_MAINFRAME)) { TRACE0("Failed to create toolbar\n"); return -1; // fail to create } ......略 return 0; }
因為創建框架窗口時需要調OnCreate函數,所以工具欄的創建也是在OnCreate中完成的。
工具欄的停靠
在創建好工具欄后,如果想要停靠工具欄,也需要添加相應的停靠代碼。工具欄停靠的步驟及需要調用的函數如下(前兩個步驟可以顛倒順序):
1. 在框架窗口中啟用停靠。
若要將工具欄停靠到某個框架窗口,則必須啟用該框架窗口(或目標)以允許停靠。可以在CFrameWndEx類中調用下面的成員函數來實現:
BOOL EnableDocking(DWORD dwDockStyle);
該函數采用一個DWORD參數,用來指定框架窗口的哪個邊可以接受停靠,可以有四種取值:CBRS_ALIGN_TOP(頂部)、CBRS_ALIGN_BOTTOM(底部)、CBRS_ALIGN_LEFT(左側)、CBRS_ALIGN_RIGHT(右側)。如果希望能夠將控制條停靠在任意位置,將CBRS_ALIGN_ANY作為參數傳遞給EnableDocking。
2. 工具欄啟用停靠。
框架窗口啟用停靠准備好后,必須以相似的方式准備工具欄。為想要停靠的每一個工具欄CMFCToolBar對象調用下面的函數:
virtual void EnableDocking(DWORD dwAlignment);
允許工具欄停靠到框架窗口,並指定工具欄應停靠的目標邊。此函數指定的目標邊必須與框架窗口中啟用停靠的邊匹配,否則工具欄無法停靠,為浮動狀態。
3. 停靠工具欄。
當用戶試圖將工具欄放置在允許停靠的框架窗口某一邊時,需要框架CFrameWndEx類調用以下函數:
void DockPane(CBasePane* pBar,UINT nDockBarID=0,LPCRECT lpRect=NULL);
參數pBar為要停靠的控制條的指針,參數nDockBarID為要停靠的框架窗口某條邊的ID,可以是以下四種取值:AFX_IDW_DOCKBAR_TOP、AFX_IDW_DOCKBAR_BOTTOM、AFX_IDW_DOCKBAR_LEFT、AFX_IDW_DOCKBAR_RIGHT。
下面我們接着看Example34的CMainFrame類的OnCreate函數實現中,工具欄的停靠過程:
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct) { if (CFrameWndEx::OnCreate(lpCreateStruct) == -1) return -1; ......略 // 調用CreateEx函數創建工具欄,並調用LoadToolBar函數加載工具欄資源 if (!m_wndToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP | CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) || !m_wndToolBar.LoadToolBar(theApp.m_bHiColorIcons ? IDR_MAINFRAME_256 : IDR_MAINFRAME)) { TRACE0("Failed to create toolbar\n"); return -1; // fail to create } ......略 // TODO: Delete these five lines if you don't want the toolbar and menubar to be dockable m_wndMenuBar.EnableDocking(CBRS_ALIGN_ANY); // 為m_wndToolBar啟用停靠 m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY); // 為框架窗口啟用停靠 EnableDocking(CBRS_ALIGN_ANY); DockPane(&m_wndMenuBar); // 停靠工具欄 DockPane(&m_wndToolBar); ......略 return 0; }
關於工具欄的知識就講到這里了。