www.pudn.com > 200518174534292.rar > FlatToolBar.cpp


//*************************************************************** 
// 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)); 
            } 
         } 
      } 
   } 
} 
// 在左边或顶部绘制gripper 
void CFlatToolBar::DrawGripper(CWindowDC *pDC, CRect& rectWindow)  
{ 
   CRect gripper = rectWindow; 
   gripper.DeflateRect(1,1); 
   if (m_dwStyle & CBRS_FLOATING)  
   { 
      // 无grippers 
   }  
   else if (m_dwStyle & CBRS_ORIENT_HORZ)  
   { 
      // gripper在左边 
      gripper.right = gripper.left+3; 
      pDC->Draw3dRect(gripper,::GetSysColor(COLOR_3DHIGHLIGHT), 
      ::GetSysColor(COLOR_3DSHADOW)); 
      gripper.OffsetRect(+4,0); 
      pDC->Draw3dRect(gripper,::GetSysColor(COLOR_3DHIGHLIGHT), 
      ::GetSysColor(COLOR_3DSHADOW)); 
      rectWindow.left += 8; 
   }  
   else  
   { 
      // gripper在顶部 
      gripper.bottom = gripper.top+3; 
      pDC->Draw3dRect(gripper,::GetSysColor(COLOR_3DHIGHLIGHT), 
      ::GetSysColor(COLOR_3DSHADOW)); 
      gripper.OffsetRect(0,+4); 
      pDC->Draw3dRect(gripper,::GetSysColor(COLOR_3DHIGHLIGHT), 
      ::GetSysColor(COLOR_3DSHADOW)); 
      rectWindow.top += 8; 
   } 
} 
// 擦除非用户区(边框) - 从MFC中复制来实现 
void CFlatToolBar::EraseNonClient()  
{ 
   // 获取剪切非用户区域的窗口 DC 
   CWindowDC dc(this); 
   CRect rectClient; 
   GetClientRect(rectClient); 
   CRect rectWindow; 
   GetWindowRect(rectWindow); 
   ScreenToClient(rectWindow); 
   rectClient.OffsetRect(-rectWindow.left, -rectWindow.top); 
   dc.ExcludeClipRect(rectClient); 
 
   // 绘制非用户区的边界 
   rectWindow.OffsetRect(-rectWindow.left, -rectWindow.top); 
   DrawBorders(&dc, rectWindow); 
 
   // 擦除非绘制部分 
   dc.IntersectClipRect(rectWindow); 
   SendMessage(WM_ERASEBKGND, (WPARAM)dc.m_hDC); 
   DrawGripper(&dc, rectWindow); // 增加的绘制gripper 
} 
// 因为按钮是透明的,所以当样式改变时我们需要重绘背景 
void CFlatToolBar::OnUpdateCmdUI(CFrameWnd* pTarget, BOOL bDisableIfNoHndler)  
{ 
   static CUIntArray styles; 
   // 保存样式 
   int nIndexMax = (int)DefWindowProc(TB_BUTTONCOUNT, 0, 0); 
   int nIndex; 
   for (nIndex = 0; nIndex < nIndexMax; nIndex++)  
   { 
      UINT dwStyle = GetButtonStyle(nIndex); 
      styles.SetAtGrow(nIndex,dwStyle); 
   } 
   // 缺省处理 
   CToolBar::OnUpdateCmdUI(pTarget,bDisableIfNoHndler); 
   // make checked button appear pushed in 
   for (nIndex = 0; nIndex < nIndexMax; nIndex++)  
   { 
      UINT dwStyle = GetButtonStyle(nIndex); 
      if (dwStyle & TBBS_CHECKBOX)  
      { 
         if (dwStyle & TBBS_CHECKED)  
            dwStyle |= TBBS_PRESSED; 
         else  
            dwStyle &= ~TBBS_PRESSED; 
         SetButtonStyle(nIndex,dwStyle); 
      } 
   } 
   // 检查样式是否改变(按钮按下或释放) 
   for (nIndex = 0; nIndex < nIndexMax; nIndex++)  
   { 
      UINT dwStyle = GetButtonStyle(nIndex); 
      if (styles[nIndex] != dwStyle)  
      { 
         RepaintBackground();    // 需要处理按钮背景 
         Invalidate();    // 重绘工具栏(不仅仅是该按钮) 
         break; 
      } 
   } 
} 
// 因为按钮是透明的, 所以我们需要在尺寸变化或移动时重新绘制背景 
void CFlatToolBar::OnWindowPosChanging(LPWINDOWPOS lpwp)  
{ 
   // 缺省处理 
   CToolBar::OnWindowPosChanging(lpwp); 
 
   // 当尺寸变化或移动时重绘背景 
   RepaintBackground(); 
   PostMessage(WM_NCPAINT); 
} 
// 绘制工具栏 
void CFlatToolBar:: OnPaint()  
{ 
   // 标准工具栏 
   CToolBar::OnPaint(); 
 
   // 添加分隔线 
   DrawSeparators(); 
} 
// 擦除非用户区(边框) - 从MFC中复制来实现 
void CFlatToolBar:: OnNcPaint()  
{ 
   EraseNonClient(); 
} 
// 计算非用户区域 - 用于调整grippers 
void CFlatToolBar::OnNcCalcSize(BOOL bCalcValidRects, NCCALCSIZE_PARAMS* lpncsp)  
{ 
   CToolBar::OnNcCalcSize(bCalcValidRects,lpncsp); 
 
   // 为左边或顶部的gripper调整非用户区域 
   if (m_dwStyle & CBRS_FLOATING)  
   { 
      // 无gripper 
   } 
   else if (m_dwStyle & CBRS_ORIENT_HORZ)  
   { 
      lpncsp->rgrc[0].left += 2; 
      lpncsp->rgrc[0].right += 2; 
   }  
   else  
   { 
      lpncsp->rgrc[0].top += 4; 
      lpncsp->rgrc[0].bottom += 4; 
   } 
}