?? mfc
字號:
<P align=justify>{</P>
<P align=justify>ASSERT_VALID(pParentWnd); // must have a parent</P>
<P align=justify>ASSERT (!((dwStyle & CBRS_SIZE_FIXED) &&</P>
<P align=justify>(dwStyle & CBRS_SIZE_DYNAMIC)));</P>
<P align=justify></P>
<P align=justify>// 保存dwStyle指定的CBRS_風格</P>
<P align=justify>m_dwStyle = dwStyle;</P>
<P align=justify>if (nID == AFX_IDW_TOOLBAR)</P>
<P align=justify>m_dwStyle |= CBRS_HIDE_INPLACE;</P>
<P align=justify></P>
<P align=justify>//去掉參數dwStyle包含的CBRS_風格</P>
<P align=justify>dwStyle &= ~CBRS_ALL;</P>
<P align=justify>//設置窗口風格</P>
<P align=justify>dwStyle |= </P>
<P align=justify>CCS_NOPARENTALIGN|CCS_NOMOVEY|CCS_NODIVIDER|CCS_NORESIZE;</P>
<P align=justify></P>
<P align=justify>//初始化通用控制,可以導致InitCommonControl的調用</P>
<P align=justify>VERIFY(AfxDeferRegisterClass(AFX_WNDCOMMCTLS_REG));</P>
<P align=justify></P>
<P align=justify>//創建窗口,將調用PreCreateWindow,OnCreate, OnNcCreate等</P>
<P align=justify>CRect rect; rect.SetRectEmpty();</P>
<P align=justify>if (!CWnd::Create(TOOLBARCLASSNAME, NULL, dwStyle, </P>
<P align=justify>rect, pParentWnd, nID))</P>
<P align=justify>return FALSE;</P>
<P align=justify></P>
<P align=justify>// Note: Parent must resize itself for control bar to be
resized</P>
<P align=justify></P>
<P align=justify>return TRUE;</P>
<P align=justify>}</P>
<P align=justify>其中:</P>
<P align=justify>Create函數的參數1表示工具條的父窗口。參數2指定窗口風格和CBRS_風格,缺省值為 WS_CHILD |
WS_VISIBLE |
CBRS_TOP,其中WS_CHILD和WS_VISIBLE是窗口風格,CBRS_TOP是CBRS_風格。參數3指定工具條ID,缺省值為AFX_IDW_TOOLBAR(0X0E800或者59392)。如果還有多個工具欄要顯示,在創建它們時則必須給每個工具欄指明ID。</P>
<P
align=justify>首先,Create函數把參數2(dwStyle)指定的窗口風格和CBRS_風格分離出來,窗口風格保留在dwStyle中,CBRS_風格保存到成員變量m_dwStyle中。CToolBar::PreCreateWindow將進一步修改這些風格。</P>
<P
align=justify>接著,Create函數調用了函數AfxDeferRegisterClass。它如果沒有注冊TOOLBARCLASSNAME表示的“窗口類”,就注冊該類;否則,返回TRUE,表示已經注冊。TOOLBARCLASSNAME表示的字符串是“ToolbarWindow32”,即“窗口類”名稱。</P>
<P align=justify>然后,調用CWnd::Create(7個參數)使用“ToolbarWindow32”“窗口類”創建工具欄。</P>
<P
align=justify>Create在創建窗口的過程中,用MFC的標準窗口過程取代原來的窗口過程,如同CFormView和CDialog窗口創建時窗口過程被取代一樣,并發送WM_CREATE和WM_NCCREATE消息。</P>
<P
align=justify>至于添加向工具欄添加按鈕,則由函數LoadToolBar完成。在分析LoadToolBar函數之前,先討論OnCreate、OnNcCreate等函數。</P>
<P align=justify></P>
<LI>處理WM_CREATE消息
<P></P>
<P align=justify>CControlBar提供了消息處理函數OnCreate來處理WM_CREATE消息。</P>
<P align=justify>int CControlBar::OnCreate(LPCREATESTRUCT lpcs)</P>
<P align=justify>{</P>
<P align=justify>//調用基類的實現</P>
<P align=justify>if (CWnd::OnCreate(lpcs) == -1)</P>
<P align=justify>return -1;</P>
<P align=justify>//針對工具欄,是否有Tooltip特性</P>
<P align=justify>if (m_dwStyle & CBRS_TOOLTIPS)</P>
<P align=justify>EnableToolTips();</P>
<P align=justify>//得到父窗口,并添加自身到其控制條列表中</P>
<P align=justify>CFrameWnd *pFrameWnd = (CFrameWnd*)GetParent();</P>
<P align=justify>if (pFrameWnd->IsFrameWnd())</P>
<P align=justify>{</P>
<P align=justify>m_pDockSite = pFrameWnd;</P>
<P align=justify>m_pDockSite->AddControlBar(this);</P>
<P align=justify>}</P>
<P align=justify>return 0;</P>
<P align=justify>}</P>
<P align=justify>如果需要支持Tooltips,則OnCreate調用EnableTooltips。</P>
<P
align=justify>m_pDockSite是CControlBar的和泊位相關的成員變量,這里把它初始化為擁有工具欄的父邊框窗口,該邊框窗口把控制條加入其控制條列表m_listControlBars中。</P>
<P
align=justify>在處理WM_CREATE之前,派生類先處理消息WM_NCCREAE。例如,CToolBar覆蓋了OnNcCreate函數。</P>
<P align=justify></P>
<LI>處理WM_NCCREATE消息
<P></P>
<P align=justify>CToolBar對WM_NCCREATE消息的處理如下:</P>
<P align=justify>BOOL CToolBar::OnNcCreate(LPCREATESTRUCT lpCreateStruct)</P>
<P align=justify>{</P>
<P align=justify>if (!CControlBar::OnNcCreate(lpCreateStruct))</P>
<P align=justify>return FALSE;</P>
<P align=justify>// if the owner was set before the toolbar was created, set
it now</P>
<P align=justify>if (m_hWndOwner != NULL)</P>
<P align=justify>DefWindowProc(TB_SETPARENT, (WPARAM)m_hWndOwner, 0);</P>
<P align=justify></P>
<P align=justify>DefWindowProc(TB_BUTTONSTRUCTSIZE, (WPARAM)sizeof(TBBUTTON),
0);</P>
<P align=justify>return TRUE;</P>
<P align=justify>}</P>
<P
align=justify>CToolBar覆蓋CcontrolBar的該函數用來設置工具條的所屬窗口和描述工具條按鈕結構的大小,這兩個動作都是通過給工具條窗口發送消息來實現的。因為這些消息被送給控制窗口類的窗口過程(Windows提供的)來處理,所以直接調用DefWindowProc,省卻了消息發送的過程。</P>
<P align=justify>在控制窗口創建之后,對于工具條來說,下一步就是向工具欄添加按鈕。</P>
<P align=justify></P>
<LI>向工具欄添加按鈕
<P></P>
<P align=justify>通過函數LoadToolBar完成向工具欄添加按鈕的任務,其實現如下:</P>
<P align=justify>BOOL CToolBar::LoadToolBar(LPCTSTR lpszResourceName)</P>
<P align=justify>{</P>
<P align=justify>ASSERT_VALID(this);</P>
<P align=justify>ASSERT(lpszResourceName != NULL);</P>
<P align=justify></P>
<P align=justify>//查找并確認按鈕位圖、字符串等資源的位置</P>
<P align=justify>HINSTANCE hInst = AfxFindResourceHandle(lpszResourceName,
RT_TOOLBAR);</P>
<P align=justify>HRSRC hRsrc = ::FindResource(hInst, lpszResourceName,
RT_TOOLBAR);</P>
<P align=justify>if (hRsrc == NULL)</P>
<P align=justify>return FALSE;</P>
<P align=justify></P>
<P align=justify>//鎖定資源</P>
<P align=justify>HGLOBAL hGlobal = LoadResource(hInst, hRsrc);</P>
<P align=justify>if (hGlobal == NULL)</P>
<P align=justify>return FALSE;</P>
<P align=justify></P>
<P align=justify>CToolBarData* pData =
(CToolBarData*)LockResource(hGlobal);</P>
<P align=justify>if (pData == NULL)</P>
<P align=justify>return FALSE;</P>
<P align=justify>ASSERT(pData->wVersion == 1);</P>
<P align=justify></P>
<P align=justify>//復制與各個位圖對應的命令ID到數組pItem</P>
<P align=justify>UINT* pItems = new UINT[pData->wItemCount];</P>
<P align=justify>for (int i = 0; i < pData->wItemCount; i++)</P>
<P align=justify>pItems[i] = pData->items()[i];</P>
<P align=justify>//添加按鈕到工具欄,指定各個按鈕對應的ID</P>
<P align=justify>BOOL bResult = SetButtons(pItems, pData->wItemCount);</P>
<P align=justify>delete[] pItems;</P>
<P align=justify></P>
<P align=justify>//設置按鈕的位圖</P>
<P align=justify>if (bResult)</P>
<P align=justify>{</P>
<P align=justify>// set new sizes of the buttons</P>
<P align=justify>CSize sizeimage(pData->wWidth, pData->wHeight);</P>
<P align=justify>CSize sizeButton(pData->wWidth + 7, pData->wHeight +
7);</P>
<P align=justify>SetSizes(sizeButton, sizeimage);</P>
<P align=justify></P>
<P align=justify>// load bitmap now that sizes are known by the toolbar
control</P>
<P align=justify>bResult = LoadBitmap(lpszResourceName);</P>
<P align=justify>}</P>
<P align=justify></P>
<P align=justify>UnlockResource(hGlobal);</P>
<P align=justify>FreeResource(hGlobal);</P>
<P align=justify></P>
<P align=justify>return bResult;</P>
<P align=justify>}</P>
<P
align=justify>LoadToolBar函數的參數指定了資源。ToolBar資源的類型是RT_TOOLBAR,ToolBar位圖資源的類型是RT_BITMAP。</P>
<P
align=justify>在RT_TOOLBAR類型的資源讀入內存之后,可以用CToolBarData結構描述。一個這樣的結構包括了ToolBar資源的如下信息:</P>
<P align=justify>工具條位圖的版本,寬度,高度,個數,各個位圖對應的命令ID。</P>
<P
align=justify>然后,LoadToolBar把這些命令ID被復制到數組pItem中;根據位圖寬度、高度形成按鈕尺寸sizeButton和位圖尺寸sizeimage。</P>
<P
align=justify>接著,調用SetBottons添加按鈕到工具欄,把各個按鈕和命令ID對應起來;調用SetSizes設置按鈕和位圖的尺寸大小;調用LoadBitmap添加或者取代工具條的位圖列表。這些動作都是調用工具欄“窗口類”的窗口過程完成的。例如,SetButtons的實現:</P>
<P align=justify>BOOL CToolBar::SetButtons(const UINT* lpIDArray, int
nIDCount)</P>
<P align=justify>{</P>
<P align=justify>ASSERT_VALID(this);</P>
<P align=justify>ASSERT(nIDCount >= 1); // must be at least one of them</P>
<P align=justify>ASSERT(lpIDArray == NULL ||</P>
<P align=justify>AfxIsValidAddress(lpIDArray, sizeof(UINT) * nIDCount,
FALSE));</P>
<P align=justify></P>
<P align=justify>//首先,刪除工具條中現有的按鈕</P>
<P align=justify>int nCount = (int)DefWindowProc(TB_BUTTONCOUNT, 0, 0);</P>
<P align=justify>while (nCount--)</P>
<P align=justify>VERIFY(DefWindowProc(TB_DELETEBUTTON, 0, 0));</P>
<P align=justify></P>
<P align=justify>if (lpIDArray != NULL)//命令ID數組非空</P>
<P align=justify>{</P>
<P align=justify>//添加新按鈕</P>
<P align=justify>TBBUTTON button; memset(&button, 0,
sizeof(TBBUTTON));</P>
<P align=justify>int iimage = 0;</P>
<P align=justify>for (int i = 0; i < nIDCount; i++)</P>
<P align=justify>{</P>
<P align=justify>button.fsState = TBSTATE_ENABLED;</P>
<P align=justify>if ((button.idCommand = *lpIDArray++) == 0)</P>
<P align=justify>{</P>
<P align=justify>//按鈕之間分隔</P>
<P align=justify>button.fsStyle = TBSTYLE_SEP;</P>
<P align=justify>//按鈕之間隔8個像素</P>
<P align=justify>button.iBitmap = 8;</P>
<P align=justify>}</P>
<P align=justify>else</P>
<P align=justify>{</P>
<P align=justify>//有位圖和命令ID的按鈕</P>
<P align=justify>button.fsStyle = TBSTYLE_BUTTON;</P>
<P align=justify>button.iBitmap = iimage++;//設置位圖索引</P>
<P align=justify>}</P>
<P align=justify>//添加按鈕</P>
<P align=justify>if (!DefWindowProc(TB_ADDBUTTONS, 1,
(LPARAM)&button))</P>
<P align=justify>return FALSE;</P>
<P align=justify>}</P>
<P align=justify>}</P>
<P align=justify>else//命令ID數組空,添加空按鈕</P>
<P align=justify>{</P>
<P align=justify>TBBUTTON button; memset(&button, 0,
sizeof(TBBUTTON));</P>
<P align=justify>button.fsState = TBSTATE_ENABLED;</P>
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -