void COXDragDockContext::DrawFocusRect(BOOL bRemoveRect) { ASSERT(m_pDC != NULL); // default to thin frame CSize size(CX_BORDER, CY_BORDER); // determine new rect and size CRect rect; CBrush* pWhiteBrush = CBrush::FromHandle((HBRUSH)::GetStockObject(WHITE_BRUSH)); CBrush* pDitherBrush = CDC::GetHalftoneBrush(); CBrush* pBrush = pWhiteBrush; if (m_dwOverDockStyle != 0) { rect = m_rectDragDock; } else { #ifndef _MAC // use thick frame instead size.cx = GetSystemMetrics(SM_CXFRAME) - CX_BORDER; size.cy = GetSystemMetrics(SM_CYFRAME) - CY_BORDER; #endif rect = m_rectFrameDragHorz; pBrush = pDitherBrush; } if (bRemoveRect) size.cx = size.cy = 0; #if _MFC_VER < 0x0700 if ( afxData.bWin4 && (HORZF(m_dwOverDockStyle) || VERTF(m_dwOverDockStyle))) #else if (HORZF(m_dwOverDockStyle) || VERTF(m_dwOverDockStyle)) #endif { // looks better one pixel in (makes the bar look pushed down) rect.InflateRect(-CX_BORDER, -CY_BORDER); } // draw it and remember last size m_pDC->DrawDragRect(&rect, size, &m_rectLast, m_sizeLast, pBrush, m_bDitherLast ? pDitherBrush : pWhiteBrush); m_rectLast = rect; m_sizeLast = size; m_bDitherLast = (pBrush == pDitherBrush); }
CCJSizeDockBar* CCJDockContext::GetDockBar(DWORD dwOverDockStyle) { DWORD dw = 0; CDockBar* pBar; if (HORZF(dwOverDockStyle)) { ASSERT(m_pDockSite->IsKindOf(RUNTIME_CLASS(CFrameWnd))); dw = CanDockDockBar(m_rectDragHorz, dwOverDockStyle & ~CBRS_ORIENT_VERT, &pBar); ASSERT(dw != 0); ASSERT(pBar != NULL); return (CCJSizeDockBar*)pBar; } if (VERTF(dwOverDockStyle)) { dw = CanDockDockBar(m_rectDragVert, dwOverDockStyle & ~CBRS_ORIENT_HORZ, &pBar); ASSERT(dw != 0); ASSERT(pBar != NULL); return (CCJSizeDockBar*)pBar; } return NULL; }
DWORD CCJDockContext::CanDockDockBar() { BOOL bStyleHorz; DWORD dwDock = 0; DWORD dwCurr = 0; ASSERT(m_dwStyle != 0); ASSERT(m_pDockSite->IsKindOf(RUNTIME_CLASS(CFrameWnd))); bStyleHorz = HORZF(m_dwStyle); bStyleHorz = m_bFlip ? !bStyleHorz : bStyleHorz; if (bStyleHorz && HORZF(m_dwDockStyle)) { dwDock = CanDockDockBar(m_rectDragHorz, m_dwDockStyle & ~CBRS_ORIENT_VERT); } else if (VERTF(m_dwDockStyle)) { dwDock = CanDockDockBar(m_rectDragVert, m_dwDockStyle & ~CBRS_ORIENT_HORZ); } if (!m_bFlip) { if (dwDock == 0 && HORZF(m_dwDockStyle)) { dwCurr = CanDockDockBar(m_rectDragVert, m_dwDockStyle & ~CBRS_ORIENT_VERT); dwDock = CanDockDockBar(m_rectDragHorz, m_dwDockStyle & ~CBRS_ORIENT_VERT); dwDock = (dwDock == dwCurr) ? dwDock : 0; } if (dwDock == 0 && VERTF(m_dwDockStyle)) { dwCurr = CanDockDockBar(m_rectDragHorz, m_dwDockStyle & ~CBRS_ORIENT_HORZ); dwDock = CanDockDockBar(m_rectDragVert, m_dwDockStyle & ~CBRS_ORIENT_HORZ); dwDock = (dwDock == dwCurr) ? dwDock : 0; } } return dwDock; }
DWORD CDockContext::CanDock() { BOOL bStyleHorz; DWORD dwDock = 0; // Dock Canidate DWORD dwCurr = 0; // Current Orientation // let's check for something in our current orientation first // then if the shift key is not forcing our orientation then // check for horizontal or vertical orientations as long // as we are close enough ASSERT(m_dwStyle != 0); bStyleHorz = HORZF(m_dwStyle); bStyleHorz = m_bFlip ? !bStyleHorz : bStyleHorz; if (bStyleHorz && HORZF(m_dwDockStyle)) dwDock = m_pDockSite->CanDock(m_rectDragHorz, m_dwDockStyle & ~CBRS_ORIENT_VERT); else if (VERTF(m_dwDockStyle)) dwDock = m_pDockSite->CanDock(m_rectDragVert, m_dwDockStyle & ~CBRS_ORIENT_HORZ); if (!m_bFlip) { if (dwDock == 0 && HORZF(m_dwDockStyle)) { dwCurr = m_pDockSite->CanDock(m_rectDragVert, m_dwDockStyle & ~CBRS_ORIENT_VERT); dwDock = m_pDockSite->CanDock(m_rectDragHorz, m_dwDockStyle & ~CBRS_ORIENT_VERT); dwDock = (dwDock == dwCurr) ? dwDock : 0; } if (dwDock == 0 && VERTF(m_dwDockStyle)) { dwCurr = m_pDockSite->CanDock(m_rectDragHorz, m_dwDockStyle & ~CBRS_ORIENT_HORZ); dwDock = m_pDockSite->CanDock(m_rectDragVert, m_dwDockStyle & ~CBRS_ORIENT_HORZ); dwDock = (dwDock == dwCurr) ? dwDock : 0; } } return dwDock; }
void CDockContext::UpdateState(BOOL* pFlag, BOOL bNewValue) { if (*pFlag != bNewValue) { *pFlag = bNewValue; m_bFlip = (HORZF(m_dwDockStyle) && VERTF(m_dwDockStyle) && m_bFlip); // shift key m_dwOverDockStyle = (m_bForceFrame) ? 0 : CanDock(); DrawFocusRect(); } }
void COXDragDockContext::Move(CPoint pt) { CPoint ptOffset = pt - m_ptLast; #ifdef _MAC // prevent dragging the floating window completely under the menu bar GDHandle hgd = _AfxFindDevice(pt.x, pt.y); if (hgd == NULL || hgd == GetMainDevice() || TestDeviceAttribute(hgd, hasAuxMenuBar)) { CRect rect; if ((HORZF(m_dwStyle) && !m_bFlip) || (VERTF(m_dwStyle) && m_bFlip)) rect = m_rectFrameDragHorz; else rect = m_rectFrameDragVert; // determine our new position rect.OffsetRect(ptOffset); // keep us on the screen if we were getting too close to the menu bar int yMBarBottom = (*hgd)->gdRect.top + GetMBarHeight() + 4; if (rect.bottom < yMBarBottom) { pt.y += yMBarBottom - rect.bottom; ptOffset.y += yMBarBottom - rect.bottom; } } #endif // offset all drag rects to new position m_rectDragHorz.OffsetRect(ptOffset); m_rectFrameDragHorz.OffsetRect(ptOffset); m_rectDragVert.OffsetRect(ptOffset); m_rectFrameDragVert.OffsetRect(ptOffset); // these rectangles only move in 1 direction m_rectDragHorzAlone.top += ptOffset.y; m_rectDragHorzAlone.bottom += ptOffset.y; m_rectDragVertAlone.left += ptOffset.x; m_rectDragVertAlone.right += ptOffset.x; m_ptLast = pt; // if control key is down don't dock m_dwOverDockStyle = m_bForceFrame ? 0 : CanDock(); // update feedback DrawFocusRect(); }
void CGuiDockContext::EndDrag() { CancelLoop(); if (m_dwOverDockStyle != 0) { CDockBar* pDockBar = GetDockBar(m_dwOverDockStyle); ASSERT(pDockBar != NULL); CRect rect = (m_dwOverDockStyle & CBRS_ORIENT_VERT) ? m_rectDragVert : m_rectDragHorz; UINT uID = _AfxGetDlgCtrlID(pDockBar->m_hWnd); if (uID >= AFX_IDW_DOCKBAR_TOP && uID <= AFX_IDW_DOCKBAR_BOTTOM) { m_uMRUDockID = uID; m_rectMRUDockPos = rect; pDockBar->ScreenToClient(&m_rectMRUDockPos); } // dock it at the specified position, RecalcLayout will snap m_pDockSite->DockControlBar(m_pBar, pDockBar, &rect); m_pDockSite->RecalcLayout(); } else if ((m_dwStyle & CBRS_SIZE_DYNAMIC) || (HORZF(m_dwStyle) && !m_bFlip) || (VERTF(m_dwStyle) && m_bFlip)) { m_dwMRUFloatStyle = CBRS_ALIGN_TOP | (m_dwDockStyle & CBRS_FLOAT_MULTI); m_ptMRUFloatPos = m_rectFrameDragHorz.TopLeft(); m_pDockSite->FloatControlBar(m_pBar, m_ptMRUFloatPos, m_dwMRUFloatStyle); } else // vertical float { m_dwMRUFloatStyle = CBRS_ALIGN_LEFT | (m_dwDockStyle & CBRS_FLOAT_MULTI); m_ptMRUFloatPos = m_rectFrameDragVert.TopLeft(); m_pDockSite->FloatControlBar(m_pBar, m_ptMRUFloatPos, m_dwMRUFloatStyle); } }
CDockBar* CDockContext::GetDockBar(DWORD dwOverDockStyle) { DWORD dw = 0; CDockBar* pBar; if (HORZF(dwOverDockStyle)) { dw = m_pDockSite->CanDock(m_rectDragHorz, dwOverDockStyle & ~CBRS_ORIENT_VERT, &pBar); ASSERT(dw != 0); ASSERT(pBar != NULL); return pBar; } if (VERTF(dwOverDockStyle)) { dw = m_pDockSite->CanDock(m_rectDragVert, dwOverDockStyle & ~CBRS_ORIENT_HORZ, &pBar); ASSERT(dw != 0); ASSERT(pBar != NULL); return pBar; } return NULL; }
void CCJDockContext::EndDragDockBar() { CancelLoop(); if (m_dwOverDockStyle != 0) { CCJSizeDockBar* pDockBar = GetDockBar(m_dwOverDockStyle); ASSERT(pDockBar != NULL); CRect rect = (m_dwOverDockStyle & CBRS_ORIENT_VERT) ? m_rectDragVert : m_rectDragHorz; UINT uID = _AfxGetDlgCtrlID(pDockBar->m_hWnd); m_uMRUDockID = uID; m_rectMRUDockPos = rect; pDockBar->ScreenToClient(&m_rectMRUDockPos); DockSizeBar(m_pBar, pDockBar, &rect); m_pDockSite->RecalcLayout(); } else if ((m_dwStyle & CBRS_SIZE_DYNAMIC) || (HORZF(m_dwStyle) && !m_bFlip) || (VERTF(m_dwStyle) && m_bFlip)) { m_dwMRUFloatStyle = CBRS_ALIGN_TOP | (m_dwDockStyle & CBRS_FLOAT_MULTI); m_ptMRUFloatPos = m_rectFrameDragHorz.TopLeft(); m_pDockSite->FloatControlBar(m_pBar, m_ptMRUFloatPos, m_dwMRUFloatStyle); m_pDockSite->RecalcLayout(); } else { m_dwMRUFloatStyle = CBRS_ALIGN_LEFT | (m_dwDockStyle & CBRS_FLOAT_MULTI); m_ptMRUFloatPos = m_rectFrameDragVert.TopLeft(); m_pDockSite->FloatControlBar(m_pBar, m_ptMRUFloatPos, m_dwMRUFloatStyle); m_pDockSite->RecalcLayout(); } }
void CDockContext::StartDrag(CPoint pt) { ASSERT_VALID(m_pBar); m_bDragging = TRUE; InitLoop(); if (m_pBar->m_dwStyle & CBRS_SIZE_DYNAMIC) { // get true bar size (including borders) CRect rect; m_pBar->GetWindowRect(rect); m_ptLast = pt; CSize sizeHorz = m_pBar->CalcDynamicLayout(0, LM_HORZ | LM_HORZDOCK); CSize sizeVert = m_pBar->CalcDynamicLayout(0, LM_VERTDOCK); CSize sizeFloat = m_pBar->CalcDynamicLayout(0, LM_HORZ | LM_MRUWIDTH); m_rectDragHorz = CRect(rect.TopLeft(), sizeHorz); m_rectDragVert = CRect(rect.TopLeft(), sizeVert); // calculate frame dragging rectangle m_rectFrameDragHorz = CRect(rect.TopLeft(), sizeFloat); m_rectFrameDragVert = CRect(rect.TopLeft(), sizeFloat); #ifdef _MAC CMiniFrameWnd::CalcBorders(&m_rectFrameDragHorz, WS_THICKFRAME | WS_CAPTION, WS_EX_FORCESIZEBOX); CMiniFrameWnd::CalcBorders(&m_rectFrameDragVert, WS_THICKFRAME | WS_CAPTION, WS_EX_FORCESIZEBOX); #else CMiniFrameWnd::CalcBorders(&m_rectFrameDragHorz); CMiniFrameWnd::CalcBorders(&m_rectFrameDragVert); #endif m_rectFrameDragHorz.InflateRect(-afxData.cxBorder2, -afxData.cyBorder2); m_rectFrameDragVert.InflateRect(-afxData.cxBorder2, -afxData.cyBorder2); } else if (m_pBar->m_dwStyle & CBRS_SIZE_FIXED) { // get true bar size (including borders) CRect rect; m_pBar->GetWindowRect(rect); m_ptLast = pt; CSize sizeHorz = m_pBar->CalcDynamicLayout(-1, LM_HORZ | LM_HORZDOCK); CSize sizeVert = m_pBar->CalcDynamicLayout(-1, LM_VERTDOCK); // calculate frame dragging rectangle m_rectFrameDragHorz = m_rectDragHorz = CRect(rect.TopLeft(), sizeHorz); m_rectFrameDragVert = m_rectDragVert = CRect(rect.TopLeft(), sizeVert); CMiniFrameWnd::CalcBorders(&m_rectFrameDragHorz); CMiniFrameWnd::CalcBorders(&m_rectFrameDragVert); m_rectFrameDragHorz.InflateRect(-afxData.cxBorder2, -afxData.cyBorder2); m_rectFrameDragVert.InflateRect(-afxData.cxBorder2, -afxData.cyBorder2); } else { // get true bar size (including borders) CRect rect; m_pBar->GetWindowRect(rect); m_ptLast = pt; BOOL bHorz = HORZF(m_dwStyle); DWORD dwMode = !bHorz ? (LM_HORZ | LM_HORZDOCK) : LM_VERTDOCK; CSize size = m_pBar->CalcDynamicLayout(-1, dwMode); // calculate inverted dragging rect if (bHorz) { m_rectDragHorz = rect; m_rectDragVert = CRect(CPoint(pt.x - rect.Height()/2, rect.top), size); } else // vertical orientation { m_rectDragVert = rect; m_rectDragHorz = CRect(CPoint(rect.left, pt.y - rect.Width()/2), size); } // calculate frame dragging rectangle m_rectFrameDragHorz = m_rectDragHorz; m_rectFrameDragVert = m_rectDragVert; CMiniFrameWnd::CalcBorders(&m_rectFrameDragHorz); CMiniFrameWnd::CalcBorders(&m_rectFrameDragVert); m_rectFrameDragHorz.InflateRect(-afxData.cxBorder2, -afxData.cyBorder2); m_rectFrameDragVert.InflateRect(-afxData.cxBorder2, -afxData.cyBorder2); } // adjust rectangles so that point is inside AdjustRectangle(m_rectDragHorz, pt); AdjustRectangle(m_rectDragVert, pt); AdjustRectangle(m_rectFrameDragHorz, pt); AdjustRectangle(m_rectFrameDragVert, pt); // initialize tracking state and enter tracking loop m_dwOverDockStyle = CanDock(); Move(pt); // call it here to handle special keys Track(); }
void CDockContext::StartDrag(CPoint pt) { ASSERT_VALID(m_pBar); m_bDragging = TRUE; InitLoop(); // GetWindowRect returns screen coordinates(not mirrored), // so if the desktop is mirrored then turn off mirroring // for the desktop dc so that we get correct focus rect drawn. // This layout change should be remembered, just in case ... if (m_pDC->GetLayout() & LAYOUT_RTL) m_pDC->SetLayout(LAYOUT_LTR); if (m_pBar->m_dwStyle & CBRS_SIZE_DYNAMIC) { // get true bar size (including borders) CRect rect; m_pBar->GetWindowRect(rect); m_ptLast = pt; CSize sizeHorz = m_pBar->CalcDynamicLayout(0, LM_HORZ | LM_HORZDOCK); CSize sizeVert = m_pBar->CalcDynamicLayout(0, LM_VERTDOCK); CSize sizeFloat = m_pBar->CalcDynamicLayout(0, LM_HORZ | LM_MRUWIDTH); m_rectDragHorz = CRect(rect.TopLeft(), sizeHorz); m_rectDragVert = CRect(rect.TopLeft(), sizeVert); // calculate frame dragging rectangle m_rectFrameDragHorz = CRect(rect.TopLeft(), sizeFloat); m_rectFrameDragVert = CRect(rect.TopLeft(), sizeFloat); CMiniFrameWnd::CalcBorders(&m_rectFrameDragHorz); CMiniFrameWnd::CalcBorders(&m_rectFrameDragVert); m_rectFrameDragHorz.InflateRect(-afxData.cxBorder2, -afxData.cyBorder2); m_rectFrameDragVert.InflateRect(-afxData.cxBorder2, -afxData.cyBorder2); } else if (m_pBar->m_dwStyle & CBRS_SIZE_FIXED) { // get true bar size (including borders) CRect rect; m_pBar->GetWindowRect(rect); m_ptLast = pt; CSize sizeHorz = m_pBar->CalcDynamicLayout(-1, LM_HORZ | LM_HORZDOCK); CSize sizeVert = m_pBar->CalcDynamicLayout(-1, LM_VERTDOCK); // calculate frame dragging rectangle m_rectFrameDragHorz = m_rectDragHorz = CRect(rect.TopLeft(), sizeHorz); m_rectFrameDragVert = m_rectDragVert = CRect(rect.TopLeft(), sizeVert); CMiniFrameWnd::CalcBorders(&m_rectFrameDragHorz); CMiniFrameWnd::CalcBorders(&m_rectFrameDragVert); m_rectFrameDragHorz.InflateRect(-afxData.cxBorder2, -afxData.cyBorder2); m_rectFrameDragVert.InflateRect(-afxData.cxBorder2, -afxData.cyBorder2); } else { // get true bar size (including borders) CRect rect; m_pBar->GetWindowRect(rect); m_ptLast = pt; BOOL bHorz = HORZF(m_dwStyle); DWORD dwMode = !bHorz ? (LM_HORZ | LM_HORZDOCK) : LM_VERTDOCK; CSize size = m_pBar->CalcDynamicLayout(-1, dwMode); // calculate inverted dragging rect if (bHorz) { m_rectDragHorz = rect; m_rectDragVert = CRect(CPoint(pt.x - rect.Height()/2, rect.top), size); } else // vertical orientation { m_rectDragVert = rect; m_rectDragHorz = CRect(CPoint(rect.left, pt.y - rect.Width()/2), size); } // calculate frame dragging rectangle m_rectFrameDragHorz = m_rectDragHorz; m_rectFrameDragVert = m_rectDragVert; CMiniFrameWnd::CalcBorders(&m_rectFrameDragHorz); CMiniFrameWnd::CalcBorders(&m_rectFrameDragVert); m_rectFrameDragHorz.InflateRect(-afxData.cxBorder2, -afxData.cyBorder2); m_rectFrameDragVert.InflateRect(-afxData.cxBorder2, -afxData.cyBorder2); } // adjust rectangles so that point is inside _AfxAdjustRectangle(m_rectDragHorz, pt); _AfxAdjustRectangle(m_rectDragVert, pt); _AfxAdjustRectangle(m_rectFrameDragHorz, pt); _AfxAdjustRectangle(m_rectFrameDragVert, pt); // initialize tracking state and enter tracking loop m_dwOverDockStyle = CanDock(); Move(pt); // call it here to handle special keys Track(); }
void CGuiDockContext::DrawFocusRect(BOOL bRemoveRect) { ASSERT(m_pDC != NULL); // default to thin frame CSize size(CX_BORDER, CY_BORDER); // determine new rect and size CRect rect; CBrush* pWhiteBrush = CBrush::FromHandle((HBRUSH)::GetStockObject(WHITE_BRUSH)); CBrush* pDitherBrush = CDC::GetHalftoneBrush(); CBrush* pBrush = pWhiteBrush; if (HORZF(m_dwOverDockStyle)) rect = m_rectDragHorz; else if (VERTF(m_dwOverDockStyle)) rect = m_rectDragVert; else { // use thick frame instead size.cx = GetSystemMetrics(SM_CXFRAME) - CX_BORDER; size.cy = GetSystemMetrics(SM_CYFRAME) - CY_BORDER; if ((HORZF(m_dwStyle) && !m_bFlip) || (VERTF(m_dwStyle) && m_bFlip)) rect = m_rectFrameDragHorz; else rect = m_rectFrameDragVert; pBrush = pDitherBrush; } if (bRemoveRect) size.cx = size.cy = 0; /* if (afxData.bWin4 && (HORZF(m_dwOverDockStyle) || VERTF(m_dwOverDockStyle))) { // looks better one pixel in (makes the bar look pushed down) rect.InflateRect(-CX_BORDER, -CY_BORDER); } */ // draw it and remember last size if (bFirstClic==TRUE) { bFirstClic=FALSE; } else{ if (bSecondClic==TRUE) { m_pDC->DrawDragRect(&rect, size, &m_rectLast, m_sizeLast, pBrush, m_bDitherLast ? pDitherBrush : pWhiteBrush); m_bDitherLast = (pBrush == pDitherBrush); m_pDC->DrawDragRect(&rect, size, &m_rectLast, m_sizeLast, pBrush, m_bDitherLast ? pDitherBrush : pWhiteBrush); bSecondClic=FALSE; } else { m_pDC->DrawDragRect(&rect, size, &m_rectLast, m_sizeLast, pBrush, m_bDitherLast ? pDitherBrush : pWhiteBrush); m_rectLast = rect; m_sizeLast = size; m_bDitherLast = (pBrush == pDitherBrush); } } }
// start dragging. This is the only routine exposed externally. // pt = mouse position at start of drag (screen co-ords) void COXDragDockContext::StartDrag(CPoint pt) { ASSERT_VALID(m_pBar); ASSERT(m_pBar->IsKindOf(RUNTIME_CLASS(COXSizeControlBar))); COXSizeControlBar* pSzBar = (COXSizeControlBar*)m_pBar; // get styles from bar m_dwDockStyle = m_pBar->m_dwDockStyle; m_dwStyle = m_pBar->m_dwStyle & CBRS_ALIGN_ANY; ASSERT(m_dwStyle != 0); // check to see we're not hanging from a COXMDIFloatWnd. // Disallow dragging if we are... if (m_pBar->IsFloating()) { CFrameWnd* pFrameWnd = m_pBar->GetParentFrame(); ASSERT(pFrameWnd != NULL); ASSERT(pFrameWnd->IsKindOf(RUNTIME_CLASS(CFrameWnd))); if (pFrameWnd->IsKindOf(RUNTIME_CLASS(COXMDIFloatWnd))) return; // do nothing if floating inside a COXMDIFloatWnd } // dragging has started message (only if window will actually dock !) if ((m_dwDockStyle & CBRS_ALIGN_ANY) == CBRS_ALIGN_ANY) AfxGetMainWnd()->SendMessage(WM_SETMESSAGESTRING, IDS_OX_MRC_STARTDOCKING); // handle pending WM_PAINT messages MSG msg; while (::PeekMessage(&msg, NULL, WM_PAINT, WM_PAINT, PM_NOREMOVE)) { if (!GetMessage(&msg, NULL, WM_PAINT, WM_PAINT)) return; ASSERT(msg.message == WM_PAINT); DispatchMessage(&msg); } // initialize drag state m_rectLast.SetRectEmpty(); m_sizeLast.cx = m_sizeLast.cy = 0; m_bForceFrame = m_bFlip = m_bDitherLast = FALSE; // get current bar location CRect rect; m_pBar->GetWindowRect(rect); m_ptLast = pt; m_ptStart = pt; BOOL bHorz = HORZF(m_dwStyle); // MFC includes code for flipping orientation using the shift key - I wasn't keen // on this... (sorry) so I've left it out for now. Some references are still left // in for it, in case I decide to implement it. // Start by working out the possible rectangles that dragging could result in. // These are: // m_rectFrameDragHorz : floating frame, horizontal orientation // m_rectFrameDragVert : floating frame, vertical orientation (not used, 'cos // flipping not allowed) // // m_rectDragHorz : docking horizontally, another bar already on this row // m_rectDragVert : docking vertically, another bar already on this row // m_rectDragHorzAlone : docking horizontally, on a new row // m_rectDragVertAlone : docking vertically, on a new row // calculate dragging rects if you drag on the new row/column // CRect rectBorder; m_pDockSite->RepositionBars(0,0xffff,AFX_IDW_PANE_FIRST, CFrameWnd::reposQuery,&rectBorder); m_pDockSite->ClientToScreen(rectBorder); CWnd* pLeftDockBar=m_pDockSite->GetControlBar(AFX_IDW_DOCKBAR_LEFT); if(pLeftDockBar!=NULL && pLeftDockBar->GetStyle()&WS_VISIBLE) { CRect rectDockBar; pLeftDockBar->GetWindowRect(rectDockBar); rectBorder.left-=rectDockBar.Width(); } CWnd* pRightDockBar=m_pDockSite->GetControlBar(AFX_IDW_DOCKBAR_RIGHT); if(pRightDockBar!=NULL && pRightDockBar->GetStyle()&WS_VISIBLE) { CRect rectDockBar; pRightDockBar->GetWindowRect(rectDockBar); rectBorder.right+=rectDockBar.Width(); } m_rectDragHorzAlone=CRect(CPoint(rectBorder.left,rect.top),rectBorder.Size()); m_rectDragVertAlone=CRect(CPoint(rect.left,rectBorder.top),rectBorder.Size()); m_rectDragHorzAlone.bottom=m_rectDragHorzAlone.top+pSzBar->m_HorzDockSize.cy; m_rectDragVertAlone.right=m_rectDragVertAlone.left+pSzBar->m_VertDockSize.cx; // ////////////////////////////////////////////////////////////// ////////////////// // int nDockAreaWidth = rectBorder.Width(); int nDockAreaHeight = rectBorder.Height(); CSize HorzAloneSize(nDockAreaWidth, pSzBar->m_HorzDockSize.cy); CSize VertAloneSize(pSzBar->m_VertDockSize.cx, nDockAreaHeight); // sizes to use when docking into a row that already has some bars. // use the stored sizes - unless they are > the max dock area - // in which case make a guess. if (pSzBar->m_VertDockSize.cy >= nDockAreaHeight - 16) VertAloneSize.cy = nDockAreaHeight / 3; else VertAloneSize.cy = pSzBar->m_VertDockSize.cy; if (pSzBar->m_HorzDockSize.cx >= nDockAreaWidth - 16) HorzAloneSize.cx = nDockAreaWidth / 3; else HorzAloneSize.cx = pSzBar->m_HorzDockSize.cx; m_rectDragHorz = CRect(rect.TopLeft(), HorzAloneSize); m_rectDragVert = CRect(rect.TopLeft(), VertAloneSize); // /////////////////// // rectangle for the floating frame... m_rectFrameDragVert = m_rectFrameDragHorz = CRect(rect.TopLeft(), pSzBar->m_FloatSize); // To work out the size we actually create a floating mini frame, and then see how big // it is CMiniDockFrameWnd* pFloatFrame = m_pDockSite->CreateFloatingFrame(bHorz ? CBRS_ALIGN_TOP : CBRS_ALIGN_LEFT); if (pFloatFrame == NULL) AfxThrowMemoryException(); pFloatFrame->CalcWindowRect(&m_rectFrameDragHorz); pFloatFrame->CalcWindowRect(&m_rectFrameDragVert); // m_rectFrameDragHorz.InflateRect(-afxData.cxBorder2, -afxData.cyBorder2); // m_rectFrameDragVert.InflateRect(-afxData.cxBorder2, -afxData.cyBorder2); pFloatFrame->DestroyWindow(); // adjust rectangles so that point is inside AdjustRectangle(m_rectDragHorzAlone, pt); AdjustRectangle(m_rectDragVertAlone, pt); AdjustRectangle(m_rectDragHorz, pt); AdjustRectangle(m_rectDragVert, pt); AdjustRectangle(m_rectFrameDragHorz, pt); AdjustRectangle(m_rectFrameDragVert, pt); // lock window update while dragging ASSERT(m_pDC == NULL); CWnd* pWnd = CWnd::GetDesktopWindow(); #ifndef _MAC if (pWnd->LockWindowUpdate()) m_pDC = pWnd->GetDCEx(NULL, DCX_WINDOW|DCX_CACHE|DCX_LOCKWINDOWUPDATE); else #endif m_pDC = pWnd->GetDCEx(NULL, DCX_WINDOW|DCX_CACHE); ASSERT(m_pDC != NULL); // initialize tracking state and enter tracking loop m_dwOverDockStyle = CanDock(); Move(pt); // call it here to handle special keys Track(); }
DWORD COXDragDockContext::CanDock() { BOOL bStyleHorz; DWORD dwDock = 0; // Dock Canidate DWORD dwCurr = 0; // Current Orientation // let's check for something in our current orientation first // then if the shift key is not forcing our orientation then // check for horizontal or vertical orientations as long // as we are close enough ASSERT(m_dwStyle != 0); bStyleHorz = HORZF(m_dwStyle); m_pTargetDockBar = NULL; // can simplify this, 'cos most of the rectangles are actually the same if (dwDock == 0 && HORZF(m_dwDockStyle)/* && m_rectDragHorzAlone.PtInRect(m_ptLast)*/) { dwDock = m_pDockSite->CanDock(m_rectDragHorzAlone, m_dwDockStyle & ~CBRS_ORIENT_VERT, (CDockBar**)&m_pTargetDockBar); } if (dwDock == 0 && VERTF(m_dwDockStyle)/* && m_rectDragVertAlone.PtInRect(m_ptLast)*/) { dwDock = m_pDockSite->CanDock(m_rectDragVertAlone, m_dwDockStyle & ~CBRS_ORIENT_HORZ, (CDockBar**)&m_pTargetDockBar); } if (dwDock != 0) // will dock somewhere - now look for 1/2 bars on the row... { if (HORZF(dwDock)) { m_rectDragDock = m_rectDragHorzAlone; dwCurr = m_pDockSite->CanDock(m_rectDragHorz, m_dwDockStyle & ~CBRS_ORIENT_VERT, (CDockBar**)&m_pTargetDockBar); if (dwCurr != 0) { int nBars=m_pTargetDockBar->BarsOnThisRow(m_pBar,m_rectDragHorzAlone); if(nBars!=0) { m_rectDragDock = m_rectDragHorz; m_rectDragDock.right = m_rectDragDock.left+ m_rectDragHorzAlone.Width()/(nBars+1); } } } if (VERTF(dwDock)) { m_rectDragDock = m_rectDragVertAlone; dwCurr = m_pDockSite->CanDock(m_rectDragVert, m_dwDockStyle & ~CBRS_ORIENT_HORZ, (CDockBar**)&m_pTargetDockBar); if (dwCurr != 0) { int nBars=m_pTargetDockBar->BarsOnThisRow(m_pBar,m_rectDragVertAlone); if(nBars!=0) { m_rectDragDock = m_rectDragVert; m_rectDragDock.bottom = m_rectDragDock.top+ m_rectDragVertAlone.Height()/(nBars+1); } } } } return dwCurr; }
void COXDragDockContext::EndDrag() { CancelDrag(); if (m_ptStart == m_ptLast) return; m_dwOverDockStyle = m_bForceFrame ? 0 : CanDock(); if (m_dwOverDockStyle != 0) { // dockbar we're going to dock at. CDockBar* pDockBar = GetDockBar(); ASSERT(pDockBar != NULL); // check the original dockbar - if a valid CSizeDockBar... // work out the row number. CDockBar* pOrigDockBar = m_pBar->m_pDockBar; int nOrigCheckSum = -1; if (pOrigDockBar != NULL && pOrigDockBar->IsKindOf(RUNTIME_CLASS(COXSizeDockBar))) nOrigCheckSum = ((COXSizeDockBar*)pOrigDockBar)->CheckSumBars(); // Now we're going to actually dock the window. // Update the appropriate size in the control bar. if (HORZF(m_dwOverDockStyle)) { ((COXSizeControlBar*)m_pBar)->m_HorzDockSize = m_rectDragDock.Size(); } else { ((COXSizeControlBar*)m_pBar)->m_VertDockSize = m_rectDragDock.Size(); } m_pDockSite->DockControlBar(m_pBar, pDockBar, m_rectDragDock); // if into a sizeable dockbar (always we be !), then adjust other bars in the same row // to attempt to maintain size if (pDockBar->IsKindOf(RUNTIME_CLASS(COXSizeDockBar))) { if (pOrigDockBar != pDockBar || ((COXSizeDockBar*)pDockBar)->CheckSumBars() != nOrigCheckSum) { ((COXSizeDockBar*)pDockBar)->AdjustForNewBar(m_pBar); } // force RecalcLayout below to adjust sizes always for the bar into // which we have docked - this is needed as if the bar doesn't // actually changed position in the array, but has changed size // (because the docking algorithm above guess the size wrong, then // we need to set it back again. ((COXSizeDockBar*)pDockBar)->m_CountBars = 0; } // This RecalcLayout is what will adjust the size. m_pDockSite->RecalcLayout(); } else { m_ptMRUFloatPos = m_rectFrameDragHorz.TopLeft(); m_pDockSite->FloatControlBar(m_pBar, m_rectFrameDragHorz.TopLeft(), CBRS_ALIGN_TOP | (m_dwDockStyle & CBRS_FLOAT_MULTI)); m_pBar->SendMessage(WM_OX_APP_AFTERFLOAT_MSG); // set flag to indicate user has moved the bar - done as a style flag on the window. CWnd* pFrameWnd = m_pBar->GetParentFrame(); ASSERT(pFrameWnd->IsKindOf(RUNTIME_CLASS(CMiniDockFrameWnd))); pFrameWnd->ModifyStyle(0, CBRS_MOVED_BY_USER); } }
void CCJDockContext::StartDragDockBar(CPoint pt) { ASSERT_VALID(m_pBar); m_bDragging = TRUE; InitLoop(); if (m_pBar->m_dwStyle & CBRS_SIZE_DYNAMIC) { CRect rect; m_pBar->GetWindowRect(rect); m_ptLast = pt; CSize sizeHorz = m_pBar->CalcDynamicLayout(0, LM_HORZ | LM_HORZDOCK); CSize sizeVert = m_pBar->CalcDynamicLayout(0, LM_VERTDOCK); CSize sizeFloat = m_pBar->CalcDynamicLayout(0, LM_HORZ | LM_MRUWIDTH); m_rectDragHorz = CRect(rect.TopLeft(), sizeHorz); m_rectDragVert = CRect(rect.TopLeft(), sizeVert); // calculate frame dragging rectangle m_rectFrameDragHorz = CRect(rect.TopLeft(), sizeFloat); m_rectFrameDragVert = CRect(rect.TopLeft(), sizeFloat); CMiniFrameWnd::CalcBorders(&m_rectFrameDragHorz); CMiniFrameWnd::CalcBorders(&m_rectFrameDragVert); m_rectFrameDragHorz.InflateRect(-afxData.cxBorder2, -afxData.cyBorder2); m_rectFrameDragVert.InflateRect(-afxData.cxBorder2, -afxData.cyBorder2); } else if (m_pBar->m_dwStyle & CBRS_SIZE_FIXED) { CRect rect; m_pBar->GetWindowRect(rect); m_ptLast = pt; CSize sizeHorz = m_pBar->CalcDynamicLayout(-1, LM_HORZ | LM_HORZDOCK); CSize sizeVert = m_pBar->CalcDynamicLayout(-1, LM_VERTDOCK); m_rectFrameDragHorz = m_rectDragHorz = CRect(rect.TopLeft(), sizeHorz); m_rectFrameDragVert = m_rectDragVert = CRect(rect.TopLeft(), sizeVert); CMiniFrameWnd::CalcBorders(&m_rectFrameDragHorz); CMiniFrameWnd::CalcBorders(&m_rectFrameDragVert); m_rectFrameDragHorz.InflateRect(-afxData.cxBorder2, -afxData.cyBorder2); m_rectFrameDragVert.InflateRect(-afxData.cxBorder2, -afxData.cyBorder2); } else { CRect rect; m_pBar->GetWindowRect(rect); m_ptLast = pt; BOOL bHorz = HORZF(m_dwStyle); DWORD dwMode = !bHorz ? (LM_HORZ | LM_HORZDOCK) : LM_VERTDOCK; CSize size = m_pBar->CalcDynamicLayout(-1, dwMode); if (bHorz) { m_rectDragHorz = rect; m_rectDragVert = CRect(CPoint(pt.x - rect.Height()/2, rect.top), size); } else { m_rectDragVert = rect; m_rectDragHorz = CRect(CPoint(rect.left, pt.y - rect.Width()/2), size); } m_rectFrameDragHorz = m_rectDragHorz; m_rectFrameDragVert = m_rectDragVert; CMiniFrameWnd::CalcBorders(&m_rectFrameDragHorz); CMiniFrameWnd::CalcBorders(&m_rectFrameDragVert); m_rectFrameDragHorz.InflateRect(-afxData.cxBorder2, -afxData.cyBorder2); m_rectFrameDragVert.InflateRect(-afxData.cxBorder2, -afxData.cyBorder2); } AdjustRectangle(m_rectDragHorz, pt); AdjustRectangle(m_rectDragVert, pt); AdjustRectangle(m_rectFrameDragHorz, pt); AdjustRectangle(m_rectFrameDragVert, pt); m_dwOverDockStyle = CanDockDockBar(); MoveDockBar(pt); TrackDockBar(); }