ControlBarEx.cpp
上传用户:xywutai
上传日期:2007-01-02
资源大小:72k
文件大小:7k
源码类别:

工具条

开发平台:

Visual C++

  1. #include "stdafx.h"
  2. #include "ControlBarEx.h"
  3. #ifdef _DEBUG
  4. #define new DEBUG_NEW
  5. #undef THIS_FILE
  6. static char THIS_FILE[] = __FILE__;
  7. #endif
  8. /////////////////////////////////////////////////////////////////////////////
  9. // CControlBarEx
  10. BEGIN_MESSAGE_MAP(CControlBarEx, CControlBar)
  11. //{{AFX_MSG_MAP(CControlBarEx)
  12. ON_WM_PAINT()
  13. ON_WM_WINDOWPOSCHANGING()
  14. //}}AFX_MSG_MAP
  15. END_MESSAGE_MAP()
  16. void CControlBarEx::SetBorders(int cxLeft, int cyTop, int cxRight, int cyBottom)
  17. {
  18.   ASSERT(cxLeft >= 0);
  19.   ASSERT(cyTop >= 0);
  20.   ASSERT(cxRight >= 0);
  21.   ASSERT(cyBottom >= 0);
  22.   m_cxLeftBorder = cxLeft;
  23.   m_cyTopBorder = cyTop;
  24.   m_cxRightBorder = cxRight;
  25.   m_cyBottomBorder = cyBottom;
  26. }
  27. LRESULT CControlBarEx::WindowProc(UINT nMsg, WPARAM wParam, LPARAM lParam)
  28. {
  29.   ASSERT_VALID(this);
  30.   LRESULT lResult;
  31.   switch (nMsg)
  32.   {
  33.   case WM_NOTIFY:
  34.   case WM_COMMAND:
  35.   case WM_DRAWITEM:
  36.   case WM_MEASUREITEM:
  37.   case WM_DELETEITEM:
  38.   case WM_COMPAREITEM:
  39.   case WM_VKEYTOITEM:
  40.   case WM_CHARTOITEM:
  41.     // send these messages to the owner if not handled
  42.     if (OnWndMsg(nMsg, wParam, lParam, &lResult))
  43.       return lResult;
  44.     else
  45.     {
  46.       // try owner next
  47.       lResult = GetOwner()->SendMessage(nMsg, wParam, lParam);
  48.       // special case for TTN_NEEDTEXTA and TTN_NEEDTEXTW
  49.       if(nMsg == WM_NOTIFY)
  50.       {
  51.         NMHDR* pNMHDR = (NMHDR*)lParam;
  52.         if (pNMHDR->code == TTN_NEEDTEXTA || pNMHDR->code == TTN_NEEDTEXTW)
  53.         {
  54.           TOOLTIPTEXTA* pTTTA = (TOOLTIPTEXTA*)pNMHDR;
  55.           TOOLTIPTEXTW* pTTTW = (TOOLTIPTEXTW*)pNMHDR;
  56.           if ((pNMHDR->code == TTN_NEEDTEXTA && (!pTTTA->lpszText || !*pTTTA->lpszText)) ||
  57.             (pNMHDR->code == TTN_NEEDTEXTW && (!pTTTW->lpszText || !*pTTTW->lpszText)))
  58.           {
  59.             // not handled by owner, so let bar itself handle it
  60.             lResult = CWnd::WindowProc(nMsg, wParam, lParam);
  61.           }
  62.         }
  63.       }
  64.       return lResult;
  65.     }
  66.   }
  67.   // otherwise, just handle in default way
  68.   lResult = CWnd::WindowProc(nMsg, wParam, lParam);
  69.   return lResult;
  70. }
  71. void CControlBarEx::OnWindowPosChanging(LPWINDOWPOS lpWndPos)
  72. {
  73.   // WINBUG: We call DefWindowProc here instead of CWnd::OnWindowPosChanging
  74.   //  (which calls CWnd::Default, which calls through the super wndproc)
  75.   //  because certain control bars that are system implemented (such as
  76.   //  CToolBar with TBSTYLE_FLAT) do not implement WM_WINDOWPOSCHANGING
  77.   //  correctly, causing repaint problems.  This code bypasses that whole
  78.   //  mess.
  79.   ::DefWindowProc(m_hWnd, WM_WINDOWPOSCHANGING, 0, (LPARAM)lpWndPos);
  80.   if (lpWndPos->flags & SWP_NOSIZE)
  81.     return;
  82.   // invalidate borders on the right
  83.   CRect rect;
  84.   GetWindowRect(&rect);
  85.   CSize sizePrev = rect.Size();
  86.   int cx = lpWndPos->cx;
  87.   int cy = lpWndPos->cy;
  88.   if (cx != sizePrev.cx && (m_dwStyle & CBRS_BORDER_RIGHT))
  89.   {
  90.     rect.SetRect(cx-afxData.cxBorder2, 0, cx, cy);
  91.     InvalidateRect(&rect);
  92.     rect.SetRect(sizePrev.cx-afxData.cxBorder2, 0, sizePrev.cx, cy);
  93.     InvalidateRect(&rect);
  94.   }
  95.   // invalidate borders on the bottom
  96.   if (cy != sizePrev.cy && (m_dwStyle & CBRS_BORDER_BOTTOM))
  97.   {
  98.     rect.SetRect(0, cy-afxData.cyBorder2, cx, cy);
  99.     InvalidateRect(&rect);
  100.     rect.SetRect(0, sizePrev.cy-afxData.cyBorder2, cx, sizePrev.cy);
  101.     InvalidateRect(&rect);
  102.   }
  103. }
  104. void CControlBarEx::OnPaint()
  105. {
  106.   // background is already filled in gray
  107.   CPaintDC dc(this);
  108.   // erase background now
  109.   if (IsVisible())
  110.     DoPaint(&dc);       // delegate to paint helper
  111. }
  112. void CControlBarEx::EraseNonClient()
  113. {
  114.   // get window DC that is clipped to the non-client area
  115.   CWindowDC dc(this);
  116.   CRect rectClient;
  117.   GetClientRect(rectClient);
  118.   CRect rectWindow;
  119.   GetWindowRect(rectWindow);
  120.   ScreenToClient(rectWindow);
  121.   rectClient.OffsetRect(-rectWindow.left, -rectWindow.top);
  122.   dc.ExcludeClipRect(rectClient);
  123.   // draw borders in non-client area
  124.   rectWindow.OffsetRect(-rectWindow.left, -rectWindow.top);
  125.   DrawBorders(&dc, rectWindow);
  126.   // erase parts not drawn
  127.   dc.IntersectClipRect(rectWindow);
  128.   SendMessage(WM_ERASEBKGND, (WPARAM)dc.m_hDC);
  129.   // draw gripper in non-client area
  130.   DrawGripper(&dc, rectWindow);
  131. }
  132. void CControlBarEx::DoPaint(CDC* pDC)
  133. {
  134.   ASSERT_VALID(this);
  135.   ASSERT_VALID(pDC);
  136.   // paint inside client area
  137.   CRect rect;
  138.   GetClientRect(rect);
  139.   DrawBorders(pDC, rect);
  140.   DrawGripper(pDC, rect);
  141. }
  142. #define CX_GRIPPER  3
  143. #define CY_GRIPPER  3
  144. #define CX_BORDER_GRIPPER 2
  145. #define CY_BORDER_GRIPPER 2
  146. void CControlBarEx::DrawGripper(CDC* pDC, const CRect& rect)
  147. {
  148.   // only draw the gripper if not floating and gripper is specified
  149.   if ((m_dwStyle & (CBRS_GRIPPER|CBRS_FLOATING)) == CBRS_GRIPPER)
  150.   {
  151.     // draw the gripper in the border
  152.     if (m_dwStyle & CBRS_ORIENT_HORZ)
  153.     {
  154.       pDC->Draw3dRect(rect.left+CX_BORDER_GRIPPER,
  155.         rect.top+m_cyTopBorder,
  156.         CX_GRIPPER, rect.Height()-m_cyTopBorder-m_cyBottomBorder,
  157.         afxData.clrBtnHilite, afxData.clrBtnShadow);
  158.     }
  159.     else
  160.     {
  161.       pDC->Draw3dRect(rect.left+m_cyTopBorder,
  162.         rect.top+CY_BORDER_GRIPPER,
  163.         rect.Width()-m_cyTopBorder-m_cyBottomBorder, CY_GRIPPER,
  164.         afxData.clrBtnHilite, afxData.clrBtnShadow);
  165.       GdiFlush();
  166.     }
  167.   }
  168. }
  169. // input CRect should be client rectangle size
  170. void CControlBarEx::CalcInsideRect(CRect& rect, BOOL bHorz) const
  171. {
  172.   ASSERT_VALID(this);
  173.   DWORD dwStyle = m_dwStyle;
  174.   if (dwStyle & CBRS_BORDER_LEFT)
  175.     rect.left += afxData.cxBorder2;
  176.   if (dwStyle & CBRS_BORDER_TOP)
  177.     rect.top += afxData.cyBorder2;
  178.   if (dwStyle & CBRS_BORDER_RIGHT)
  179.     rect.right -= afxData.cxBorder2;
  180.   if (dwStyle & CBRS_BORDER_BOTTOM)
  181.     rect.bottom -= afxData.cyBorder2;
  182.   // inset the top and bottom.
  183.   if (bHorz)
  184.   {
  185.     rect.left += m_cxLeftBorder;
  186.     rect.top += m_cyTopBorder;
  187.     rect.right -= m_cxRightBorder;
  188.     rect.bottom -= m_cyBottomBorder;
  189.     if ((m_dwStyle & (CBRS_GRIPPER|CBRS_FLOATING)) == CBRS_GRIPPER)
  190.       rect.left += CX_BORDER_GRIPPER+CX_GRIPPER+CX_BORDER_GRIPPER;
  191.   }
  192.   else
  193.   {
  194.     rect.left += m_cyTopBorder;
  195.     rect.top += m_cxLeftBorder;
  196.     rect.right -= m_cyBottomBorder;
  197.     rect.bottom -= m_cxRightBorder;
  198.     if ((m_dwStyle & (CBRS_GRIPPER|CBRS_FLOATING)) == CBRS_GRIPPER)
  199.       rect.top += CY_BORDER_GRIPPER+CY_GRIPPER+CY_BORDER_GRIPPER;
  200.   }
  201. }
  202. /////////////////////////////////////////////////////////////////////////////
  203. IMPLEMENT_DYNAMIC(CControlBarEx, CControlBar)
  204. /////////////////////////////////////////////////////////////////////////////