SIZECBAR.CPP
上传用户:nbkytg
上传日期:2021-02-14
资源大小:126k
文件大小:25k
源码类别:

工具条

开发平台:

Visual C++

  1. /////////////////////////////////////////////////////////////////////////
  2. // Copyright (C) 1998 by Cristi Posea
  3. // All rights reserved
  4. //
  5. // Distribute freely, except: don't remove my name from the source or
  6. // documentation (don't take credit for my work), mark your changes
  7. // (don't get me blamed for your possible bugs), don't alter or remove
  8. // this notice.
  9. // No warrantee of any kind, express or implied, is included with this
  10. // software; use at your own risk, responsibility for damages (if any) to
  11. // anyone resulting from the use of this software rests entirely with the
  12. // user.
  13. //
  14. // Send bug reports, bug fixes, enhancements, requests, flames, etc.,
  15. // and I'll try to keep a version up to date.  I can be reached at:
  16. //    cristi@gds.ro
  17. /////////////////////////////////////////////////////////////////////////
  18. //
  19. // Acknowledgements:
  20. //  o   Thanks to Harlan R. Seymour (harlan@hcube.com) for motivating me
  21. //      to update this code. Also he prompted me to a bug durring 
  22. //      the developement phase.
  23. //  o   Thanks to Zafir Anjum (zafir@codeguru.com) for publishing this
  24. //      code on his cool site (www.codeguru.com).
  25. //  o   Some ideeas for the gripper came from the CToolBarEx flat toolbar
  26. //      by Joerg Koenig (Joerg.Koenig@rhein-neckar.de). Also he inspired
  27. //      me on writting this notice:) . Thanks, Joerg!
  28. //  o   Thanks to Jakawan Ratiwanich (jack@alpha.fsec.ucf.edu) and to
  29. //      Udo Schaefer(Udo.Schaefer@vcase.de) for the dwStyle bug fix under
  30. //      VC++ 6.0.
  31. //  o   Thanks to Microsoft developers for the MFC source code. After
  32. //      all, most of this class code came from there.
  33. //
  34. /////////////////////////////////////////////////////////////////////////
  35. //
  36. // Usage:
  37. // o    Derive your class from CSizingControlBar. Then create your child
  38. //      controls/windows on it.
  39. // o    Include your class header in Mainfrm.cpp and add a member 
  40. //      variable to CMainFrame. In CMainFrame::OnCreate(), create the
  41. //      control bar, enable it to dock, and so on... like a toolbar or
  42. //      any control bar.
  43. // o    More details at
  44. //      http://www.codeguru.com/docking/docking_window.shtml or search
  45. //      http://www.codeguru.com for my name if the article has moved.
  46. //
  47. /////////////////////////////////////////////////////////////////////////
  48. // SizingControlBar.cpp : implementation file
  49. //
  50. #include "stdafx.h"
  51. #include "afxpriv.h"    // for CDockContext
  52. #include "sizecbar.h"
  53. //#include "afximpl.h"
  54. #ifdef _DEBUG
  55. #define new DEBUG_NEW
  56. #undef THIS_FILE
  57. static char THIS_FILE[] = __FILE__;
  58. #endif
  59. /////////////////////////////////////////////////////////////////////////
  60. // CSizingControlBar
  61. CSizingControlBar::CSizingControlBar()
  62. {
  63.     m_sizeMin = CSize(32, 32);
  64.     m_sizeHorz = CSize(200, 200);
  65.     m_sizeVert = CSize(200, 200);
  66.     m_sizeFloat = CSize(200, 200);
  67.     m_bTracking = FALSE;
  68.     m_bInRecalcNC = FALSE;
  69.     m_cxEdge = 5;
  70. m_bDragShowContent = FALSE;
  71. }
  72. CSizingControlBar::~CSizingControlBar()
  73. {
  74. }
  75. BEGIN_MESSAGE_MAP(CSizingControlBar, CControlBar)
  76.     //{{AFX_MSG_MAP(CSizingControlBar)
  77.     ON_WM_PAINT()
  78.     ON_WM_NCPAINT()
  79.     ON_WM_WINDOWPOSCHANGED()
  80.     ON_WM_NCCALCSIZE()
  81.     ON_WM_LBUTTONUP()
  82.     ON_WM_MOUSEMOVE()
  83.     ON_WM_NCLBUTTONDOWN()
  84.     ON_WM_LBUTTONDOWN()
  85.     ON_WM_LBUTTONDBLCLK()
  86. ON_WM_RBUTTONDOWN()
  87.     ON_WM_CAPTURECHANGED()
  88.     ON_WM_NCHITTEST()
  89.     ON_WM_SETCURSOR()
  90. ON_WM_NCLBUTTONUP()
  91. ON_WM_NCMOUSEMOVE()
  92.     ON_WM_SIZE()
  93. //}}AFX_MSG_MAP
  94. ON_NOTIFY_EX(TTN_NEEDTEXT,0,OnTipNotify)
  95. END_MESSAGE_MAP()
  96. /////////////////////////////////////////////////////////////////////////
  97. // CSizingControlBar message handlers
  98. BOOL CSizingControlBar::Create(LPCTSTR lpszWindowName, CWnd* pParentWnd,
  99.                                CSize sizeDefault, BOOL bHasGripper,
  100.                                UINT nID, DWORD dwStyle)
  101. {
  102.     ASSERT_VALID(pParentWnd);   // must have a parent
  103.     ASSERT (!((dwStyle & CBRS_SIZE_FIXED)
  104.         && (dwStyle & CBRS_SIZE_DYNAMIC)));
  105.     // save the style
  106.     SetBarStyle(dwStyle & CBRS_ALL);
  107.     CString wndclass = ::AfxRegisterWndClass(CS_DBLCLKS,
  108.         ::LoadCursor(NULL, IDC_ARROW),
  109.         ::GetSysColorBrush(COLOR_BTNFACE), 0);
  110.     dwStyle &= ~CBRS_ALL;
  111.     dwStyle &= WS_VISIBLE | WS_CHILD;
  112.     if (!CWnd::Create(wndclass, lpszWindowName, dwStyle, CRect(0,0,0,0),
  113.         pParentWnd, nID))
  114.         return FALSE;
  115.     m_sizeHorz = sizeDefault;
  116.     m_sizeVert = sizeDefault;
  117.     m_sizeFloat = sizeDefault;
  118.     m_bHasGripper = bHasGripper;
  119.     m_cyGripper = m_bHasGripper ? 12 : 0;
  120. //允许ToolTips
  121. EnableToolTips(TRUE);
  122.     return TRUE;
  123. }
  124. BOOL CSizingControlBar::IsHorzDocked() const
  125. {
  126.     return (m_nDockBarID == AFX_IDW_DOCKBAR_TOP ||
  127.         m_nDockBarID == AFX_IDW_DOCKBAR_BOTTOM);
  128. }
  129. BOOL CSizingControlBar::IsVertDocked() const
  130. {
  131.     return (m_nDockBarID == AFX_IDW_DOCKBAR_LEFT ||
  132.         m_nDockBarID == AFX_IDW_DOCKBAR_RIGHT);
  133. }
  134. CSize CSizingControlBar::CalcFixedLayout(BOOL bStretch, BOOL bHorz)
  135. {
  136.     CRect rc;
  137.     m_pDockSite->GetControlBar(AFX_IDW_DOCKBAR_TOP)->GetWindowRect(rc);
  138.     int nHorzDockBarWidth = bStretch ? 32767 : rc.Width() + 4;
  139.     m_pDockSite->GetControlBar(AFX_IDW_DOCKBAR_LEFT)->GetWindowRect(rc);
  140.     int nVertDockBarHeight = bStretch ? 32767 : rc.Height() + 4;
  141.     if (bHorz)
  142.         return CSize(nHorzDockBarWidth, m_sizeHorz.cy);
  143.     else
  144.         return CSize(m_sizeVert.cx, nVertDockBarHeight);
  145. }
  146. CSize CSizingControlBar::CalcDynamicLayout(int nLength, DWORD dwMode)
  147. {
  148.     if (dwMode & (LM_HORZDOCK | LM_VERTDOCK))
  149.     {
  150.         if (nLength == -1)
  151.             GetDockingFrame()->DelayRecalcLayout();
  152.         return CControlBar::CalcDynamicLayout(nLength,dwMode);
  153.     }
  154.     if (dwMode & LM_MRUWIDTH)
  155.         return m_sizeFloat;
  156.     if (dwMode & LM_COMMIT)
  157.     {
  158.         m_sizeFloat.cx = nLength;
  159.         return m_sizeFloat;
  160.     }
  161.     if (dwMode & LM_LENGTHY)
  162.         return CSize(m_sizeFloat.cx,
  163.             m_sizeFloat.cy = max(m_sizeMin.cy, nLength));
  164.     else
  165.         return CSize(max(m_sizeMin.cx, nLength), m_sizeFloat.cy);
  166. }
  167. void CSizingControlBar::OnWindowPosChanged(WINDOWPOS FAR* lpwndpos) 
  168. {
  169.     CControlBar::OnWindowPosChanged(lpwndpos);
  170.     // Find on which side are we docked
  171.     m_nDockBarID = GetParent()->GetDlgCtrlID();
  172.     if (!m_bInRecalcNC)
  173.     {
  174.         m_bInRecalcNC = TRUE;
  175.         // Force recalc the non-client area
  176.         SetWindowPos(NULL, 0, 0, 0, 0,
  177.             SWP_NOMOVE | SWP_NOSIZE |
  178.             SWP_NOACTIVATE | SWP_NOZORDER |
  179.             SWP_FRAMECHANGED);
  180.         m_bInRecalcNC = FALSE;
  181.     }
  182. }
  183. // cache of last needed cursor
  184. AFX_STATIC_DATA HCURSOR _afx_hcurLast = NULL;
  185. AFX_STATIC_DATA HCURSOR _afx_hcurDestroy = NULL;
  186. AFX_STATIC_DATA UINT _afx_idcPrimaryLast = 0; // store the primary IDC
  187. BOOL CSizingControlBar::OnSetCursor(CWnd* pWnd, UINT nHitTest,
  188.                                     UINT message) 
  189. {
  190.   /*if((nHitTest == HTSYSMENU) && !IsFloating())
  191. {
  192. // MessageBox("aa");
  193. TOOLTIPTEXT m_psttt;
  194.         m_psttt.hdr.hwndFrom=m_hWnd;
  195.         m_psttt.hdr.idFrom=pWnd->GetDlgCtrlID();
  196.         m_psttt.hdr.code=TTN_NEEDTEXT;   
  197. m_psttt.uFlags= TTF_IDISHWND;
  198. SetStatusText(ID_DIALAGBAR_FLOAT);
  199.  //     SendMessage(WM_NOTIFY); 
  200. }
  201.    else if ((nHitTest == HTMINBUTTON) && !IsFloating())
  202. MessageBox("bb");
  203. */
  204. if ((nHitTest != HTSIZE) || m_bTracking)
  205.         return CControlBar::OnSetCursor(pWnd, nHitTest, message);
  206. UINT idcPrimary;        // app supplied cursor
  207. LPCTSTR idcSecondary;    // system supplied cursor (MAKEINTRESOURCE)
  208.     /*if (IsHorzDocked())
  209.         ::SetCursor(::LoadCursor(NULL, IDC_SIZENS));
  210.     else
  211.         ::SetCursor(::LoadCursor(NULL, IDC_SIZEWE));*/
  212. // ------- change by syx
  213. if(IsHorzDocked())
  214. {
  215. idcPrimary = AFX_IDC_VSPLITBAR;
  216. idcSecondary = IDC_SIZENS;
  217. }
  218. else
  219. {
  220. idcPrimary = AFX_IDC_HSPLITBAR;
  221. idcSecondary = IDC_SIZEWE;
  222. }
  223. HCURSOR hcurToDestroy = NULL;
  224. if(idcPrimary != _afx_idcPrimaryLast)
  225. {
  226. HINSTANCE hInst = AfxFindResourceHandle(
  227. MAKEINTRESOURCE(idcPrimary), RT_GROUP_CURSOR);
  228. // load in another cursor
  229. hcurToDestroy = _afx_hcurDestroy;
  230. // Note: If this LoadCursor call fails, it is likely that
  231. //  _AFX_NO_SPLITTER_RESOURCES is defined in your .RC file.
  232. // To correct the situation, remove the following line from your
  233. //  resource script:
  234. //      #define _AFX_NO_SPLITTER_RESOURCES
  235. // This should be done using the Resource.Set Includes... command.
  236. if((_afx_hcurDestroy = _afx_hcurLast =
  237. ::LoadCursor(hInst, MAKEINTRESOURCE(idcPrimary))) == NULL)
  238. {
  239. // will not look as good
  240. TRACE0("Warning: Could not find splitter cursor - using system provided alternative.n");
  241. ASSERT(_afx_hcurDestroy == NULL);    // will not get destroyed
  242. _afx_hcurLast = ::LoadCursor(NULL, idcSecondary);
  243. ASSERT(_afx_hcurLast != NULL);
  244. }
  245. _afx_idcPrimaryLast = idcPrimary;
  246. }
  247. ASSERT(_afx_hcurLast != NULL);
  248. ::SetCursor(_afx_hcurLast);
  249. ASSERT(_afx_hcurLast != hcurToDestroy);
  250. if (hcurToDestroy != NULL)
  251. ::DestroyCursor(hcurToDestroy); // destroy after being set
  252. // ------- change by syx
  253. return TRUE;
  254. }
  255. /////////////////////////////////////////////////////////////////////////
  256. // Mouse Handling
  257. //
  258. void CSizingControlBar::OnLButtonDown(UINT nFlags, CPoint point) 
  259. {
  260.     if (m_pDockBar != NULL)
  261.     {
  262.         // start the drag
  263.         ASSERT(m_pDockContext != NULL);
  264.         ClientToScreen(&point);
  265.         m_pDockContext->StartDrag(point);
  266.     }
  267.     else
  268.         CWnd::OnLButtonDown(nFlags, point);
  269. }
  270. void CSizingControlBar::OnLButtonDblClk(UINT nFlags, CPoint point) 
  271. {
  272.     if (m_pDockBar != NULL)
  273.     {
  274.         // toggle docking
  275.         ASSERT(m_pDockContext != NULL);
  276.         m_pDockContext->ToggleDocking();
  277.     }
  278.     else
  279.         CWnd::OnLButtonDblClk(nFlags, point);
  280. }
  281. void CSizingControlBar::OnNcLButtonDown(UINT nHitTest, CPoint point) 
  282. {
  283.     CWindowDC dc(this);
  284.     if (m_bTracking) return;
  285. if((nHitTest == HTSYSMENU) && !IsFloating())
  286. {
  287. dc.DrawEdge(m_rectClose,EDGE_SUNKEN,BF_RECT);
  288. }
  289.     else if ((nHitTest == HTMINBUTTON) && !IsFloating())
  290. dc.DrawEdge(m_rectUndock,EDGE_SUNKEN,BF_RECT);
  291.     else if ((nHitTest == HTSIZE) && !IsFloating())
  292.         StartTracking();
  293.     else    
  294. CControlBar::OnNcLButtonDown(nHitTest, point);
  295. }
  296. void CSizingControlBar::OnLButtonUp(UINT nFlags, CPoint point) 
  297. {
  298.     if (m_bTracking)
  299.         StopTracking(TRUE);
  300.     CControlBar::OnLButtonUp(nFlags, point);
  301. }
  302. void CSizingControlBar::OnRButtonDown(UINT nFlags, CPoint point) 
  303. {
  304.     if (m_bTracking)
  305.         StopTracking(FALSE);
  306. CControlBar::OnRButtonDown(nFlags, point);
  307. }
  308. void CSizingControlBar::OnMouseMove(UINT nFlags, CPoint point) 
  309. {
  310.     if (m_bTracking)
  311.     {
  312. ASSERT (!IsFloating());
  313. CPoint pt = point;
  314. ClientToScreen(&pt);
  315. OnTrackUpdateSize(pt);
  316.     }
  317.     CControlBar::OnMouseMove(nFlags, point);
  318. }
  319. void CSizingControlBar::OnCaptureChanged(CWnd *pWnd) 
  320. {
  321.     if (m_bTracking && pWnd != this)
  322.         StopTracking(FALSE); // cancel tracking
  323.     CControlBar::OnCaptureChanged(pWnd);
  324. }
  325. void CSizingControlBar::OnNcCalcSize(BOOL bCalcValidRects,
  326.                                      NCCALCSIZE_PARAMS FAR* lpncsp) 
  327. {
  328.     // Compute the rectangle of the mobile edge
  329.     GetWindowRect(m_rectBorder);
  330.     m_rectBorder.OffsetRect(-m_rectBorder.left, -m_rectBorder.top);
  331.     m_rectBorder.DeflateRect(1, 1);
  332.     
  333.     m_rectGripper = m_rectBorder;
  334.     m_rectGripper.DeflateRect(5, 5);
  335.     m_rectGripper.right -= m_cxEdge;
  336.     m_rectGripper.bottom -= m_cxEdge;
  337.     CRect rc = lpncsp->rgrc[0];
  338.     DWORD dwBorderStyle = m_dwStyle | CBRS_BORDER_ANY;
  339.     switch(m_nDockBarID)
  340.     {
  341.     case AFX_IDW_DOCKBAR_TOP:
  342.         dwBorderStyle &= ~CBRS_BORDER_BOTTOM;
  343.         rc.DeflateRect(m_cyGripper + 2, 2, 2, m_cxEdge + 2);
  344.         m_rectBorder.top = m_rectBorder.bottom - m_cxEdge;
  345.         break;
  346.     case AFX_IDW_DOCKBAR_BOTTOM:
  347.         dwBorderStyle &= ~CBRS_BORDER_TOP;
  348.         rc.DeflateRect(m_cyGripper + 2, m_cxEdge + 2, 2, 2);
  349.         m_rectBorder.bottom = m_rectBorder.top + m_cxEdge;
  350.         m_rectGripper.OffsetRect(0, m_cxEdge);
  351.         break;
  352.     case AFX_IDW_DOCKBAR_LEFT:
  353.         dwBorderStyle &= ~CBRS_BORDER_RIGHT;
  354.         rc.DeflateRect(2, m_cyGripper + 2, m_cxEdge + 2, 6);
  355.         m_rectBorder.left = m_rectBorder.right - m_cxEdge;
  356.         break;
  357.     case AFX_IDW_DOCKBAR_RIGHT:
  358.         dwBorderStyle &= ~CBRS_BORDER_LEFT;
  359.         rc.DeflateRect(m_cxEdge + 2, m_cyGripper + 2, 2, 6);
  360.         m_rectBorder.right = m_rectBorder.left + m_cxEdge;
  361.         m_rectGripper.OffsetRect(m_cxEdge, 0);
  362.         break;
  363.     default:
  364.         m_rectBorder.SetRectEmpty();
  365.         break;
  366.     }
  367.     lpncsp->rgrc[0] = rc;
  368.     SetBarStyle(dwBorderStyle);
  369. }
  370. void CSizingControlBar::OnNcPaint() 
  371. {
  372.     // get window DC that is clipped to the non-client area
  373.     CWindowDC dc(this);
  374.     CRect rectClient;
  375.     GetClientRect(rectClient);
  376.     CRect rectWindow;
  377.     GetWindowRect(rectWindow);
  378.     ScreenToClient(rectWindow);
  379.     rectClient.OffsetRect(-rectWindow.left, -rectWindow.top);
  380.     dc.ExcludeClipRect(rectClient);
  381.     // draw borders in non-client area
  382.     rectWindow.OffsetRect(-rectWindow.left, -rectWindow.top);
  383.     DrawBorders(&dc, rectWindow);
  384.     // erase parts not drawn
  385.     dc.IntersectClipRect(rectWindow);
  386.     // erase NC background the hard way
  387.     HBRUSH hbr = (HBRUSH)GetClassLong(m_hWnd, GCL_HBRBACKGROUND);
  388.     ::FillRect(dc.m_hDC, rectWindow, hbr);
  389.     // paint the mobile edge
  390.     dc.Draw3dRect(m_rectBorder, ::GetSysColor(COLOR_BTNHIGHLIGHT),
  391.         ::GetSysColor(COLOR_BTNSHADOW));
  392.     if (m_bHasGripper)
  393.     {
  394.         // paint the gripper
  395.  //       CRect gripper = m_rectGripper;
  396.      CRect gripper;
  397. GetWindowRect( gripper );
  398. ScreenToClient( gripper );
  399. gripper.OffsetRect( -gripper.left, -gripper.top );
  400.     
  401.         if (IsHorzDocked())
  402.         {
  403.             // gripper at left
  404.      /*       gripper.right = gripper.left + 3;
  405.             dc.Draw3dRect(gripper, ::GetSysColor(COLOR_BTNHIGHLIGHT),
  406.                 ::GetSysColor(COLOR_BTNSHADOW));
  407.             gripper.OffsetRect(3, 0);
  408.             dc.Draw3dRect(gripper, ::GetSysColor(COLOR_BTNHIGHLIGHT),
  409.                 ::GetSysColor(COLOR_BTNSHADOW));
  410. // gripper at left
  411. m_rectGripper.top = gripper.top + 40;
  412. m_rectGripper.bottom = gripper.bottom;
  413. m_rectGripper.left = gripper.left;
  414. m_rectGripper.right = gripper.left + 20;
  415. */
  416. // draw close box
  417. m_rectClose.left = gripper.left + 3;
  418. m_rectClose.right = m_rectClose.left + 12;
  419. m_rectClose.top = gripper.top + 10;
  420. m_rectClose.bottom = m_rectClose.top + 12;
  421. dc.DrawFrameControl(m_rectClose, DFC_CAPTION, DFCS_CAPTIONCLOSE);
  422. // draw docking toggle box
  423. m_rectUndock = m_rectClose;
  424. m_rectUndock.OffsetRect(0,13);
  425. dc.DrawFrameControl(m_rectUndock, DFC_CAPTION, DFCS_CAPTIONMAX);
  426. gripper.top += 38;
  427. gripper.bottom -= 10;
  428. gripper.left += 5;
  429. gripper.right = gripper.left+3;
  430.         dc.Draw3dRect( gripper, ::GetSysColor(COLOR_BTNHIGHLIGHT),
  431.                 ::GetSysColor(COLOR_BTNSHADOW) );
  432. gripper.OffsetRect(4, 0);
  433.         dc.Draw3dRect( gripper, ::GetSysColor(COLOR_BTNHIGHLIGHT),
  434.                 ::GetSysColor(COLOR_BTNSHADOW));        
  435. }
  436.         else if (IsVertDocked())
  437.         {
  438.             // gripper at top
  439.      /*      gripper.bottom = gripper.top + 3;
  440.             dc.Draw3dRect(gripper, ::GetSysColor(COLOR_BTNHIGHLIGHT),
  441.                 ::GetSysColor(COLOR_BTNSHADOW));
  442.             gripper.OffsetRect(0, 3);
  443.             dc.Draw3dRect(gripper, ::GetSysColor(COLOR_BTNHIGHLIGHT),
  444.                 ::GetSysColor(COLOR_BTNSHADOW));
  445.         */
  446. // gripper at top
  447. /* m_rectGripper.top = gripper.top;
  448. m_rectGripper.bottom = gripper.top + 20;
  449. m_rectGripper.left = gripper.left;
  450. m_rectGripper.right = gripper.right - 24;
  451. */
  452. // draw close box
  453. m_rectClose.right = gripper.right - 10;
  454. m_rectClose.left = m_rectClose.right - 11;
  455. m_rectClose.top = gripper.top+3;//+ 7
  456. m_rectClose.bottom = m_rectClose.top + 11;
  457. dc.DrawFrameControl(m_rectClose, DFC_CAPTION, DFCS_CAPTIONCLOSE);
  458. // draw docking toggle box
  459. m_rectUndock = m_rectClose;
  460. m_rectUndock.OffsetRect(-13,0);
  461. dc.DrawFrameControl(m_rectUndock, DFC_CAPTION, DFCS_CAPTIONMAX);
  462. gripper.right -= 38;
  463. gripper.left += 10;
  464. gripper.top += 5;
  465. gripper.bottom = gripper.top + 3;
  466. dc.Draw3dRect( gripper, ::GetSysColor(COLOR_BTNHIGHLIGHT),
  467.                 ::GetSysColor(COLOR_BTNSHADOW) );
  468. gripper.OffsetRect(0, 4);
  469.         dc.Draw3dRect( gripper, ::GetSysColor(COLOR_BTNHIGHLIGHT),
  470.                 ::GetSysColor(COLOR_BTNSHADOW) );
  471. }
  472.     }
  473.     ReleaseDC(&dc);
  474. }
  475. void CSizingControlBar::OnPaint() 
  476. {
  477.     // overridden to skip border painting based on clientrect
  478.     CPaintDC dc(this);
  479. }
  480. UINT CSizingControlBar::OnNcHitTest(CPoint point) 
  481. {
  482.     if (IsFloating())
  483.         return CControlBar::OnNcHitTest(point);
  484.     CRect rc;
  485.     GetWindowRect(rc);
  486.     point.Offset(-rc.left, -rc.top);
  487. if(m_rectClose.PtInRect(point))
  488. return HTSYSMENU;
  489. else if (m_rectUndock.PtInRect(point))
  490. return HTMINBUTTON;
  491. /* else if (m_rectGripper.PtInRect(point))
  492. return HTCAPTION;
  493.     else if (m_rectBorder.PtInRect(point))
  494.         return HTSIZE;
  495.     else
  496.         return CControlBar::OnNcHitTest(point);
  497. */
  498.     if (m_rectBorder.PtInRect(point))
  499.         return HTSIZE;
  500.     else
  501.         return HTCLIENT;
  502. }
  503. /////////////////////////////////////////////////////////////////////////
  504. // CSizingControlBar implementation helpers
  505. void CSizingControlBar::StartTracking()
  506. {
  507.     SetCapture();
  508.     // make sure no updates are pending
  509.     RedrawWindow(NULL, NULL, RDW_ALLCHILDREN | RDW_UPDATENOW);
  510. m_bDragShowContent = QueryDragFullWindows();
  511. if (!m_bDragShowContent)
  512.     m_pDockSite->LockWindowUpdate();
  513. m_sizeOld = IsHorzDocked() ? m_sizeHorz : m_sizeVert;
  514. CRect rect;
  515. GetWindowRect(&rect);
  516.     m_ptOld = m_rectBorder.CenterPoint() + rect.TopLeft();
  517. m_sizeMax = CalcMaxSize();
  518.     m_bTracking = TRUE;
  519.     
  520. if (!m_bDragShowContent)
  521.     OnTrackInvertTracker();
  522. }
  523. void CSizingControlBar::StopTracking(BOOL bAccept)
  524. {
  525. if (!m_bDragShowContent)
  526. {
  527. OnTrackInvertTracker();
  528.     m_pDockSite->UnlockWindowUpdate();
  529. }
  530.     m_bTracking = FALSE;
  531.     ReleaseCapture();
  532.     
  533.     if (!bAccept) // resize canceled?
  534. {
  535. // restore old size
  536. if (IsHorzDocked())
  537.         m_sizeHorz = m_sizeOld;
  538. else
  539. m_sizeVert = m_sizeOld;
  540. }
  541.     m_pDockSite->DelayRecalcLayout();
  542. }
  543. void CSizingControlBar::OnTrackUpdateSize(CPoint& point)
  544. {
  545. BOOL bHorz = IsHorzDocked();
  546.     CSize sizeNew = m_sizeOld;
  547.     if ((m_nDockBarID == AFX_IDW_DOCKBAR_TOP) ||
  548. (m_nDockBarID == AFX_IDW_DOCKBAR_LEFT))
  549.         sizeNew += point - m_ptOld;
  550. else
  551.         sizeNew -= point - m_ptOld;
  552. // check limits
  553.    sizeNew.cx = max(m_sizeMin.cx, sizeNew.cx);
  554.    sizeNew.cy = max(m_sizeMin.cy, sizeNew.cy);
  555.    sizeNew.cx = min(m_sizeMax.cx, sizeNew.cx);
  556.    sizeNew.cy = min(m_sizeMax.cy, sizeNew.cy);
  557.     if ((sizeNew.cy == m_sizeHorz.cy) && bHorz ||
  558. (sizeNew.cx == m_sizeVert.cx) && !bHorz)
  559. return; // no size change
  560. if (!m_bDragShowContent)
  561. OnTrackInvertTracker();
  562.     if (bHorz)
  563. m_sizeHorz = sizeNew;
  564. else
  565. m_sizeVert = sizeNew;
  566. if (!m_bDragShowContent)
  567. OnTrackInvertTracker();
  568. else
  569.     m_pDockSite->DelayRecalcLayout();
  570. }
  571. CSize CSizingControlBar::CalcMaxSize()
  572. {
  573. // the control bar cannot grow with more than the size of 
  574. // remaining client area of the frame
  575. CRect rect;
  576. m_pDockSite->GetClientRect(&rect);
  577. CSize size = rect.Size();
  578. CWnd* pBar;
  579. if (IsHorzDocked())
  580. {
  581. if (pBar = m_pDockSite->GetControlBar(AFX_IDW_DOCKBAR_TOP))
  582. {
  583. pBar->GetWindowRect(&rect);
  584. size -= rect.Size();
  585. }
  586. if (pBar = m_pDockSite->GetControlBar(AFX_IDW_DOCKBAR_BOTTOM))
  587. {
  588. pBar->GetWindowRect(&rect);
  589. size -= rect.Size();
  590. }
  591. if (pBar = m_pDockSite->GetControlBar(AFX_IDW_STATUS_BAR))
  592. {
  593. pBar->GetWindowRect(&rect);
  594. size -= rect.Size();
  595. }
  596. }
  597. else
  598. {
  599. if (pBar = m_pDockSite->GetControlBar(AFX_IDW_DOCKBAR_LEFT))
  600. {
  601. pBar->GetWindowRect(&rect);
  602. size -= rect.Size();
  603. }
  604. if (pBar = m_pDockSite->GetControlBar(AFX_IDW_DOCKBAR_RIGHT))
  605. {
  606. pBar->GetWindowRect(&rect);
  607. size -= rect.Size();
  608. }
  609. }
  610. size -= CSize(4, 4);
  611.     size += IsHorzDocked() ? m_sizeHorz : m_sizeVert;
  612. return size;
  613. }
  614. void CSizingControlBar::OnTrackInvertTracker()
  615. {
  616.     ASSERT_VALID(this);
  617.     ASSERT(m_bTracking);
  618. CRect rect = m_rectBorder;
  619.     CRect rectBar, rectFrame;
  620.     GetWindowRect(rectBar);
  621.     rect.OffsetRect(rectBar.TopLeft());
  622.     m_pDockSite->GetWindowRect(rectFrame);
  623.     rect.OffsetRect(-rectFrame.left, -rectFrame.top);
  624. switch (m_nDockBarID)
  625. {
  626. case AFX_IDW_DOCKBAR_TOP:
  627. rect.OffsetRect(0, m_sizeHorz.cy - m_sizeOld.cy); break;
  628. case AFX_IDW_DOCKBAR_BOTTOM:
  629. rect.OffsetRect(0, m_sizeOld.cy - m_sizeHorz.cy); break;
  630. case AFX_IDW_DOCKBAR_LEFT:
  631. rect.OffsetRect(m_sizeVert.cx - m_sizeOld.cx, 0); break;
  632. case AFX_IDW_DOCKBAR_RIGHT:
  633. rect.OffsetRect(m_sizeOld.cx - m_sizeVert.cx, 0); break;
  634. }
  635. if (IsVertDocked())
  636.     rect.bottom -= 4;
  637.     rect.DeflateRect(1, 1);
  638.     CDC *pDC = m_pDockSite->GetDCEx(NULL,
  639.         DCX_WINDOW|DCX_CACHE|DCX_LOCKWINDOWUPDATE);
  640.     CBrush* pBrush = CDC::GetHalftoneBrush();
  641.     HBRUSH hOldBrush = NULL;
  642.     if (pBrush != NULL)
  643.         hOldBrush = (HBRUSH)::SelectObject(pDC->m_hDC, pBrush->m_hObject);
  644.     pDC->PatBlt(rect.left, rect.top,
  645. rect.Width(), rect.Height(), PATINVERT);
  646.     if (hOldBrush != NULL)
  647.         ::SelectObject(pDC->m_hDC, hOldBrush);
  648.     m_pDockSite->ReleaseDC(pDC);
  649. }
  650. BOOL CSizingControlBar::QueryDragFullWindows() const
  651. {
  652. TCHAR sDragfullWindows[2];
  653. DWORD cbDragfullWindows = sizeof(DWORD);
  654. DWORD dwType;
  655. HKEY hKey;
  656. BOOL bRet = FALSE;
  657. RegOpenKeyEx(HKEY_CURRENT_USER, _T("Control Panel\desktop"),
  658. 0, KEY_QUERY_VALUE, &hKey);
  659. if (!FAILED(RegQueryValueEx(hKey, _T("DragfullWindows"),
  660. NULL, &dwType, (LPBYTE)&sDragfullWindows, &cbDragfullWindows)))
  661. if (!_tcscmp(sDragfullWindows, _T("1")))
  662. bRet = TRUE;
  663. RegCloseKey(hKey);
  664. return bRet;
  665. }
  666. void CSizingControlBar::OnNcLButtonUp(UINT nHitTest, CPoint point) 
  667. {
  668. // TODO: Add your message handler code here and/or call default
  669. /*    if (m_bTracking) return;
  670.     if ((nHitTest == HTSIZE) && !IsFloating())
  671.         StartTracking();
  672.     else    
  673.         CControlBar::OnNcLButtonDown(nHitTest, point);
  674. */
  675.     if (m_bTracking) return;
  676. if((nHitTest == HTSYSMENU) && !IsFloating())
  677. {
  678. // CFrameWnd::ShowControlBar((CControlBar*),((GetStyle() & WS_VISIBLE)==0),FALSE);
  679. ShowWindow(SW_HIDE);
  680. m_pDockContext->ToggleDocking();
  681. }
  682.     else if ((nHitTest == HTMINBUTTON) && !IsFloating())
  683.         m_pDockContext->ToggleDocking();
  684. else if ((nHitTest == HTCAPTION) && !IsFloating() && (m_pDockBar != NULL))
  685.     {
  686.         // start the drag
  687.         ASSERT(m_pDockContext != NULL);
  688.         m_pDockContext->StartDrag(point);
  689.     }
  690.     else if ((nHitTest == HTSIZE) && !IsFloating())
  691.         StartTracking();
  692.     else    
  693.      //   CControlBar::OnNcLButtonDown(nHitTest, point);
  694. CControlBar::OnNcLButtonUp(nHitTest, point);
  695. }
  696. void CSizingControlBar::OnNcMouseMove(UINT nHitTest, CPoint point) 
  697. {
  698. // TODO: Add your message handler code here and/or call default
  699.     CWindowDC dc(this);
  700. if(!(m_rectClose.PtInRect(point)) && !IsFloating())
  701. dc.DrawEdge(m_rectClose,EDGE_RAISED,BF_RECT);
  702.     if(!(m_rectUndock.PtInRect(point)) && !IsFloating())
  703. dc.DrawEdge(m_rectUndock,EDGE_RAISED,BF_RECT);
  704. CControlBar::OnNcMouseMove(nHitTest, point);
  705. }
  706. void CSizingControlBar::ShowContrl(BOOL m_show)
  707. {
  708. if(m_show)
  709. ShowWindow(SW_SHOWNORMAL);
  710. else
  711. ShowWindow(SW_HIDE);
  712. }
  713. void CSizingControlBar::SetStatusText(UINT nID)
  714. {  
  715. if(nID==0)//HTSYSMENU
  716.         nID=AFX_IDS_IDLEMESSAGE;
  717.     CWnd *pWnd=AfxGetMainWnd()->GetDescendantWindow(AFX_IDW_STATUS_BAR);
  718.     if(pWnd)  
  719. {     
  720. AfxGetMainWnd()->SendMessage(WM_SETMESSAGESTRING ,nID);
  721.     pWnd->SendMessage(WM_IDLEUPDATECMDUI);
  722.         pWnd->UpdateWindow();
  723.     }
  724. }
  725. BOOL CSizingControlBar::OnTipNotify( UINT id, NMHDR * pNMHDR, LRESULT * pResult )
  726. {
  727. TOOLTIPTEXT *pTTT = (TOOLTIPTEXT *)pNMHDR; 
  728. UINT nID =pNMHDR->idFrom;
  729.     if (pTTT->uFlags & TTF_IDISHWND)
  730.     {
  731.         nID = ::GetDlgCtrlID((HWND)nID);  
  732. if(nID)
  733.         {
  734. CString szFullText;
  735. CString StrTipText;
  736. szFullText.LoadString(nID);
  737. AfxExtractSubString(StrTipText,szFullText,1,'n');   
  738. if(!StrTipText.IsEmpty())
  739.  strcpy(pTTT->lpszText,StrTipText);
  740. pTTT->hinst = AfxGetResourceHandle(); 
  741. return(TRUE);
  742.         }  
  743. }   
  744. return FALSE;
  745. }