FlatToolBar.cpp
上传用户:trilite
上传日期:2007-04-24
资源大小:261k
文件大小:7k
源码类别:

酒店行业

开发平台:

Visual C++

  1. //***************************************************************
  2. // FlatToolBar.cpp
  3. #include "stdafx.h"
  4. #include "flattoolbar.h"
  5. #ifdef _DEBUG                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     
  6. #undef THIS_FILE
  7. #define new DEBUG_NEW
  8. static char BASED_CODE THIS_FILE[] = __FILE__;
  9. #endif
  10. BEGIN_MESSAGE_MAP(CFlatToolBar, CToolBar)
  11. //{{AFX_MSG_MAP(CFlatToolBar)
  12. ON_WM_WINDOWPOSCHANGING()
  13. ON_WM_PAINT()
  14. ON_WM_NCPAINT()
  15. ON_WM_NCCALCSIZE()
  16. //}}AFX_MSG_MAP
  17. END_MESSAGE_MAP()
  18. IMPLEMENT_DYNAMIC(CFlatToolBar,CToolBar)
  19. // 必须在建立之后,因为MFC要清除多余的样式位
  20. void CFlatToolBar::SetFlatLookStyle() 
  21. {
  22.    // 设置平面样式(透明的)
  23.    ModifyStyle(0,TBSTYLE_FLAT);
  24.    
  25.    // others are...
  26.    // #define TBSTYLE_TOOLTIPS 0x0100
  27.    // #define TBSTYLE_WRAPABLE 0x0200
  28.    // #define TBSTYLE_ALTDRAG 0x0400
  29.    // #define TBSTYLE_FLAT 0x0800
  30.    // #define TBSTYLE_LIST 0x1000
  31. }
  32. // 因为按钮是透明的,所以我们需要重新绘制背景
  33. void CFlatToolBar::RepaintBackground() 
  34. {
  35.    CRect rc; GetWindowRect(&rc); // 获取工具栏的矩形区域
  36.    CWnd* pParent = GetParent(); // 获取父窗口
  37.    pParent->ScreenToClient(&rc); // 转换为父窗口的坐标
  38.    pParent->InvalidateRect(&rc); // 绘制其下面的矩形
  39. }
  40. // 在用户区中绘制分隔线
  41. void CFlatToolBar::DrawSeparators() 
  42. {
  43.    CClientDC dc(this); // get a dc for the client area
  44.    DrawSeparators(&dc); // draw the separators on it
  45. }
  46. // 绘制分隔线
  47. void CFlatToolBar::DrawSeparators(CClientDC* pDC) 
  48. {
  49.    // 水平与垂直
  50.    bool ishorz = (m_dwStyle & CBRS_ORIENT_HORZ) != 0;
  51.    // 获取按钮数目
  52.    int nIndexMax = (int)DefWindowProc(TB_BUTTONCOUNT, 0, 0);
  53.    int nIndex;
  54.    // 试一下每个按钮
  55.    for (nIndex = 0; nIndex < nIndexMax; nIndex++) 
  56.    {
  57.       UINT dwStyle = GetButtonStyle(nIndex);
  58.       UINT wStyle = LOWORD(dwStyle);
  59.       // 如果是分隔线
  60.       if (wStyle == TBBS_SEPARATOR) 
  61.       {
  62.          // 获取它的矩形和宽度
  63.          CRect rect;
  64.          GetItemRect(nIndex,rect);
  65.          // 如果对分隔线足够用
  66.          int w = rect.Width();
  67.          if (w <= 8) 
  68.          {
  69.             if (ishorz) 
  70.             {
  71.                // 在中间绘制分隔线
  72.                CRect rectbar = rect;
  73.                int x = (rectbar.left+rectbar.right)/2;
  74.                rectbar.left = x-1; rectbar.right = x+1;
  75.                pDC->Draw3dRect(rectbar,::GetSysColor(COLOR_3DSHADOW),
  76.                ::GetSysColor(COLOR_3DHILIGHT));
  77.             }
  78.             else 
  79.             {
  80.                // 在中间绘制分隔线
  81.                CRect rectbar = rect;
  82.                rectbar.left = rectbar.left - m_sizeButton.cx;
  83.                rectbar.right = rectbar.left + m_sizeButton.cx;
  84.                rectbar.top = rectbar.bottom+1;
  85.                rectbar.bottom = rectbar.top+3;
  86.                int y = (rectbar.top+rectbar.bottom)/2;
  87.                rectbar.top = y-1; 
  88.                rectbar.bottom = y+1;
  89.                pDC->Draw3dRect(rectbar,::GetSysColor(COLOR_3DSHADOW),
  90.                ::GetSysColor(COLOR_3DHILIGHT));
  91.             }
  92.          }
  93.       }
  94.    }
  95. }
  96. // 在左边或顶部绘制gripper
  97. void CFlatToolBar::DrawGripper(CWindowDC *pDC, CRect& rectWindow) 
  98. {
  99.    CRect gripper = rectWindow;
  100.    gripper.DeflateRect(1,1);
  101.    if (m_dwStyle & CBRS_FLOATING) 
  102.    {
  103.       // 无grippers
  104.    } 
  105.    else if (m_dwStyle & CBRS_ORIENT_HORZ) 
  106.    {
  107.       // gripper在左边
  108.       gripper.right = gripper.left+3;
  109.       pDC->Draw3dRect(gripper,::GetSysColor(COLOR_3DHIGHLIGHT),
  110.       ::GetSysColor(COLOR_3DSHADOW));
  111.       gripper.OffsetRect(+4,0);
  112.       pDC->Draw3dRect(gripper,::GetSysColor(COLOR_3DHIGHLIGHT),
  113.       ::GetSysColor(COLOR_3DSHADOW));
  114.       rectWindow.left += 8;
  115.    } 
  116.    else 
  117.    {
  118.       // gripper在顶部
  119.       gripper.bottom = gripper.top+3;
  120.       pDC->Draw3dRect(gripper,::GetSysColor(COLOR_3DHIGHLIGHT),
  121.       ::GetSysColor(COLOR_3DSHADOW));
  122.       gripper.OffsetRect(0,+4);
  123.       pDC->Draw3dRect(gripper,::GetSysColor(COLOR_3DHIGHLIGHT),
  124.       ::GetSysColor(COLOR_3DSHADOW));
  125.       rectWindow.top += 8;
  126.    }
  127. }
  128. // 擦除非用户区(边框) - 从MFC中复制来实现
  129. void CFlatToolBar::EraseNonClient() 
  130. {
  131.    // 获取剪切非用户区域的窗口 DC
  132.    CWindowDC dc(this);
  133.    CRect rectClient;
  134.    GetClientRect(rectClient);
  135.    CRect rectWindow;
  136.    GetWindowRect(rectWindow);
  137.    ScreenToClient(rectWindow);
  138.    rectClient.OffsetRect(-rectWindow.left, -rectWindow.top);
  139.    dc.ExcludeClipRect(rectClient);
  140.    // 绘制非用户区的边界
  141.    rectWindow.OffsetRect(-rectWindow.left, -rectWindow.top);
  142.    DrawBorders(&dc, rectWindow);
  143.    // 擦除非绘制部分
  144.    dc.IntersectClipRect(rectWindow);
  145.    SendMessage(WM_ERASEBKGND, (WPARAM)dc.m_hDC);
  146.    DrawGripper(&dc, rectWindow); // 增加的绘制gripper
  147. }
  148. // 因为按钮是透明的,所以当样式改变时我们需要重绘背景
  149. void CFlatToolBar::OnUpdateCmdUI(CFrameWnd* pTarget, BOOL bDisableIfNoHndler) 
  150. {
  151.    static CUIntArray styles;
  152.    // 保存样式
  153.    int nIndexMax = (int)DefWindowProc(TB_BUTTONCOUNT, 0, 0);
  154.    int nIndex;
  155.    for (nIndex = 0; nIndex < nIndexMax; nIndex++) 
  156.    {
  157.       UINT dwStyle = GetButtonStyle(nIndex);
  158.       styles.SetAtGrow(nIndex,dwStyle);
  159.    }
  160.    // 缺省处理
  161.    CToolBar::OnUpdateCmdUI(pTarget,bDisableIfNoHndler);
  162.    // make checked button appear pushed in
  163.    for (nIndex = 0; nIndex < nIndexMax; nIndex++) 
  164.    {
  165.       UINT dwStyle = GetButtonStyle(nIndex);
  166.       if (dwStyle & TBBS_CHECKBOX) 
  167.       {
  168.          if (dwStyle & TBBS_CHECKED) 
  169.             dwStyle |= TBBS_PRESSED;
  170.          else 
  171.             dwStyle &= ~TBBS_PRESSED;
  172.          SetButtonStyle(nIndex,dwStyle);
  173.       }
  174.    }
  175.    // 检查样式是否改变(按钮按下或释放)
  176.    for (nIndex = 0; nIndex < nIndexMax; nIndex++) 
  177.    {
  178.       UINT dwStyle = GetButtonStyle(nIndex);
  179.       if (styles[nIndex] != dwStyle) 
  180.       {
  181.          RepaintBackground();    // 需要处理按钮背景
  182.          Invalidate();    // 重绘工具栏(不仅仅是该按钮)
  183.          break;
  184.       }
  185.    }
  186. }
  187. // 因为按钮是透明的, 所以我们需要在尺寸变化或移动时重新绘制背景
  188. void CFlatToolBar::OnWindowPosChanging(LPWINDOWPOS lpwp) 
  189. {
  190.    // 缺省处理
  191.    CToolBar::OnWindowPosChanging(lpwp);
  192.    // 当尺寸变化或移动时重绘背景
  193.    RepaintBackground();
  194.    PostMessage(WM_NCPAINT);
  195. }
  196. // 绘制工具栏
  197. void CFlatToolBar:: OnPaint() 
  198. {
  199.    // 标准工具栏
  200.    CToolBar::OnPaint();
  201.    // 添加分隔线
  202.    DrawSeparators();
  203. }
  204. // 擦除非用户区(边框) - 从MFC中复制来实现
  205. void CFlatToolBar:: OnNcPaint() 
  206. {
  207.    EraseNonClient();
  208. }
  209. // 计算非用户区域 - 用于调整grippers
  210. void CFlatToolBar::OnNcCalcSize(BOOL bCalcValidRects, NCCALCSIZE_PARAMS* lpncsp) 
  211. {
  212.    CToolBar::OnNcCalcSize(bCalcValidRects,lpncsp);
  213.    // 为左边或顶部的gripper调整非用户区域
  214.    if (m_dwStyle & CBRS_FLOATING) 
  215.    {
  216.       // 无gripper
  217.    }
  218.    else if (m_dwStyle & CBRS_ORIENT_HORZ) 
  219.    {
  220.       lpncsp->rgrc[0].left += 2;
  221.       lpncsp->rgrc[0].right += 2;
  222.    } 
  223.    else 
  224.    {
  225.       lpncsp->rgrc[0].top += 4;
  226.       lpncsp->rgrc[0].bottom += 4;
  227.    }
  228. }