SIZECBAR.CPP
上传用户:rxhxxy
上传日期:2007-01-02
资源大小:72k
文件大小:12k
源码类别:

TreeView控件

开发平台:

Visual C++

  1. // SizingControlBar.cpp : implementation file
  2. //
  3. #include "stdafx.h"
  4. #include "afxpriv.h"    // for CDockContext
  5. #include "sizecbar.h"
  6. #ifdef _DEBUG
  7. #define new DEBUG_NEW
  8. #undef THIS_FILE
  9. static char THIS_FILE[] = __FILE__;
  10. #endif
  11. /////////////////////////////////////////////////////////////////////////////
  12. // CSizingControlBar
  13. #define SCBF_MAXHALFCLIENTX 
  14. #define SCBF_MAXHALFCLIENTY
  15. CSizingControlBar::CSizingControlBar()
  16. {
  17.     m_sizeMin = CSize(10, 10);
  18.     m_sizeHorz = CSize(200, 200);
  19.     m_sizeVert = CSize(200, 200);
  20.     m_sizeFloat = CSize(200, 200);
  21.     m_bTracking = FALSE;
  22.     m_bInRecalcNC = FALSE;
  23.     m_cxEdge = 6;
  24. }
  25. CSizingControlBar::~CSizingControlBar()
  26. {
  27. }
  28. BEGIN_MESSAGE_MAP(CSizingControlBar, CControlBar)
  29.     //{{AFX_MSG_MAP(CSizingControlBar)
  30.     ON_WM_LBUTTONUP()
  31.     ON_WM_MOUSEMOVE()
  32.     ON_WM_SETCURSOR()
  33. ON_WM_WINDOWPOSCHANGING()
  34.     ON_WM_WINDOWPOSCHANGED()
  35.     ON_WM_NCPAINT()
  36.     ON_WM_NCLBUTTONDOWN()
  37.     ON_WM_NCHITTEST()
  38.     ON_WM_NCCALCSIZE()
  39.     ON_WM_LBUTTONDOWN()
  40.     ON_WM_CAPTURECHANGED()
  41.     ON_WM_SIZE()
  42.     ON_WM_LBUTTONDBLCLK()
  43.     //}}AFX_MSG_MAP
  44. END_MESSAGE_MAP()
  45. /////////////////////////////////////////////////////////////////////////////
  46. // CSizingControlBar message handlers
  47. void CSizingControlBar::OnUpdateCmdUI(class CFrameWnd *pTarget, int bDisableIfNoHndler)
  48. {
  49.     UpdateDialogControls(pTarget, bDisableIfNoHndler);
  50. }
  51. BOOL CSizingControlBar::Create(CWnd* pParentWnd, CSize sizeDefault, UINT nID, DWORD dwStyle) 
  52. {
  53.     ASSERT_VALID(pParentWnd);   // must have a parent
  54.     ASSERT (!((dwStyle & CBRS_SIZE_FIXED) && (dwStyle & CBRS_SIZE_DYNAMIC)));
  55.     // save the style
  56.     m_dwStyle = dwStyle;
  57.     dwStyle &= ~CBRS_ALL;
  58.     dwStyle |= CCS_NOMOVEY|CCS_NODIVIDER|CCS_NORESIZE;
  59.     m_sizeHorz = sizeDefault;
  60.     m_sizeVert = sizeDefault;
  61.     m_sizeFloat = sizeDefault;
  62. // without CS_BYTEALIGNWINDOW treectrl doesn't expand, 
  63.     CString wndclass = AfxRegisterWndClass(CS_DBLCLKS|CS_BYTEALIGNWINDOW, LoadCursor(NULL, IDC_ARROW),
  64.         CreateSolidBrush(GetSysColor(COLOR_BTNFACE)), 0);
  65.     if (!CWnd::Create(wndclass, NULL, dwStyle, CRect(0,0,0,0),
  66.         pParentWnd, nID))
  67.         return FALSE;
  68.     return TRUE;
  69. }
  70. CSize CSizingControlBar::CalcFixedLayout(BOOL bStretch, BOOL bHorz)
  71. {
  72.     CRect rc;
  73.     m_pDockSite->GetControlBar(AFX_IDW_DOCKBAR_TOP)->GetWindowRect(rc);
  74.     int nHorzDockBarWidth = bStretch ? 32767 : rc.Width() + 4;
  75.     m_pDockSite->GetControlBar(AFX_IDW_DOCKBAR_LEFT)->GetWindowRect(rc);
  76.     int nVertDockBarHeight = bStretch ? 32767 : rc.Height() + 4;
  77.     if (bHorz)
  78.         return CSize(nHorzDockBarWidth, m_sizeHorz.cy);
  79.     else
  80.         return CSize(m_sizeVert.cx, nVertDockBarHeight);
  81. }
  82. CSize CSizingControlBar::CalcDynamicLayout(int nLength, DWORD dwMode)
  83. {
  84.     if (dwMode & (LM_HORZDOCK | LM_VERTDOCK))
  85.         return CControlBar::CalcDynamicLayout(nLength,dwMode);
  86.     if (dwMode & LM_MRUWIDTH)
  87.         return m_sizeFloat;
  88.     if (dwMode & LM_COMMIT)
  89.     {
  90.         m_sizeFloat.cx = nLength;
  91.         return m_sizeFloat;
  92.     }
  93.     if (dwMode & LM_LENGTHY)
  94.         return CSize(m_sizeFloat.cx,
  95.             m_sizeFloat.cy = max(m_sizeMin.cy, nLength));
  96.     else
  97.         return CSize(max(m_sizeMin.cx, nLength), m_sizeFloat.cy);
  98. }
  99. void CSizingControlBar::OnWindowPosChanging(LPWINDOWPOS lpwp)
  100. {
  101. CControlBar::OnWindowPosChanging(lpwp);
  102. if (!(lpwp->flags & SWP_NOMOVE)) { // if moved:
  103. CRect rc; // Fill rectangle with..
  104. GetWindowRect(&rc); // ..my rectangle.
  105. ScreenToClient(&rc); // .. and convert to parent coords
  106. InvalidateRect(&rc); // paint old rectangle because
  107. // OnWindowPosChanged() does the rest
  108. }
  109. }
  110. void CSizingControlBar::OnWindowPosChanged(LPWINDOWPOS lpwp) 
  111. {
  112.     CControlBar::OnWindowPosChanged(lpwp);
  113.     if (m_bInRecalcNC) return;
  114.     // Find on which side are we docked
  115.     UINT nDockBarID = GetParent()->GetDlgCtrlID();
  116.     // Return if dropped at same location
  117.     if (nDockBarID == m_nDockBarID // no docking side change
  118.         && (lpwp->flags & SWP_NOSIZE) // no size change
  119.         && ((m_dwStyle & CBRS_BORDER_ANY) != CBRS_BORDER_ANY))
  120.         return; 
  121.     m_nDockBarID = nDockBarID;
  122. // Force recalc the non-client area
  123.     m_bInRecalcNC = TRUE;
  124.     SetWindowPos(NULL, 0, 0, 0, 0,
  125.         SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER |
  126.         SWP_NOACTIVATE | SWP_FRAMECHANGED);
  127.     m_bInRecalcNC = FALSE;
  128. }
  129. BOOL CSizingControlBar::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message) 
  130. {
  131.     if ((nHitTest != HTSIZE) || m_bTracking)
  132.         return CControlBar::OnSetCursor(pWnd, nHitTest, message);
  133.     if (IsHorz())
  134.         SetCursor(LoadCursor(NULL, IDC_SIZENS));
  135.     else
  136.         SetCursor(LoadCursor(NULL, IDC_SIZEWE));
  137.     return TRUE;
  138. }
  139. /////////////////////////////////////////////////////////////////////////
  140. // Mouse Handling
  141. //
  142. void CSizingControlBar::OnLButtonUp(UINT nFlags, CPoint point) 
  143. {
  144.     if (!m_bTracking)
  145.         CControlBar::OnLButtonUp(nFlags, point);
  146.     else
  147.     {
  148.         ClientToWnd(point);
  149.         StopTracking(TRUE);
  150.     }
  151. }
  152. void CSizingControlBar::OnMouseMove(UINT nFlags, CPoint point) 
  153. {
  154.     if (IsFloating() || !m_bTracking)
  155.     {
  156.         CControlBar::OnMouseMove(nFlags, point);
  157.         return;
  158.     }
  159.     CPoint cpt = m_rectTracker.CenterPoint();
  160.     ClientToWnd(point);
  161.     if (IsHorz())
  162.     {
  163.         if (cpt.y != point.y)
  164.         {
  165.             OnInvertTracker(m_rectTracker);
  166.             m_rectTracker.OffsetRect(0, point.y - cpt.y);
  167.             OnInvertTracker(m_rectTracker);
  168.     }
  169.     }
  170.     else 
  171.     {
  172.         if (cpt.x != point.x)
  173.         {
  174.             OnInvertTracker(m_rectTracker);
  175.             m_rectTracker.OffsetRect(point.x - cpt.x, 0);
  176.             OnInvertTracker(m_rectTracker);
  177.         }
  178.     }
  179. }
  180. void CSizingControlBar::OnNcCalcSize(BOOL bCalcValidRects, NCCALCSIZE_PARAMS FAR* lpncsp) 
  181. {
  182.     // Compute the rectangle of the mobile edge
  183.     GetWindowRect(m_rectBorder);
  184.     m_rectBorder = CRect(0, 0, m_rectBorder.Width(), m_rectBorder.Height());
  185.     
  186.     DWORD dwBorderStyle = m_dwStyle | CBRS_BORDER_ANY;
  187.     switch(m_nDockBarID)
  188.     {
  189.     case AFX_IDW_DOCKBAR_TOP:
  190.         dwBorderStyle &= ~CBRS_BORDER_BOTTOM;
  191.         lpncsp->rgrc[0].bottom += -m_cxEdge;
  192.         m_rectBorder.top = m_rectBorder.bottom - m_cxEdge;
  193.         break;
  194.     case AFX_IDW_DOCKBAR_BOTTOM:
  195.         dwBorderStyle &= ~CBRS_BORDER_TOP;
  196.         lpncsp->rgrc[0].top += m_cxEdge;
  197.         m_rectBorder.bottom = m_rectBorder.top + m_cxEdge;
  198.         break;
  199.     case AFX_IDW_DOCKBAR_LEFT:
  200.         dwBorderStyle &= ~CBRS_BORDER_RIGHT;
  201.         lpncsp->rgrc[0].right += -m_cxEdge;
  202.         m_rectBorder.left = m_rectBorder.right - m_cxEdge;
  203.         break;
  204.     case AFX_IDW_DOCKBAR_RIGHT:
  205.         dwBorderStyle &= ~CBRS_BORDER_LEFT;
  206.         lpncsp->rgrc[0].left += m_cxEdge;
  207.         m_rectBorder.right = m_rectBorder.left + m_cxEdge;
  208.         break;
  209.     default:
  210.         m_rectBorder.SetRectEmpty();
  211.         break;
  212.     }
  213.     SetBarStyle(dwBorderStyle);
  214. }
  215. void CSizingControlBar::OnNcPaint() 
  216. {
  217.     EraseNonClient();
  218.     CDC *pDC = GetWindowDC();
  219.     pDC->Draw3dRect(m_rectBorder, GetSysColor(COLOR_BTNHIGHLIGHT),
  220.                     GetSysColor(COLOR_BTNSHADOW));
  221.     ReleaseDC(pDC);
  222. }
  223. void CSizingControlBar::OnNcLButtonDown(UINT nHitTest, CPoint point) 
  224. {
  225.     if (m_bTracking) return;
  226.     if ((nHitTest == HTSIZE) && !IsFloating())
  227.         StartTracking();
  228.     else    
  229.         CControlBar::OnNcLButtonDown(nHitTest, point);
  230. }
  231. UINT CSizingControlBar::OnNcHitTest(CPoint point) 
  232. {
  233.     if (IsFloating())
  234.         return CControlBar::OnNcHitTest(point);
  235.     CRect rc;
  236.     GetWindowRect(rc);
  237.     point.Offset(-rc.left, -rc.top);
  238.     if (m_rectBorder.PtInRect(point))
  239.         return HTSIZE;
  240.     else
  241.         return CControlBar::OnNcHitTest(point);
  242. }
  243. void CSizingControlBar::OnLButtonDown(UINT nFlags, CPoint point) 
  244. {
  245.     // only start dragging if clicked in "void" space
  246.     if (m_pDockBar != NULL )
  247.     {
  248.         // start the drag
  249.         ASSERT(m_pDockContext != NULL);
  250.         ClientToScreen(&point);
  251.         m_pDockContext->StartDrag(point);
  252.     }
  253.     else
  254.     {
  255.         CWnd::OnLButtonDown(nFlags, point);
  256.     }
  257. }
  258. void CSizingControlBar::OnLButtonDblClk(UINT nFlags, CPoint point) 
  259. {
  260.     // only toggle docking if clicked in "void" space
  261.     if (m_pDockBar != NULL)
  262.     {
  263.         // toggle docking
  264.         ASSERT(m_pDockContext != NULL);
  265.         m_pDockContext->ToggleDocking();
  266.     }
  267.     else
  268.     {
  269.         CWnd::OnLButtonDblClk(nFlags, point);
  270.     }
  271. }
  272. void CSizingControlBar::StartTracking()
  273. {
  274.     SetCapture();
  275.     // make sure no updates are pending
  276.     m_pDockSite->LockWindowUpdate();
  277.     m_ptOld = m_rectBorder.CenterPoint();
  278.     m_bTracking = TRUE;
  279.     
  280.     m_rectTracker = m_rectBorder;
  281.     if (!IsHorz()) m_rectTracker.bottom -= 4;
  282.     OnInvertTracker(m_rectTracker);
  283. }
  284. void CSizingControlBar::OnCaptureChanged(CWnd *pWnd) 
  285. {
  286.     if (m_bTracking && pWnd != this)
  287.         StopTracking(FALSE); // cancel tracking
  288.     CControlBar::OnCaptureChanged(pWnd);
  289. }
  290. // <raip
  291. BOOL CSizingControlBar::ShowPane(BOOL bShow) 
  292. {
  293. BOOL bRet;
  294. if (m_sizeVert.cx > 0)
  295. m_sizeStoreVert = m_sizeVert;
  296. if (m_sizeHorz.cy > 0)
  297. m_sizeStoreHorz = m_sizeHorz;
  298. if (!bShow)
  299. {
  300. if (IsHorz())
  301. m_sizeHorz.cy = 0;
  302. else 
  303. m_sizeVert.cx = 0;
  304. bRet = FALSE;
  305. else 
  306. {
  307. m_sizeHorz = m_sizeStoreHorz;
  308. m_sizeVert = m_sizeStoreVert;
  309. bRet = TRUE;
  310. }
  311.     m_pDockSite->DelayRecalcLayout();
  312. return bRet;
  313. }
  314. // raip>
  315. void CSizingControlBar::StopTracking(BOOL bAccept)
  316. {
  317.     OnInvertTracker(m_rectTracker);
  318.     m_pDockSite->UnlockWindowUpdate();
  319.     m_bTracking = FALSE;
  320.     ReleaseCapture();
  321.     
  322.     if (!bAccept) return;
  323.     int maxsize, minsize, newsize;
  324.     CRect rcc;
  325.     m_pDockSite->GetClientRect(rcc);
  326.     newsize = IsHorz() ? m_sizeHorz.cy : m_sizeVert.cx;
  327.     maxsize = newsize + (IsHorz() ? rcc.Height() : rcc.Width());
  328.     minsize = IsHorz() ? m_sizeMin.cy : m_sizeMin.cx;
  329.     CPoint point = m_rectTracker.CenterPoint();
  330.     switch (m_nDockBarID)
  331.     {
  332.     case AFX_IDW_DOCKBAR_TOP:
  333.         newsize += point.y - m_ptOld.y; break;
  334.     case AFX_IDW_DOCKBAR_BOTTOM:
  335.         newsize += -point.y + m_ptOld.y; break;
  336.     case AFX_IDW_DOCKBAR_LEFT:
  337.         newsize += point.x - m_ptOld.x; break;
  338.     case AFX_IDW_DOCKBAR_RIGHT:
  339.         newsize += -point.x + m_ptOld.x; break;
  340.     }
  341.     newsize = max(minsize, min(maxsize, newsize));
  342.     if (IsHorz()) {
  343. #ifdef SCBF_MAXHALFCLIENTY
  344. if (newsize >= rcc.Height()/2)
  345. newsize = rcc.Height()/2;
  346. #endif
  347. m_sizeHorz.cy = newsize;
  348. }
  349.     else {
  350. #ifdef SCBF_MAXHALFCLIENTX
  351. if (newsize >= rcc.Width()/2)
  352. newsize = rcc.Width()/2;
  353. #endif
  354. m_sizeVert.cx = newsize;
  355. }
  356.     m_pDockSite->DelayRecalcLayout();
  357. }
  358. void CSizingControlBar::OnInvertTracker(const CRect& rect)
  359. {
  360.     ASSERT_VALID(this);
  361.     ASSERT(!rect.IsRectEmpty());
  362.     ASSERT(m_bTracking);
  363.     CRect rct = rect, rcc, rcf;
  364.     GetWindowRect(rcc);
  365.     m_pDockSite->GetWindowRect(rcf);
  366.     rct.OffsetRect(rcc.left - rcf.left, rcc.top - rcf.top);
  367.     rct.DeflateRect(1, 1);
  368.     CDC *pDC = m_pDockSite->GetDCEx(NULL,
  369.         DCX_WINDOW|DCX_CACHE|DCX_LOCKWINDOWUPDATE);
  370.     CBrush* pBrush = CDC::GetHalftoneBrush();
  371.     HBRUSH hOldBrush = NULL;
  372.     if (pBrush != NULL)
  373.         hOldBrush = (HBRUSH)SelectObject(pDC->m_hDC, pBrush->m_hObject);
  374.     pDC->PatBlt(rct.left, rct.top, rct.Width(), rct.Height(), PATINVERT);
  375.     if (hOldBrush != NULL)
  376.         SelectObject(pDC->m_hDC, hOldBrush);
  377.     m_pDockSite->ReleaseDC(pDC);
  378. }
  379. BOOL CSizingControlBar::IsHorz() const
  380. {
  381.     return (m_nDockBarID == AFX_IDW_DOCKBAR_TOP ||
  382.         m_nDockBarID == AFX_IDW_DOCKBAR_BOTTOM);
  383. }
  384. CPoint& CSizingControlBar::ClientToWnd(CPoint& point)
  385. {
  386.     if (m_nDockBarID == AFX_IDW_DOCKBAR_BOTTOM)
  387.         point.y += m_cxEdge;
  388.     else if (m_nDockBarID == AFX_IDW_DOCKBAR_RIGHT)
  389.         point.x += m_cxEdge;
  390.     return point;
  391. }