home *** CD-ROM | disk | FTP | other *** search
/ Team Palmtops 7 / Palmtops_numero07.iso / WinCE / SDKWindowsCE / HandHeldPCPro30 / sdk.exe / Jupiter SDK / data1.cab / MFC / src / dockcont.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1999-02-19  |  17.8 KB  |  644 lines

  1. // This is a part of the Microsoft Foundation Classes C++ library.
  2. // Copyright (C) 1992-1998 Microsoft Corporation
  3. // All rights reserved.
  4. //
  5. // This source code is only intended as a supplement to the
  6. // Microsoft Foundation Classes Reference and related
  7. // electronic documentation provided with the library.
  8. // See these sources for detailed information regarding the
  9. // Microsoft Foundation Classes product.
  10.  
  11. #include "stdafx.h"
  12. #if !defined(_WIN32_WCE_NO_DOCKBARS)
  13.  
  14. #ifdef AFX_CORE3_SEG
  15. #pragma code_seg(AFX_CORE3_SEG)
  16. #endif
  17.  
  18. #ifdef _DEBUG
  19. #undef THIS_FILE
  20. static char THIS_FILE[] = __FILE__;
  21. #endif
  22.  
  23. #define new DEBUG_NEW
  24.  
  25. #define HORZF(dw) (dw & CBRS_ORIENT_HORZ)
  26. #define VERTF(dw) (dw & CBRS_ORIENT_VERT)
  27.  
  28. AFX_STATIC void AFXAPI _AfxAdjustRectangle(CRect& rect, CPoint pt)
  29. {
  30.     int nXOffset = (pt.x < rect.left) ? (pt.x - rect.left) :
  31.                     (pt.x > rect.right) ? (pt.x - rect.right) : 0;
  32.     int nYOffset = (pt.y < rect.top) ? (pt.y - rect.top) :
  33.                     (pt.y > rect.bottom) ? (pt.y - rect.bottom) : 0;
  34.     rect.OffsetRect(nXOffset, nYOffset);
  35. }
  36.  
  37. /////////////////////////////////////////////////////////////////////////////
  38. // CDockContext
  39.  
  40. CDockContext::CDockContext(CControlBar* pBar)
  41. {
  42.     ASSERT(pBar != NULL);
  43.     ASSERT(pBar->m_pDockSite != NULL);
  44.  
  45.     m_pBar = pBar;
  46.     m_pDockSite = pBar->m_pDockSite;
  47.  
  48.     m_uMRUDockID = 0;
  49.     m_rectMRUDockPos.left = 0;
  50.     m_rectMRUDockPos.top = 0;
  51.     if (pBar->m_dwStyle & CBRS_SIZE_DYNAMIC)
  52.         m_dwMRUFloatStyle = pBar->m_dwStyle & (CBRS_ALIGN_TOP | CBRS_SIZE_DYNAMIC);
  53.     else if (pBar->m_dwStyle & CBRS_ORIENT_HORZ)
  54.         m_dwMRUFloatStyle = CBRS_ALIGN_TOP | (pBar->m_dwStyle & CBRS_FLOAT_MULTI);
  55.     else
  56.         m_dwMRUFloatStyle = CBRS_ALIGN_LEFT | (pBar->m_dwStyle & CBRS_FLOAT_MULTI);
  57.     m_ptMRUFloatPos.x = CW_USEDEFAULT;
  58.  
  59.     ASSERT(m_pDockSite->IsFrameWnd());
  60.     m_pDC = NULL;
  61. }
  62.  
  63. CDockContext::~CDockContext()
  64. {
  65.     ASSERT(m_pBar != NULL);
  66.     if (m_pBar->m_pDockBar != NULL)
  67.         m_pBar->m_pDockBar->RemoveControlBar(m_pBar, -1, FALSE);
  68. }
  69.  
  70. /////////////////////////////////////////////////////////////////////////////
  71. // CDockContext Drag Operations
  72.  
  73. void CDockContext::StartDrag(CPoint pt)
  74. {
  75.     ASSERT_VALID(m_pBar);
  76.     m_bDragging = TRUE;
  77.  
  78.     InitLoop();
  79.  
  80.     // GetWindowRect returns screen coordinates(not mirrored),
  81.     // so if the desktop is mirrored then turn off mirroring
  82.     // for the desktop dc so that we get correct focus rect drawn.
  83.     // This layout change should be remembered, just in case ...
  84.  
  85.     if (m_pDC->GetLayout() & LAYOUT_RTL)
  86.         m_pDC->SetLayout(LAYOUT_LTR);
  87.  
  88.     if (m_pBar->m_dwStyle & CBRS_SIZE_DYNAMIC)
  89.     {
  90.         // get true bar size (including borders)
  91.         CRect rect;
  92.         m_pBar->GetWindowRect(rect);
  93.         m_ptLast = pt;
  94.         CSize sizeHorz = m_pBar->CalcDynamicLayout(0, LM_HORZ | LM_HORZDOCK);
  95.         CSize sizeVert = m_pBar->CalcDynamicLayout(0, LM_VERTDOCK);
  96.         CSize sizeFloat = m_pBar->CalcDynamicLayout(0, LM_HORZ | LM_MRUWIDTH);
  97.  
  98.         m_rectDragHorz = CRect(rect.TopLeft(), sizeHorz);
  99.         m_rectDragVert = CRect(rect.TopLeft(), sizeVert);
  100.  
  101.         // calculate frame dragging rectangle
  102.         m_rectFrameDragHorz = CRect(rect.TopLeft(), sizeFloat);
  103.         m_rectFrameDragVert = CRect(rect.TopLeft(), sizeFloat);
  104.  
  105.         CMiniFrameWnd::CalcBorders(&m_rectFrameDragHorz);
  106.         CMiniFrameWnd::CalcBorders(&m_rectFrameDragVert);
  107.  
  108.         m_rectFrameDragHorz.InflateRect(-afxData.cxBorder2, -afxData.cyBorder2);
  109.         m_rectFrameDragVert.InflateRect(-afxData.cxBorder2, -afxData.cyBorder2);
  110.     }
  111.     else if (m_pBar->m_dwStyle & CBRS_SIZE_FIXED)
  112.     {
  113.         // get true bar size (including borders)
  114.         CRect rect;
  115.         m_pBar->GetWindowRect(rect);
  116.         m_ptLast = pt;
  117.         CSize sizeHorz = m_pBar->CalcDynamicLayout(-1, LM_HORZ | LM_HORZDOCK);
  118.         CSize sizeVert = m_pBar->CalcDynamicLayout(-1, LM_VERTDOCK);
  119.  
  120.         // calculate frame dragging rectangle
  121.         m_rectFrameDragHorz = m_rectDragHorz = CRect(rect.TopLeft(), sizeHorz);
  122.         m_rectFrameDragVert = m_rectDragVert = CRect(rect.TopLeft(), sizeVert);
  123.  
  124.         CMiniFrameWnd::CalcBorders(&m_rectFrameDragHorz);
  125.         CMiniFrameWnd::CalcBorders(&m_rectFrameDragVert);
  126.         m_rectFrameDragHorz.InflateRect(-afxData.cxBorder2, -afxData.cyBorder2);
  127.         m_rectFrameDragVert.InflateRect(-afxData.cxBorder2, -afxData.cyBorder2);
  128.     }
  129.     else
  130.     {
  131.         // get true bar size (including borders)
  132.         CRect rect;
  133.         m_pBar->GetWindowRect(rect);
  134.         m_ptLast = pt;
  135.         BOOL bHorz = HORZF(m_dwStyle);
  136.         DWORD dwMode = !bHorz ? (LM_HORZ | LM_HORZDOCK) : LM_VERTDOCK;
  137.         CSize size = m_pBar->CalcDynamicLayout(-1, dwMode);
  138.  
  139.         // calculate inverted dragging rect
  140.         if (bHorz)
  141.         {
  142.             m_rectDragHorz = rect;
  143.             m_rectDragVert = CRect(CPoint(pt.x - rect.Height()/2, rect.top), size);
  144.         }
  145.         else // vertical orientation
  146.         {
  147.             m_rectDragVert = rect;
  148.             m_rectDragHorz = CRect(CPoint(rect.left, pt.y - rect.Width()/2), size);
  149.         }
  150.  
  151.         // calculate frame dragging rectangle
  152.         m_rectFrameDragHorz = m_rectDragHorz;
  153.         m_rectFrameDragVert = m_rectDragVert;
  154.  
  155.         CMiniFrameWnd::CalcBorders(&m_rectFrameDragHorz);
  156.         CMiniFrameWnd::CalcBorders(&m_rectFrameDragVert);
  157.         m_rectFrameDragHorz.InflateRect(-afxData.cxBorder2, -afxData.cyBorder2);
  158.         m_rectFrameDragVert.InflateRect(-afxData.cxBorder2, -afxData.cyBorder2);
  159.     }
  160.  
  161.     // adjust rectangles so that point is inside
  162.     _AfxAdjustRectangle(m_rectDragHorz, pt);
  163.     _AfxAdjustRectangle(m_rectDragVert, pt);
  164.     _AfxAdjustRectangle(m_rectFrameDragHorz, pt);
  165.     _AfxAdjustRectangle(m_rectFrameDragVert, pt);
  166.  
  167.     // initialize tracking state and enter tracking loop
  168.     m_dwOverDockStyle = CanDock();
  169.     Move(pt);   // call it here to handle special keys
  170.     Track();
  171. }
  172.  
  173. void CDockContext::Move(CPoint pt)
  174. {
  175.     CPoint ptOffset = pt - m_ptLast;
  176.  
  177.     // offset all drag rects to new position
  178.     m_rectDragHorz.OffsetRect(ptOffset);
  179.     m_rectFrameDragHorz.OffsetRect(ptOffset);
  180.     m_rectDragVert.OffsetRect(ptOffset);
  181.     m_rectFrameDragVert.OffsetRect(ptOffset);
  182.     m_ptLast = pt;
  183.  
  184.     // if control key is down don't dock
  185.     m_dwOverDockStyle = m_bForceFrame ? 0 : CanDock();
  186.  
  187.     // update feedback
  188.     DrawFocusRect();
  189. }
  190.  
  191. void CDockContext::OnKey(int nChar, BOOL bDown)
  192. {
  193.     if (nChar == VK_CONTROL)
  194.         UpdateState(&m_bForceFrame, bDown);
  195.     if (nChar == VK_SHIFT)
  196.         UpdateState(&m_bFlip, bDown);
  197. }
  198.  
  199. void CDockContext::EndDrag()
  200. {
  201.     CancelLoop();
  202.  
  203.     if (m_dwOverDockStyle != 0)
  204.     {
  205.         CDockBar* pDockBar = GetDockBar(m_dwOverDockStyle);
  206.         ASSERT(pDockBar != NULL);
  207.  
  208.         CRect rect = (m_dwOverDockStyle & CBRS_ORIENT_VERT) ?
  209.             m_rectDragVert : m_rectDragHorz;
  210.  
  211.         UINT uID = _AfxGetDlgCtrlID(pDockBar->m_hWnd);
  212.         if (uID >= AFX_IDW_DOCKBAR_TOP &&
  213.             uID <= AFX_IDW_DOCKBAR_BOTTOM)
  214.         {
  215.             m_uMRUDockID = uID;
  216.             m_rectMRUDockPos = rect;
  217.             pDockBar->ScreenToClient(&m_rectMRUDockPos);
  218.         }
  219.  
  220.         // dock it at the specified position, RecalcLayout will snap
  221.         m_pDockSite->DockControlBar(m_pBar, pDockBar, &rect);
  222.         m_pDockSite->RecalcLayout();
  223.     }
  224.     else if ((m_dwStyle & CBRS_SIZE_DYNAMIC) || (HORZF(m_dwStyle) && !m_bFlip) ||
  225.             (VERTF(m_dwStyle) && m_bFlip))
  226.     {
  227.         m_dwMRUFloatStyle = CBRS_ALIGN_TOP | (m_dwDockStyle & CBRS_FLOAT_MULTI);
  228.         m_ptMRUFloatPos = m_rectFrameDragHorz.TopLeft();
  229.         m_pDockSite->FloatControlBar(m_pBar, m_ptMRUFloatPos, m_dwMRUFloatStyle);
  230.     }
  231.     else // vertical float
  232.     {
  233.         m_dwMRUFloatStyle = CBRS_ALIGN_LEFT | (m_dwDockStyle & CBRS_FLOAT_MULTI);
  234.         m_ptMRUFloatPos = m_rectFrameDragVert.TopLeft();
  235.         m_pDockSite->FloatControlBar(m_pBar, m_ptMRUFloatPos, m_dwMRUFloatStyle);
  236.     }
  237. }
  238.  
  239. /////////////////////////////////////////////////////////////////////////////
  240. // CDockContext Resize Operations
  241.  
  242. #define m_rectRequestedSize     m_rectDragHorz
  243. #define m_rectActualSize        m_rectDragVert
  244. #define m_rectActualFrameSize   m_rectFrameDragHorz
  245. #define m_rectFrameBorders      m_rectFrameDragVert
  246.  
  247. void CDockContext::StartResize(int nHitTest, CPoint pt)
  248. {
  249.     ASSERT_VALID(m_pBar);
  250.     ASSERT(m_pBar->m_dwStyle & CBRS_SIZE_DYNAMIC);
  251.     m_bDragging = FALSE;
  252.  
  253.     InitLoop();
  254.  
  255.     // GetWindowRect returns screen coordinates(not mirrored)
  256.     // So if the desktop is mirrored then turn off mirroring
  257.     // for the desktop dc so that we draw correct focus rect 
  258.  
  259.     if (m_pDC->GetLayout() & LAYOUT_RTL)
  260.         m_pDC->SetLayout(LAYOUT_LTR);
  261.  
  262.     // get true bar size (including borders)
  263.     CRect rect;
  264.     m_pBar->GetWindowRect(rect);
  265.     m_ptLast = pt;
  266.     m_nHitTest = nHitTest;
  267.  
  268.     CSize size = m_pBar->CalcDynamicLayout(0, LM_HORZ | LM_MRUWIDTH);
  269.     m_rectRequestedSize = CRect(rect.TopLeft(), size);
  270.     m_rectActualSize = CRect(rect.TopLeft(), size);
  271.     m_rectActualFrameSize = CRect(rect.TopLeft(), size);
  272.  
  273.     // calculate frame rectangle
  274.     CMiniFrameWnd::CalcBorders(&m_rectActualFrameSize);
  275.     m_rectActualFrameSize.InflateRect(-afxData.cxBorder2, -afxData.cyBorder2);
  276.  
  277.     m_rectFrameBorders = CRect(CPoint(0,0),
  278.         m_rectActualFrameSize.Size() - m_rectActualSize.Size());
  279.  
  280.     // initialize tracking state and enter tracking loop
  281.     m_dwOverDockStyle = 0;
  282.     Stretch(pt);   // call it here to handle special keys
  283.     Track();
  284. }
  285.  
  286. void CDockContext::Stretch(CPoint pt)
  287. {
  288.     CPoint ptOffset = pt - m_ptLast;
  289.  
  290.     // offset all drag rects to new position
  291.     int nLength = 0;
  292.     DWORD dwMode = LM_HORZ;
  293.     if (m_nHitTest == HTLEFT || m_nHitTest == HTRIGHT)
  294.     {
  295.         if (m_nHitTest == HTLEFT)
  296.             m_rectRequestedSize.left += ptOffset.x;
  297.         else
  298.             m_rectRequestedSize.right += ptOffset.x;
  299.         nLength = m_rectRequestedSize.Width();
  300.     }
  301.     else
  302.     {
  303.         dwMode |= LM_LENGTHY;
  304.         if (m_nHitTest == HTTOP)
  305.             m_rectRequestedSize.top += ptOffset.y;
  306.         else
  307.             m_rectRequestedSize.bottom += ptOffset.y;
  308.         nLength = m_rectRequestedSize.Height();
  309.     }
  310.     nLength = (nLength >= 0) ? nLength : 0;
  311.  
  312.     CSize size = m_pBar->CalcDynamicLayout(nLength, dwMode);
  313.  
  314.     CRect rectDesk;
  315.     HWND hWndDesk = ::GetDesktopWindow();
  316.     ::GetWindowRect(hWndDesk, &rectDesk);
  317.     CRect rectTemp = m_rectActualFrameSize;
  318.  
  319.     if (m_nHitTest == HTLEFT || m_nHitTest == HTTOP)
  320.     {
  321.         rectTemp.left = rectTemp.right -
  322.             (size.cx + m_rectFrameBorders.Width());
  323.         rectTemp.top = rectTemp.bottom -
  324.             (size.cy + m_rectFrameBorders.Height());
  325.         CRect rect;
  326.         if (rect.IntersectRect(rectDesk, rectTemp))
  327.         {
  328.             m_rectActualSize.left = m_rectActualSize.right - size.cx;
  329.             m_rectActualSize.top = m_rectActualSize.bottom - size.cy;
  330.             m_rectActualFrameSize.left = rectTemp.left;
  331.             m_rectActualFrameSize.top = rectTemp.top;
  332.         }
  333.     }
  334.     else
  335.     {
  336.         rectTemp.right = rectTemp.left +
  337.             (size.cx + m_rectFrameBorders.Width());
  338.         rectTemp.bottom = rectTemp.top +
  339.             (size.cy + m_rectFrameBorders.Height());
  340.         CRect rect;
  341.         if (rect.IntersectRect(rectDesk, rectTemp))
  342.         {
  343.             m_rectActualSize.right = m_rectActualSize.left + size.cx;
  344.             m_rectActualSize.bottom = m_rectActualSize.top + size.cy;
  345.             m_rectActualFrameSize.right = rectTemp.right;
  346.             m_rectActualFrameSize.bottom = rectTemp.bottom;
  347.         }
  348.     }
  349.     m_ptLast = pt;
  350.  
  351.     // update feedback
  352.     DrawFocusRect();
  353. }
  354.  
  355. void CDockContext::EndResize()
  356. {
  357.     CancelLoop();
  358.  
  359.     m_pBar->CalcDynamicLayout(m_rectActualSize.Width(), LM_HORZ | LM_COMMIT);
  360.     m_pDockSite->FloatControlBar(m_pBar, m_rectActualFrameSize.TopLeft(),
  361.         CBRS_ALIGN_TOP | (m_dwDockStyle & CBRS_FLOAT_MULTI) | CBRS_SIZE_DYNAMIC);
  362. }
  363.  
  364. /////////////////////////////////////////////////////////////////////////////
  365. // CDockContext Double Click Operations
  366.  
  367. void CDockContext::ToggleDocking()
  368. {
  369.     if (m_pBar->IsFloating())
  370.     {
  371.         // Dock it only if is allowed to be docked
  372.         if (m_pBar->m_dwDockStyle & CBRS_ALIGN_ANY)
  373.         {
  374.             ASSERT((m_uMRUDockID >= AFX_IDW_DOCKBAR_TOP &&
  375.                 m_uMRUDockID <= AFX_IDW_DOCKBAR_BOTTOM) ||
  376.                 m_uMRUDockID == 0);
  377.  
  378.             CRect rect = m_rectMRUDockPos;
  379.             CDockBar* pDockBar = NULL;
  380.             if (m_uMRUDockID != 0)
  381.             {
  382.                 pDockBar = (CDockBar*)m_pDockSite->GetControlBar(m_uMRUDockID);
  383.                 pDockBar->ClientToScreen(&rect);
  384.             }
  385.  
  386.             // dock it at the specified position, RecalcLayout will snap
  387.             m_pDockSite->ReDockControlBar(m_pBar, pDockBar, &rect);
  388.             m_pDockSite->RecalcLayout();
  389.         }
  390.     }
  391.     else
  392.     {
  393.         CPoint ptFloat = m_ptMRUFloatPos;
  394.         if (ptFloat.x < 0 || ptFloat.y < 0)
  395.         {
  396.             ptFloat = m_rectMRUDockPos.TopLeft();
  397.             m_pBar->GetParent()->ClientToScreen(&ptFloat);
  398.         }
  399.         m_pDockSite->FloatControlBar(m_pBar, ptFloat, m_dwMRUFloatStyle);
  400.     }
  401. }
  402.  
  403. /////////////////////////////////////////////////////////////////////////////
  404. // CDockContext Operations
  405.  
  406. void CDockContext::InitLoop()
  407. {
  408.     // handle pending WM_PAINT messages
  409.     MSG msg;
  410.     while (::PeekMessage(&msg, NULL, WM_PAINT, WM_PAINT, PM_NOREMOVE))
  411.     {
  412.         if (!GetMessage(&msg, NULL, WM_PAINT, WM_PAINT))
  413.             return;
  414.         DispatchMessage(&msg);
  415.     }
  416.  
  417.     // get styles from bar
  418.     m_dwDockStyle = m_pBar->m_dwDockStyle;
  419.     m_dwStyle = m_pBar->m_dwStyle & CBRS_ALIGN_ANY;
  420.     ASSERT(m_dwStyle != 0);
  421.  
  422.     // initialize state
  423.     m_rectLast.SetRectEmpty();
  424.     m_sizeLast.cx = m_sizeLast.cy = 0;
  425.     m_bForceFrame = m_bFlip = m_bDitherLast = FALSE;
  426.  
  427.     // lock window update while dragging
  428.     ASSERT(m_pDC == NULL);
  429.     CWnd* pWnd = CWnd::GetDesktopWindow();
  430.     if (pWnd->LockWindowUpdate())
  431.         m_pDC = pWnd->GetDCEx(NULL, DCX_WINDOW|DCX_CACHE|DCX_LOCKWINDOWUPDATE);
  432.     else
  433.         m_pDC = pWnd->GetDCEx(NULL, DCX_WINDOW|DCX_CACHE);
  434.     ASSERT(m_pDC != NULL);
  435. }
  436.  
  437. void CDockContext::CancelLoop()
  438. {
  439.     DrawFocusRect(TRUE);    // gets rid of focus rect
  440.     ReleaseCapture();
  441.  
  442.     CWnd* pWnd = CWnd::GetDesktopWindow();
  443.     pWnd->UnlockWindowUpdate();
  444.     if (m_pDC != NULL)
  445.     {
  446.         pWnd->ReleaseDC(m_pDC);
  447.         m_pDC = NULL;
  448.     }
  449. }
  450.  
  451. /////////////////////////////////////////////////////////////////////////////
  452. // Implementation
  453.  
  454. void CDockContext::DrawFocusRect(BOOL bRemoveRect)
  455. {
  456.     ASSERT(m_pDC != NULL);
  457.  
  458.     // default to thin frame
  459.     CSize size(CX_BORDER, CY_BORDER);
  460.  
  461.     // determine new rect and size
  462.     CRect rect;
  463.     CBrush* pWhiteBrush = CBrush::FromHandle((HBRUSH)::GetStockObject(WHITE_BRUSH));
  464.     CBrush* pDitherBrush = CDC::GetHalftoneBrush();
  465.     CBrush* pBrush = pWhiteBrush;
  466.  
  467.     if (HORZF(m_dwOverDockStyle))
  468.         rect = m_rectDragHorz;
  469.     else if (VERTF(m_dwOverDockStyle))
  470.         rect = m_rectDragVert;
  471.     else
  472.     {
  473.         // use thick frame instead
  474.         size.cx = GetSystemMetrics(SM_CXFRAME) - CX_BORDER;
  475.         size.cy = GetSystemMetrics(SM_CYFRAME) - CY_BORDER;
  476.         if ((HORZF(m_dwStyle) && !m_bFlip) || (VERTF(m_dwStyle) && m_bFlip))
  477.             rect = m_rectFrameDragHorz;
  478.         else
  479.             rect = m_rectFrameDragVert;
  480.         pBrush = pDitherBrush;
  481.     }
  482.     if (bRemoveRect)
  483.         size.cx = size.cy = 0;
  484.  
  485.     if (afxData.bWin4 &&
  486.         (HORZF(m_dwOverDockStyle) || VERTF(m_dwOverDockStyle)))
  487.     {
  488.         // looks better one pixel in (makes the bar look pushed down)
  489.         rect.InflateRect(-CX_BORDER, -CY_BORDER);
  490.     }
  491.  
  492.     // draw it and remember last size
  493.     m_pDC->DrawDragRect(&rect, size, &m_rectLast, m_sizeLast,
  494.         pBrush, m_bDitherLast ? pDitherBrush : pWhiteBrush);
  495.     m_rectLast = rect;
  496.     m_sizeLast = size;
  497.     m_bDitherLast = (pBrush == pDitherBrush);
  498. }
  499.  
  500. void CDockContext::UpdateState(BOOL* pFlag, BOOL bNewValue)
  501. {
  502.     if (*pFlag != bNewValue)
  503.     {
  504.         *pFlag = bNewValue;
  505.         m_bFlip = (HORZF(m_dwDockStyle) && VERTF(m_dwDockStyle) && m_bFlip); // shift key
  506.         m_dwOverDockStyle = (m_bForceFrame) ? 0 : CanDock();
  507.         DrawFocusRect();
  508.     }
  509. }
  510.  
  511. DWORD CDockContext::CanDock()
  512. {
  513.     BOOL bStyleHorz;
  514.     DWORD dwDock = 0; // Dock Canidate
  515.     DWORD dwCurr = 0; // Current Orientation
  516.  
  517.     // let's check for something in our current orientation first
  518.     // then if the shift key is not forcing our orientation then
  519.     // check for horizontal or vertical orientations as long
  520.     // as we are close enough
  521.     ASSERT(m_dwStyle != 0);
  522.  
  523.     bStyleHorz = HORZF(m_dwStyle);
  524.     bStyleHorz = m_bFlip ? !bStyleHorz : bStyleHorz;
  525.  
  526.     if (bStyleHorz && HORZF(m_dwDockStyle))
  527.         dwDock = m_pDockSite->CanDock(m_rectDragHorz,
  528.                                       m_dwDockStyle & ~CBRS_ORIENT_VERT);
  529.     else if (VERTF(m_dwDockStyle))
  530.         dwDock = m_pDockSite->CanDock(m_rectDragVert,
  531.                                       m_dwDockStyle & ~CBRS_ORIENT_HORZ);
  532.  
  533.     if (!m_bFlip)
  534.     {
  535.         if (dwDock == 0 && HORZF(m_dwDockStyle))
  536.         {
  537.             dwCurr = m_pDockSite->CanDock(m_rectDragVert,
  538.                                           m_dwDockStyle & ~CBRS_ORIENT_VERT);
  539.             dwDock = m_pDockSite->CanDock(m_rectDragHorz,
  540.                                           m_dwDockStyle & ~CBRS_ORIENT_VERT);
  541.             dwDock = (dwDock == dwCurr) ? dwDock : 0;
  542.         }
  543.         if (dwDock == 0 && VERTF(m_dwDockStyle))
  544.         {
  545.             dwCurr = m_pDockSite->CanDock(m_rectDragHorz,
  546.                                           m_dwDockStyle & ~CBRS_ORIENT_HORZ);
  547.             dwDock = m_pDockSite->CanDock(m_rectDragVert,
  548.                                           m_dwDockStyle & ~CBRS_ORIENT_HORZ);
  549.             dwDock = (dwDock == dwCurr) ? dwDock : 0;
  550.         }
  551.     }
  552.  
  553.     return dwDock;
  554. }
  555.  
  556. CDockBar* CDockContext::GetDockBar(DWORD dwOverDockStyle)
  557. {
  558.     DWORD dw = 0;
  559.     CDockBar* pBar;
  560.     if (HORZF(dwOverDockStyle))
  561.     {
  562.         dw = m_pDockSite->CanDock(m_rectDragHorz,
  563.             dwOverDockStyle & ~CBRS_ORIENT_VERT, &pBar);
  564.         ASSERT(dw != 0);
  565.         ASSERT(pBar != NULL);
  566.         return pBar;
  567.     }
  568.     if (VERTF(dwOverDockStyle))
  569.     {
  570.         dw = m_pDockSite->CanDock(m_rectDragVert,
  571.             dwOverDockStyle & ~CBRS_ORIENT_HORZ, &pBar);
  572.         ASSERT(dw != 0);
  573.         ASSERT(pBar != NULL);
  574.         return pBar;
  575.     }
  576.     return NULL;
  577. }
  578.  
  579. BOOL CDockContext::Track()
  580. {
  581.     // don't handle if capture already set
  582.     if (::GetCapture() != NULL)
  583.         return FALSE;
  584.  
  585.     // set capture to the window which received this message
  586.     m_pBar->SetCapture();
  587.     ASSERT(m_pBar == CWnd::GetCapture());
  588.  
  589.     // get messages until capture lost or cancelled/accepted
  590.     while (CWnd::GetCapture() == m_pBar)
  591.     {
  592.         MSG msg;
  593.         if (!::GetMessage(&msg, NULL, 0, 0))
  594.         {
  595.             AfxPostQuitMessage(msg.wParam);
  596.             break;
  597.         }
  598.  
  599.         switch (msg.message)
  600.         {
  601.         case WM_LBUTTONUP:
  602.             if (m_bDragging)
  603.                 EndDrag();
  604.             else
  605.                 EndResize();
  606.             return TRUE;
  607.         case WM_MOUSEMOVE:
  608.             if (m_bDragging)
  609.                 Move(msg.pt);
  610.             else
  611.                 Stretch(msg.pt);
  612.             break;
  613.         case WM_KEYUP:
  614.             if (m_bDragging)
  615.                 OnKey((int)msg.wParam, FALSE);
  616.             break;
  617.         case WM_KEYDOWN:
  618.             if (m_bDragging)
  619.                 OnKey((int)msg.wParam, TRUE);
  620.             if (msg.wParam == VK_ESCAPE)
  621.             {
  622.                 CancelLoop();
  623.                 return FALSE;
  624.             }
  625.             break;
  626.         case WM_RBUTTONDOWN:
  627.             CancelLoop();
  628.             return FALSE;
  629.  
  630.         // just dispatch rest of the messages
  631.         default:
  632.             DispatchMessage(&msg);
  633.             break;
  634.         }
  635.     }
  636.  
  637.     CancelLoop();
  638.  
  639.     return FALSE;
  640. }
  641.  
  642. /////////////////////////////////////////////////////////////////////////////
  643. #endif // _WIN32_WCE_NO_DOCKING
  644.