sizecbar.cpp
上传用户:popouu88
上传日期:2013-02-11
资源大小:2894k
文件大小:41k
源码类别:

IP电话/视频会议

开发平台:

Visual C++

  1. // sizecbar.cpp : implementation file
  2. //
  3. #include "../stdafx.h"
  4. #include "sizecbar.h"
  5. #ifdef _DEBUG
  6. #define new DEBUG_NEW
  7. #undef THIS_FILE
  8. static char THIS_FILE[] = __FILE__;
  9. #endif
  10. /////////////////////////////////////////////////////////////////////////
  11. // CSizingControlBar
  12. IMPLEMENT_DYNAMIC(CSizingControlBar, baseCSizingControlBar);
  13. CSizingControlBar::CSizingControlBar()
  14. {
  15.     m_szMinHorz = CSize(33, 32);
  16.     m_szMinVert = CSize(33, 32);
  17.     m_szMinFloat = CSize(37, 32);
  18.     m_szHorz = CSize(200, 200);
  19.     m_szVert = CSize(200, 200);
  20.     m_szFloat = CSize(200, 200);
  21.     m_bTracking = FALSE;
  22.     m_bKeepSize = FALSE;
  23.     m_bParentSizing = FALSE;
  24.     m_cxEdge = 5;
  25.     m_bDragShowContent = FALSE;
  26.     m_nDockBarID = 0;
  27.     m_dwSCBStyle = 0;
  28. }
  29. CSizingControlBar::~CSizingControlBar()
  30. {
  31. }
  32. BEGIN_MESSAGE_MAP(CSizingControlBar, baseCSizingControlBar)
  33.     //{{AFX_MSG_MAP(CSizingControlBar)
  34.     ON_WM_CREATE()
  35.     ON_WM_NCPAINT()
  36.     ON_WM_NCCALCSIZE()
  37.     ON_WM_NCHITTEST()
  38.     ON_WM_CAPTURECHANGED()
  39.     ON_WM_SETTINGCHANGE()
  40.     ON_WM_LBUTTONUP()
  41.     ON_WM_MOUSEMOVE()
  42.     ON_WM_NCLBUTTONDOWN()
  43.     ON_WM_LBUTTONDOWN()
  44.     ON_WM_LBUTTONDBLCLK()
  45.     ON_WM_RBUTTONDOWN()
  46.     ON_WM_WINDOWPOSCHANGING()
  47.     ON_WM_PAINT()
  48.     ON_WM_CLOSE()
  49.     ON_WM_SIZE()
  50.     ON_WM_NCMOUSEMOVE()
  51. //}}AFX_MSG_MAP
  52.     ON_MESSAGE(WM_SETTEXT, OnSetText)
  53. END_MESSAGE_MAP()
  54. // old creation method, still here for compatibility reasons
  55. BOOL CSizingControlBar::Create(LPCTSTR lpszWindowName, CWnd* pParentWnd,
  56.                                CSize sizeDefault, BOOL bHasGripper,
  57.                                UINT nID, DWORD dwStyle)
  58. {
  59.     UNUSED_ALWAYS(bHasGripper);
  60.     m_szHorz = m_szVert = m_szFloat = sizeDefault;
  61.     return Create(lpszWindowName, pParentWnd, nID, dwStyle);
  62. }
  63. // preffered creation method
  64. BOOL CSizingControlBar::Create(LPCTSTR lpszWindowName,
  65.                                CWnd* pParentWnd, UINT nID,
  66.                                DWORD dwStyle)
  67. {
  68.     // must have a parent
  69.     ASSERT_VALID(pParentWnd);
  70.     // cannot be both fixed and dynamic
  71.     // (CBRS_SIZE_DYNAMIC is used for resizng when floating)
  72.     ASSERT (!((dwStyle & CBRS_SIZE_FIXED) &&
  73.               (dwStyle & CBRS_SIZE_DYNAMIC)));
  74.     m_dwStyle = dwStyle & CBRS_ALL; // save the control bar styles
  75.     // register and create the window - skip CControlBar::Create()
  76.     CString wndclass = ::AfxRegisterWndClass(CS_DBLCLKS,
  77.         ::LoadCursor(NULL, IDC_ARROW),
  78.         /* ::GetSysColorBrush(COLOR_BTNFACE) */ ::CreateSolidBrush( RGB( 90 , 150 , 206 ) ) , 0);
  79.     dwStyle &= ~CBRS_ALL; // keep only the generic window styles
  80.     dwStyle |= WS_CLIPCHILDREN; // prevents flashing
  81.     if (!CWnd::Create(wndclass, lpszWindowName, dwStyle,
  82.         CRect(0, 0, 0, 0), pParentWnd, nID))
  83.         return FALSE;
  84.     return TRUE;
  85. }
  86. /////////////////////////////////////////////////////////////////////////
  87. // CSizingControlBar operations
  88. #if defined(_SCB_REPLACE_MINIFRAME) && !defined(_SCB_MINIFRAME_CAPTION)
  89. void CSizingControlBar::EnableDocking(DWORD dwDockStyle)
  90. {
  91.     // must be CBRS_ALIGN_XXX or CBRS_FLOAT_MULTI only
  92.     ASSERT((dwDockStyle & ~(CBRS_ALIGN_ANY|CBRS_FLOAT_MULTI)) == 0);
  93.     // cannot have the CBRS_FLOAT_MULTI style
  94.     ASSERT((dwDockStyle & CBRS_FLOAT_MULTI) == 0);
  95.     // the bar must have CBRS_SIZE_DYNAMIC style
  96.     ASSERT((m_dwStyle & CBRS_SIZE_DYNAMIC) != 0);
  97.     m_dwDockStyle = dwDockStyle;
  98.     if (m_pDockContext == NULL)
  99.         m_pDockContext = new CSCBDockContext(this);
  100.     // permanently wire the bar's owner to its current parent
  101.     if (m_hWndOwner == NULL)
  102.         m_hWndOwner = ::GetParent(m_hWnd);
  103. }
  104. #endif
  105. /////////////////////////////////////////////////////////////////////////
  106. // CSizingControlBar message handlers
  107. int CSizingControlBar::OnCreate(LPCREATESTRUCT lpCreateStruct) 
  108. {
  109.     if (baseCSizingControlBar::OnCreate(lpCreateStruct) == -1)
  110.         return -1;
  111.     // query SPI_GETDRAGFULLWINDOWS system parameter
  112.     // OnSettingChange() will update m_bDragShowContent
  113.     m_bDragShowContent = FALSE;
  114.     ::SystemParametersInfo(SPI_GETDRAGFULLWINDOWS, 0,
  115.         &m_bDragShowContent, 0);
  116.     // uncomment this line if you want raised borders
  117. //    m_dwSCBStyle |= SCBS_SHOWEDGES;
  118.     return 0;
  119. }
  120. LRESULT CSizingControlBar::OnSetText(WPARAM wParam, LPARAM lParam)
  121. {
  122.     UNUSED_ALWAYS(wParam);
  123.     LRESULT lResult = CWnd::Default();
  124.     if (IsFloating() &&
  125.         GetParentFrame()->IsKindOf(RUNTIME_CLASS(CMiniDockFrameWnd)))
  126.     {
  127.         m_pDockBar->SetWindowText((LPCTSTR) lParam); // update dockbar
  128.         GetParentFrame()->DelayRecalcLayout(); // refresh miniframe
  129.     }
  130.     return lResult;
  131. }
  132. const BOOL CSizingControlBar::IsFloating() const
  133. {
  134.     return !IsHorzDocked() && !IsVertDocked();
  135. }
  136. const BOOL CSizingControlBar::IsHorzDocked() const
  137. {
  138.     return (m_nDockBarID == AFX_IDW_DOCKBAR_TOP ||
  139.         m_nDockBarID == AFX_IDW_DOCKBAR_BOTTOM);
  140. }
  141. const BOOL CSizingControlBar::IsVertDocked() const
  142. {
  143.     return (m_nDockBarID == AFX_IDW_DOCKBAR_LEFT ||
  144.         m_nDockBarID == AFX_IDW_DOCKBAR_RIGHT);
  145. }
  146. const BOOL CSizingControlBar::IsSideTracking() const
  147. {
  148.     // don't call this when not tracking
  149.     ASSERT(m_bTracking && !IsFloating());
  150.     return (m_htEdge == HTLEFT || m_htEdge == HTRIGHT) ?
  151.         IsHorzDocked() : IsVertDocked();
  152. }
  153. CSize CSizingControlBar::CalcFixedLayout(BOOL bStretch, BOOL bHorz)
  154. {
  155.     if (bStretch) // the bar is stretched (is not the child of a dockbar)
  156.         if (bHorz)
  157.             return CSize(32767, m_szHorz.cy);
  158.         else
  159.             return CSize(m_szVert.cx, 32767);
  160.     // dirty cast - we need access to protected CDockBar members
  161.     CSCBDockBar* pDockBar = (CSCBDockBar*) m_pDockBar;
  162.     // force imediate RecalcDelayShow() for all sizing bars on the row
  163.     // with delayShow/delayHide flags set to avoid IsVisible() problems
  164.     CSCBArray arrSCBars;
  165.     GetRowSizingBars(arrSCBars);
  166.     AFX_SIZEPARENTPARAMS layout;
  167.     layout.hDWP = pDockBar->m_bLayoutQuery ?
  168.         NULL : ::BeginDeferWindowPos(arrSCBars.GetSize());
  169.     for (int i = 0; i < arrSCBars.GetSize(); i++)
  170.         if (arrSCBars[i]->m_nStateFlags & (delayHide|delayShow))
  171.             arrSCBars[i]->RecalcDelayShow(&layout);
  172.     if (layout.hDWP != NULL)
  173.         ::EndDeferWindowPos(layout.hDWP);
  174.     // get available length
  175.     CRect rc = pDockBar->m_rectLayout;
  176.     if (rc.IsRectEmpty())
  177.         m_pDockSite->GetClientRect(&rc);
  178.     int nLengthTotal = bHorz ? rc.Width() + 2 : rc.Height() - 2;
  179.     if (IsVisible() && !IsFloating() &&
  180.         m_bParentSizing && arrSCBars[0] == this)
  181.         if (NegotiateSpace(nLengthTotal, (bHorz != FALSE)))
  182.             AlignControlBars();
  183.     m_bParentSizing = FALSE;
  184.     if (bHorz)
  185.         return CSize(max(m_szMinHorz.cx, m_szHorz.cx),
  186.                      max(m_szMinHorz.cy, m_szHorz.cy));
  187.     return CSize(max(m_szMinVert.cx, m_szVert.cx),
  188.                  max(m_szMinVert.cy, m_szVert.cy));
  189. }
  190. CSize CSizingControlBar::CalcDynamicLayout(int nLength, DWORD dwMode)
  191. {
  192.     if (dwMode & (LM_HORZDOCK | LM_VERTDOCK)) // docked ?
  193.     {
  194.         if (nLength == -1)
  195.             m_bParentSizing = TRUE;
  196.         return baseCSizingControlBar::CalcDynamicLayout(nLength, dwMode);
  197.     }
  198.     if (dwMode & LM_MRUWIDTH) return m_szFloat;
  199.     if (dwMode & LM_COMMIT) return m_szFloat; // already committed
  200. #ifndef _SCB_REPLACE_MINIFRAME
  201.     // check for dialgonal resizing hit test
  202.     int nHitTest = m_pDockContext->m_nHitTest;
  203.     if (IsFloating() &&
  204.         (nHitTest == HTTOPLEFT || nHitTest == HTBOTTOMLEFT ||
  205.         nHitTest == HTTOPRIGHT || nHitTest == HTBOTTOMRIGHT))
  206.     {
  207.         CPoint ptCursor;
  208.         ::GetCursorPos(&ptCursor);
  209.         CRect rFrame, rBar;
  210.         GetParentFrame()->GetWindowRect(&rFrame);
  211.         GetWindowRect(&rBar);
  212.         
  213.         if (nHitTest == HTTOPLEFT || nHitTest == HTBOTTOMLEFT)
  214.         {
  215.             m_szFloat.cx = rFrame.left + rBar.Width() - ptCursor.x;
  216.             m_pDockContext->m_rectFrameDragHorz.left = 
  217.                 min(ptCursor.x, rFrame.left + rBar.Width() - m_szMinFloat.cx);
  218.         }
  219.         if (nHitTest == HTTOPLEFT || nHitTest == HTTOPRIGHT)
  220.         {
  221.             m_szFloat.cy = rFrame.top + rBar.Height() - ptCursor.y;
  222.             m_pDockContext->m_rectFrameDragHorz.top =
  223.                 min(ptCursor.y, rFrame.top + rBar.Height() - m_szMinFloat.cy);
  224.         }
  225.         if (nHitTest == HTTOPRIGHT || nHitTest == HTBOTTOMRIGHT)
  226.             m_szFloat.cx = rBar.Width() + ptCursor.x - rFrame.right;
  227.         if (nHitTest == HTBOTTOMLEFT || nHitTest == HTBOTTOMRIGHT)
  228.             m_szFloat.cy = rBar.Height() + ptCursor.y - rFrame.bottom;
  229.     }
  230.     else
  231. #endif //_SCB_REPLACE_MINIFRAME
  232.         ((dwMode & LM_LENGTHY) ? m_szFloat.cy : m_szFloat.cx) = nLength;
  233.     m_szFloat.cx = max(m_szFloat.cx, m_szMinFloat.cx);
  234.     m_szFloat.cy = max(m_szFloat.cy, m_szMinFloat.cy);
  235.     return m_szFloat;
  236. }
  237. void CSizingControlBar::OnWindowPosChanging(WINDOWPOS FAR* lpwndpos)
  238. {
  239.     // force non-client recalc if moved or resized
  240.     lpwndpos->flags |= SWP_FRAMECHANGED;
  241.     baseCSizingControlBar::OnWindowPosChanging(lpwndpos);
  242.     // find on which side are we docked
  243.     m_nDockBarID = GetParent()->GetDlgCtrlID();
  244.     if (!IsFloating())
  245.         if (lpwndpos->flags & SWP_SHOWWINDOW)
  246.             m_bKeepSize = TRUE;
  247. }
  248. /////////////////////////////////////////////////////////////////////////
  249. // Mouse Handling
  250. //
  251. void CSizingControlBar::OnLButtonDown(UINT nFlags, CPoint point)
  252. {
  253.     if (m_pDockBar != NULL)
  254.     {
  255.         // start the drag
  256.         ASSERT(m_pDockContext != NULL);
  257.         ClientToScreen(&point);
  258.         m_pDockContext->StartDrag(point);
  259.     }
  260.     else
  261.         CWnd::OnLButtonDown(nFlags, point);
  262. }
  263. void CSizingControlBar::OnLButtonDblClk(UINT nFlags, CPoint point)
  264. {
  265.     if (m_pDockBar != NULL)
  266.     {
  267.         // toggle docking
  268.         ASSERT(m_pDockContext != NULL);
  269.         m_pDockContext->ToggleDocking();
  270.     }
  271.     else
  272.         CWnd::OnLButtonDblClk(nFlags, point);
  273. }
  274. void CSizingControlBar::OnNcLButtonDown(UINT nHitTest, CPoint point) 
  275. {
  276.     UNUSED_ALWAYS(point);
  277.     if (m_bTracking || IsFloating())
  278.         return;
  279.     if ((nHitTest >= HTSIZEFIRST) && (nHitTest <= HTSIZELAST))
  280.         StartTracking(nHitTest, point); // sizing edge hit
  281. }
  282. void CSizingControlBar::OnLButtonUp(UINT nFlags, CPoint point)
  283. {
  284.     if (m_bTracking)
  285.         StopTracking();
  286.     baseCSizingControlBar::OnLButtonUp(nFlags, point);
  287. }
  288. void CSizingControlBar::OnRButtonDown(UINT nFlags, CPoint point)
  289. {
  290.     if (m_bTracking)
  291.         StopTracking();
  292.     baseCSizingControlBar::OnRButtonDown(nFlags, point);
  293. }
  294. void CSizingControlBar::OnMouseMove(UINT nFlags, CPoint point)
  295. {
  296.     if (m_bTracking)
  297.     {
  298.         CPoint ptScreen = point;
  299.         ClientToScreen(&ptScreen);
  300.         OnTrackUpdateSize(ptScreen);
  301.     }
  302.     baseCSizingControlBar::OnMouseMove(nFlags, point);
  303. }
  304. void CSizingControlBar::OnCaptureChanged(CWnd *pWnd)
  305. {
  306.     if (m_bTracking && (pWnd != this))
  307.         StopTracking();
  308.     baseCSizingControlBar::OnCaptureChanged(pWnd);
  309. }
  310. void CSizingControlBar::OnNcCalcSize(BOOL bCalcValidRects,
  311.                                      NCCALCSIZE_PARAMS FAR* lpncsp)
  312. {
  313.     UNUSED_ALWAYS(bCalcValidRects);
  314. #ifndef _SCB_REPLACE_MINIFRAME
  315.     // Enable diagonal resizing for floating miniframe
  316.     if (IsFloating())
  317.     {
  318.         CFrameWnd* pFrame = GetParentFrame();
  319.         if (pFrame != NULL &&
  320.             pFrame->IsKindOf(RUNTIME_CLASS(CMiniFrameWnd)))
  321.         {
  322.             DWORD dwStyle = ::GetWindowLong(pFrame->m_hWnd, GWL_STYLE);
  323.             if ((dwStyle & MFS_4THICKFRAME) != 0)
  324.             {   //系统菜单
  325.                 pFrame->ModifyStyle( WS_SYSMENU | MFS_4THICKFRAME, 0); // clear
  326.                 GetParent()->ModifyStyle(0, WS_CLIPCHILDREN);
  327.             }
  328.         }
  329.     }
  330. #endif _SCB_REPLACE_MINIFRAME
  331.     // compute the the client area
  332.     m_dwSCBStyle &= ~SCBS_EDGEALL;
  333.     // add resizing edges between bars on the same row
  334.     if (!IsFloating() && m_pDockBar != NULL)
  335.     {
  336.         CSCBArray arrSCBars;
  337.         int nThis;
  338.         GetRowSizingBars(arrSCBars, nThis);
  339.         BOOL bHorz = IsHorzDocked();
  340.         if (nThis > 0)
  341.             m_dwSCBStyle |= bHorz ? SCBS_EDGELEFT : SCBS_EDGETOP;
  342.         if (nThis < arrSCBars.GetUpperBound())
  343.             m_dwSCBStyle |= bHorz ? SCBS_EDGERIGHT : SCBS_EDGEBOTTOM;
  344.     }
  345.     NcCalcClient(&lpncsp->rgrc[0], m_nDockBarID);
  346. }
  347. void CSizingControlBar::NcCalcClient(LPRECT pRc, UINT nDockBarID)
  348. {
  349.     CRect rc(pRc);
  350.     rc.DeflateRect(3, 5, 3, 3);
  351.     if (nDockBarID != AFX_IDW_DOCKBAR_FLOAT)
  352.         rc.DeflateRect(2, 0, 2, 2);
  353.     switch(nDockBarID)
  354.     {
  355.     case AFX_IDW_DOCKBAR_TOP:
  356.         m_dwSCBStyle |= SCBS_EDGEBOTTOM;
  357.         break;
  358.     case AFX_IDW_DOCKBAR_BOTTOM:
  359.         m_dwSCBStyle |= SCBS_EDGETOP;
  360.         break;
  361.     case AFX_IDW_DOCKBAR_LEFT:
  362.         m_dwSCBStyle |= SCBS_EDGERIGHT;
  363.         break;
  364.     case AFX_IDW_DOCKBAR_RIGHT:
  365.         m_dwSCBStyle |= SCBS_EDGELEFT;
  366.         break;
  367.     }
  368.     // make room for edges only if they will be painted
  369.     if (m_dwSCBStyle & SCBS_SHOWEDGES)
  370.         rc.DeflateRect(
  371.             (m_dwSCBStyle & SCBS_EDGELEFT) ? m_cxEdge : 0,
  372.             (m_dwSCBStyle & SCBS_EDGETOP) ? m_cxEdge : 0,
  373.             (m_dwSCBStyle & SCBS_EDGERIGHT) ? m_cxEdge : 0,
  374.             (m_dwSCBStyle & SCBS_EDGEBOTTOM) ? m_cxEdge : 0);
  375.     *pRc = rc;
  376. }
  377. void CSizingControlBar::OnNcPaint()
  378. {
  379.     // get window DC that is clipped to the non-client area
  380.     CWindowDC dc(this);
  381.     CRect rcClient, rcBar;
  382.     GetClientRect(rcClient);
  383.     ClientToScreen(rcClient);
  384.     GetWindowRect(rcBar);
  385.     rcClient.OffsetRect(-rcBar.TopLeft());
  386.     rcBar.OffsetRect(-rcBar.TopLeft());
  387.     CDC mdc;
  388.     mdc.CreateCompatibleDC(&dc);
  389.     
  390.     CBitmap bm;
  391.     bm.CreateCompatibleBitmap(&dc, rcBar.Width(), rcBar.Height());
  392.     CBitmap* pOldBm = mdc.SelectObject(&bm);
  393.     // draw borders in non-client area
  394.     CRect rcDraw = rcBar;
  395.     DrawBorders(&mdc, rcDraw);
  396.     // erase the NC background
  397.     mdc.FillRect(rcDraw, CBrush::FromHandle(
  398.         (HBRUSH) GetClassLong(m_hWnd, GCL_HBRBACKGROUND)));
  399.     if (m_dwSCBStyle & SCBS_SHOWEDGES)
  400.     {
  401.         CRect rcEdge; // paint the sizing edges
  402.         for (int i = 0; i < 4; i++)
  403.             if (GetEdgeRect(rcBar, GetEdgeHTCode(i), rcEdge))
  404.                 mdc.Draw3dRect(rcEdge, ::GetSysColor(COLOR_BTNHIGHLIGHT),
  405.                     ::GetSysColor(COLOR_BTNSHADOW));
  406.     }
  407.     NcPaintGripper(&mdc, rcClient);
  408.     // client area is not our bussiness :)
  409.     dc.IntersectClipRect(rcBar);
  410.     dc.ExcludeClipRect(rcClient);
  411.     dc.BitBlt(0, 0, rcBar.Width(), rcBar.Height(), &mdc, 0, 0, SRCCOPY);
  412.     ReleaseDC(&dc);
  413.     mdc.SelectObject(pOldBm);
  414.     bm.DeleteObject();
  415.     mdc.DeleteDC();
  416. }
  417. void CSizingControlBar::NcPaintGripper(CDC* pDC, CRect rcClient)
  418. {
  419.     UNUSED_ALWAYS(pDC);
  420.     UNUSED_ALWAYS(rcClient);
  421. }
  422. void CSizingControlBar::OnPaint()
  423. {
  424.     // overridden to skip border painting based on clientrect
  425.     CPaintDC dc(this);
  426. }
  427. UINT CSizingControlBar::OnNcHitTest(CPoint point)
  428. {
  429.     CRect rcBar, rcEdge;
  430.     GetWindowRect(rcBar);
  431.     if (!IsFloating())
  432.         for (int i = 0; i < 4; i++)
  433.             if (GetEdgeRect(rcBar, GetEdgeHTCode(i), rcEdge))
  434.                 if (rcEdge.PtInRect(point))
  435.                     return GetEdgeHTCode(i);
  436.     return HTCLIENT;
  437. }
  438. void CSizingControlBar::OnSettingChange(UINT uFlags, LPCTSTR lpszSection)
  439. {
  440.     baseCSizingControlBar::OnSettingChange(uFlags, lpszSection);
  441.     m_bDragShowContent = FALSE;
  442.     ::SystemParametersInfo(SPI_GETDRAGFULLWINDOWS, 0,
  443.         &m_bDragShowContent, 0); // update
  444. }
  445. void CSizingControlBar::OnSize(UINT nType, int cx, int cy)
  446. {
  447.     UNUSED_ALWAYS(nType);
  448.     
  449.     if ((m_dwSCBStyle & SCBS_SIZECHILD) != 0)
  450.     {
  451.         // automatic child resizing - only one child is allowed
  452.         CWnd* pWnd = GetWindow(GW_CHILD);
  453.         if (pWnd != NULL)
  454.         {
  455.             pWnd->MoveWindow(0, 0, cx, cy);
  456.             ASSERT(pWnd->GetWindow(GW_HWNDNEXT) == NULL);
  457.         }
  458.     }
  459. }
  460. void CSizingControlBar::OnClose()
  461. {
  462.     // do nothing: protection against accidentally destruction by the
  463.     //   child control (i.e. if user hits Esc in a child editctrl)
  464. }
  465. /////////////////////////////////////////////////////////////////////////
  466. // CSizingControlBar implementation helpers
  467. void CSizingControlBar::StartTracking(UINT nHitTest, CPoint point)
  468. {
  469.     SetCapture();
  470.     // make sure no updates are pending
  471.     if (!m_bDragShowContent)
  472.         RedrawWindow(NULL, NULL, RDW_ALLCHILDREN | RDW_UPDATENOW);
  473.     m_htEdge = nHitTest;
  474.     m_bTracking = TRUE;
  475.     BOOL bHorz = IsHorzDocked();
  476.     BOOL bHorzTracking = m_htEdge == HTLEFT || m_htEdge == HTRIGHT;
  477.     m_nTrackPosOld = bHorzTracking ? point.x : point.y;
  478.     CRect rcBar, rcEdge;
  479.     GetWindowRect(rcBar);
  480.     GetEdgeRect(rcBar, m_htEdge, rcEdge);
  481.     m_nTrackEdgeOfs = m_nTrackPosOld -
  482.         (bHorzTracking ? rcEdge.CenterPoint().x : rcEdge.CenterPoint().y);
  483.     
  484.     CSCBArray arrSCBars;
  485.     int nThis;
  486.     GetRowSizingBars(arrSCBars, nThis);
  487.     m_nTrackPosMin = m_nTrackPosMax = m_nTrackPosOld;
  488.     if (!IsSideTracking())
  489.     {
  490.         // calc minwidth as the max minwidth of the sizing bars on row
  491.         int nMinWidth = bHorz ? m_szMinHorz.cy : m_szMinVert.cx;
  492.         for (int i = 0; i < arrSCBars.GetSize(); i++)
  493.             nMinWidth = max(nMinWidth, bHorz ? 
  494.                 arrSCBars[i]->m_szMinHorz.cy :
  495.                 arrSCBars[i]->m_szMinVert.cx);
  496.         int nExcessWidth = (bHorz ? m_szHorz.cy : m_szVert.cx) - nMinWidth;
  497.         // the control bar cannot grow with more than the width of
  498.         // remaining client area of the mainframe
  499.         CRect rcT;
  500.         m_pDockSite->RepositionBars(0, 0xFFFF, AFX_IDW_PANE_FIRST,
  501.             reposQuery, &rcT, NULL, TRUE);
  502.         int nMaxWidth = bHorz ? rcT.Height() - 2 : rcT.Width() - 2;
  503.         BOOL bTopOrLeft = m_htEdge == HTTOP || m_htEdge == HTLEFT;
  504.         m_nTrackPosMin -= bTopOrLeft ? nMaxWidth : nExcessWidth;
  505.         m_nTrackPosMax += bTopOrLeft ? nExcessWidth : nMaxWidth;
  506.     }
  507.     else
  508.     {
  509.         // side tracking:
  510.         // max size is the actual size plus the amount the other
  511.         // sizing bars can be decreased until they reach their minsize
  512.         if (m_htEdge == HTBOTTOM || m_htEdge == HTRIGHT)
  513.             nThis++;
  514.         for (int i = 0; i < arrSCBars.GetSize(); i++)
  515.         {
  516.             CSizingControlBar* pBar = arrSCBars[i];
  517.             int nExcessWidth = bHorz ? 
  518.                 pBar->m_szHorz.cx - pBar->m_szMinHorz.cx :
  519.                 pBar->m_szVert.cy - pBar->m_szMinVert.cy;
  520.             if (i < nThis)
  521.                 m_nTrackPosMin -= nExcessWidth;
  522.             else
  523.                 m_nTrackPosMax += nExcessWidth;
  524.         }
  525.     }
  526.     OnTrackInvertTracker(); // draw tracker
  527. }
  528. void CSizingControlBar::StopTracking()
  529. {
  530.     OnTrackInvertTracker(); // erase tracker
  531.     m_bTracking = FALSE;
  532.     ReleaseCapture();
  533.     m_pDockSite->DelayRecalcLayout();
  534.     //新增项目
  535. ( ( CFrameWnd * )this->GetParent( )->GetParent( ) )->RecalcLayout( );
  536. }
  537. void CSizingControlBar::OnTrackUpdateSize(CPoint& point)
  538. {
  539.     ASSERT(!IsFloating());
  540.     BOOL bHorzTrack = m_htEdge == HTLEFT || m_htEdge == HTRIGHT;
  541.     int nTrackPos = bHorzTrack ? point.x : point.y;
  542.     nTrackPos = max(m_nTrackPosMin, min(m_nTrackPosMax, nTrackPos));
  543.     int nDelta = nTrackPos - m_nTrackPosOld;
  544.     if (nDelta == 0)
  545.         return; // no pos change
  546.     OnTrackInvertTracker(); // erase tracker
  547.     m_nTrackPosOld = nTrackPos;
  548.     
  549.     BOOL bHorz = IsHorzDocked();
  550.     CSize sizeNew = bHorz ? m_szHorz : m_szVert;
  551.     switch (m_htEdge)
  552.     {
  553.     case HTLEFT:    sizeNew -= CSize(nDelta, 0); break;
  554.     case HTTOP:     sizeNew -= CSize(0, nDelta); break;
  555.     case HTRIGHT:   sizeNew += CSize(nDelta, 0); break;
  556.     case HTBOTTOM:  sizeNew += CSize(0, nDelta); break;
  557.     }
  558.     CSCBArray arrSCBars;
  559.     int nThis;
  560.     GetRowSizingBars(arrSCBars, nThis);
  561.     if (!IsSideTracking())
  562.         for (int i = 0; i < arrSCBars.GetSize(); i++)
  563.         {
  564.             CSizingControlBar* pBar = arrSCBars[i];
  565.             // make same width (or height)
  566.             (bHorz ? pBar->m_szHorz.cy : pBar->m_szVert.cx) =
  567.                 bHorz ? sizeNew.cy : sizeNew.cx;
  568.         }
  569.     else
  570.     {
  571.         int nGrowingBar = nThis;
  572.         BOOL bBefore = m_htEdge == HTTOP || m_htEdge == HTLEFT;
  573.         if (bBefore && nDelta > 0)
  574.             nGrowingBar--;
  575.         if (!bBefore && nDelta < 0)
  576.             nGrowingBar++;
  577.         if (nGrowingBar != nThis)
  578.             bBefore = !bBefore;
  579.         // nGrowing is growing
  580.         nDelta = abs(nDelta);
  581.         CSizingControlBar* pBar = arrSCBars[nGrowingBar];
  582.         (bHorz ? pBar->m_szHorz.cx : pBar->m_szVert.cy) += nDelta;
  583.         // the others are shrinking
  584.         int nFirst = bBefore ? nGrowingBar - 1 : nGrowingBar + 1;
  585.         int nLimit = bBefore ? -1 : arrSCBars.GetSize();
  586.         for (int i = nFirst; nDelta != 0 && i != nLimit; i += (bBefore ? -1 : 1))
  587.         {
  588.             CSizingControlBar* pBar = arrSCBars[i];
  589.                 
  590.             int nDeltaT = min(nDelta,
  591.                 (bHorz ? pBar->m_szHorz.cx : pBar->m_szVert.cy) -
  592.                 (bHorz ? pBar->m_szMinHorz.cx : pBar->m_szMinVert.cy));
  593.             (bHorz ? pBar->m_szHorz.cx : pBar->m_szVert.cy) -= nDeltaT;
  594.             nDelta -= nDeltaT;
  595.         }
  596.     }
  597.     OnTrackInvertTracker(); // redraw tracker at new pos
  598.     if (m_bDragShowContent)
  599.         m_pDockSite->DelayRecalcLayout();
  600. }
  601. void CSizingControlBar::OnTrackInvertTracker()
  602. {
  603.     ASSERT(m_bTracking);
  604.     if (m_bDragShowContent)
  605.         return; // don't show tracker if DragFullWindows is on
  606.     BOOL bHorz = IsHorzDocked();
  607.     CRect rc, rcBar, rcDock, rcFrame;
  608.     GetWindowRect(rcBar);
  609.     m_pDockBar->GetWindowRect(rcDock);
  610.     m_pDockSite->GetWindowRect(rcFrame);
  611.     VERIFY(GetEdgeRect(rcBar, m_htEdge, rc));
  612.     if (!IsSideTracking())
  613.         rc = bHorz ? 
  614.             CRect(rcDock.left + 1, rc.top, rcDock.right - 1, rc.bottom) :
  615.             CRect(rc.left, rcDock.top + 1, rc.right, rcDock.bottom - 1);
  616.     BOOL bHorzTracking = m_htEdge == HTLEFT || m_htEdge == HTRIGHT;
  617.     int nOfs = m_nTrackPosOld - m_nTrackEdgeOfs;
  618.     nOfs -= bHorzTracking ? rc.CenterPoint().x : rc.CenterPoint().y;
  619.     rc.OffsetRect(bHorzTracking ? nOfs : 0, bHorzTracking ? 0 : nOfs);
  620.     rc.OffsetRect(-rcFrame.TopLeft());
  621.     CDC *pDC = m_pDockSite->GetDCEx(NULL,
  622.         DCX_WINDOW | DCX_CACHE | DCX_LOCKWINDOWUPDATE);
  623.     CBrush* pBrush = CDC::GetHalftoneBrush();
  624.     CBrush* pBrushOld = pDC->SelectObject(pBrush);
  625.     pDC->PatBlt(rc.left, rc.top, rc.Width(), rc.Height(), PATINVERT);
  626.     
  627.     pDC->SelectObject(pBrushOld);
  628.     m_pDockSite->ReleaseDC(pDC);
  629. }
  630. BOOL CSizingControlBar::GetEdgeRect(CRect rcWnd, UINT nHitTest,
  631.                                     CRect& rcEdge)
  632. {
  633.     rcEdge = rcWnd;
  634.     if (m_dwSCBStyle & SCBS_SHOWEDGES)
  635.         rcEdge.DeflateRect(1, 1);
  636.     BOOL bHorz = IsHorzDocked();
  637.     switch (nHitTest)
  638.     {
  639.     case HTLEFT:
  640.         if (!(m_dwSCBStyle & SCBS_EDGELEFT)) return FALSE;
  641.         rcEdge.right = rcEdge.left + m_cxEdge;
  642.         rcEdge.DeflateRect(0, bHorz ? m_cxEdge: 0);
  643.         break;
  644.     case HTTOP:
  645.         if (!(m_dwSCBStyle & SCBS_EDGETOP)) return FALSE;
  646.         rcEdge.bottom = rcEdge.top + m_cxEdge;
  647.         rcEdge.DeflateRect(bHorz ? 0 : m_cxEdge, 0);
  648.         break;
  649.     case HTRIGHT:
  650.         if (!(m_dwSCBStyle & SCBS_EDGERIGHT)) return FALSE;
  651.         rcEdge.left = rcEdge.right - m_cxEdge;
  652.         rcEdge.DeflateRect(0, bHorz ? m_cxEdge: 0);
  653.         break;
  654.     case HTBOTTOM:
  655.         if (!(m_dwSCBStyle & SCBS_EDGEBOTTOM)) return FALSE;
  656.         rcEdge.top = rcEdge.bottom - m_cxEdge;
  657.         rcEdge.DeflateRect(bHorz ? 0 : m_cxEdge, 0);
  658.         break;
  659.     default:
  660.         ASSERT(FALSE); // invalid hit test code
  661.     }
  662.     return TRUE;
  663. }
  664. UINT CSizingControlBar::GetEdgeHTCode(int nEdge)
  665. {
  666.     if (nEdge == 0) return HTLEFT;
  667.     if (nEdge == 1) return HTTOP;
  668.     if (nEdge == 2) return HTRIGHT;
  669.     if (nEdge == 3) return HTBOTTOM;
  670.     ASSERT(FALSE); // invalid edge code
  671.     return HTNOWHERE;
  672. }
  673. void CSizingControlBar::GetRowInfo(int& nFirst, int& nLast, int& nThis)
  674. {
  675.     ASSERT_VALID(m_pDockBar); // verify bounds
  676.     nThis = m_pDockBar->FindBar(this);
  677.     ASSERT(nThis != -1);
  678.     int i, nBars = m_pDockBar->m_arrBars.GetSize();
  679.     // find the first and the last bar in row
  680.     for (nFirst = -1, i = nThis - 1; i >= 0 && nFirst == -1; i--)
  681.         if (m_pDockBar->m_arrBars[i] == NULL)
  682.             nFirst = i + 1;
  683.     for (nLast = -1, i = nThis + 1; i < nBars && nLast == -1; i++)
  684.         if (m_pDockBar->m_arrBars[i] == NULL)
  685.             nLast = i - 1;
  686.     ASSERT((nLast != -1) && (nFirst != -1));
  687. }
  688. void CSizingControlBar::GetRowSizingBars(CSCBArray& arrSCBars)
  689. {
  690.     int nThis; // dummy
  691.     GetRowSizingBars(arrSCBars, nThis);
  692. }
  693. void CSizingControlBar::GetRowSizingBars(CSCBArray& arrSCBars, int& nThis)
  694. {
  695.     arrSCBars.RemoveAll();
  696.     int nFirstT, nLastT, nThisT;
  697.     GetRowInfo(nFirstT, nLastT, nThisT);
  698.     nThis = -1;
  699.     for (int i = nFirstT; i <= nLastT; i++)
  700.     {
  701.         CSizingControlBar* pBar =
  702.             (CSizingControlBar*) m_pDockBar->m_arrBars[i];
  703.         if (HIWORD(pBar) == 0) continue; // placeholder
  704.         if (!pBar->IsVisible()) continue;
  705.         if (pBar->IsKindOf(RUNTIME_CLASS(CSizingControlBar)))
  706.         {
  707.             if (pBar == this)
  708.                 nThis = arrSCBars.GetSize();
  709.             arrSCBars.Add(pBar);
  710.         }
  711.     }
  712. }
  713. BOOL CSizingControlBar::NegotiateSpace(int nLengthTotal, BOOL bHorz)
  714. {
  715.     ASSERT(bHorz == IsHorzDocked());
  716.     int nFirst, nLast, nThis;
  717.     GetRowInfo(nFirst, nLast, nThis);
  718.     int nLengthAvail = nLengthTotal;
  719.     int nLengthActual = 0;
  720.     int nLengthMin = 2;
  721.     int nWidthMax = 0;
  722.     CSizingControlBar* pBar;
  723.     for (int i = nFirst; i <= nLast; i++)
  724.     {
  725.         pBar = (CSizingControlBar*) m_pDockBar->m_arrBars[i];
  726.         if (HIWORD(pBar) == 0) continue; // placeholder
  727.         if (!pBar->IsVisible()) continue;
  728.         BOOL bIsSizingBar = 
  729.             pBar->IsKindOf(RUNTIME_CLASS(CSizingControlBar));
  730.         int nLengthBar; // minimum length of the bar
  731.         if (bIsSizingBar)
  732.             nLengthBar = bHorz ? pBar->m_szMinHorz.cx - 2 :
  733.                 pBar->m_szMinVert.cy - 2;
  734.         else
  735.         {
  736.             CRect rcBar;
  737.             pBar->GetWindowRect(&rcBar);
  738.             nLengthBar = bHorz ? rcBar.Width() - 2 : rcBar.Height() - 2;
  739.         }
  740.         nLengthMin += nLengthBar;
  741.         if (nLengthMin > nLengthTotal)
  742.         {
  743.             // split the row after fixed bar
  744.             if (i < nThis)
  745.             {
  746.                 m_pDockBar->m_arrBars.InsertAt(i + 1,
  747.                     (CControlBar*) NULL);
  748.                 return FALSE;
  749.             }
  750.             
  751.             // only this sizebar remains on the row, adjust it to minsize
  752.             if (i == nThis)
  753.             {
  754.                 if (bHorz)
  755.                     m_szHorz.cx = m_szMinHorz.cx;
  756.                 else
  757.                     m_szVert.cy = m_szMinVert.cy;
  758.                 return TRUE; // the dockbar will split the row for us
  759.             }
  760.             // we have enough bars - go negotiate with them
  761.             m_pDockBar->m_arrBars.InsertAt(i, (CControlBar*) NULL);
  762.             nLast = i - 1;
  763.             break;
  764.         }
  765.         if (bIsSizingBar)
  766.         {
  767.             nLengthActual += bHorz ? pBar->m_szHorz.cx - 2 : 
  768.                 pBar->m_szVert.cy - 2;
  769.             nWidthMax = max(nWidthMax, bHorz ? pBar->m_szHorz.cy :
  770.                 pBar->m_szVert.cx);
  771.         }
  772.         else
  773.             nLengthAvail -= nLengthBar;
  774.     }
  775.     CSCBArray arrSCBars;
  776.     GetRowSizingBars(arrSCBars);
  777.     int nNumBars = arrSCBars.GetSize();
  778.     int nDelta = nLengthAvail - nLengthActual;
  779.     // return faster when there is only one sizing bar per row (this one)
  780.     if (nNumBars == 1)
  781.     {
  782.         ASSERT(arrSCBars[0] == this);
  783.         if (nDelta == 0)
  784.             return TRUE;
  785.         
  786.         m_bKeepSize = FALSE;
  787.         (bHorz ? m_szHorz.cx : m_szVert.cy) += nDelta;
  788.         return TRUE;
  789.     }
  790.     // make all the bars the same width
  791.     for (i = 0; i < nNumBars; i++)
  792.         if (bHorz)
  793.             arrSCBars[i]->m_szHorz.cy = nWidthMax;
  794.         else
  795.             arrSCBars[i]->m_szVert.cx = nWidthMax;
  796.     // distribute the difference between the bars,
  797.     // but don't shrink them below their minsizes
  798.     while (nDelta != 0)
  799.     {
  800.         int nDeltaOld = nDelta;
  801.         for (i = 0; i < nNumBars; i++)
  802.         {
  803.             pBar = arrSCBars[i];
  804.             int nLMin = bHorz ?
  805.                 pBar->m_szMinHorz.cx : pBar->m_szMinVert.cy;
  806.             int nL = bHorz ? pBar->m_szHorz.cx : pBar->m_szVert.cy;
  807.             if ((nL == nLMin) && (nDelta < 0) || // already at min length
  808.                 pBar->m_bKeepSize) // or wants to keep its size
  809.                 continue;
  810.             // sign of nDelta
  811.             int nDelta2 = (nDelta == 0) ? 0 : ((nDelta < 0) ? -1 : 1);
  812.             (bHorz ? pBar->m_szHorz.cx : pBar->m_szVert.cy) += nDelta2;
  813.             nDelta -= nDelta2;
  814.             if (nDelta == 0) break;
  815.         }
  816.         // clear m_bKeepSize flags
  817.         if ((nDeltaOld == nDelta) || (nDelta == 0))
  818.             for (i = 0; i < nNumBars; i++)
  819.                 arrSCBars[i]->m_bKeepSize = FALSE;
  820.     }
  821.     return TRUE;
  822. }
  823. void CSizingControlBar::AlignControlBars()
  824. {
  825.     int nFirst, nLast, nThis;
  826.     GetRowInfo(nFirst, nLast, nThis);
  827.     BOOL bHorz = IsHorzDocked();
  828.     BOOL bNeedRecalc = FALSE;
  829.     int nAlign = bHorz ? -2 : 0;
  830.     CRect rc, rcDock;
  831.     m_pDockBar->GetWindowRect(&rcDock);
  832.     for (int i = nFirst; i <= nLast; i++)
  833.     {
  834.         CSizingControlBar* pBar =
  835.             (CSizingControlBar*) m_pDockBar->m_arrBars[i];
  836.         if (HIWORD(pBar) == 0) continue; // placeholder
  837.         if (!pBar->IsVisible()) continue;
  838.         pBar->GetWindowRect(&rc);
  839.         rc.OffsetRect(-rcDock.TopLeft());
  840.         if (pBar->IsKindOf(RUNTIME_CLASS(CSizingControlBar)))
  841.             rc = CRect(rc.TopLeft(),
  842.                 bHorz ? pBar->m_szHorz : pBar->m_szVert);
  843.         if ((bHorz ? rc.left : rc.top) != nAlign)
  844.         {
  845.             if (!bHorz)
  846.                 rc.OffsetRect(0, nAlign - rc.top - 2);
  847.             else if (m_nDockBarID == AFX_IDW_DOCKBAR_TOP)
  848.                 rc.OffsetRect(nAlign - rc.left, -2);
  849.             else
  850.                 rc.OffsetRect(nAlign - rc.left, 0);
  851.             pBar->MoveWindow(rc);
  852.             bNeedRecalc = TRUE;
  853.         }
  854.         nAlign += (bHorz ? rc.Width() : rc.Height()) - 2;
  855.     }
  856.     if (bNeedRecalc)
  857.         m_pDockSite->DelayRecalcLayout();
  858. }
  859. void CSizingControlBar::OnUpdateCmdUI(CFrameWnd* pTarget,
  860.                                       BOOL bDisableIfNoHndler)
  861. {
  862.     UNUSED_ALWAYS(bDisableIfNoHndler);
  863.     UNUSED_ALWAYS(pTarget);
  864. }
  865. void CSizingControlBar::LoadState(LPCTSTR lpszProfileName)
  866. {
  867.     ASSERT_VALID(this);
  868.     ASSERT(GetSafeHwnd()); // must be called after Create()
  869. #if defined(_SCB_REPLACE_MINIFRAME) && !defined(_SCB_MINIFRAME_CAPTION)
  870.     // compensate the caption miscalculation in CFrameWnd::SetDockState()
  871.     CDockState state;
  872.     state.LoadState(lpszProfileName);
  873.     UINT nID = GetDlgCtrlID();
  874.     for (int i = 0; i < state.m_arrBarInfo.GetSize(); i++)
  875.     {
  876.         CControlBarInfo* pInfo = (CControlBarInfo*)state.m_arrBarInfo[i];
  877.         ASSERT(pInfo != NULL);
  878.         if (!pInfo->m_bFloating)
  879.             continue;
  880.         
  881.         // this is a floating dockbar - check the ID array
  882.         for (int j = 0; j < pInfo->m_arrBarID.GetSize(); j++)
  883.             if ((DWORD) pInfo->m_arrBarID[j] == nID)
  884.             {
  885.                 // found this bar - offset origin and save settings
  886.                 pInfo->m_pointPos.x++;
  887.                 pInfo->m_pointPos.y +=
  888.                     ::GetSystemMetrics(SM_CYSMCAPTION) + 1;
  889.                 pInfo->SaveState(lpszProfileName, i);
  890.             }
  891.     }
  892. #endif //_SCB_REPLACE_MINIFRAME && !_SCB_MINIFRAME_CAPTION
  893.     CWinApp* pApp = AfxGetApp();
  894.     TCHAR szSection[256];
  895.     wsprintf(szSection, _T("%s-SCBar-%d"), lpszProfileName,
  896.         GetDlgCtrlID());
  897.     m_szHorz.cx = max(m_szMinHorz.cx, (int) pApp->GetProfileInt(
  898.         szSection, _T("sizeHorzCX"), m_szHorz.cx));
  899.     m_szHorz.cy = max(m_szMinHorz.cy, (int) pApp->GetProfileInt(
  900.         szSection, _T("sizeHorzCY"), m_szHorz.cy));
  901.     m_szVert.cx = max(m_szMinVert.cx, (int) pApp->GetProfileInt(
  902.         szSection, _T("sizeVertCX"), m_szVert.cx));
  903.     m_szVert.cy = max(m_szMinVert.cy, (int) pApp->GetProfileInt(
  904.         szSection, _T("sizeVertCY"), m_szVert.cy));
  905.     m_szFloat.cx = max(m_szMinFloat.cx, (int) pApp->GetProfileInt(
  906.         szSection, _T("sizeFloatCX"), m_szFloat.cx));
  907.     m_szFloat.cy = max(m_szMinFloat.cy, (int) pApp->GetProfileInt(
  908.         szSection, _T("sizeFloatCY"), m_szFloat.cy));
  909. }
  910. void CSizingControlBar::SaveState(LPCTSTR lpszProfileName)
  911. {
  912.     // place your SaveState or GlobalSaveState call in
  913.     // CMainFrame's OnClose() or DestroyWindow(), not in OnDestroy()
  914.     ASSERT_VALID(this);
  915.     ASSERT(GetSafeHwnd());
  916.     CWinApp* pApp = AfxGetApp();
  917.     TCHAR szSection[256];
  918.     wsprintf(szSection, _T("%s-SCBar-%d"), lpszProfileName,
  919.         GetDlgCtrlID());
  920.     pApp->WriteProfileInt(szSection, _T("sizeHorzCX"), m_szHorz.cx);
  921.     pApp->WriteProfileInt(szSection, _T("sizeHorzCY"), m_szHorz.cy);
  922.     pApp->WriteProfileInt(szSection, _T("sizeVertCX"), m_szVert.cx);
  923.     pApp->WriteProfileInt(szSection, _T("sizeVertCY"), m_szVert.cy);
  924.     pApp->WriteProfileInt(szSection, _T("sizeFloatCX"), m_szFloat.cx);
  925.     pApp->WriteProfileInt(szSection, _T("sizeFloatCY"), m_szFloat.cy);
  926. }
  927. void CSizingControlBar::GlobalLoadState(CFrameWnd* pFrame,
  928.                                         LPCTSTR lpszProfileName)
  929. {
  930.     POSITION pos = pFrame->m_listControlBars.GetHeadPosition();
  931.     while (pos != NULL)
  932.     {
  933.         CSizingControlBar* pBar = 
  934.             (CSizingControlBar*) pFrame->m_listControlBars.GetNext(pos);
  935.         ASSERT(pBar != NULL);
  936.         if (pBar->IsKindOf(RUNTIME_CLASS(CSizingControlBar)))
  937.             pBar->LoadState(lpszProfileName);
  938.     }
  939. }
  940. void CSizingControlBar::GlobalSaveState(CFrameWnd* pFrame,
  941.                                         LPCTSTR lpszProfileName)
  942. {
  943.     POSITION pos = pFrame->m_listControlBars.GetHeadPosition();
  944.     while (pos != NULL)
  945.     {
  946.         CSizingControlBar* pBar =
  947.             (CSizingControlBar*) pFrame->m_listControlBars.GetNext(pos);
  948.         ASSERT(pBar != NULL);
  949.         if (pBar->IsKindOf(RUNTIME_CLASS(CSizingControlBar)))
  950.             pBar->SaveState(lpszProfileName);
  951.     }
  952. }
  953. #ifdef _SCB_REPLACE_MINIFRAME
  954. #ifndef _SCB_MINIFRAME_CAPTION
  955. /////////////////////////////////////////////////////////////////////////////
  956. // CSCBDockContext Drag Operations
  957. static void AdjustRectangle(CRect& rect, CPoint pt)
  958. {
  959.     int nXOffset = (pt.x < rect.left) ? (pt.x - rect.left) :
  960.                     (pt.x > rect.right) ? (pt.x - rect.right) : 0;
  961.     int nYOffset = (pt.y < rect.top) ? (pt.y - rect.top) :
  962.                     (pt.y > rect.bottom) ? (pt.y - rect.bottom) : 0;
  963.     rect.OffsetRect(nXOffset, nYOffset);
  964. }
  965. void CSCBDockContext::StartDrag(CPoint pt)
  966. {
  967.     ASSERT_VALID(m_pBar);
  968.     m_bDragging = TRUE;
  969.     InitLoop();
  970.     ASSERT((m_pBar->m_dwStyle & CBRS_SIZE_DYNAMIC) != 0);
  971.     // get true bar size (including borders)
  972.     CRect rect;
  973.     m_pBar->GetWindowRect(rect);
  974.     m_ptLast = pt;
  975.     CSize sizeHorz = m_pBar->CalcDynamicLayout(0, LM_HORZ | LM_HORZDOCK);
  976.     CSize sizeVert = m_pBar->CalcDynamicLayout(0, LM_VERTDOCK);
  977.     CSize sizeFloat = m_pBar->CalcDynamicLayout(0, LM_HORZ | LM_MRUWIDTH);
  978.     m_rectDragHorz = CRect(rect.TopLeft(), sizeHorz);
  979.     m_rectDragVert = CRect(rect.TopLeft(), sizeVert);
  980.     // calculate frame dragging rectangle
  981.     m_rectFrameDragHorz = CRect(rect.TopLeft(), sizeFloat);
  982. #ifdef _MAC
  983.     CMiniFrameWnd::CalcBorders(&m_rectFrameDragHorz,
  984.         WS_THICKFRAME, WS_EX_FORCESIZEBOX);
  985. #else
  986.     CMiniFrameWnd::CalcBorders(&m_rectFrameDragHorz, WS_THICKFRAME);
  987. #endif
  988.     m_rectFrameDragHorz.DeflateRect(2, 2);
  989.     m_rectFrameDragVert = m_rectFrameDragHorz;
  990.     
  991.     // adjust rectangles so that point is inside
  992.     AdjustRectangle(m_rectDragHorz, pt);
  993.     AdjustRectangle(m_rectDragVert, pt);
  994.     AdjustRectangle(m_rectFrameDragHorz, pt);
  995.     AdjustRectangle(m_rectFrameDragVert, pt);
  996.     // initialize tracking state and enter tracking loop
  997.     m_dwOverDockStyle = CanDock();
  998.     Move(pt);   // call it here to handle special keys
  999.     Track();
  1000. }
  1001. #endif //_SCB_MINIFRAME_CAPTION
  1002. /////////////////////////////////////////////////////////////////////////////
  1003. // CSCBMiniDockFrameWnd
  1004. IMPLEMENT_DYNCREATE(CSCBMiniDockFrameWnd, baseCSCBMiniDockFrameWnd);
  1005. BEGIN_MESSAGE_MAP(CSCBMiniDockFrameWnd, baseCSCBMiniDockFrameWnd)
  1006.     //{{AFX_MSG_MAP(CSCBMiniDockFrameWnd)
  1007.     ON_WM_NCLBUTTONDOWN()
  1008.     ON_WM_GETMINMAXINFO()
  1009.     ON_WM_WINDOWPOSCHANGING()
  1010.     ON_WM_SIZE()
  1011.     //}}AFX_MSG_MAP
  1012. END_MESSAGE_MAP()
  1013. BOOL CSCBMiniDockFrameWnd::Create(CWnd* pParent, DWORD dwBarStyle)
  1014. {
  1015.     // set m_bInRecalcLayout to avoid flashing during creation
  1016.     // RecalcLayout will be called once something is docked
  1017.     m_bInRecalcLayout = TRUE;
  1018.     DWORD dwStyle = WS_POPUP|WS_CAPTION|WS_SYSMENU|MFS_MOVEFRAME|
  1019.         MFS_4THICKFRAME|MFS_SYNCACTIVE|MFS_BLOCKSYSMENU|
  1020.         FWS_SNAPTOBARS;
  1021.     if (dwBarStyle & CBRS_SIZE_DYNAMIC)
  1022.         dwStyle &= ~MFS_MOVEFRAME;
  1023.     DWORD dwExStyle = 0;
  1024. #ifdef _MAC
  1025.     if (dwBarStyle & CBRS_SIZE_DYNAMIC)
  1026.         dwExStyle |= WS_EX_FORCESIZEBOX;
  1027.     else
  1028.         dwStyle &= ~(MFS_MOVEFRAME|MFS_4THICKFRAME);
  1029. #endif
  1030.     if (!CMiniFrameWnd::CreateEx(dwExStyle,
  1031.         NULL, &afxChNil, dwStyle, rectDefault, pParent))
  1032.     {
  1033.         m_bInRecalcLayout = FALSE;
  1034.         return FALSE;
  1035.     }
  1036.     dwStyle = dwBarStyle & (CBRS_ALIGN_LEFT|CBRS_ALIGN_RIGHT) ?
  1037.         CBRS_ALIGN_LEFT : CBRS_ALIGN_TOP;
  1038.     dwStyle |= dwBarStyle & CBRS_FLOAT_MULTI;
  1039.     CMenu* pSysMenu = GetSystemMenu(FALSE);
  1040.     //pSysMenu->DeleteMenu(SC_SIZE, MF_BYCOMMAND);
  1041.     CString strHide;
  1042.     if (strHide.LoadString(AFX_IDS_HIDE))
  1043.     {
  1044.         pSysMenu->DeleteMenu(SC_CLOSE, MF_BYCOMMAND);
  1045.         pSysMenu->AppendMenu(MF_STRING|MF_ENABLED, SC_CLOSE, strHide);
  1046.     }
  1047.     // must initially create with parent frame as parent
  1048.     if (!m_wndDockBar.Create(pParent, WS_CHILD | WS_VISIBLE | dwStyle,
  1049.         AFX_IDW_DOCKBAR_FLOAT))
  1050.     {
  1051.         m_bInRecalcLayout = FALSE;
  1052.         return FALSE;
  1053.     }
  1054.     // set parent to CMiniDockFrameWnd
  1055.     m_wndDockBar.SetParent(this);
  1056.     m_bInRecalcLayout = FALSE;
  1057.     return TRUE;
  1058. }
  1059. void CSCBMiniDockFrameWnd::OnNcLButtonDown(UINT nHitTest, CPoint point)
  1060. {
  1061.     if (nHitTest == HTCAPTION || nHitTest == HTCLOSE)
  1062.     {
  1063.         baseCSCBMiniDockFrameWnd::OnNcLButtonDown(nHitTest, point);
  1064.         return;
  1065.     }
  1066.     if (GetSizingControlBar() != NULL)
  1067.         CMiniFrameWnd::OnNcLButtonDown(nHitTest, point);
  1068.     else
  1069.         baseCSCBMiniDockFrameWnd::OnNcLButtonDown(nHitTest, point);
  1070. }
  1071. CSizingControlBar* CSCBMiniDockFrameWnd::GetSizingControlBar()
  1072. {
  1073.     CWnd* pWnd = GetWindow(GW_CHILD); // get the dockbar
  1074.     if (pWnd == NULL)
  1075.         return NULL;
  1076.     
  1077.     pWnd = pWnd->GetWindow(GW_CHILD); // get the controlbar
  1078.     if (pWnd == NULL)
  1079.         return NULL;
  1080.     if (!pWnd->IsKindOf(RUNTIME_CLASS(CSizingControlBar)))
  1081.         return NULL;
  1082.     return (CSizingControlBar*) pWnd;
  1083. }
  1084. void CSCBMiniDockFrameWnd::OnSize(UINT nType, int cx, int cy) 
  1085. {
  1086.     CSizingControlBar* pBar = GetSizingControlBar();
  1087.     if ((pBar != NULL) && (GetStyle() & MFS_4THICKFRAME) == 0
  1088.         && pBar->IsVisible())
  1089.         pBar->m_szFloat = CSize(cx + 4, cy + 4);
  1090.     baseCSCBMiniDockFrameWnd::OnSize(nType, cx, cy);
  1091. }
  1092. void CSCBMiniDockFrameWnd::OnGetMinMaxInfo(MINMAXINFO FAR* lpMMI)
  1093. {
  1094.     baseCSCBMiniDockFrameWnd::OnGetMinMaxInfo(lpMMI);
  1095.     CSizingControlBar* pBar = GetSizingControlBar();
  1096.     if (pBar != NULL)
  1097.     {
  1098.         CRect r(CPoint(0, 0), pBar->m_szMinFloat - CSize(4, 4));
  1099. #ifndef _SCB_MINIFRAME_CAPTION
  1100.         CMiniFrameWnd::CalcBorders(&r, WS_THICKFRAME);
  1101. #else
  1102.         CMiniFrameWnd::CalcBorders(&r, WS_THICKFRAME|WS_CAPTION);
  1103. #endif //_SCB_MINIFRAME_CAPTION
  1104.         lpMMI->ptMinTrackSize.x = r.Width();
  1105.         lpMMI->ptMinTrackSize.y = r.Height();
  1106.     }
  1107. }
  1108. void CSCBMiniDockFrameWnd::OnWindowPosChanging(WINDOWPOS FAR* lpwndpos) 
  1109. {
  1110.     if ((GetStyle() & MFS_4THICKFRAME) != 0)
  1111.     {
  1112.         CSizingControlBar* pBar = GetSizingControlBar();
  1113.         if (pBar != NULL)
  1114.         {
  1115.             lpwndpos->flags |= SWP_NOSIZE; // don't size this time
  1116.             // prevents flicker
  1117.             pBar->m_pDockBar->ModifyStyle(0, WS_CLIPCHILDREN);
  1118.             // enable diagonal resizing
  1119.             ModifyStyle(MFS_4THICKFRAME, 0);
  1120. #ifndef _SCB_MINIFRAME_CAPTION
  1121.             // remove caption
  1122.             ModifyStyle(WS_SYSMENU|WS_CAPTION, 0);
  1123. #endif
  1124.             DelayRecalcLayout();
  1125.             pBar->PostMessage(WM_NCPAINT);
  1126.         }
  1127.     }
  1128.     CMiniFrameWnd::OnWindowPosChanging(lpwndpos);
  1129. }
  1130. #endif //_SCB_REPLACE_MINIFRAME