void CGuiDocBarExten::BarsDocking(CFrameWnd * pFrame, DWORD dwDockStyle) { ASSERT_VALID(pFrame); // must be CBRS_ALIGN_XXX or CBRS_FLOAT_MULTI only ASSERT((dwDockStyle & ~(CBRS_ALIGN_ANY|CBRS_FLOAT_MULTI)) == 0); pFrame->EnableDocking(dwDockStyle); for (int i = 0; i < 4; i++) { if (dwDockBarMap[i][1] & dwDockStyle & CBRS_ALIGN_ANY) { CDockBar* pDock = (CDockBar*)pFrame->GetControlBar(dwDockBarMap[i][0]); if( pDock == 0 || ! pDock->IsKindOf(RUNTIME_CLASS(CGuiDocBarExten)) ) { BOOL bNeedDelete = ! pDock->m_bAutoDelete; pDock->m_pDockSite->RemoveControlBar(pDock); pDock->m_pDockSite = 0; pDock->DestroyWindow(); if( bNeedDelete ) delete pDock; pDock = 0; } if( pDock == 0 ) { pDock = new CGuiDocBarExten; ASSERT_VALID(pDock); if ((!pDock) || (!pDock->Create(pFrame, WS_CLIPSIBLINGS|WS_CLIPCHILDREN|WS_CHILD|WS_VISIBLE | dwDockBarMap[i][1], dwDockBarMap[i][0]))) { AfxThrowResourceException(); } } } } }
DWORD CFrameWnd::CanDock( CRect rect, DWORD dwDockStyle, CDockBar **ppDockBar ) /*****************************************************************************/ { POSITION position = m_listControlBars.GetHeadPosition(); while( position != NULL ) { CControlBar *pControlBar = (CControlBar *)m_listControlBars.GetNext( position ); ASSERT( pControlBar != NULL ); if( pControlBar->IsDockBar() && (pControlBar->GetBarStyle() & dwDockStyle) ) { CDockBar *pDockBar = (CDockBar *)pControlBar; ASSERT( pDockBar->IsKindOf( RUNTIME_CLASS( CDockBar ) ) ); if( !pDockBar->m_bFloating || (pDockBar->GetBarStyle() & CBRS_FLOAT_MULTI) ) { CRect rectBar; pDockBar->GetWindowRect( &rectBar ); RECT rectJunk; if( rectBar.left == rectBar.right ) { rectBar.right++; } if( rectBar.top == rectBar.bottom ) { rectBar.bottom++; } if( ::IntersectRect( &rectJunk, &rect, &rectBar ) ) { if( ppDockBar != NULL ) { *ppDockBar = pDockBar; } return( pDockBar->GetBarStyle() & dwDockStyle ); } } } } return( 0L ); }
void CFrameWnd::DockControlBar( CControlBar *pBar, UINT nDockBarID, LPCRECT lpRect ) /**********************************************************************************/ { CDockBar *pDockBar = NULL; if( nDockBarID != 0 ) { pDockBar = (CDockBar *)GetControlBar( nDockBarID ); if( pDockBar == NULL ) { // We're trying to dock to a dock bar that doesn't exist, so just don't do // anything. return; } if( !(pBar->m_dwDockStyle & (pDockBar->m_dwStyle & CBRS_ALIGN_ANY)) ) { // We don't support docking to a bar of this style, so just don't do // anything. return; } ASSERT( pDockBar->IsKindOf( RUNTIME_CLASS( CDockBar ) ) ); if( lpRect != NULL ) { RECT rectJunk; CRect rectBar; pDockBar->GetWindowRect( &rectBar ); if( rectBar.left == rectBar.right ) { rectBar.left--; rectBar.right++; } if( rectBar.top == rectBar.bottom ) { rectBar.top--; rectBar.bottom++; } if( !::IntersectRect( &rectJunk, &rectBar, lpRect ) ) { // The rectangle and the dock bar identifier don't coincide, so just // don't do anything. return; } } } else if( lpRect != NULL ){ CanDock( *lpRect, pBar->m_dwDockStyle, &pDockBar ); } else { CanDock( CRect( 0, 0, 32767, 32767 ), pBar->m_dwDockStyle, &pDockBar ); } if( pDockBar != NULL ) { ASSERT( pDockBar->IsKindOf( RUNTIME_CLASS( CDockBar ) ) ); pDockBar->DockControlBar( pBar, lpRect ); } }
void ForceLayoutAdjust(CControlBar * pBar) // if control bar supplied, then set just resize it { CDockBar * pDockBar; ASSERT(pBar != NULL); pDockBar = pBar->m_pDockBar; if (pDockBar!= NULL && pDockBar->IsKindOf(RUNTIME_CLASS(CSizeDockBar))) ((CSizeDockBar *)pDockBar)->m_CountBars = 0; }
//-------------------------------------------------------------------------------------------- void CMRCMDIFrameWndSizeDock::UnFloatInMDIChild(CControlBar* pBar, CPoint point, DWORD dwStyle) // removes the control bar from an MDI floating window, and then floats the bar //-------------------------------------------------------------------------------------------- { ASSERT(pBar != NULL); ASSERT(pBar->IsFloating()); CMRCMDIFloatWnd * pFloatFrame = (CMRCMDIFloatWnd *)pBar->GetParentFrame(); ASSERT(pFloatFrame->IsKindOf(RUNTIME_CLASS(CMRCMDIFloatWnd))); // point at which to float is ignored at present - use the co-ordinates of the current frame CRect rcMDIFloat; pFloatFrame->GetWindowRect(&rcMDIFloat); point = rcMDIFloat.TopLeft(); // This is basically the code from MFC's CFrameWnd::FloatControlBar(), with the // test to avoid destroying/creating the floating frame window removed. // Tried explicitly removing the control bar, but this doesn't work as it destroys the // CMDIFloatWnd, which in turn kills the child control bar. So need to create the floating // frame first, and then dock into this. ASSERT(m_pFloatingFrameClass != NULL); CMiniDockFrameWnd* pDockFrame = CreateFloatingFrame(dwStyle); ASSERT(pDockFrame != NULL); pDockFrame->SetWindowPos(NULL, point.x, point.y, 0, 0, SWP_NOSIZE|SWP_NOZORDER|SWP_NOACTIVATE); if (pDockFrame->m_hWndOwner == NULL) pDockFrame->m_hWndOwner = pBar->m_hWnd; CDockBar* pDockBar = (CDockBar*)pDockFrame->GetDlgItem(AFX_IDW_DOCKBAR_FLOAT); ASSERT(pDockBar != NULL); ASSERT(pDockBar->IsKindOf(RUNTIME_CLASS(CDockBar))); ASSERT(pBar->m_pDockSite == this); // if this assertion occurred it is because the parent of pBar was not // initially this CFrameWnd when pBar's OnCreate was called // (this control bar should have been created with a different // parent initially) pDockBar->DockControlBar(pBar); pDockFrame->RecalcLayout(); pDockFrame->ShowWindow(SW_SHOWNA); pDockFrame->UpdateWindow(); }
void CFrameWnd::FloatControlBar( CControlBar *pBar, CPoint pt, DWORD dwStyle ) /****************************************************************************/ { ASSERT( pBar != NULL ); if( pBar->IsFloating() && !(pBar->m_pDockBar->GetBarStyle() & CBRS_FLOAT_MULTI) ) { CFrameWnd *pFrame = pBar->GetParentFrame(); pFrame->SetWindowPos( NULL, pt.x, pt.y, 0, 0, SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOZORDER ); } else { CMiniDockFrameWnd *pFrame = CreateFloatingFrame( dwStyle ); ASSERT( pFrame != NULL ); CDockBar *pDockBar = (CDockBar *)pFrame->GetDlgItem( AFX_IDW_DOCKBAR_FLOAT ); ASSERT( pDockBar != NULL ); ASSERT( pDockBar->IsKindOf( RUNTIME_CLASS( CDockBar ) ) ); pDockBar->DockControlBar( pBar ); if( pt.x != CW_USEDEFAULT && pt.y != CW_USEDEFAULT ) { pFrame->SetWindowPos( NULL, pt.x, pt.y, 0, 0, SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOZORDER ); } pFrame->ShowWindow( SW_SHOW ); pFrame->UpdateWindow(); RecalcLayout(); } }
//----------------------------------------------------------------------------------------------------- void CMRCMDIFrameWndSizeDock::FloatControlBarInMDIChild(CControlBar* pBar, CPoint point, DWORD dwStyle) // float a control bar in an MDI Child window // pBar = bar to float // point = position in screen co-ordinates //----------------------------------------------------------------------------------------------------- { ASSERT(pBar != NULL); // point is in screen co-ords - map to client ::ScreenToClient(m_hWndMDIClient, &point); // clip to client MDI client rectangle - ensures it's going to be visible CRect rcMDIClient; ::GetClientRect(m_hWndMDIClient, &rcMDIClient); point.x = min (point.x, rcMDIClient.right - 32); point.x = max (point.x, rcMDIClient.left); point.y = min (point.y, rcMDIClient.bottom - 20); point.y = max (point.y, rcMDIClient.top); // If the bar is already floating in an MDI child, then just move it // MFC has a similar optimization for CMiniDockFrameWnd if (pBar->m_pDockSite != NULL && pBar->m_pDockBar != NULL) { CDockBar* pDockBar = pBar->m_pDockBar; ASSERT(pDockBar->IsKindOf(RUNTIME_CLASS(CDockBar))); CFrameWnd* pDockFrame = (CFrameWnd*)pDockBar->GetParent(); ASSERT(pDockFrame != NULL); ASSERT(pDockFrame->IsKindOf(RUNTIME_CLASS(CFrameWnd))); if (pDockFrame->IsKindOf(RUNTIME_CLASS(CMRCMDIFloatWnd))) { // already a floating as an MDI child, so just move it. if (pDockBar->m_bFloating && pDockBar->GetDockedCount() == 1 && (dwStyle & pDockBar->m_dwStyle & CBRS_ALIGN_ANY) != 0) { pDockFrame->SetWindowPos(NULL, point.x, point.y, 0, 0, SWP_NOSIZE|SWP_NOZORDER|SWP_NOACTIVATE); return; } } } // Create a CMRCMDIFloatWnd, and dock the bar into it. CMRCMDIFloatWnd * pDockFrame = (CMRCMDIFloatWnd *)(RUNTIME_CLASS(CMRCMDIFloatWnd))->CreateObject(); ASSERT(pDockFrame != NULL); if (!pDockFrame->Create(this, dwStyle)) AfxThrowResourceException(); pDockFrame->SetWindowPos(NULL, point.x, point.y, 0, 0, SWP_NOSIZE|SWP_NOZORDER|SWP_NOACTIVATE); if (pDockFrame->m_hWndOwner == NULL) pDockFrame->m_hWndOwner = pBar->m_hWnd; // Gets the dockbar created by the CMRCMDIFloatWnd CDockBar* pDockBar = (CDockBar*)pDockFrame->GetDlgItem(AFX_IDW_DOCKBAR_FLOAT); ASSERT(pDockBar != NULL); ASSERT(pDockBar->IsKindOf(RUNTIME_CLASS(CDockBar))); ASSERT(pBar->m_pDockSite == this); // if this assertion occurred it is because the parent of pBar was not // initially this CFrameWnd when pBar's OnCreate was called // (this control bar should have been created with a different // parent initially) pDockBar->DockControlBar(pBar); pDockFrame->RecalcLayout(); pDockFrame->ShowWindow(SW_SHOWNA); pDockFrame->UpdateWindow(); }
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); } }