编译:张圣华
本文所讨论的工具栏类是同标准的 MFC CToolBar 一同工作的。
注意:你必须有新的 COMCTL32.DLL (版本4.7或更高)。它是随 Internet Explorer 3 一同发行,并且将做为 Windows 98 的标准组件。如果你使用的是 VC++ 5,则你已经有该动态库了。
所谓类似 Word 97 的增强工具栏具有平面外观,它的左边带有“gripper”并且各组间带有分隔线。当鼠标移动到上面时,按钮就会突出来。
MFC 使用样式位来控制其平面外观。所以你不能在建立工具栏时来设置这种样式,你必须建立之后使用SetFlatLookStyle()函数来修改其样式。
平面外观工具栏是透明绘制的。不幸的是,MFC 没有介绍该如何编写这种透明的工具栏,所以需要你重绘背景。这要通过变尺寸和移动信息来实现,例如当你拖动可移动的工具栏。你也可以通过其按钮样式改变时来实现。例如,当按钮从按状态变成释放状态时,背景需要重新绘制。
工具栏控制本身并不在各组按钮间绘制分隔线,只是在其间增加一个空格。该类将截取 WM_PAINT 消息,并在正确的位置添加分隔线。
工具栏控制也不支持在起左边或顶部的gripper。该类将调整其用户区并绘制相应的gripper。
使用本类,只要简单的把你的 CToolBar 变成 CFlatToolBar,并在建立工具栏后调用 SetFlatLookStyle() 函数 (既当工具栏位图装入之后 )。
// FlatToolBar.h // (c) 1997, Roger Onslow class CFlatToolBar : public CToolBar { DECLARE_DYNAMIC(CFlatToolBar); public: void SetFlatLookStyle(); void RepaintBackground(); void DrawSeparators(); void DrawSeparators(CClientDC* pDC); void EraseNonClient(); void DrawGripper(CWindowDC *pDC, CRect& rectWindow); protected: // ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(CFlatToolBar) virtual void OnUpdateCmdUI(CFrameWnd* pTarget, BOOL bDisableIfNoHndler); //}}AFX_VIRTUAL // 消息处理函数 protected: //{{AFX_MSG(CFlatToolBar) afx_msg void OnWindowPosChanging(LPWINDOWPOS lpWndPos); afx_msg void OnPaint(); afx_msg void OnNcPaint(); afx_msg void OnNcCalcSize( BOOL bCalcValidRects, NCCALCSIZE_PARAMS* lpncsp ); //}}AFX_MSG DECLARE_MESSAGE_MAP(); }; //*************************************************************** // FlatToolBar.cpp #include "stdafx.h" #include "flattoolbar.h" #ifdef _DEBUG #undef THIS_FILE #define new DEBUG_NEW static char BASED_CODE THIS_FILE[] = __FILE__; #endif BEGIN_MESSAGE_MAP(CFlatToolBar, CToolBar) //{{AFX_MSG_MAP(CFlatToolBar) ON_WM_WINDOWPOSCHANGING() ON_WM_PAINT() ON_WM_NCPAINT() ON_WM_NCCALCSIZE() //}}AFX_MSG_MAP END_MESSAGE_MAP() IMPLEMENT_DYNAMIC(CFlatToolBar,CToolBar) // 必须在建立之后,因为MFC要清除多余的样式位 void CFlatToolBar::SetFlatLookStyle() { // 设置平面样式(透明的) ModifyStyle(0,TBSTYLE_FLAT); // others are... // #define TBSTYLE_TOOLTIPS 0x0100 // #define TBSTYLE_WRAPABLE 0x0200 // #define TBSTYLE_ALTDRAG 0x0400 // #define TBSTYLE_FLAT 0x0800 // #define TBSTYLE_LIST 0x1000 } // 因为按钮是透明的,所以我们需要重新绘制背景 void CFlatToolBar::RepaintBackground() { CRect rc; GetWindowRect(&rc); // 获取工具栏的矩形区域 CWnd* pParent = GetParent(); // 获取父窗口 pParent->ScreenToClient(&rc); // 转换为父窗口的坐标 pParent->InvalidateRect(&rc); // 绘制其下面的矩形 } // 在用户区中绘制分隔线 void CFlatToolBar::DrawSeparators() { CClientDC dc(this); // get a dc for the client area DrawSeparators(&dc); // draw the separators on it } // 绘制分隔线 void CFlatToolBar::DrawSeparators(CClientDC* pDC) { // 水平与垂直 bool ishorz = (m_dwStyle & CBRS_ORIENT_HORZ) != 0; // 获取按钮数目 int nIndexMax = (int)DefWindowProc(TB_BUTTONCOUNT, 0, 0); int nIndex; // 试一下每个按钮 for (nIndex = 0; nIndex < nIndexMax; nIndex++) { UINT dwStyle = GetButtonStyle(nIndex); UINT wStyle = LOWORD(dwStyle); // 如果是分隔线 if (wStyle == TBBS_SEPARATOR) { // 获取它的矩形和宽度 CRect rect; GetItemRect(nIndex,rect); // 如果对分隔线足够用 int w = rect.Width(); if (w <= 8) { if (ishorz) { // 在中间绘制分隔线 CRect rectbar = rect; int x = (rectbar.left+rectbar.right)/2; rectbar.left = x-1; rectbar.right = x+1; pDC->Draw3dRect(rectbar,::GetSysColor(COLOR_3DSHADOW), ::GetSysColor(COLOR_3DHILIGHT)); } else { // 在中间绘制分隔线 CRect rectbar = rect; rectbar.left = rectbar.left - m_sizeButton.cx; rectbar.right = rectbar.left + m_sizeButton.cx; rectbar.top = rectbar.bottom+1; rectbar.bottom = rectbar.top+3; int y = (rectbar.top+rectbar.bottom)/2; rectbar.top = y-1; rectbar.bottom = y+1; pDC->Draw3dRect(rectbar,::GetSysColor(COLOR_3DSHADOW), ::GetSysColor(COLOR_3DHILIGHT)); } } } } } <  
说明:本教程来源互联网或网友上传或出版商,仅为学习研究或媒体推广,wanshiok.com不保证资料的完整性。
1/2 1 2 下一页 尾页 |