// This is part of the Professional User Interface Suite library.
// Copyright (C) 2001-2004 FOSS Software, Inc.
// All rights reserved.
//
// http://www.prof-uis.com
// http://www.fossware.com
// mailto:foss@fossware.com
//
// This source code can be used, modified and redistributed
// under the terms of the license agreement that is included
// in the Professional User Interface Suite package.
//
// Warranties and Disclaimers:
// THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND
// INCLUDING, BUT NOT LIMITED TO, WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
// IN NO EVENT WILL FOSS SOFTWARE INC. BE LIABLE FOR ANY DIRECT,
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES,
// INCLUDING DAMAGES FOR LOSS OF PROFITS, LOSS OR INACCURACY OF DATA,
// INCURRED BY ANY PERSON FROM SUCH PERSON'S USAGE OF THIS SOFTWARE
// EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
#include "stdafx.h"
#if (!defined __EXTDOCKBAR_H)
#include "ExtDockBar.h"
#endif
#if (!defined __EXT_MFC_NO_TAB_CONTROLBARS)
#if (!defined __EXT_CONTROLBAR_TABBED_FEATURES_H)
#include "ExtControlBarTabbedFeatures.h"
#endif // __EXT_CONTROLBAR_TABBED_FEATURES_H
#endif // (!defined __EXT_MFC_NO_TAB_CONTROLBARS)
#if _MFC_VER < 0x700
#include <../src/AfxImpl.h>
#else
#include <../src/mfc/AfxImpl.h>
#endif
#if (!defined __EXT_MEMORY_DC_H)
#include <../Src/ExtMemoryDC.h>
#endif
#if (!defined __EXT_MFC_NO_CUSTOMIZE)
#if (!defined __EXTCUSTOMIZE_H)
#include <ExtCustomize.h>
#endif
#endif // (!defined __EXT_MFC_NO_CUSTOMIZE)
#include <../profuisdll/resource.h>
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////
// CExtDockBar window
IMPLEMENT_DYNCREATE(CExtDockBar, CDockBar);
BEGIN_MESSAGE_MAP(CExtDockBar, CDockBar)
//{{AFX_MSG_MAP(CExtDockBar)
//}}AFX_MSG_MAP
ON_WM_CONTEXTMENU()
ON_WM_CANCELMODE()
ON_WM_ERASEBKGND()
ON_MESSAGE(WM_SIZEPARENT, OnSizeParent)
ON_WM_NCCALCSIZE()
ON_WM_NCPAINT()
ON_WM_DESTROY()
ON_MESSAGE(WM_HELPHITTEST, OnHelpHitTest)
END_MESSAGE_MAP()
bool CExtDockBar::g_bControlBarFixSizePixel = true;
bool CExtDockBar::g_bExtendedRepositioning = false;
bool CExtDockBar::g_bDockBarClassRegistered = false;
CExtDockBar::CExtDockBar(
UINT nCircleNo // = 0
)
: m_nCircleNo( nCircleNo )
, m_bLockedOptimize( false )
, m_pDockBarOuter( NULL )
, m_pDockBarInner( NULL )
, m_rcLastInvisiblePreCalc( 0, 0, 0, 0 )
, m_bInDynamicLayoutUpdate( false )
#if (!defined __EXT_MFC_NO_TAB_CONTROLBARS)
, m_pWndAutoHideArea( NULL )
#endif // (!defined __EXT_MFC_NO_TAB_CONTROLBARS)
{
VERIFY( RegisterDockBarClass() );
}
bool CExtDockBar::RegisterDockBarClass()
{
if( g_bDockBarClassRegistered )
return true;
WNDCLASS wndclass;
HINSTANCE hInst = AfxGetInstanceHandle();
if( ! ::GetClassInfo(
hInst,
__EXT_DOCKBAR_CLASS_NAME,
&wndclass
)
)
{
// otherwise we need to register a new class
wndclass.style = CS_GLOBALCLASS;
wndclass.lpfnWndProc = ::DefWindowProc;
wndclass.cbClsExtra = wndclass.cbWndExtra = 0;
wndclass.hInstance = hInst;
wndclass.hIcon = NULL;
wndclass.hCursor =
::LoadCursor(
NULL, //hInst,
IDC_ARROW
)
;
ASSERT( wndclass.hCursor != NULL );
wndclass.hbrBackground = NULL;
wndclass.lpszMenuName = NULL;
wndclass.lpszClassName = __EXT_DOCKBAR_CLASS_NAME;
if( !::AfxRegisterClass( &wndclass ) )
{
ASSERT( FALSE );
//AfxThrowResourceException();
return false;
}
}
g_bDockBarClassRegistered = true;
return true;
}
void CExtDockBar::PreSubclassWindow()
{
CDockBar::PreSubclassWindow();
}
BOOL CExtDockBar::PreCreateWindow(CREATESTRUCT& cs)
{
if( ( !RegisterDockBarClass() )
|| ( !CWnd::PreCreateWindow(cs) )
)
{
ASSERT( FALSE );
return FALSE;
}
cs.lpszClass = __EXT_DOCKBAR_CLASS_NAME;
return TRUE;
}
LRESULT CExtDockBar::OnHelpHitTest(WPARAM wParam, LPARAM lParam)
{
wParam;
lParam;
return 0L;
}
#if (!defined __EXT_MFC_NO_CUSTOMIZE)
void CExtDockBar::OnCustomizeModeEnter()
{
ASSERT_VALID( this );
#if (!defined __EXT_MFC_NO_TAB_CONTROLBARS)
if( _GetCircleNo() > 0 )
return;
if( m_pWndAutoHideArea == NULL )
return;
ASSERT_VALID( m_pWndAutoHideArea );
m_pWndAutoHideArea->OnCustomizeModeEnter();
#endif // (!defined __EXT_MFC_NO_TAB_CONTROLBARS)
}
void CExtDockBar::OnCustomizeModeLeave()
{
ASSERT_VALID( this );
#if (!defined __EXT_MFC_NO_TAB_CONTROLBARS)
if( _GetCircleNo() > 0 )
return;
if( m_pWndAutoHideArea == NULL )
return;
ASSERT_VALID( m_pWndAutoHideArea );
m_pWndAutoHideArea->OnCustomizeModeLeave();
#endif // (!defined __EXT_MFC_NO_TAB_CONTROLBARS)
}
#endif // (!defined __EXT_MFC_NO_CUSTOMIZE)
void CExtDockBar::OnCancelMode()
{
ASSERT_VALID( this );
CDockBar::OnCancelMode();
BOOL bHelpMode =
::AfxGetApp()->m_bHelpMode
|| CExtControlBar::FindHelpMode( this )
;
if( !bHelpMode )
CExtPopupMenuWnd::CancelMenuTracking();
CWnd::CancelToolTips();
//ASSERT( !CExtPopupMenuWnd::IsMenuTracking() );
}
CFrameWnd * CExtDockBar::_GetDockingFrameImpl()
{
ASSERT_VALID( this );
return
CExtControlBar::_GetDockingFrameImpl( (CControlBar *)this );
}
#if (!defined __EXT_MFC_NO_CUSTOMIZE)
bool CExtDockBar::_AppendAddRemoveButtonsCustomizeMenu(
CExtPopupMenuWnd * pPopup,
CControlBar * pBarEventSrc
)
{
ASSERT_VALID( pPopup );
ASSERT_VALID( pBarEventSrc );
ASSERT( pBarEventSrc->GetSafeHwnd() != NULL && ::IsWindow(pBarEventSrc->GetSafeHwnd()) );
if( !pBarEventSrc->IsKindOf(RUNTIME_CLASS(CExtToolControlBar)) )
{
ASSERT( FALSE );
return false;
}
CExtCustomizeSite * pSite =
CExtCustomizeSite::GetCustomizeSite( pBarEventSrc->m_hWnd );
if( pSite == NULL )
return true;
if( !pSite->BarIsRegistered((CExtToolControlBar*)pBarEventSrc) )
return true;
pSite->BarDefCmdTargetSet((CExtToolControlBar*)pBarEventSrc);
bool bUserBar = false;
VERIFY(
pSite->GetToolbarCustomizeInfo(
(CExtToolControlBar*)pBarEventSrc, NULL, NULL, NULL,
&bUserBar
)
);
CExtCmdItem * pCmdItem =
g_CmdManager->CmdGetPtr(
g_CmdManager->ProfileNameFromWnd( pBarEventSrc->m_hWnd ),
ID_EXT_ADD_REMOVE_BUTTONS
);
CExtSafeString strAddRemoveButtons;
if( pCmdItem )
strAddRemoveButtons = pCmdItem->m_sMenuText;
if( strAddRemoveButtons.IsEmpty() )
strAddRemoveButtons = _T("&Add/remove buttons");
VERIFY(
pPopup->ItemInsert(
(UINT)CExtPopupMenuWnd::TYPE_POPUP,
-1,
strAddRemoveButtons
)
);
CExtPopupMenuWnd::MENUITEMDATA & miARB =
pPopup->ItemGetInfo( pPopup->ItemGetCount() - 1 );
miARB.SetChildCombine();
miARB.SetToolButton();
CExtPopupMenuWnd * pAddRemoveButtons = miARB.GetPopup();
ASSERT( pAddRemoveButtons != NULL );
VERIFY( pAddRemoveButtons->ItemInsert( ID_EXT_CUSTOMIZE ) );
CExtPopupMenuWnd::MENUITEMDATA & miCustomize =
pAddRemoveButtons->ItemGetInfo(
pAddRemoveButtons->ItemGetCount() - 1
);
miCustomize.SetForceEnabled();
if( !bUserBar )
{
bool bAddResetBarHere = true;
if( pBarEventSrc->m_pDockBar != NULL )
{
ASSERT_VALID( pBarEventSrc->m_pDockBar );
MfcControlBarVector_t vBars;
if( pBarEventSrc->IsFloating() )
vBars.Add( pBarEventSrc );
else
{
int nPos = pBarEventSrc->m_pDockBar->FindBar( pBarEventSrc );
ASSERT( nPos >= 0 && nPos < pBarEventSrc->m_pDockBar->m_arrBars.GetSize() );
for( nPos--; nPos >= 0 && pBarEventSrc->m_pDockBar->m_arrBars[nPos] != NULL; nPos-- );
nPos++;
ASSERT( nPos >= 0 && nPos < pBarEventSrc->m_pDockBar->m_arrBars.GetSize() );
for( ; pBarEventSrc->m_pDockBar->m_arrBars[nPos] != NULL && nPos < pBarEventSrc->m_pDockBar->m_arrBars.GetSize(); nPos++ )
{
CControlBar * pBarInRow = (CControlBar *)pBarEventSrc->m_pDockBar->m_arrBars[nPos];
if( pBarInRow == NULL || __PLACEHODLER_BAR_PTR(pBarInRow) )
continue;
ASSERT_VALID( pBarInRow );
ASSERT_KINDOF( CControlBar, pBarInRow );
if( !pBarInRow->IsKindOf(RUNTIME_CLASS(CExtToolControlBar)) )
continue;
vBars.Add( pBarInRow );
}
} // else from if( pBarEventSrc->IsFloating() )
int nCount = vBars.GetSize();
ASSERT( nCount >= 1 );
for( int i = 0; i < nCount; )
{
CExtToolControlBar * pBar = (CExtToolControlBar*)vBars[i];
ASSERT_VALID( pBar );
ASSERT_KINDOF( CExtToolControlBar, pBar );
if( ( !pSite->BarIsRegistered(pBar) )
|| ( !pBar->OnCustomizeCanShowHideButtons() )
)
{
vBars.RemoveAt( i );
nCount--;
continue;
}
bool bUserItem = false;
VERIFY(
pSite->GetToolbarCustomizeInfo(
pBar, NULL, NULL, NULL,
&bUserItem
)
);
if( bUserItem )
{
vBars.RemoveAt( i );
nCount--;
continue;
}
i++;
} // for( int i = 0; i < nCount; i++ )
ASSERT( nCount == vBars.GetSize() );
if( nCount > 0 )
{
bAddResetBarHere = false;
for( i = 0; i < nCount; i++ )
{
CExtToolControlBar * pBar = (CExtToolControlBar*)vBars[i];
ASSERT_VALID( pBar );
ASSERT_KINDOF( CExtToolControlBar, pBar );
CString sBarName;
pBar->GetWindowText( sBarName );
VERIFY(
pAddRemoveButtons->ItemInsert(
(UINT)CExtPopupMenuWnd::TYPE_POPUP,
i,
(LPCTSTR)sBarName
)
);
CExtPopupMenuWnd::MENUITEMDATA & mi = pAddRemoveButtons->ItemGetInfo(i);
CExtPopupMenuWnd * pFolder = mi.GetPopup();
ASSERT_VALID( pFolder );
pBar->OnCustomizeInitShowHideButtonMenu( pFolder );
ASSERT( pFolder->ItemGetCount() > 0 );
VERIFY( pFolder->ItemInsert() );
VERIFY( pFolder->ItemInsert( ID_EXT_RESET_TOOLBAR ) );
CExtPopupMenuWnd::MENUITEMDATA & miResetToolbar =
pFolder->ItemGetInfo(
pFolder->ItemGetCount() - 1
);
miResetToolbar.SetForceEnabled();
miResetToolbar.SetCmdDeliverCb(
(CExtPopupMenuWnd::MENUITEMDATA::pCbItemClick)
CExtToolControlBar::stat_CbCmdDeliver
);
miResetToolbar.LParamSet( (LPARAM)pBar );
} // for( i = 0; i < nCount; i++ )
VERIFY(
pAddRemoveButtons->ItemInsert(
(UINT)CExtPopupMenuWnd::TYPE_SEPARATOR,
i
)
);
} // if( nCount > 0 )
} // if( pBarEventSrc->m_pDockBar != NULL )
if( bAddResetBarHere )
{
VERIFY( pAddRemoveButtons->ItemInsert( ID_EXT_RESET_TOOLBAR ) );
CExtPopupMenuWnd::MENUITEMDATA & miResetToolbar =
pAddRemoveButtons->ItemGetInfo(
pAddRemoveButtons->ItemGetCount() - 1
);
miResetToolbar.SetForceEnabled();
miResetToolbar.SetCmdDeliverCb(
(CExtPopupMenuWnd::MENUITEMDATA::pCbItemClick)
CExtToolControlBar::stat_CbCmdDeliver
);
miResetToolbar.LParamSet( (LPARAM)pBarEventSrc );
} // if( bAddResetBarHere )
} // if( !bUserBar )
return true;
}
#endif // (!defined __EXT_MFC_NO_CUSTOMIZE)
bool CExtDockBar::_ConstructDockSiteControlBarPopupMenu(
CFrameWnd * pFrame,
CExtPopupMenuWnd * pPopup,
SHORT nHelperNotificationType,
CControlBar * pBarEventSrc,
UINT nMsgID, // = WM_NULL
CObject * pObjectSrc // = NULL
)
{
ASSERT_VALID( pFrame );
ASSERT( pPopup != NULL );
CExtControlBar::POPUP_MENU_EVENT_DATA _pmed(
nHelperNotificationType,
pPopup,
pBarEventSrc,
CPoint( -1, -1 ),
nMsgID,
pObjectSrc
);
bool bPreNotificationPassed = _pmed.NotifyTarget( false );
if( !bPreNotificationPassed )
{
ExtControlBarVector_t vBars;
CExtControlBar::_GetFrameControlBars(
pFrame,
vBars
);
bool bOleInplaceItemActivated =
CExtControlBar::IsOleIpObjActive( pFrame );
int nBarsCount = vBars.GetSize();
CExtControlBar * pPrevBar = NULL;
for( int i=0; i<nBarsCount; i++ )
{
CExtControlBar * pBar = vBars[i];
ASSERT_VALID( pBar );
if( pBar->GetSafeHwnd() == NULL
|| ( ! ::IsWindow(pBar->GetSafeHwnd()) )
)
continue;
// do not include dynamic bars
if( pBar->IsKindOf( RUNTIME_CLASS(CExtDynControlBar) ) )
continue;
// do not include temporary hidden bars
if( pBar->m_nStateFlags &
//(CControlBar::delayHide | CControlBar::tempHide)
CControlBar::tempHide
)
continue;
// do not include some bars when OLE inplace object active
if( bOleInplaceItemActivated &&
(pBar->m_dwStyle & CBRS_HIDE_INPLACE)
)
continue;
// do not include bars without caption
CString sBarText;
pBar->GetWindowText( sBarText );
if( sBarText.IsEmpty() )
{
// do not include bars without window text to menu
// ASSERT( FALSE );
continue;
}
if( pPrevBar != NULL
&&
pPrevBar->IsFixedDockStyle() != pBar->IsFixedDockStyle()
)
{
VERIFY(
pPopup->ItemInsert(
CExtPopupMenuWnd::TYPE_SEPARATOR
)
);
}
int nBarID = pBar->GetDlgCtrlID();
ASSERT( CExtCmdManager::IsCommand(nBarID) );
CExtCmdItem _cmd;
_cmd.m_nCmdID = nBarID;
_cmd.m_sMenuText = sBarText;
_cmd.TipsLoad();
g_CmdManager->CmdSetup(
g_CmdManager->ProfileNameFromWnd( pFrame->GetSafeHwnd() ),
_cmd
);
if( pBar->OnConstructDockSiteControlBarPopupMenu(pPopup) )
pPrevBar = pBar;
} // for( int i=0; i<nBarsCount; i++ )
} // if( !bPreNotificationPassed )
// remove double separators
INT nCount = pPopup->ItemGetCount();
for( INT nItem = 1; nItem < nCount; )
{
CExtPopupMenuWnd::MENUITEMDATA & _miiPrev =
pPopup->ItemGetInfo( nItem - 1 );
if( !_miiPrev.IsSeparator() )
{
nItem++;
continue;
}
CExtPopupMenuWnd::MENUITEMDATA & _miiCurr =
pPopup->ItemGetInfo( nItem );
if( !_miiCurr.IsSeparator() )
{
nItem++;
continue;
}
pPopup->ItemRemove( nItem );
nCount--;
} // for( INT nItem = 1; nItem < nCount; )
#if (!defined __EXT_MFC_NO_CUSTOMIZE)
if( (!bPreNotificationPassed)
&& ( nHelperNotificationType == CExtControlBar::POPUP_MENU_EVENT_DATA::__PMED_CONTROLBAR_CTX
|| nHelperNotificationType == CExtControlBar::POPUP_MENU_EVENT_DATA::__PMED_CONTROLBAR_NC_CTX
|| nHelperNotificationType == CExtControlBar::POPUP_MENU_EVENT_DATA::__PMED_DOCKBAR_CTX
|| nHelperNotificationType == CExtControlBar::POPUP_MENU_EVENT_DATA::__PMED_STATUSBAR_CTX
|| nHelperNotificationType == CExtControlBar::POPUP_MENU_EVENT_DATA::__PMED_MINIFRAME_NC_CTX
)
&& CExtCustomizeSite::GetCustomizeSite(
pBarEventSrc->GetSafeHwnd()
) != NULL
)
{ // add customize command
// add tail separator
nCount = pPopup->ItemGetCount();
if( nCount > 0 )
{
CExtPopupMenuWnd::MENUITEMDATA & _mii =
pPopup->ItemGetInfo( nCount - 1 );
if( !_mii.IsSeparator() )
pPopup->ItemInsert();
} // if( nCount > 0 )
VERIFY( pPopup->ItemInsert( ID_EXT_CUSTOMIZE ) );
CExtPopupMenuWnd::MENUITEMDATA & mi =
pPopup->ItemGetInfo(
pPopup->ItemGetCount() - 1
);
mi.SetForceEnabled();
} // add customize command
#endif // (!defined __EXT_MFC_NO_CUSTOMIZE)
_pmed.NotifyTarget( true );
// remove tail separator
nCount = pPopup->ItemGetCount();
if( nCount > 0 )
{
CExtPopupMenuWnd::MENUITEMDATA & _mii =
pPopup->ItemGetInfo( nCount - 1 );
if( _mii.IsSeparator() )
pPopup->ItemRemove( nCount - 1 );
} // if( nCount > 0 )
return true;
}
void CExtDockBar::OnContextMenu(CWnd* pWnd, CPoint point)
{
ASSERT_VALID( this );
pWnd;
#if (!defined __EXT_MFC_NO_CUSTOMIZE)
CExtCustomizeSite * pSite =
CExtCustomizeSite::GetCustomizeSite( m_hWnd );
if( pSite != NULL
&& pSite->IsCustomizeMode()
)
return;
#endif // (!defined __EXT_MFC_NO_CUSTOMIZE)
if( CExtControlBar::FindHelpMode(this) )
return;
// find any control bar
CControlBar * pBar = NULL;
for( int nPos = 0; nPos < m_arrBars.GetSize(); nPos++ )
{
pBar = GetDockedControlBar(nPos);
if( pBar != NULL )
{
ASSERT_VALID( pBar );
break;
}
}
if( pBar == NULL )
return;
CFrameWnd * pFrame = _GetDockingFrameImpl();
HWND hWndTrack = pBar->GetOwner()->GetSafeHwnd();
ASSERT( hWndTrack != NULL && ::IsWindow(hWndTrack) );
CExtPopupMenuWnd * pPopup = new CExtPopupMenuWnd;
VERIFY( pPopup->CreatePopupMenu(hWndTrack) );
if( ! _ConstructDockSiteControlBarPopupMenu(
pFrame,
pPopup,
CExtControlBar::POPUP_MENU_EVENT_DATA::__PMED_DOCKBAR_CTX,
this,
WM_CONTEXTMENU,
NULL
)
)
{
delete pPopup;
return;
}
if( pPopup->ItemGetCount() == 0 )
{
delete pPopup;
return;
}
::SetFocus( hWndTrack );
if( ! pPopup->TrackPopupMenu(
TPMX_OWNERDRAW_FIXED,
point.x,
point.y
)
)
{
delete pPopup;
}
}
void CExtDockBar::DoPaint(CDC* pDC)
{
ASSERT_VALID( this );
ASSERT_VALID( pDC );
CExtPaintManager::stat_ExcludeChildAreas(
pDC->GetSafeHdc(),
GetSafeHwnd()
);
CRect rcClient;
GetClientRect( &rcClient );
CExtMemoryDC dc( pDC, &rcClient );
ASSERT( dc.GetSafeHdc() != NULL );
if( dc.GetSafeHdc() != NULL )
pDC = &dc;
g_PaintManager->PaintDockBarClientArea(
*pDC,
rcClient,
this
);
g_PaintManager->OnPaintSessionComplete( this );
}
BOOL CExtDockBar::OnEraseBkgnd( CDC* pDC )
{
ASSERT_VALID( this );
ASSERT_VALID( pDC );
pDC;
// CExtPaintManager::stat_ExcludeChildAreas(
// *pDC,
// *this
// );
// return CDockBar::OnEraseBkgnd(pDC);
return TRUE;
}
void CExtDockBar::OnDynamicLayoutUpdate()
{
ASSERT_VALID( this );
ASSERT_KINDOF( CExtDockBar, this );
if( m_bLockedOptimize )
return;
if( m_bInDynamicLayoutUpdate )
return;
m_bInDynamicLayoutUpdate = true;
ASSERT( m_arrBars.GetSize() >= 1 );
for( INT nBar = 1; nBar < m_arrBars.GetSize(); nBar++ )
{
CExtControlBar * pBar = (CExtControlBar *)
m_arrBars[ nBar ];
if( pBar == NULL )
continue;
if( __PLACEHODLER_BAR_PTR(pBar) )
continue;
ASSERT_VALID( pBar );
ASSERT_KINDOF( CExtControlBar, pBar );
if( pBar->IsFixedMode() || pBar->IsFixedDockStyle() )
continue;
if( !pBar->IsVisible() )
continue;
if( !pBar->IsKindOf(RUNTIME_CLASS(CExtDynControlBar)) )
continue;
ASSERT_VALID( ((CExtDynControlBar *)pBar)->m_pWndDynDocker );
((CExtDynControlBar *)pBar)->m_pWndDynDocker->OnDynamicLayoutUpdate();
}
RedrawWindow(
NULL, NULL,
RDW_INVALIDATE //|RDW_UPDATENOW
|RDW_ERASE //|RDW_ERASENOW
|RDW_ALLCHILDREN|RDW_FRAME
);
m_bInDynamicLayoutUpdate = false;
}
void CExtDockBar::OnDynamicLayoutOptimize()
{
if( m_bLockedOptimize )
return;
ASSERT( m_arrBars.GetSize() >= 1 );
for( INT nBar = 1; nBar < m_arrBars.GetSize(); nBar++ )
{
CExtControlBar * pBar = (CExtControlBar *)
m_arrBars[ nBar ];
if( pBar == NULL )
continue;
if( __PLACEHODLER_BAR_PTR(pBar) )
continue;
ASSERT_VALID( pBar );
ASSERT_KINDOF( CExtControlBar, pBar );
if( pBar->IsFixedMode() || pBar->IsFixedDockStyle() )
continue;
if( !pBar->IsVisible() )
continue;
if( !pBar->IsKindOf(RUNTIME_CLASS(CExtDynControlBar)) )
continue;
ASSERT_VALID( ((CExtDynControlBar *)pBar)->m_pWndDynDocker );
((CExtDynControlBar *)pBar)->m_pWndDynDocker->OnDynamicLayoutOptimize();
}
}
CSize CExtDockBar::CalcFixedLayout(
BOOL bStretch,
BOOL bHorz
)
{
// based on MFC's source of
// CDockBar::CalcFixedLayout()
ASSERT_VALID(this);
CSize sizeFixed =
CControlBar::CalcFixedLayout( bStretch, bHorz );
// get max size
CSize sizeMax;
if( !m_rectLayout.IsRectEmpty() )
sizeMax = m_rectLayout.Size();
else
{
CFrameWnd * pFrame = GetParentFrame();
CRect rcFrameWindow;
pFrame->GetClientRect( &rcFrameWindow );
sizeMax = rcFrameWindow.Size();
}
// prepare for layout
AFX_SIZEPARENTPARAMS layout;
layout.hDWP = m_bLayoutQuery ?
NULL : ::BeginDeferWindowPos( m_arrBars.GetSize() );
CPoint pt( 0, 0 );
int nWidth = 0;
BOOL bWrapped = FALSE;
for( int nPos = 0; nPos < m_arrBars.GetSize(); nPos++ )
{ // layout all the control bars
CControlBar * pBar = GetDockedControlBar(nPos);
void * pVoid = m_arrBars[nPos];
if( pBar != NULL )
{
CRect rcBarWin, rcBarClient;
pBar->GetWindowRect( &rcBarWin );
pBar->ScreenToClient( & rcBarWin );
pBar->GetClientRect( &rcBarClient );
CSize sizeBarMin =
rcBarWin.Size() - rcBarClient.Size();
if( pBar->IsKindOf(RUNTIME_CLASS(CExtControlBar)) )
{
if( ! ((CExtControlBar*)pBar)->IsFixedMode() )
{
sizeBarMin =
CSize(
((CExtControlBar *)pBar)->_CalcDesiredMinHW(),
((CExtControlBar *)pBar)->_CalcDesiredMinVH()
);
} // if( ! ((CExtControlBar*)pBar)->IsFixedMode() )
} // if( pBar->IsKindOf(RUNTIME_CLASS(CExtControlBar)) )
if( pBar->IsVisible() )
{
// get ideal rect for bar
DWORD dwMode = 0;
if( (pBar->m_dwStyle & CBRS_SIZE_DYNAMIC)
&&
(pBar->m_dwStyle & CBRS_FLOATING)
)
dwMode |= LM_HORZ | LM_MRUWIDTH;
else if(pBar->m_dwStyle & CBRS_ORIENT_HORZ)
dwMode |= LM_HORZ | LM_HORZDOCK;
else
dwMode |= LM_VERTDOCK;
CSize sizeBar =
pBar->CalcDynamicLayout(-1, dwMode);
CRect rc(pt, sizeBar);
// get current rect for bar
CRect rcBar;
pBar->GetWindowRect( &rcBar );
ScreenToClient( &rcBar );
if( bHorz )
{
// Offset Calculated Rect out to Actual
if( rcBar.left > rc.left
&& !m_bFloating
)
rc.OffsetRect(
rcBar.left - rc.left,
0
);
// If ControlBar goes off the right, then right justify
if( rc.right > sizeMax.cx
&& !m_bFloating
)
{
int x = rc.Width();
x = max(sizeMax.cx - x, pt.x);
rc.OffsetRect(
x - rc.left,
0
);
if( rc.right > sizeMax.cx )
rc.right -= rc.right - sizeMax.cx;
}
// If ControlBar has been wrapped, then left justify
if( bWrapped )
{
bWrapped = FALSE;
rc.OffsetRect( - rc.left, 0 );
}
// If ControlBar is completely invisible, then wrap it
else if(
rc.Width() < sizeBarMin.cx
||
(rc.left >= sizeMax.cx)
&& (nPos > 0) && (m_arrBars[nPos - 1] != NULL)
)
{
if( !pBar->IsKindOf(RUNTIME_CLASS(CExtControlBar))
|| (
pBar->IsKindOf(RUNTIME_CLASS(CExtControlBar))
&&
((CExtControlBar*)pBar)->IsFixedMode()
)
)
{
m_arrBars.InsertAt(
nPos,
(CObject*)NULL
);
pBar = NULL;
pVoid = NULL;
bWrapped = TRUE;
}
}
if( !bWrapped )
{
if(rc != rcBar)
{
if( !m_bLayoutQuery &&
!(pBar->m_dwStyle & CBRS_FLOATING)
)
pBar->m_pDockContext->
m_rectMRUDockPos = rc;
AfxRepositionWindow(
&layout,
pBar->m_hWnd,
&rc
);
}
pt.x = rc.left + sizeBar.cx;
nWidth = max(nWidth, sizeBar.cy);
} // if( !bWrapped )
} // if( bHorz )
else
{
// Offset Calculated Rect out to Actual
if( rcBar.top > rc.top
&& !m_bFloating
)
rc.OffsetRect(
0,
rcBar.top - rc.top
);
// If ControlBar goes off the bottom, then bottom justify
if( rc.bottom > sizeMax.cy
&& !m_bFloating
)
{
int y = rc.Height();
y = max(sizeMax.cy - y, pt.y);
rc.OffsetRect(
0,
y - rc.top
);
if( rc.bottom > sizeMax.cy )
rc.bottom -= rc.bottom - sizeMax.cy;
}
// If ControlBar has been wrapped, then top justify
if( bWrapped )
{
bWrapped = FALSE;
rc.OffsetRect( 0, - rc.top );
}
// If ControlBar is completely invisible, then wrap it
else if(
rc.Height() < sizeBarMin.cy
||
(rc.top >= sizeMax.cy)
&& (nPos > 0) && (m_arrBars[nPos - 1] != NULL)
)
{
if( !pBar->IsKindOf(RUNTIME_CLASS(CExtControlBar))
|| (
pBar->IsKindOf(RUNTIME_CLASS(CExtControlBar))
&&
((CExtControlBar*)pBar)->IsFixedMode()
)
)
{
m_arrBars.InsertAt(
nPos,
(CObject*)NULL
);
pBar = NULL;
pVoid = NULL;
bWrapped = TRUE;
}
}
if( !bWrapped )
{
if(rc != rcBar)
{
if( !m_bLayoutQuery
&& !(pBar->m_dwStyle & CBRS_FLOATING)
&& pBar->m_pDockContext != NULL
)
pBar->m_pDockContext->
m_rectMRUDockPos = rc;
AfxRepositionWindow(
&layout,
pBar->m_hWnd,
&rc
);
}
pt.y = rc.top + sizeBar.cy;
nWidth = max(nWidth, sizeBar.cx);
} // if( !bWrapped )
} // else from if( bHorz )
// if( !m_bLayoutQuery && pBar != NULL )
// {
// if( pBar->IsKindOf(RUNTIME_CLASS(CExtDynControlBar)) )
// {
// ASSERT_VALID( ((CExtDynControlBar *)pBar)->m_pWndDynDocker );
// ((CExtDynControlBar *)pBar)->m_pWndDynDocker->OnDynamicLayoutUpdate();
// }
// }
} // if( pBar->IsVisible() )
if( !bWrapped )
// handle any delay/show hide for the bar
pBar->RecalcDelayShow( &layout );
} // if( pBar != NULL )
else
{
if( g_bExtendedRepositioning )
{
// try to remove wrapping:
// are we have free space in the end of previous row?
if( nPos > 0 && nPos != m_arrBars.GetSize()-1 )
{
int nPosPrev = nPos-1;
CControlBar * pPrevBar = NULL;
do
{
pPrevBar = GetDockedControlBar(nPosPrev--);
if( pPrevBar != NULL
&& pPrevBar->IsVisible()
&& (!pPrevBar->IsFloating())
)
{
// get ideal rect for prev bar
DWORD dwMode = 0;
if( (pPrevBar->m_dwStyle & CBRS_SIZE_DYNAMIC)
&&
(pPrevBar->m_dwStyle & CBRS_FLOATING)
)
dwMode |= LM_HORZ | LM_MRUWIDTH;
else if(pPrevBar->m_dwStyle & CBRS_ORIENT_HORZ)
dwMode |= LM_HORZ | LM_HORZDOCK;
else
dwMode |= LM_VERTDOCK;
CSize sizePrevBar =
pPrevBar->CalcDynamicLayout(-1, dwMode);
CRect rcPrev(pt, sizePrevBar);
if( bHorz )
{
if( rcPrev.right > sizeMax.cx
&& !m_bFloating
)
pPrevBar = NULL;
}
else
{
if( rcPrev.bottom > sizeMax.cy
&& !m_bFloating
)
pPrevBar = NULL;
}
if( pPrevBar != NULL )
break;
}
pPrevBar = NULL;
} while( nPosPrev >= 0 );
if( pPrevBar != NULL )
{
m_arrBars.RemoveAt(nPos);
nPos--;
continue;
}
} // if( nPos > 0 && nPos != m_arrBars.GetSize()-1 )
} // if( g_bExtendedRepositioning )
} // else from if( pBar != NULL )
if( pBar == NULL && pVoid == NULL && nWidth != 0 )
{
// end of row because pBar == NULL
if( bHorz )
{
pt.y += nWidth;
sizeFixed.cx = max(sizeFixed.cx, pt.x);
sizeFixed.cy = max(sizeFixed.cy, pt.y);
pt.x = 0;
sizeFixed.cy--;
}
else
{
pt.x += nWidth;
sizeFixed.cx = max(sizeFixed.cx, pt.x);
sizeFixed.cy = max(sizeFixed.cy, pt.y);
pt.y = 0;
sizeFixed.cx--;
}
nWidth = 0;
}
} // layout all the control bars
if( !m_bLayoutQuery )
{
ASSERT( layout.hDWP != NULL );
if( layout.hDWP != NULL )
{
VERIFY( ::EndDeferWindowPos(layout.hDWP) );
}
} // if( !m_bLayoutQuery )
// adjust size for borders on the dock bar itself
CRect rc( 0, 0, 0, 0 );
CalcInsideRect(rc, bHorz);
if( (!bStretch || !bHorz) && sizeFixed.cx != 0 )
sizeFixed.cx +=
-rc.right + rc.left
+ g_bControlBarFixSizePixel ? 1 : 0;
if( (!bStretch || bHorz) && sizeFixed.cy != 0 )
sizeFixed.cy +=
-rc.bottom + rc.top
+ g_bControlBarFixSizePixel ? 1 : 0;
if( !m_bLayoutQuery )
OnDynamicLayoutUpdate();
return sizeFixed;
}
void CExtDockBar::RemoveAllPlaceHolders(
bool bSearchPlaceHolder // = true
)
{
ASSERT_VALID( this );
INT nCount = m_arrBars.GetSize();
ASSERT( nCount > 0 );
ASSERT( m_arrBars[0] == NULL );
MfcControlBarVector_t vPlaceHolders;
for( INT nBar = 1; nBar < nCount; nBar++ )
{
CControlBar * pBar = (CControlBar *) m_arrBars[ nBar ];
if( pBar == NULL )
continue;
if( __PLACEHODLER_BAR_PTR(pBar) )
{
vPlaceHolders.Add( pBar );
continue;
}
ASSERT_VALID( pBar );
ASSERT_KINDOF( CControlBar, pBar );
}
nCount = vPlaceHolders.GetSize();
for( nBar = 0; nBar < nCount; nBar++ )
{
CControlBar * pBar = vPlaceHolders[nBar];
RemovePlaceHolder( pBar, bSearchPlaceHolder );
}
}
void CExtDockBar::RemovePlaceHolder(
CControlBar * pBar,
bool bSearchPlaceHolder, // = true
bool * p_bRemoved // = NULL
)
{
if( p_bRemoved != NULL )
*p_bRemoved = false;
// remove remembered docking position
if( HIWORD(pBar) != 0 )
pBar = (CControlBar*)_AfxGetDlgCtrlID(pBar->m_hWnd);
int nOldPos = FindBar(pBar);
if( nOldPos > 0)
{
m_arrBars.RemoveAt(nOldPos);
// remove section indicator (NULL) if nothing else in section
if( m_arrBars[nOldPos-1] == NULL
&& m_arrBars[nOldPos] == NULL
)
m_arrBars.RemoveAt(nOldPos);
if( p_bRemoved != NULL )
*p_bRemoved = true;
return;
}
if( !bSearchPlaceHolder )
return;
_RemovePlaceHolder(
m_pDockSite,
pBar,
p_bRemoved
);
}
void CExtDockBar::_RemovePlaceHolder(
CFrameWnd * pFrame,
CControlBar * pBar,
bool * p_bRemoved // = NULL
)
{
ASSERT_VALID( pFrame );
ASSERT( pBar != NULL ); // may be placeholder ID
POSITION pos = pFrame->m_listControlBars.GetHeadPosition();
for( ; pos != NULL; )
{
CControlBar * pTestBar = (CControlBar *)
pFrame->m_listControlBars.GetNext( pos );
ASSERT_VALID( pTestBar );
ASSERT_KINDOF( CControlBar, pTestBar );
if( !pTestBar->IsDockBar() )
{
if( pTestBar->IsKindOf(RUNTIME_CLASS(CExtDynControlBar)) )
{
CExtDockDynBar * pDynDocker =
((CExtDynControlBar*)pTestBar)->
m_pWndDynDocker;
ASSERT_VALID( pDynDocker );
bool bRemoved = false;
pDynDocker->RemovePlaceHolder(
pBar,
false,
&bRemoved
);
if( bRemoved )
{
if( p_bRemoved != NULL )
*p_bRemoved = true;
return;
}
}
continue;
}
ASSERT_KINDOF( CDockBar, pTestBar );
// dirty, but safe
bool bRemoved = false;
((CExtDockBar *)pTestBar)->RemovePlaceHolder(
pBar,
false,
&bRemoved
);
if( bRemoved )
{
if( p_bRemoved != NULL )
*p_bRemoved = true;
return;
}
}
}
void CExtDockBar::_SlideDockControlBar(
CControlBar* pBar,
LPCRECT lpRect,
BOOL bMovingEnabled,
const POINT * ptDesiredMid // = NULL
)
{
ASSERT_VALID( this);
ASSERT_VALID( pBar );
ASSERT_KINDOF( CControlBar, pBar );
CRect rcBar;
pBar->GetWindowRect( &rcBar );
if( pBar->m_pDockBar == this
&& (lpRect == NULL || rcBar == *lpRect)
)
{
// already docked and no change in position
return;
}
// set CBRS_FLOAT_MULTI style if docking bar has it
if( m_bFloating
&& (pBar->m_dwDockStyle & CBRS_FLOAT_MULTI)
)
m_dwStyle |= CBRS_FLOAT_MULTI;
m_dwStyle &= ~(CBRS_SIZE_FIXED | CBRS_SIZE_DYNAMIC);
m_dwStyle |=
pBar->m_dwStyle & (CBRS_SIZE_FIXED | CBRS_SIZE_DYNAMIC);
if( !(m_dwStyle & CBRS_FLOAT_MULTI) )
{
CString sTitle;
pBar->GetWindowText( sTitle );
AfxSetWindowText( m_hWnd, (LPCTSTR)sTitle );
}
// align correctly and turn on all borders
DWORD dwStyle = pBar->GetBarStyle();
dwStyle &= ~(CBRS_ALIGN_ANY);
dwStyle |= (m_dwStyle & CBRS_ALIGN_ANY) | CBRS_BORDER_ANY;
if( m_bFloating )
dwStyle |= CBRS_FLOATING;
else
dwStyle &= ~CBRS_FLOATING;
pBar->SetBarStyle( dwStyle );
// hide first if changing to a new docking site to avoid flashing
bool bShow = false;
if( bMovingEnabled &&
pBar->m_pDockBar != this && pBar->IsWindowVisible() )
{
pBar->SetWindowPos(NULL, 0, 0, 0, 0,
SWP_NOSIZE|SWP_NOMOVE|SWP_NOZORDER|SWP_NOACTIVATE|SWP_HIDEWINDOW);
bShow = true;
}
int nPos = -1;
if( lpRect != NULL )
{
// insert into appropriate row
CRect rc( lpRect );
ScreenToClient( &rc );
CPoint ptMid(
(ptDesiredMid == NULL) ?
rc.left + rc.Width()/2 : ptDesiredMid->x,
(ptDesiredMid == NULL) ?
rc.top + rc.Height()/2 : ptDesiredMid->y
);
nPos = _InsertByPointImpl( pBar, rc, ptMid );
ASSERT_VALID( this );
ASSERT_BAR_LOCATION_IN_ROW( this, pBar );
// position at requested position
if( bMovingEnabled )
pBar->SetWindowPos(
NULL,
rc.left, rc.top, rc.Width(), rc.Height(),
SWP_NOREDRAW|SWP_NOSENDCHANGING
|SWP_NOZORDER|SWP_NOOWNERZORDER
|SWP_NOACTIVATE|SWP_NOCOPYBITS
);
}
else
{
// always add on current row, then create new one
m_arrBars.Add(pBar);
m_arrBars.Add(NULL);
ASSERT_VALID( this );
ASSERT_BAR_LOCATION_IN_ROW( this, pBar );
// align off the edge initially
if( bMovingEnabled )
pBar->SetWindowPos(
NULL,
-afxData.cxBorder2, -afxData.cyBorder2,
0, 0,
SWP_NOREDRAW|SWP_NOSENDCHANGING
|SWP_NOZORDER|SWP_NOOWNERZORDER
|SWP_NOACTIVATE|SWP_NOCOPYBITS
|SWP_NOSIZE
);
}
// attach it to the docking site
if( pBar->GetParent() != this )
pBar->SetParent(this);
if( pBar->m_pDockBar == this )
{
//pBar->m_pDockBar->
RemoveControlBar(
pBar,
nPos,
0,
false // (!bMovingEnabled) ? true : false
);
ASSERT_VALID( this );
} // if( pBar->m_pDockBar == this )
else if( pBar->m_pDockBar != NULL )
{
ASSERT_KINDOF( CDockBar, pBar->m_pDockBar );
if( pBar->m_pDockBar->IsKindOf(RUNTIME_CLASS(CExtDockBar)) )
{
bool bOptimizeDockBarLayout = false;
if( !((CExtDockBar *)(pBar->m_pDockBar))->m_bFloating )
bOptimizeDockBarLayout = true;
((CExtDockBar *)(pBar->m_pDockBar))->
RemoveControlBar(
pBar,
-1,
m_bFloating && !pBar->m_pDockBar->m_bFloating,
false // (!bMovingEnabled) ? true : false
);
ASSERT_VALID( this );
if( bOptimizeDockBarLayout )
((CExtDockBar *)(pBar->m_pDockBar))->OnDynamicLayoutOptimize();
}
else
{
pBar->m_pDockBar->
RemoveControlBar(
pBar,
//ph//
0, //-1,
m_bFloating && !pBar->m_pDockBar->m_bFloating
);
ASSERT_VALID( this );
}
} // else if( pBar->m_pDockBar != NULL )
pBar->m_pDockBar = this;
ASSERT( pBar->m_pDockContext != NULL );
pBar->m_pDockContext->m_uMRUDockID = GetDlgCtrlID();
if( lpRect != NULL )
pBar->m_pDockContext->m_rectMRUDockPos = *lpRect;
if( bShow )
{
ASSERT(!pBar->IsWindowVisible());
//pBar->SetWindowPos(NULL, 0, 0, 0, 0,
// SWP_NOSIZE|SWP_NOMOVE|SWP_NOZORDER|SWP_NOACTIVATE|SWP_SHOWWINDOW);
pBar->SetWindowPos(NULL,
lpRect->left,
lpRect->top,
lpRect->right-lpRect->left,
lpRect->bottom-lpRect->top,
SWP_NOSIZE/*|SWP_NOMOVE*/|SWP_NOZORDER|SWP_NOACTIVATE|SWP_SHOWWINDOW);
}
// remove any place holder for pBar in this dockbar
RemovePlaceHolder( pBar, true );
ASSERT_VALID( this );
// // get parent frame for recalc layout
//CFrameWnd* pFrameWnd = GetDockingFrame();
// pFrameWnd->DelayRecalcLayout();
_OptimizeCircles();
}
void CExtDockBar::_NewRowDockControlBar(
CControlBar * pExtBarDocked,
CControlBar * pExtBarNew,
bool bLessIndex
)
{
ASSERT_VALID( this);
ASSERT_VALID( pExtBarDocked );
ASSERT_KINDOF( CControlBar, pExtBarDocked );
ASSERT_VALID( pExtBarNew );
ASSERT_KINDOF( CControlBar, pExtBarNew );
CFrameWnd * pNewDockingFrameWnd = pExtBarNew->GetDockingFrame();
INT nNewDockBarGetDockedVisibleCount = -1;
BOOL bNewFloating = pExtBarNew->IsFloating();
BOOL bNewExt = pExtBarNew->IsKindOf( RUNTIME_CLASS(CExtControlBar) );
if( pExtBarNew->GetParent() != this )
{
if( bNewExt )
((CExtControlBar *)pExtBarNew)->m_bUpdatingChain = true;
pExtBarNew->SetWindowPos(
NULL, 0, 0, 0, 0,
SWP_NOSIZE|SWP_NOMOVE|SWP_NOZORDER|SWP_NOACTIVATE
|SWP_HIDEWINDOW
);
pExtBarNew->SetParent( this );
if( bNewExt )
((CExtControlBar *)pExtBarNew)->m_bUpdatingChain = false;
}
// align correctly and turn on all borders
DWORD dwStyle = pExtBarNew->GetBarStyle();
dwStyle &= ~(CBRS_ALIGN_ANY);
dwStyle |= (m_dwStyle & CBRS_ALIGN_ANY) | CBRS_BORDER_ANY;
if( m_bFloating )
dwStyle |= CBRS_FLOATING;
else
dwStyle &= ~CBRS_FLOATING;
pExtBarNew->SetBarStyle( dwStyle );
INT nCountOfSideBars = m_arrBars.GetSize();
CControlBar * pRemoveBar = NULL;
HWND hWndDockBarOld = NULL;
if( pExtBarNew->m_pDockBar != this )
{
if( pExtBarNew->m_pDockBar != NULL )
{
nNewDockBarGetDockedVisibleCount =
GetDockedVisibleCount();
ASSERT_VALID( pExtBarNew->m_pDockBar );
ASSERT_KINDOF( CDockBar, pExtBarNew->m_pDockBar );
if( pExtBarNew->IsWindowVisible() )
pExtBarNew->SetWindowPos(
NULL, 0, 0, 0, 0,
SWP_NOSIZE|SWP_NOMOVE|SWP_NOZORDER|SWP_NOACTIVATE
|SWP_HIDEWINDOW
);
ASSERT_VALID( pExtBarNew->m_pDockBar );
if( !pExtBarNew->m_pDockBar->m_bFloating
&& pExtBarNew->m_pDockBar->IsKindOf(RUNTIME_CLASS(CExtDockBar))
)
{
hWndDockBarOld = pExtBarNew->m_pDockBar->GetSafeHwnd();
((CExtDockBar *)pExtBarNew->m_pDockBar)->RemoveControlBar( pExtBarNew );
// optimized at final state with all circles
// ((CExtDockBar *)pExtBarNew->m_pDockBar)->OnDynamicLayoutOptimize();
}
else
pExtBarNew->m_pDockBar->RemoveControlBar( pExtBarNew );
//ASSERT_VALID( pExtBarNew->m_pDockBar ); this may be alredy destroyed floating dockbar
} // if( pExtBarNew->m_pDockBar != NULL )
} // if( pExtBarNew->m_pDockBar != this )
else
{
if( pExtBarDocked != pExtBarNew )
{
INT nPos = FindBar( pExtBarNew );
ASSERT( nPos >= 0 && nPos < nCountOfSideBars );
m_arrBars.RemoveAt( nPos );
nCountOfSideBars --;
ASSERT( nCountOfSideBars > 1 );
if( ( nCountOfSideBars == nPos
&& m_arrBars[nPos-1] == NULL )
||
( nCountOfSideBars > nPos
&& m_arrBars[nPos-1] == NULL
&& m_arrBars[nPos] == NULL
)
)
{
// remove empty row
m_arrBars.RemoveAt( nPos-1 );
nCountOfSideBars --;
}
ASSERT_VALID( this );
} // if( pExtBarDocked != pExtBarNew )
else
pRemoveBar = pExtBarNew;
} // else from if( pExtBarNew->m_pDockBar != this )
INT nIdxDockedBar = FindBar( pExtBarDocked );
ASSERT( nIdxDockedBar >= 0 && nIdxDockedBar < nCountOfSideBars );
INT nIncrement = bLessIndex ? -1 : 1;
for( INT nIdx = nIdxDockedBar; true; nIdx += nIncrement )
{
CControlBar * pBar = (CControlBar *) m_arrBars[ nIdx ];
if( nIdx == 0
|| nIdx == (nCountOfSideBars-1)
|| pBar == NULL
)
{
ASSERT( m_arrBars[0] == NULL );
m_arrBars.InsertAt( nIdx, pExtBarNew );
m_arrBars.InsertAt( nIdx, (CControlBar *)NULL );
ASSERT_VALID( this );
break;
}
#ifdef _DEBUG
if( __PLACEHODLER_BAR_PTR(pBar) )
continue;
ASSERT_VALID( pBar );
ASSERT_KINDOF( CControlBar, pBar );
#endif // _DEBUG
} // for( INT nIdx = nIdxDockedBar; true; nIdx += nIncrement )
CDockBar * pOldDockBar = pExtBarNew->m_pDockBar;
pExtBarNew->m_pDockBar = this;
ASSERT_BAR_LOCATION_IN_ROW( this, pExtBarNew );
ASSERT( pExtBarNew->m_pDockContext != NULL );
pExtBarNew->m_pDockContext->m_uMRUDockID = GetDlgCtrlID();
if( pRemoveBar != NULL )
{
INT nPos = FindBar( pRemoveBar, nIdx+1 );
nCountOfSideBars = m_arrBars.GetSize();
ASSERT( nPos >= 0 && nPos < nCountOfSideBars );
m_arrBars.RemoveAt( nPos );
nCountOfSideBars --;
ASSERT( nCountOfSideBars > 1 );
if( ( nCountOfSideBars == nPos
&& m_arrBars[nPos-1] == NULL )
||
( nCountOfSideBars > nPos
&& m_arrBars[nPos-1] == NULL
&& m_arrBars[nPos] == NULL
)
)
{
// remove empty row
m_arrBars.RemoveAt( nPos-1 );
// nCountOfSideBars --;
}
ASSERT_VALID( this );
}
if( bNewFloating && nNewDockBarGetDockedVisibleCount == 0 )
{
if( pOldDockBar->GetDockedCount() == 0 )
pNewDockingFrameWnd->DestroyWindow();
else
pNewDockingFrameWnd->ShowWindow( SW_HIDE );
}
// else
// pNewDockingFrameWnd->DelayRecalcLayout();
// ASSERT( !pExtBarNew->IsWindowVisible() );
pExtBarNew->SetWindowPos(NULL, 0, 0, 0, 0,
SWP_NOSIZE|SWP_NOMOVE|SWP_NOZORDER|SWP_NOACTIVATE
|SWP_SHOWWINDOW|SWP_FRAMECHANGED
);
OnDynamicLayoutUpdate();
if( hWndDockBarOld != NULL
&& hWndDockBarOld != GetSafeHwnd()
&& ::IsWindow(hWndDockBarOld)
)
{
CWnd * pWndDockBar = FromHandlePermanent( hWndDockBarOld );
if( pWndDockBar != NULL
&& pWndDockBar->GetSafeHwnd() == hWndDockBarOld
)
{
ASSERT( pWndDockBar != this );
ASSERT_KINDOF( CExtDockBar, pWndDockBar );
((CExtDockBar *)pWndDockBar)->OnDynamicLayoutUpdate();
}
}
CFrameWnd * pFrame = GetParentFrame();
ASSERT_VALID( pFrame );
if( !pFrame->IsKindOf(RUNTIME_CLASS(CMiniFrameWnd)) )
_OptimizeCircles();
}
void CExtDockBar::_InnerOuterDockControlBar(
CControlBar * pBar,
bool bInner
)
{
ASSERT_VALID( this );
ASSERT_VALID( pBar );
ASSERT_KINDOF( CControlBar, pBar );
UINT nOwnID = GetDlgCtrlID();
ASSERT_DOCKBAR_DLGCTRLID_DOCKED( nOwnID );
bool bDockAtStartIdx = false;
if( nOwnID == AFX_IDW_DOCKBAR_RIGHT
|| nOwnID == AFX_IDW_DOCKBAR_BOTTOM
)
bDockAtStartIdx = true;
if( !bInner )
bDockAtStartIdx = false;
if( pBar->m_pDockBar == this )
{
INT nCountOfBars = m_arrBars.GetSize();
ASSERT( nCountOfBars > 2 );
if( m_arrBars[1] == pBar )
return;
INT nBarPos = FindBar( pBar );
ASSERT( nBarPos > 0 && nBarPos < nCountOfBars );
m_arrBars.RemoveAt( nBarPos );
nCountOfBars --;
if( m_arrBars[nBarPos - 1] == NULL
&& m_arrBars[ nBarPos ] == NULL
)
{
m_arrBars.RemoveAt( nBarPos );
nCountOfBars --;
}
//ASSERT_VALID( this );
if( bDockAtStartIdx )
{
m_arrBars.InsertAt( 1, pBar );
nCountOfBars++;
ASSERT( nCountOfBars == m_arrBars.GetSize() );
if( nCountOfBars < 3 || m_arrBars[2] != NULL )
m_arrBars.InsertAt( 2, (CControlBar *)NULL );
ASSERT_VALID( this );
} // if( bDockAtStartIdx )
else
{
m_arrBars.InsertAt( nCountOfBars, (CControlBar *)NULL );
m_arrBars.InsertAt( nCountOfBars, pBar );
ASSERT_VALID( this );
} // else from if( bDockAtStartIdx )
} // if( pBar->m_pDockBar == this )
else
{
CFrameWnd * pDockingFrameWnd = pBar->GetDockingFrame();
INT nDockBarGetDockedVisibleCount = -1;
BOOL bFloating = pBar->IsFloating();
ASSERT( pBar->GetParent() != this );
pBar->SetWindowPos(
NULL, 0, 0, 0, 0,
SWP_NOSIZE|SWP_NOMOVE|SWP_NOZORDER|SWP_NOACTIVATE
|SWP_HIDEWINDOW
);
pBar->SetParent( this );
// align correctly and turn on all borders
DWORD dwStyle = pBar->GetBarStyle();
dwStyle &= ~(CBRS_ALIGN_ANY);
dwStyle |= (m_dwStyle & CBRS_ALIGN_ANY) | CBRS_BORDER_ANY;
if( m_bFloating )
dwStyle |= CBRS_FLOATING;
else
dwStyle &= ~CBRS_FLOATING;
pBar->SetBarStyle( dwStyle );
ASSERT( pBar->m_pDockBar != this );
if( pBar->IsWindowVisible() )
pBar->SetWindowPos(
NULL, 0, 0, 0, 0,
SWP_NOSIZE|SWP_NOMOVE|SWP_NOZORDER|SWP_NOACTIVATE
|SWP_HIDEWINDOW
);
if( pBar->m_pDockBar != NULL )
{
ASSERT_VALID( pBar->m_pDockBar );
ASSERT_KINDOF( CDockBar, pBar->m_pDockBar );
if( !pBar->m_pDockBar->m_bFloating
&& pBar->m_pDockBar->IsKindOf(RUNTIME_CLASS(CExtDockBar))
)
{
((CExtDockBar *)pBar->m_pDockBar)->RemoveControlBar( pBar );
((CExtDockBar *)pBar->m_pDockBar)->OnDynamicLayoutOptimize();
}
else
pBar->m_pDockBar->RemoveControlBar( pBar );
//ASSERT_VALID( pBar->m_pDockBar ); this may be alredy destroyed floating dockbar
}
//ASSERT_VALID( this );
INT nCountOfBars = m_arrBars.GetSize();
ASSERT( nCountOfBars > 0 );
if( bDockAtStartIdx )
{
m_arrBars.InsertAt( 1, pBar );
nCountOfBars++;
if( nCountOfBars < 3 || m_arrBars[2] != NULL )
m_arrBars.InsertAt( 2, (CControlBar *)NULL );
ASSERT_VALID( this );
} // if( bDockAtStartIdx )
else
{
m_arrBars.InsertAt( nCountOfBars, (CControlBar *)NULL );
m_arrBars.InsertAt( nCountOfBars, pBar );
if( nCountOfBars > 1 // (+ v.2.23) - fixes initial mutual sizes in row/col problem
&& m_arrBars[nCountOfBars-1] == NULL
)
m_arrBars.RemoveAt( nCountOfBars-1, 1 );
ASSERT_VALID( this );
} // else from if( bDockAtStartIdx )
CDockBar * pOldDockBar = pBar->m_pDockBar;
pBar->m_pDockBar = this;
ASSERT_BAR_LOCATION_IN_ROW( this, pBar );
ASSERT( pBar->m_pDockContext != NULL );
pBar->m_pDockContext->m_uMRUDockID = GetDlgCtrlID();
if( bFloating && nDockBarGetDockedVisibleCount == 0 )
{
if( pOldDockBar->GetDockedCount() == 0 )
pDockingFrameWnd->DestroyWindow();
else
pDockingFrameWnd->ShowWindow( SW_HIDE );
}
// else
// pDockingFrameWnd->DelayRecalcLayout();
// ASSERT( !pBar->IsWindowVisible() );
pBar->SetWindowPos(NULL, 0, 0, 0, 0,
SWP_NOSIZE|SWP_NOMOVE|SWP_NOZORDER|SWP_NOACTIVATE
|SWP_SHOWWINDOW|SWP_FRAMECHANGED
);
ASSERT_VALID( this );
} // else from if( pBar->m_pDockBar == this )
_OptimizeCircles();
}
void CExtDockBar::_LockSequenceOptimization( bool bLock )
{
ASSERT_VALID( this );
ASSERT_KINDOF( CExtDockBar, this );
m_bLockedOptimize = bLock;
}
void CExtDockDynBar::_LockSequenceOptimization( bool bLock )
{
ASSERT_VALID( this );
ASSERT_KINDOF( CExtDockDynBar, this );
m_bLockedOptimize = bLock;
CExtDynControlBar * pDynBar =
STATIC_DOWNCAST(
CExtDynControlBar,
GetParent()
);
ASSERT( pDynBar->m_pWndDynDocker == this );
ASSERT_VALID( pDynBar->m_pDockBar );
if( pDynBar->m_pDockBar->IsKindOf(RUNTIME_CLASS(CExtDockBar)) )
((CExtDockBar *)pDynBar->m_pDockBar)->_LockSequenceOptimization( bLock );
}
void CExtDockBar::DockControlBar(
CControlBar * pBar,
LPCRECT lpRect, // = NULL
bool bSmoothMode // = false
)
{
ASSERT_VALID(this);
ASSERT_VALID(pBar);
ASSERT_KINDOF(CControlBar, pBar);
CRect rectBar;
pBar->GetWindowRect( &rectBar );
if( pBar->m_pDockBar == this
&& (lpRect == NULL || rectBar == *lpRect)
)
{
// already docked and no change in position
return;
}
// set CBRS_FLOAT_MULTI style if docking bar has it
if( m_bFloating && (pBar->m_dwDockStyle & CBRS_FLOAT_MULTI) )
m_dwStyle |= CBRS_FLOAT_MULTI;
m_dwStyle &= ~(CBRS_SIZE_FIXED | CBRS_SIZE_DYNAMIC);
m_dwStyle |= pBar->m_dwStyle & (CBRS_SIZE_FIXED | CBRS_SIZE_DYNAMIC);
if( !(m_dwStyle & CBRS_FLOAT_MULTI) )
{
CString sTitle;
pBar->GetWindowText( sTitle );
AfxSetWindowText( m_hWnd, (LPCTSTR)sTitle );
}
// align correctly and turn on all borders
DWORD dwStyle = pBar->GetBarStyle();
dwStyle &= ~(CBRS_ALIGN_ANY);
dwStyle |= (m_dwStyle & CBRS_ALIGN_ANY) | CBRS_BORDER_ANY;
if( m_bFloating )
dwStyle |= CBRS_FLOATING;
else
dwStyle &= ~CBRS_FLOATING;
pBar->SetBarStyle(dwStyle);
// hide first if changing to a new docking site to avoid flashing
BOOL bShow = FALSE;
if( pBar->m_pDockBar != this && pBar->IsWindowVisible() )
{
pBar->SetWindowPos(
NULL,
0, 0, 0, 0,
SWP_NOSIZE|SWP_NOMOVE|SWP_NOZORDER|SWP_NOACTIVATE|SWP_HIDEWINDOW
);
bShow = TRUE;
}
int nPos = -1;
if( lpRect != NULL )
{
// insert into appropriate row
CRect rect(lpRect);
ScreenToClient(&rect);
CPoint ptMid(rect.left + rect.Width()/2, rect.top + rect.Height()/2);
//nPos = Insert(pBar, rect, ptMid);
nPos = CDockBar::Insert(pBar, rect, ptMid);
ASSERT( nPos > 0 && nPos < (m_arrBars.GetSize()-1) );
// adjust with the previous full-row-mode neiborhood
// based on the fixed-style docking algorithm
CControlBar * pBarNeiborhood =
(CControlBar *)(m_arrBars[nPos-1]);
if( pBarNeiborhood != NULL
&& (! (__PLACEHODLER_BAR_PTR(pBarNeiborhood)) )
)
{
ASSERT_VALID( pBarNeiborhood );
CExtControlBar * pExtBarNeiborhood =
DYNAMIC_DOWNCAST( CExtControlBar, pBarNeiborhood );
if( pExtBarNeiborhood != NULL
&& pExtBarNeiborhood->IsFixedDockStyle()
&& pExtBarNeiborhood->_GetFullRowMode()
)
m_arrBars.InsertAt( nPos++, (CControlBar *)NULL );
}
// adjust with the next full-row-mode neiborhood
// based on the fixed-style docking algorithm
pBarNeiborhood =
(CControlBar *)(m_arrBars[nPos+1]);
if( pBarNeiborhood != NULL
&& (! (__PLACEHODLER_BAR_PTR(pBarNeiborhood)) )
)
{
ASSERT_VALID( pBarNeiborhood );
CExtControlBar * pExtBarNeiborhood =
DYNAMIC_DOWNCAST( CExtControlBar, pBarNeiborhood );
if( pExtBarNeiborhood != NULL
&& pExtBarNeiborhood->IsFixedDockStyle()
&& pExtBarNeiborhood->_GetFullRowMode()
)
m_arrBars.InsertAt( nPos+1, (CControlBar *)NULL );
}
// position at requested position
pBar->SetWindowPos(NULL, rect.left, rect.top, rect.Width(),
rect.Height(), SWP_NOZORDER|SWP_NOACTIVATE|SWP_NOCOPYBITS);
}
else
{
// always add on current row, then create new one
m_arrBars.Add(pBar);
m_arrBars.Add(NULL);
// align off the edge initially
pBar->SetWindowPos(
NULL,
-afxData.cxBorder2, -afxData.cyBorder2, 0, 0,
SWP_NOSIZE|SWP_NOZORDER|SWP_NOACTIVATE|SWP_NOCOPYBITS
);
}
// attach it to the docking site
if (pBar->GetParent() != this)
pBar->SetParent(this);
if( pBar->m_pDockBar == this )
//pBar->m_pDockBar->
RemoveControlBar(pBar, nPos);
else if( pBar->m_pDockBar != NULL )
{
ASSERT_KINDOF( CDockBar, pBar->m_pDockBar );
if( pBar->m_pDockBar->IsKindOf(RUNTIME_CLASS(CExtDockBar)) )
{
bool bOptimizeDockBarLayout = false;
if( !((CExtDockBar *)(pBar->m_pDockBar))->m_bFloating )
bOptimizeDockBarLayout = true;
((CExtDockBar *)(pBar->m_pDockBar))->
RemoveControlBar(
pBar,
-1,
m_bFloating && !pBar->m_pDockBar->m_bFloating,
false // (!bMovingEnabled) ? true : false
);
ASSERT_VALID( this );
if( bOptimizeDockBarLayout
&& !m_bLockedOptimize
)
((CExtDockBar *)(pBar->m_pDockBar))->OnDynamicLayoutOptimize();
}
else
{
pBar->m_pDockBar->
RemoveControlBar(
pBar,
//ph//
0, //-1,
m_bFloating && !pBar->m_pDockBar->m_bFloating
);
ASSERT_VALID( this );
}
}
pBar->m_pDockBar = this;
if( bShow )
{
ASSERT(!pBar->IsWindowVisible());
pBar->SetWindowPos(
NULL,
0, 0, 0, 0,
SWP_NOSIZE|SWP_NOMOVE|SWP_NOZORDER|SWP_NOACTIVATE|SWP_SHOWWINDOW
);
}
else if( bSmoothMode && lpRect != NULL )
{
CRect rcSmooth( *lpRect );
ScreenToClient( &rcSmooth );
pBar->SetWindowPos(
NULL,
rcSmooth.left, rcSmooth.top,
rcSmooth.Width(), rcSmooth.Height(),
SWP_NOZORDER|SWP_NOACTIVATE|SWP_NOSENDCHANGING|SWP_NOREDRAW
);
} // else if( bSmoothMode && lpRect != NULL )
// remove any place holder for pBar in this dockbar
RemovePlaceHolder( pBar, true );
ASSERT_VALID( this );
if( pBar->IsKindOf(RUNTIME_CLASS(CExtControlBar))
&& ((CExtControlBar*)pBar)->_GetFullRowMode()
)
{
nPos = FindBar( pBar );
ASSERT( nPos > 0 && nPos < (m_arrBars.GetSize()-1) );
if( m_arrBars[nPos+1] == NULL )
{
if( m_arrBars[nPos-1] != NULL )
{
m_arrBars.InsertAt( nPos, (CControlBar *)NULL );
ASSERT_VALID( this );
}
} // if( m_arrBars[nPos+1] == NULL )
else
{
if( m_arrBars[nPos-1] == NULL )
{
m_arrBars.InsertAt( nPos+1, (CControlBar *)NULL );
ASSERT_VALID( this );
}
else
{
for( int nPos2 = nPos-1; m_arrBars[nPos2] != NULL; nPos2-- );
ASSERT( nPos2 >= 0 );
m_arrBars.RemoveAt( nPos );
m_arrBars.InsertAt( nPos2, pBar );
m_arrBars.InsertAt( nPos2, (CControlBar *)NULL );
ASSERT_VALID( this );
}
} // else from if( m_arrBars[nPos+1] == NULL )
}
// get parent frame for recalc layout
CFrameWnd* pFrameWnd = GetDockingFrame();
pFrameWnd->DelayRecalcLayout();
// OPTFIX:
// if( !pFrameWnd->IsKindOf(RUNTIME_CLASS(CMiniFrameWnd)) )
// _OptimizeCircles();
}
void CExtDockBar::DrawBorders(CDC* pDC, CRect& rect)
{
ASSERT_VALID( this );
ASSERT_VALID( pDC );
CExtPaintManager::PAINTCONTROLBARBORDERSDATA _pcbbd(
this,
CExtPaintManager::__CB_OUTER_DOCKBAR,
m_dwStyle, // |CBRS_BORDER_ANY|CBRS_BORDER_3D
rect
);
g_PaintManager->PaintControlBarBorders( *pDC, _pcbbd );
}
void CExtDockBar::DrawGripper(CDC* pDC, const CRect& rect)
{
ASSERT_VALID( this );
pDC,
rect;
}
LRESULT CExtDockBar::OnSizeParent(WPARAM wParam, LPARAM lParam)
{
ASSERT_VALID( this );
// if( CExtControlBar::g_bUpdatingDragState )
// return 0;
if( m_bLockedOptimize )
return 0;
LRESULT lResult =
CDockBar::OnSizeParent(wParam,lParam);
// if( _GetCircleNo() == 0 )
// return lResult;
if( (m_dwStyle & CBRS_ALIGN_ANY) == 0 )
return lResult;
UINT nOwnID = GetDlgCtrlID();
if( nOwnID == AFX_IDW_DOCKBAR_FLOAT )
return lResult;
ASSERT_DOCKBAR_DLGCTRLID_DOCKED( nOwnID );
//DWORD dwWndStyle = GetStyle();
//bool bWndVisible = (dwWndStyle & WS_VISIBLE) ? true : false;
// if( bWndVisible )
// {
// if( GetDockedVisibleCount() != 0 )
// return lResult;
// }
AFX_SIZEPARENTPARAMS * lpLayout = (AFX_SIZEPARENTPARAMS*)lParam;
ASSERT( lpLayout != NULL );
// if( lpLayout->hDWP == NULL )
// return lResult;
m_rcLastInvisiblePreCalc = lpLayout->rect;
switch( nOwnID )
{
case AFX_IDW_DOCKBAR_TOP:
// ASSERT( m_rcLastInvisiblePreCalc.left <= m_rcLastInvisiblePreCalc.right );
m_rcLastInvisiblePreCalc.bottom = m_rcLastInvisiblePreCalc.top; // + 1;
break;
case AFX_IDW_DOCKBAR_BOTTOM:
// ASSERT( m_rcLastInvisiblePreCalc.left <= m_rcLastInvisiblePreCalc.right );
m_rcLastInvisiblePreCalc.top = m_rcLastInvisiblePreCalc.bottom; // - 1;
break;
case AFX_IDW_DOCKBAR_LEFT:
// ASSERT( m_rcLastInvisiblePreCalc.top <= m_rcLastInvisiblePreCalc.bottom );
m_rcLastInvisiblePreCalc.right = m_rcLastInvisiblePreCalc.left; // + 1;
break;
case AFX_IDW_DOCKBAR_RIGHT:
// ASSERT( m_rcLastInvisiblePreCalc.top <= m_rcLastInvisiblePreCalc.bottom );
m_rcLastInvisiblePreCalc.left = m_rcLastInvisiblePreCalc.right; // - 1;
break;
#ifdef _DEBUG
default:
ASSERT( FALSE );
break;
#endif // _DEBUG
} // switch( nOwnID )
// MoveWindow( &m_rcLastInvisiblePreCalc, FALSE );
CFrameWnd * pFrame = _GetDockingFrameImpl();
ASSERT_VALID( pFrame );
ASSERT_KINDOF( CFrameWnd, pFrame );
ASSERT( !pFrame->IsKindOf(RUNTIME_CLASS(CMiniFrameWnd)) );
pFrame->ClientToScreen( &m_rcLastInvisiblePreCalc );
return lResult;
}
BOOL CExtDockBar::RemoveControlBar(
CControlBar * pBar,
int nPosExclude, // -1
int nAddPlaceHolder, // = 0
bool bEnableFrameDelayRecalcLayout // = true
)
{
//ph//
// temp
if( pBar->IsKindOf( RUNTIME_CLASS(CExtControlBar) )
&& (! ((CExtControlBar*)pBar)->IsFixedDockStyle() )
)
nAddPlaceHolder = 0;
ASSERT_VALID( this );
ASSERT(
nAddPlaceHolder == 1
|| nAddPlaceHolder == 0
|| nAddPlaceHolder == -1
);
ASSERT_VALID( this );
ASSERT( pBar != NULL );
int nPos = FindBar( pBar, nPosExclude );
ASSERT( nPos > 0 );
if( nAddPlaceHolder == 1 )
{
m_arrBars[ nPos ] = (void*)
_AfxGetDlgCtrlID( pBar->m_hWnd );
// check for already existing place holder
int nPosOld =
FindBar(
(CControlBar *) m_arrBars[ nPos ],
nPos
);
if( nPosOld > 0 )
{
m_arrBars.RemoveAt( nPos );
// remove section indicator (NULL) if nothing
// else in section
if( m_arrBars[ nPos - 1 ] == NULL
&& m_arrBars[ nPos ] == NULL
)
m_arrBars.RemoveAt( nPos );
} // if( nPosOld > 0 )
} // if( nAddPlaceHolder == 1 )
else
{
m_arrBars.RemoveAt( nPos );
if( m_arrBars[nPos-1] == NULL
&& m_arrBars[nPos] == NULL
)
m_arrBars.RemoveAt( nPos );
// Remove any pre-existing place holders.
if( nAddPlaceHolder != -1 )
RemovePlaceHolder( pBar, true );
} // else from if( nAddPlaceHolder == 1 )
// don't do anything more in the shutdown case!
if( pBar->m_pDockContext == NULL )
return FALSE;
// get parent frame for recalc layout/frame destroy
CFrameWnd * pFrameWnd = GetDockingFrame();
if( m_bFloating && GetDockedVisibleCount() == 0 )
{
if( GetDockedCount() == 0 )
{
pFrameWnd->DestroyWindow();
return TRUE; // Self-Destruct
}
else
pFrameWnd->ShowWindow( SW_HIDE );
} // if( m_bFloating && GetDockedVisibleCount() == 0 )
else
{
#if (!defined __EXT_MFC_NO_TAB_CONTROLBARS)
if( IsKindOf(RUNTIME_CLASS(CExtDockDynTabBar)) )
{
// TO FIX:
//CExtDockDynTabBar * pTabbedDocker =
// STATIC_DOWNCAST(
// CExtDockDynTabBar,
// this
// );
//pTabbedDocker->_SyncTabbedChilds(false,true);
//OnDynamicLayoutUpdate();
//pFrameWnd->RecalcLayout();
// HWND hWndOwn = GetSafeHwnd();
// ASSERT( hWndOwn != NULL );
// ASSERT( ::IsWindow(hWndOwn) );
// OnDynamicLayoutOptimize();
// if( !::IsWindow(hWndOwn) )
// return TRUE;
CExtDynTabControlBar * pTabbedBar =
STATIC_DOWNCAST(
CExtDynTabControlBar,
GetParent()
);
//pTabbedBar->SyncSwitcher();
pTabbedBar->OnRepositionSingleChild();
}
#endif // (!defined __EXT_MFC_NO_TAB_CONTROLBARS)
if( bEnableFrameDelayRecalcLayout )
pFrameWnd->DelayRecalcLayout();
} // else from if( m_bFloating && GetDockedVisibleCount() == 0 )
return TRUE;
}
int CExtDockBar::Insert(
CControlBar * pBarIns,
CRect rect,
CPoint ptMid
)
{
return _InsertByPointImpl( pBarIns, rect, ptMid );
}
int CExtDockBar::_InsertByPointImpl(
CControlBar * pBarIns,
CRect rect,
CPoint ptMid
)
{
ASSERT_VALID( this );
ASSERT( pBarIns != NULL );
// ASSERT( pBarIns->m_pDockBar == this );
BOOL bExtBar = pBarIns->IsKindOf(RUNTIME_CLASS(CExtControlBar));
BOOL bExtFixedBar = FALSE;
if( bExtBar )
bExtFixedBar = ((CExtControlBar *)pBarIns)->IsFixedMode();
BOOL bFixedBar = !bExtBar || bExtFixedBar;
INT nPos = 0, nPosInsAfter = -1, nWidth = 0, nTotalWidth = 0;
INT nCountOfSideBars = m_arrBars.GetSize();
BOOL bHorz = m_dwStyle & CBRS_ORIENT_HORZ;
CRect rcDockBarWnd;
GetWindowRect( &rcDockBarWnd );
if( rcDockBarWnd.PtInRect(ptMid) )
{
for( ; nPos < nCountOfSideBars; nPos++ )
{
CControlBar * pBar = GetDockedControlBar( nPos );
if( pBar != NULL && pBar->IsVisible() )
{
CRect rcBar;
pBar->GetWindowRect( &rcBar );
//ScreenToClient( &rcBar );
nWidth =
max(
nWidth,
bHorz ? rcBar.Size().cy : rcBar.Size().cx - 1
);
if( bHorz
? ( rect.left > rcBar.left )
: ( rect.top > rcBar.top )
)
{
//nPosInsAfter = nPos; // orig
if( bFixedBar )
{
if( !pBar->IsKindOf(RUNTIME_CLASS(CExtControlBar)) )
nPosInsAfter = nPos;
else if(
((CExtControlBar *)pBar)->IsFixedMode()
)
nPosInsAfter = nPos;
}
else
nPosInsAfter = nPos;
}
if( bFixedBar
&& rcBar.PtInRect( ptMid )
)
{
INT nDistUp = 0, nDistDown = 0;
if( bHorz )
{
nDistUp = ptMid.y - rcBar.top;
nDistDown = rcBar.bottom - ptMid.y;
} // if( bHorz )
else
{
nDistUp = ptMid.x - rcBar.left;
nDistDown = rcBar.right - ptMid.x;
} // else from if( bHorz )
bool bNextRow = ( nDistUp < nDistDown ) ? false : true;
CControlBar * pFirstBar =
CExtControlBar::_GetFirstControlBarInRow(
pBar,
bNextRow
);
ASSERT_VALID( pFirstBar );
nPosInsAfter = FindBar( pFirstBar );
ASSERT( nPosInsAfter > 0 && nPosInsAfter < nCountOfSideBars );
if( bNextRow )
{
m_arrBars.InsertAt( nPosInsAfter+1, pBarIns );
m_arrBars.InsertAt( nPosInsAfter+1, (CObject*)NULL );
ASSERT_VALID( this );
ASSERT_BAR_LOCATION_IN_ROW( this, pBarIns );
return nPosInsAfter+2;
}
else
{
m_arrBars.InsertAt( nPosInsAfter, (CObject*)NULL );
m_arrBars.InsertAt( nPosInsAfter, pBarIns );
ASSERT_VALID( this );
ASSERT_BAR_LOCATION_IN_ROW( this, pBarIns );
return nPosInsAfter+1;
}
// if( !bNextRow )
/// nPosInsAfter --;
// break;
}
} // if( pBar != NULL && pBar->IsVisible() )
else
{
if( pBar != NULL )
continue;
// end of row because pBar == NULL
nTotalWidth += nWidth - afxData.cyBorder2;
nWidth = 0;
if( (bHorz ? ptMid.y : ptMid.x) < nTotalWidth )
{
if( nPos == 0 ) // first section
{
m_arrBars.InsertAt( 1, (CObject*)NULL );
m_arrBars.InsertAt( 1, pBarIns );
ASSERT_VALID( this );
ASSERT_BAR_LOCATION_IN_ROW( this, pBarIns );
return 1;
} // if( nPos == 0 )
else
{
if( !bFixedBar )
{
m_arrBars.InsertAt( nPos, pBarIns );
ASSERT_VALID( this );
ASSERT_BAR_LOCATION_IN_ROW( this, pBarIns );
}
//if( nPosInsAfter < 0 || !bFixedBar )
if( nPosInsAfter < 0 )
break;
ASSERT( nPosInsAfter >= 0 && nPosInsAfter <= nCountOfSideBars );
CControlBar * pBar2 = (CControlBar *)m_arrBars[ nPosInsAfter ];
if( pBar2 == NULL )
break;
if( __PLACEHODLER_BAR_PTR(pBar2) )
break;
CRect rcBar2;
pBar2->GetWindowRect( &rcBar2 );
INT nDistUp = 0, nDistDown = 0;
if( bHorz )
{
nDistUp = ptMid.y - rcBar2.top;
nDistDown = rcBar2.bottom - ptMid.y;
} // if( bHorz )
else
{
nDistUp = ptMid.x - rcBar2.left;
nDistDown = rcBar2.right - ptMid.x;
} // else from if( bHorz )
bool bNextRow = ( nDistUp < nDistDown ) ? false : true;
CControlBar * pFirstBar =
CExtControlBar::_GetFirstControlBarInRow(
pBar2,
bNextRow
);
ASSERT_VALID( pFirstBar );
nPosInsAfter = FindBar( pFirstBar );
ASSERT( nPosInsAfter > 0 && nPosInsAfter < nCountOfSideBars );
if( bNextRow )
{
m_arrBars.InsertAt( nPosInsAfter+1, pBarIns );
m_arrBars.InsertAt( nPosInsAfter+1, (CObject*)NULL );
ASSERT_VALID( this );
ASSERT_BAR_LOCATION_IN_ROW( this, pBarIns );
return nPosInsAfter+2;
}
else
{
m_arrBars.InsertAt( nPosInsAfter, (CObject*)NULL );
m_arrBars.InsertAt( nPosInsAfter, pBarIns );
ASSERT_VALID( this );
ASSERT_BAR_LOCATION_IN_ROW( this, pBarIns );
return nPosInsAfter+1;
}
} // else from if( nPos == 0 )
}
// nPosInsAfter = nPos;
} // else from if( pBar != NULL && pBar->IsVisible() )
} // for( ; nPos < nCountOfSideBars; nPos++ )
} // if( rcDockBarWnd.PtInRect(ptMid) )
if( nPosInsAfter < 0 )
{
INT nDistUp = 0, nDistDown = 0;
if( bHorz )
{
nDistUp = ptMid.y - rcDockBarWnd.top;
nDistDown = rcDockBarWnd.bottom - ptMid.y;
} // if( bHorz )
else
{
nDistUp = ptMid.x - rcDockBarWnd.left;
nDistDown = rcDockBarWnd.right - ptMid.x;
} // else from if( bHorz )
bool bNextRow =
( abs(nDistUp) < abs(nDistDown) )
? false : true;
nPosInsAfter = bNextRow ? (nCountOfSideBars-1) : 1;
}
ASSERT( nPosInsAfter < nCountOfSideBars );
if( nPosInsAfter == nCountOfSideBars-1 )
m_arrBars.InsertAt( nCountOfSideBars, (CObject*)NULL ); // upper bound NULL
if( m_arrBars[ nPosInsAfter ] != NULL )
{
if( nPosInsAfter+1 < nCountOfSideBars
&& m_arrBars[nPosInsAfter+1] != NULL
)
m_arrBars.InsertAt( nPosInsAfter+1, (CObject*)NULL );
}
m_arrBars.InsertAt( nPosInsAfter+1, pBarIns );
for( nPos = nPosInsAfter; nPos > 0; nPos-- )
{
CControlBar * pBar = (CControlBar *)m_arrBars[nPos];
if( pBar == NULL )
break;
if( __PLACEHODLER_BAR_PTR(pBar) )
{
pBar = _GetDockingFrameImpl()->GetControlBar( LOWORD( DWORD(pBar) ) );
if( pBar == NULL )
continue;
}
BOOL bPrevFixedCheck = TRUE;
if( pBar->IsKindOf(RUNTIME_CLASS(CExtControlBar))
&& !((CExtControlBar *)pBar)->IsFixedMode()
)
bPrevFixedCheck = FALSE;
if( bFixedBar != bPrevFixedCheck )
{
m_arrBars.InsertAt( nPosInsAfter+1, (CObject*)NULL );
nPosInsAfter++;
}
break;
} // for( INT nPos = nPosInsAfter; nPos > 0; nPos-- )
// ASSERT( FindBar(pBarIns) == (nPosInsAfter+1) );
ASSERT_VALID( this );
ASSERT_BAR_LOCATION_IN_ROW( this, pBarIns );
return nPosInsAfter+1;
}
#ifdef _DEBUG
void CExtDockBar::_AssertValid_CheckBarRows() const
{
ASSERT( this != NULL );
if( m_hWnd == NULL )
return;
if( ! ::IsWindow(m_hWnd) )
return;
CRect rcMyWnd;
GetWindowRect( &rcMyWnd );
CSize sizeMyWnd = rcMyWnd.Size();
if( sizeMyWnd.cx < 40 || sizeMyWnd.cy < 40 )
return;
INT nCountOfSideBars = m_arrBars.GetSize();
ASSERT( nCountOfSideBars > 0 );
// first should be NULL
CControlBar * pFirstPosBar = (CControlBar *) m_arrBars[ 0 ];
ASSERT( pFirstPosBar == NULL );
if( m_nCircleNo == 0 )
return;
// walk all rows and verify no empty rows
INT nRowEntryCount = 0; // including placeholders
INT nBar = 1;
if( nCountOfSideBars > 2 )
{
for( ; nBar < nCountOfSideBars; nBar++ )
{
CControlBar * pBar = (CControlBar *) m_arrBars[ nBar ];
if( pBar == NULL )
{
ASSERT( nRowEntryCount > 0 );
nRowEntryCount = 0;
continue;
}
nRowEntryCount++;
} // for( ; nBar < nCountOfSideBars; nBar++ )
}
}
void CExtDockBar::_AssertValid_FixedBarNotInNonfixedRow(
CDockBar * pDockBar,
CControlBar * pBar
)
{
// verify bar and its dockbar
ASSERT_VALID( pBar );
ASSERT_KINDOF( CControlBar, pBar->m_pDockBar );
ASSERT( !pBar->IsDockBar() );
ASSERT( !pBar->IsKindOf(RUNTIME_CLASS(CDockBar)) );
// ASSERT( !pBar->IsFloating() );
// ASSERT( pBar->m_pDockBar != NULL );
// ASSERT_VALID( pBar->m_pDockBar );
// ASSERT_KINDOF( CExtDockBar, pBar->m_pDockBar );
//CExtDockBar * pDockBar = (CExtDockBar *)pBar->m_pDockBar;
ASSERT_VALID( pDockBar );
ASSERT_KINDOF( CDockBar, pDockBar );
bool bCheckingFixedBar = true;
// verify bar is not a kind of resizable bar
if( pBar->IsKindOf(RUNTIME_CLASS(CExtControlBar)) )
{
CExtControlBar * pExtBar = (CExtControlBar *)pBar;
if( !pExtBar->IsFixedDockStyle() )
bCheckingFixedBar = false;
}
INT nCountOfSideBars = pDockBar->m_arrBars.GetSize();
ASSERT( nCountOfSideBars > 0 );
INT nBarPosInDockBar = pDockBar->FindBar( pBar );
ASSERT( nBarPosInDockBar > 0 && nBarPosInDockBar < nCountOfSideBars );
// walk to begin of row
for( INT nBar = nBarPosInDockBar-1; nBar > 0; nBar-- )
{
CControlBar * pBarExamine = (CControlBar *)
pDockBar->m_arrBars[ nBar ];
if( pBarExamine == NULL )
break; // ok
if( __PLACEHODLER_BAR_PTR(pBarExamine) )
continue;
ASSERT_VALID( pBarExamine );
ASSERT_KINDOF( CControlBar, pBarExamine );
ASSERT( pBarExamine->m_pDockBar == pDockBar );
bool bFixedBar = true;
if( pBarExamine->IsKindOf(RUNTIME_CLASS(CExtControlBar)) )
{
CExtControlBar * pExtBar = (CExtControlBar *)pBarExamine;
//ASSERT( pExtBar->IsFixedMode() );
if( !pExtBar->IsFixedDockStyle() )
bFixedBar = false;
}
ASSERT( bCheckingFixedBar == bFixedBar );
}
// walk to end of row
for( nBar = nBarPosInDockBar+1; nBar < nCountOfSideBars; nBar++ )
{
CControlBar * pBarExamine = (CControlBar *)
pDockBar->m_arrBars[ nBar ];
if( pBarExamine == NULL )
break; // ok
if( __PLACEHODLER_BAR_PTR(pBarExamine) )
continue;
ASSERT_VALID( pBarExamine );
ASSERT_KINDOF( CControlBar, pBarExamine );
ASSERT( pBarExamine->m_pDockBar == pDockBar );
bool bFixedBar = true;
if( pBarExamine->IsKindOf(RUNTIME_CLASS(CExtControlBar)) )
{
CExtControlBar * pExtBar = (CExtControlBar *)pBarExamine;
//ASSERT( pExtBar->IsFixedMode() );
if( !pExtBar->IsFixedDockStyle() )
bFixedBar = false;
}
ASSERT( bCheckingFixedBar == bFixedBar );
}
}
#endif // _DEBUG
void CExtDockBar::OnNcCalcSize(
BOOL bCalcValidRects,
NCCALCSIZE_PARAMS * lpncsp
)
{
ASSERT_VALID( this );
bCalcValidRects;
lpncsp;
#if (defined __DEBUG_PAINTING_AREAS_DOCKBAR__ )
CRect & rcClientLoc =
reinterpret_cast < CRect & > ( lpncsp->rgrc[0] );
rcClientLoc.DeflateRect( 0, 0, 1, 1 );
#endif // __DEBUG_PAINTING_AREAS_DOCKBAR__
}
void CExtDockBar::OnNcPaint()
{
ASSERT_VALID( this );
#if (defined __DEBUG_PAINTING_AREAS_DOCKBAR__ )
CRect rcBarWnd, rcBarClient;
GetWindowRect( &rcBarWnd );
GetClientRect( &rcBarClient );
ClientToScreen( &rcBarClient );
if( rcBarWnd == rcBarClient )
return;
CPoint ptDevOffset = -rcBarWnd.TopLeft();
rcBarWnd.OffsetRect( ptDevOffset );
rcBarClient.OffsetRect( ptDevOffset );
CWindowDC dcBarWnd( this );
ASSERT( dcBarWnd.GetSafeHdc() != NULL );
dcBarWnd.ExcludeClipRect( &rcBarClient );
BOOL bDynamicDockBar = IsKindOf( RUNTIME_CLASS(CExtDockDynBar) );
COLORREF clrDebugMargin = bDynamicDockBar
? RGB( 255, 255, 0 )
: RGB( 255, 0, 255 );
dcBarWnd.FillSolidRect( &rcBarWnd, clrDebugMargin );
#endif // __DEBUG_PAINTING_AREAS_DOCKBAR__
}
CExtDockBar * CExtDockBar::_GetInCircle(
UINT nDockBarID,
bool bEnableCreateNew // = true
)
{
ASSERT_VALID( this );
UINT nOwnID = GetDlgCtrlID();
if( nDockBarID == nOwnID )
return this;
CFrameWnd * pFrame = GetParentFrame();
ASSERT_VALID( pFrame );
ASSERT( !pFrame->IsKindOf(RUNTIME_CLASS(CMiniFrameWnd)) );
return
_GetInCircle(
pFrame,
m_nCircleNo,
nDockBarID,
bEnableCreateNew
);
}
CExtDockBar * CExtDockBar::_GetInCircle(
CFrameWnd * pFrame,
UINT nCircleNo,
UINT nDockBarID,
bool bEnableCreateNew // = true
)
{
ASSERT_VALID( pFrame );
POSITION pos = pFrame->m_listControlBars.GetHeadPosition();
ASSERT( pos != NULL );
while( pos != NULL )
{
CControlBar * pBar = (CControlBar *)
pFrame->m_listControlBars.GetNext( pos );
ASSERT_VALID( pBar );
ASSERT_KINDOF( CControlBar, pBar );
if( !pBar->IsKindOf(RUNTIME_CLASS(CExtDockBar)) )
continue;
UINT nID = pBar->GetDlgCtrlID();
if( nID != nDockBarID )
continue;
UINT nCircleNo2 = ((CExtDockBar *)pBar)->_GetCircleNo();
if( nCircleNo == nCircleNo2 )
return ((CExtDockBar *)pBar);
} // while( pos != NULL )
if( !bEnableCreateNew )
return NULL;
_CreateInnerCircle( pFrame );
CExtDockBar * pDockBar =
_GetInCircle(
pFrame,
nCircleNo,
nDockBarID,
bEnableCreateNew
);
ASSERT_VALID( pDockBar );
return pDockBar;
}
UINT CExtDockBar::_CreateInnerCircle()
{
ASSERT_VALID( this );
if( _GetDockBarInner() != NULL )
{
ASSERT_VALID( _GetDockBarInner() );
return ( _GetCircleNo() + 1 );
}
CFrameWnd * pFrame = GetParentFrame();
ASSERT_VALID( pFrame );
ASSERT( !pFrame->IsKindOf(RUNTIME_CLASS(CMiniFrameWnd)) );
return _CreateInnerCircle( pFrame );
}
UINT CExtDockBar::_CreateInnerCircle( CFrameWnd * pFrame )
{
ASSERT_VALID( pFrame );
ASSERT( !pFrame->IsKindOf(RUNTIME_CLASS(CMiniFrameWnd)) );
UINT nCircleNo = 0;
CExtDockBar * vInnerCircle[4] = { NULL, NULL, NULL, NULL };
CExtDockBar * vCreatingCircle[4] = { NULL, NULL, NULL, NULL };
POSITION pos = pFrame->m_listControlBars.GetHeadPosition();
ASSERT( pos != NULL );
while( pos != NULL )
{
CControlBar * pBar = (CControlBar *)
pFrame->m_listControlBars.GetNext( pos );
ASSERT_VALID( pBar );
ASSERT_KINDOF( CControlBar, pBar );
if( !pBar->IsKindOf(RUNTIME_CLASS(CExtDockBar)) )
continue;
if( pBar->IsKindOf(RUNTIME_CLASS(CExtDockDynBar)) )
continue;
UINT nCircleNo2 = ((CExtDockBar *)pBar)->_GetCircleNo();
if( nCircleNo2 < nCircleNo )
continue;
nCircleNo = nCircleNo2;
UINT nID = pBar->GetDlgCtrlID();
//if( nID == AFX_IDW_DOCKBAR_FLOAT )
// continue;
ASSERT_DOCKBAR_DLGCTRLID_DOCKED( nID );
switch( nID )
{
case AFX_IDW_DOCKBAR_TOP:
vInnerCircle[0] = ((CExtDockBar *)pBar);
break;
case AFX_IDW_DOCKBAR_BOTTOM:
vInnerCircle[1] = ((CExtDockBar *)pBar);
break;
case AFX_IDW_DOCKBAR_LEFT:
vInnerCircle[2] = ((CExtDockBar *)pBar);
break;
case AFX_IDW_DOCKBAR_RIGHT:
vInnerCircle[3] = ((CExtDockBar *)pBar);
break;
#ifdef _DEBUG
default:
ASSERT( FALSE );
break;
#endif // _DEBUG
} // switch( nID )
} // while( pos != NULL )
ASSERT( vInnerCircle[0] != NULL );
ASSERT( vInnerCircle[1] != NULL );
ASSERT( vInnerCircle[2] != NULL );
ASSERT( vInnerCircle[3] != NULL );
#ifdef _DEBUG
if( vInnerCircle[0]->m_pDockBarInner == NULL )
{
ASSERT( vInnerCircle[1]->m_pDockBarInner == NULL );
ASSERT( vInnerCircle[2]->m_pDockBarInner == NULL );
ASSERT( vInnerCircle[3]->m_pDockBarInner == NULL );
}
else
{
ASSERT( vInnerCircle[1]->m_pDockBarInner != NULL );
ASSERT( vInnerCircle[2]->m_pDockBarInner != NULL );
ASSERT( vInnerCircle[3]->m_pDockBarInner != NULL );
}
if( vInnerCircle[0]->m_pDockBarOuter == NULL )
{
ASSERT( vInnerCircle[1]->m_pDockBarOuter == NULL );
ASSERT( vInnerCircle[2]->m_pDockBarOuter == NULL );
ASSERT( vInnerCircle[3]->m_pDockBarOuter == NULL );
}
else
{
ASSERT( vInnerCircle[1]->m_pDockBarOuter != NULL );
ASSERT( vInnerCircle[2]->m_pDockBarOuter != NULL );
ASSERT( vInnerCircle[3]->m_pDockBarOuter != NULL );
}
#endif // _DEBUG
nCircleNo ++;
for( INT i = 0; i<4; i++ )
{
CExtDockBar * pBar = vInnerCircle[i];
UINT nID = pBar->GetDlgCtrlID();
ASSERT_DOCKBAR_DLGCTRLID_DOCKED( nID );
ASSERT( vCreatingCircle[i] == NULL );
vCreatingCircle[i] =
new CExtDockBar( nCircleNo );
static const DWORD dwAlignFlags[4] =
{
CBRS_ALIGN_TOP,
CBRS_ALIGN_BOTTOM,
CBRS_ALIGN_LEFT,
CBRS_ALIGN_RIGHT
};
DWORD dwStyle =
WS_CHILD|WS_VISIBLE|WS_CLIPSIBLINGS|WS_CLIPCHILDREN
|dwAlignFlags[i] // |CBRS_ALIGN_ANY
;
VERIFY(
vCreatingCircle[i]->Create( pFrame, dwStyle, nID )
);
ASSERT( pBar->m_pDockBarInner == NULL );
ASSERT( vCreatingCircle[i]->m_pDockBarInner == NULL );
ASSERT( vCreatingCircle[i]->m_pDockBarOuter == NULL );
pBar->m_pDockBarInner = vCreatingCircle[i];
vCreatingCircle[i]->m_pDockBarOuter = pBar;
vCreatingCircle[i]->SetBarStyle( pBar->GetBarStyle() );
#if (!defined __EXT_MFC_NO_TAB_CONTROLBARS)
vCreatingCircle[i]->m_pWndAutoHideArea =
pBar->m_pWndAutoHideArea;
#endif // (!defined __EXT_MFC_NO_TAB_CONTROLBARS)
if( (pBar->GetStyle() & WS_VISIBLE) != NULL
&& pBar->GetDockedVisibleCount() != 0
)
{
pBar->GetWindowRect( &vCreatingCircle[i]->m_rcLastInvisiblePreCalc );
switch( nID )
{
case AFX_IDW_DOCKBAR_TOP:
ASSERT( vCreatingCircle[i]->m_rcLastInvisiblePreCalc.left <= vCreatingCircle[i]->m_rcLastInvisiblePreCalc.right );
vCreatingCircle[i]->m_rcLastInvisiblePreCalc.bottom = vCreatingCircle[i]->m_rcLastInvisiblePreCalc.top; // + 1;
break;
case AFX_IDW_DOCKBAR_BOTTOM:
ASSERT( vCreatingCircle[i]->m_rcLastInvisiblePreCalc.left <= vCreatingCircle[i]->m_rcLastInvisiblePreCalc.right );
vCreatingCircle[i]->m_rcLastInvisiblePreCalc.top = vCreatingCircle[i]->m_rcLastInvisiblePreCalc.bottom; // - 1;
break;
case AFX_IDW_DOCKBAR_LEFT:
ASSERT( vCreatingCircle[i]->m_rcLastInvisiblePreCalc.top <= vCreatingCircle[i]->m_rcLastInvisiblePreCalc.bottom );
vCreatingCircle[i]->m_rcLastInvisiblePreCalc.right = vCreatingCircle[i]->m_rcLastInvisiblePreCalc.left; // + 1;
break;
case AFX_IDW_DOCKBAR_RIGHT:
ASSERT( vCreatingCircle[i]->m_rcLastInvisiblePreCalc.top <= vCreatingCircle[i]->m_rcLastInvisiblePreCalc.bottom );
vCreatingCircle[i]->m_rcLastInvisiblePreCalc.left = vCreatingCircle[i]->m_rcLastInvisiblePreCalc.right; // - 1;
break;
#ifdef _DEBUG
default:
ASSERT( FALSE );
break;
#endif // _DEBUG
} // switch( nID )
} // if( (pBar->GetStyle()&WS_VISIBLE) != NULL .....
else
vCreatingCircle[i]->m_rcLastInvisiblePreCalc = pBar->m_rcLastInvisiblePreCalc;
// reposition created circle in parent HWND list
switch( nID )
{
case AFX_IDW_DOCKBAR_TOP:
ASSERT( i == 0 );
ASSERT( vCreatingCircle[i] != NULL );
ASSERT( vCreatingCircle[i]->GetSafeHwnd() != NULL );
ASSERT( ::IsWindow( vCreatingCircle[i]->GetSafeHwnd() ) );
ASSERT( vInnerCircle[3] != NULL );
ASSERT( vInnerCircle[3]->GetSafeHwnd() != NULL );
ASSERT( ::IsWindow( vInnerCircle[3]->GetSafeHwnd() ) );
VERIFY(
::SetWindowPos(
vCreatingCircle[i]->GetSafeHwnd(),
vInnerCircle[3]->GetSafeHwnd(),
0, 0, 0, 0,
SWP_NOSIZE|SWP_NOMOVE
|SWP_NOREDRAW|SWP_NOACTIVATE|SWP_NOCOPYBITS
|SWP_NOSENDCHANGING
)
);
break;
case AFX_IDW_DOCKBAR_BOTTOM:
case AFX_IDW_DOCKBAR_LEFT:
case AFX_IDW_DOCKBAR_RIGHT:
ASSERT( i >= 1 && i <= 3 );
ASSERT( vCreatingCircle[i] != NULL );
ASSERT( vCreatingCircle[i]->GetSafeHwnd() != NULL );
ASSERT( ::IsWindow( vCreatingCircle[i]->GetSafeHwnd() ) );
ASSERT( vCreatingCircle[i-1] != NULL );
ASSERT( vCreatingCircle[i-1]->GetSafeHwnd() != NULL );
ASSERT( ::IsWindow( vCreatingCircle[i-1]->GetSafeHwnd() ) );
VERIFY(
::SetWindowPos(
vCreatingCircle[i]->GetSafeHwnd(),
vCreatingCircle[i-1]->GetSafeHwnd(),
0, 0, 0, 0,
SWP_NOSIZE|SWP_NOMOVE
|SWP_NOREDRAW|SWP_NOACTIVATE|SWP_NOCOPYBITS
|SWP_NOSENDCHANGING
)
);
break;
#ifdef _DEBUG
default:
ASSERT( FALSE );
break;
#endif // _DEBUG
} // switch( nID )
}
ASSERT( vInnerCircle[0]->m_pDockBarInner != NULL );
ASSERT( vInnerCircle[1]->m_pDockBarInner != NULL );
ASSERT( vInnerCircle[2]->m_pDockBarInner != NULL );
ASSERT( vInnerCircle[3]->m_pDockBarInner != NULL );
#if (!defined __EXT_MFC_NO_TAB_CONTROLBARS)
if( vInnerCircle[0]->m_pWndAutoHideArea != NULL )
{
vInnerCircle[0]->m_pWndAutoHideArea->AdjustOrder();
vInnerCircle[1]->m_pWndAutoHideArea->AdjustOrder();
vInnerCircle[2]->m_pWndAutoHideArea->AdjustOrder();
vInnerCircle[3]->m_pWndAutoHideArea->AdjustOrder();
}
#endif // (!defined __EXT_MFC_NO_TAB_CONTROLBARS)
ASSERT( nCircleNo > 0 );
return nCircleNo;
}
void CExtDockBar::_InjectInnerCircle()
{
ASSERT_VALID( this );
_InjectCircle( m_nCircleNo + 1 );
}
void CExtDockBar::_InjectCircle( UINT nCircleNo )
{
ASSERT_VALID( this );
ASSERT( nCircleNo > 0 );
CFrameWnd * pFrame = GetParentFrame();
ASSERT_VALID( pFrame );
ASSERT( !pFrame->IsKindOf(RUNTIME_CLASS(CMiniFrameWnd)) );
_InjectCircle( pFrame, nCircleNo );
}
void CExtDockBar::_InjectCircle( CFrameWnd * pFrame, UINT nCircleNo )
{
ASSERT_VALID( pFrame );
ASSERT( nCircleNo > 0 );
CExtDockBar * vCircleOld[4];
vCircleOld[0] = (CExtDockBar *)pFrame->GetControlBar( AFX_IDW_DOCKBAR_TOP );
vCircleOld[1] = (CExtDockBar *)pFrame->GetControlBar( AFX_IDW_DOCKBAR_BOTTOM );
vCircleOld[2] = (CExtDockBar *)pFrame->GetControlBar( AFX_IDW_DOCKBAR_LEFT );
vCircleOld[3] = (CExtDockBar *)pFrame->GetControlBar( AFX_IDW_DOCKBAR_RIGHT );
bool bEmptyCircleExist = true;
for( INT nDockSide = 0; nDockSide < 4; nDockSide++ )
{
ASSERT_VALID( vCircleOld[nDockSide] );
ASSERT_KINDOF( CExtDockBar, vCircleOld[nDockSide] );
ASSERT( vCircleOld[nDockSide]->_GetCircleNo() == 0 );
vCircleOld[nDockSide] = vCircleOld[nDockSide]->_GetBarByCircleNo( nCircleNo );
ASSERT_VALID( vCircleOld[nDockSide] );
ASSERT( vCircleOld[nDockSide]->_GetCircleNo() == nCircleNo );
if( ! vCircleOld[nDockSide]->_CanBeSafeOptimized() )
bEmptyCircleExist = false;
} // for( INT nDockSide = 0; nDockSide < 4; nDockSide++ )
if( bEmptyCircleExist )
{
#if (!defined __EXT_MFC_NO_TAB_CONTROLBARS)
if( vCircleOld[0]->m_pWndAutoHideArea != NULL )
{
vCircleOld[0]->m_pWndAutoHideArea->AdjustOrder();
vCircleOld[1]->m_pWndAutoHideArea->AdjustOrder();
vCircleOld[2]->m_pWndAutoHideArea->AdjustOrder();
vCircleOld[3]->m_pWndAutoHideArea->AdjustOrder();
}
#endif // (!defined __EXT_MFC_NO_TAB_CONTROLBARS)
return;
}
CExtDockBar * vCircleNew[4] = { NULL, NULL, NULL, NULL };
for( nDockSide = 0; nDockSide < 4; nDockSide++ )
{
ASSERT_VALID( vCircleOld[nDockSide] );
ASSERT( vCircleOld[nDockSide]->_GetCircleNo() == nCircleNo );
UINT nID = vCircleOld[nDockSide]->GetDlgCtrlID();
ASSERT_DOCKBAR_DLGCTRLID_DOCKED( nID );
vCircleNew[nDockSide] =
new CExtDockBar( nCircleNo );
#if (!defined __EXT_MFC_NO_TAB_CONTROLBARS)
vCircleNew[nDockSide]->m_pWndAutoHideArea =
vCircleOld[nDockSide]->m_pWndAutoHideArea;
#endif // (!defined __EXT_MFC_NO_TAB_CONTROLBARS)
static const DWORD dwAlignFlags[4] =
{
CBRS_ALIGN_TOP,
CBRS_ALIGN_BOTTOM,
CBRS_ALIGN_LEFT,
CBRS_ALIGN_RIGHT
};
DWORD dwStyle =
WS_CHILD|WS_VISIBLE|WS_CLIPSIBLINGS|WS_CLIPCHILDREN
|dwAlignFlags[nDockSide] // |CBRS_ALIGN_ANY
;
VERIFY(
vCircleNew[nDockSide]->Create( pFrame, dwStyle, nID )
);
ASSERT( vCircleNew[nDockSide]->m_pDockBarInner == NULL );
ASSERT( vCircleNew[nDockSide]->m_pDockBarOuter == NULL );
ASSERT( vCircleOld[nDockSide]->m_pDockBarOuter != NULL );
ASSERT( vCircleOld[nDockSide]->m_pDockBarOuter->m_pDockBarInner == vCircleOld[nDockSide] );
vCircleOld[nDockSide]->m_pDockBarOuter->m_pDockBarInner = vCircleNew[nDockSide];
vCircleNew[nDockSide]->m_pDockBarOuter = vCircleOld[nDockSide]->m_pDockBarOuter;
vCircleOld[nDockSide]->m_pDockBarOuter = vCircleNew[nDockSide];
vCircleNew[nDockSide]->m_pDockBarInner = vCircleOld[nDockSide];
vCircleNew[nDockSide]->SetBarStyle(
vCircleOld[nDockSide]->GetBarStyle()
);
if( (vCircleOld[nDockSide]->GetStyle() & WS_VISIBLE) != NULL
&& vCircleOld[nDockSide]->GetDockedVisibleCount() != 0
)
{
vCircleOld[nDockSide]->GetWindowRect(
&(vCircleNew[nDockSide]->m_rcLastInvisiblePreCalc)
);
switch( nID )
{
case AFX_IDW_DOCKBAR_TOP:
ASSERT( vCircleNew[nDockSide]->m_rcLastInvisiblePreCalc.left <= vCircleNew[nDockSide]->m_rcLastInvisiblePreCalc.right );
vCircleNew[nDockSide]->m_rcLastInvisiblePreCalc.bottom = vCircleNew[nDockSide]->m_rcLastInvisiblePreCalc.top; // + 1;
break;
case AFX_IDW_DOCKBAR_BOTTOM:
ASSERT( vCircleNew[nDockSide]->m_rcLastInvisiblePreCalc.left <= vCircleNew[nDockSide]->m_rcLastInvisiblePreCalc.right );
vCircleNew[nDockSide]->m_rcLastInvisiblePreCalc.top = vCircleNew[nDockSide]->m_rcLastInvisiblePreCalc.bottom; // - 1;
break;
case AFX_IDW_DOCKBAR_LEFT:
ASSERT( vCircleNew[nDockSide]->m_rcLastInvisiblePreCalc.top <= vCircleNew[nDockSide]->m_rcLastInvisiblePreCalc.bottom );
vCircleNew[nDockSide]->m_rcLastInvisiblePreCalc.right = vCircleNew[nDockSide]->m_rcLastInvisiblePreCalc.left; // + 1;
break;
case AFX_IDW_DOCKBAR_RIGHT:
ASSERT( vCircleNew[nDockSide]->m_rcLastInvisiblePreCalc.top <= vCircleNew[nDockSide]->m_rcLastInvisiblePreCalc.bottom );
vCircleNew[nDockSide]->m_rcLastInvisiblePreCalc.left = vCircleNew[nDockSide]->m_rcLastInvisiblePreCalc.right; // - 1;
break;
#ifdef _DEBUG
default:
ASSERT( FALSE );
break;
#endif // _DEBUG
} // switch( nID )
} // if( (vCircleOld[nDockSide]->GetStyle()&WS_VISIBLE) != NULL .....
else
vCircleNew[nDockSide]->m_rcLastInvisiblePreCalc =
vCircleOld[nDockSide]->m_rcLastInvisiblePreCalc;
for( CExtDockBar * pResetNoBar = vCircleOld[nDockSide];
pResetNoBar != NULL;
pResetNoBar = pResetNoBar->m_pDockBarInner
)
pResetNoBar->m_nCircleNo++;
switch( nID )
{
case AFX_IDW_DOCKBAR_TOP:
ASSERT( nDockSide == 0 );
ASSERT( vCircleOld[3]->m_pDockBarOuter != NULL );
ASSERT( vCircleOld[3]->m_pDockBarOuter->GetSafeHwnd() != NULL );
ASSERT( ::IsWindow( vCircleOld[3]->m_pDockBarOuter->GetSafeHwnd() ) );
ASSERT( vCircleNew[nDockSide] != NULL );
ASSERT( vCircleNew[nDockSide]->GetSafeHwnd() != NULL );
ASSERT( ::IsWindow( vCircleNew[nDockSide]->GetSafeHwnd() ) );
VERIFY(
::SetWindowPos(
vCircleNew[nDockSide]->GetSafeHwnd(),
vCircleOld[3]->m_pDockBarOuter->GetSafeHwnd(),
0, 0, 0, 0,
SWP_NOSIZE|SWP_NOMOVE
|SWP_NOREDRAW|SWP_NOACTIVATE|SWP_NOCOPYBITS
|SWP_NOSENDCHANGING
)
);
break;
case AFX_IDW_DOCKBAR_BOTTOM:
case AFX_IDW_DOCKBAR_LEFT:
case AFX_IDW_DOCKBAR_RIGHT:
ASSERT( nDockSide > 0 );
ASSERT( vCircleNew[nDockSide-1] != NULL );
ASSERT( vCircleNew[nDockSide-1]->GetSafeHwnd() != NULL );
ASSERT( ::IsWindow( vCircleNew[nDockSide-1]->GetSafeHwnd() ) );
ASSERT( vCircleNew[nDockSide] != NULL );
ASSERT( vCircleNew[nDockSide]->GetSafeHwnd() != NULL );
ASSERT( ::IsWindow( vCircleNew[nDockSide]->GetSafeHwnd() ) );
VERIFY(
::SetWindowPos(
vCircleNew[nDockSide]->GetSafeHwnd(),
vCircleNew[nDockSide-1]->GetSafeHwnd(),
0, 0, 0, 0,
SWP_NOSIZE|SWP_NOMOVE
|SWP_NOREDRAW|SWP_NOACTIVATE|SWP_NOCOPYBITS
|SWP_NOSENDCHANGING
)
);
break;
#ifdef _DEBUG
default:
ASSERT( FALSE );
break;
#endif // _DEBUG
} // switch( nID )
// VERIFY(
// ::SetWindowPos(
// vCircleNew[nDockSide]->GetSafeHwnd(),
// vCircleOld[nDockSide]->m_pDockBarOuter->_GetHwndForInjectingAfter(),
// 0, 0, 0, 0,
// SWP_NOSIZE|SWP_NOMOVE
// |SWP_NOREDRAW|SWP_NOACTIVATE|SWP_NOCOPYBITS
// |SWP_NOSENDCHANGING
// )
// );
} // for( nDockSide = 0; nDockSide < 4; nDockSide++ )
ASSERT_VALID( vCircleNew[0] );
ASSERT_VALID( vCircleNew[1] );
ASSERT_VALID( vCircleNew[2] );
ASSERT_VALID( vCircleNew[3] );
#if (!defined __EXT_MFC_NO_TAB_CONTROLBARS)
if( vCircleNew[0]->m_pWndAutoHideArea != NULL )
{
vCircleNew[0]->m_pWndAutoHideArea->AdjustOrder();
vCircleNew[1]->m_pWndAutoHideArea->AdjustOrder();
vCircleNew[2]->m_pWndAutoHideArea->AdjustOrder();
vCircleNew[3]->m_pWndAutoHideArea->AdjustOrder();
}
#endif // (!defined __EXT_MFC_NO_TAB_CONTROLBARS)
}
#ifdef _DEBUG
void CExtDockBar::_Assert_HwndIsDockbar(
HWND hWndDockBar,
UINT nDockBarID,
UINT nCircleNo
)
{
ASSERT_DOCKBAR_DLGCTRLID_DOCKED( nDockBarID );
ASSERT( hWndDockBar != NULL );
ASSERT( ::IsWindow( hWndDockBar ) );
CWnd * pWndDockBar = CWnd::FromHandlePermanent( hWndDockBar );
ASSERT_VALID( pWndDockBar );
CExtDockBar * pDockBar =
STATIC_DOWNCAST( CExtDockBar, pWndDockBar );
UINT nRealDockBarID = pDockBar->GetDlgCtrlID();
ASSERT_DOCKBAR_DLGCTRLID_DOCKED( nRealDockBarID );
ASSERT( nDockBarID == nRealDockBarID );
UINT nRealCircleNo = pDockBar->_GetCircleNo();
ASSERT( nRealCircleNo == nCircleNo );
}
#if (!defined __EXT_MFC_NO_TAB_CONTROLBARS)
void CExtDockBar::_Assert_HwndIsAutoHider(
HWND hWndAutoHider,
UINT nAutoHiderID
)
{
ASSERT( hWndAutoHider != NULL );
ASSERT( ::IsWindow( hWndAutoHider ) );
CWnd * pWndAutoHider = CWnd::FromHandlePermanent( hWndAutoHider );
ASSERT_VALID( pWndAutoHider );
CExtDynAutoHideArea * pAutoHider =
STATIC_DOWNCAST( CExtDynAutoHideArea, pWndAutoHider );
UINT nRealAutoHiderID = pAutoHider->GetDlgCtrlID();
ASSERT_DOCKBAR_DLGCTRLID_DOCKED( nRealAutoHiderID );
ASSERT( nAutoHiderID == nRealAutoHiderID );
}
#endif // (!defined __EXT_MFC_NO_TAB_CONTROLBARS)
#endif // _DEBUG
//HWND CExtDockBar::_GetHwndForInjectingAfter()
//{
// ASSERT_VALID( this );
//HWND hWndOwn = GetSafeHwnd();
// ASSERT( hWndOwn != NULL );
// ASSERT( ::IsWindow( hWndOwn ) );
//
//UINT nOwnID = GetDlgCtrlID();
// ASSERT_DOCKBAR_DLGCTRLID_DOCKED( nOwnID );
//
//HWND hWndAutoHideArea = m_pWndAutoHideArea->GetSafeHwnd();
//UINT nOwnCircleNo = _GetCircleNo();
//
//HWND hWndInsertAfter =
// (hWndAutoHideArea != NULL && nOwnCircleNo == 0)
// ? hWndAutoHideArea
// : hWndOwn
// ;
// switch( nOwnID )
// {
// case AFX_IDW_DOCKBAR_TOP:
// {
// // get dockbar in same circle (nOwnCircleNo) - bottom
// hWndInsertAfter = ::GetWindow( hWndInsertAfter, GW_HWNDNEXT );
// ASSERT_HWND_IS_DOCKBAR( hWndInsertAfter, AFX_IDW_DOCKBAR_BOTTOM, nOwnCircleNo );
// // get dockbar in same circle (nOwnCircleNo) - left
// hWndInsertAfter = ::GetWindow( hWndInsertAfter, GW_HWNDNEXT );
// ASSERT_HWND_IS_DOCKBAR( hWndInsertAfter, AFX_IDW_DOCKBAR_LEFT, nOwnCircleNo );
// // get dockbar in same circle (nOwnCircleNo) - right
// hWndInsertAfter = ::GetWindow( hWndInsertAfter, GW_HWNDNEXT );
// ASSERT_HWND_IS_DOCKBAR( hWndInsertAfter, AFX_IDW_DOCKBAR_RIGHT, nOwnCircleNo );
// if( nOwnCircleNo == 0 && hWndAutoHideArea != NULL )
// {
// // get autohider - top
// hWndInsertAfter = ::GetWindow( hWndInsertAfter, GW_HWNDNEXT );
// ASSERT_HWND_IS_AUTOHIDER( hWndInsertAfter, AFX_IDW_DOCKBAR_TOP );
// // get autohider - bottom
// hWndInsertAfter = ::GetWindow( hWndInsertAfter, GW_HWNDNEXT );
// ASSERT_HWND_IS_AUTOHIDER( hWndInsertAfter, AFX_IDW_DOCKBAR_BOTTOM );
// // get autohider - left
// hWndInsertAfter = ::GetWindow( hWndInsertAfter, GW_HWNDNEXT );
// ASSERT_HWND_IS_AUTOHIDER( hWndInsertAfter, AFX_IDW_DOCKBAR_LEFT );
// // get autohider - right
// hWndInsertAfter = ::GetWindow( hWndInsertAfter, GW_HWNDNEXT );
// ASSERT_HWND_IS_AUTOHIDER( hWndInsertAfter, AFX_IDW_DOCKBAR_RIGHT );
// }
// }
// break; // case AFX_IDW_DOCKBAR_TOP
// case AFX_IDW_DOCKBAR_BOTTOM:
// {
// // get dockbar in same circle (nOwnCircleNo) - left
// hWndInsertAfter = ::GetWindow( hWndInsertAfter, GW_HWNDNEXT );
// ASSERT_HWND_IS_DOCKBAR( hWndInsertAfter, AFX_IDW_DOCKBAR_LEFT, nOwnCircleNo );
// // get dockbar in same circle (nOwnCircleNo) - right
// hWndInsertAfter = ::GetWindow( hWndInsertAfter, GW_HWNDNEXT );
// ASSERT_HWND_IS_DOCKBAR( hWndInsertAfter, AFX_IDW_DOCKBAR_RIGHT, nOwnCircleNo );
// if( nOwnCircleNo == 0 && hWndAutoHideArea != NULL )
// {
// // get autohider - top
// hWndInsertAfter = ::GetWindow( hWndInsertAfter, GW_HWNDNEXT );
// ASSERT_HWND_IS_AUTOHIDER( hWndInsertAfter, AFX_IDW_DOCKBAR_TOP );
// // get autohider - bottom
// hWndInsertAfter = ::GetWindow( hWndInsertAfter, GW_HWNDNEXT );
// ASSERT_HWND_IS_AUTOHIDER( hWndInsertAfter, AFX_IDW_DOCKBAR_BOTTOM );
// // get autohider - left
// hWndInsertAfter = ::GetWindow( hWndInsertAfter, GW_HWNDNEXT );
// ASSERT_HWND_IS_AUTOHIDER( hWndInsertAfter, AFX_IDW_DOCKBAR_LEFT );
// // get autohider - right
// hWndInsertAfter = ::GetWindow( hWndInsertAfter, GW_HWNDNEXT );
// ASSERT_HWND_IS_AUTOHIDER( hWndInsertAfter, AFX_IDW_DOCKBAR_RIGHT );
// }
// // get dockbar in next circle (nOwnCircleNo+1) - top
// hWndInsertAfter = ::GetWindow( hWndInsertAfter, GW_HWNDNEXT );
// ASSERT_HWND_IS_DOCKBAR( hWndInsertAfter, AFX_IDW_DOCKBAR_TOP, (nOwnCircleNo+1) );
// }
// break; // case AFX_IDW_DOCKBAR_BOTTOM
// case AFX_IDW_DOCKBAR_LEFT:
// {
// // get dockbar in same circle (nOwnCircleNo) - right
// hWndInsertAfter = ::GetWindow( hWndInsertAfter, GW_HWNDNEXT );
// ASSERT_HWND_IS_DOCKBAR( hWndInsertAfter, AFX_IDW_DOCKBAR_RIGHT, nOwnCircleNo );
// if( nOwnCircleNo == 0 && hWndAutoHideArea != NULL )
// {
// // get autohider - top
// hWndInsertAfter = ::GetWindow( hWndInsertAfter, GW_HWNDNEXT );
// ASSERT_HWND_IS_AUTOHIDER( hWndInsertAfter, AFX_IDW_DOCKBAR_TOP );
// // get autohider - bottom
// hWndInsertAfter = ::GetWindow( hWndInsertAfter, GW_HWNDNEXT );
// ASSERT_HWND_IS_AUTOHIDER( hWndInsertAfter, AFX_IDW_DOCKBAR_BOTTOM );
// // get autohider - left
// hWndInsertAfter = ::GetWindow( hWndInsertAfter, GW_HWNDNEXT );
// ASSERT_HWND_IS_AUTOHIDER( hWndInsertAfter, AFX_IDW_DOCKBAR_LEFT );
// // get autohider - right
// hWndInsertAfter = ::GetWindow( hWndInsertAfter, GW_HWNDNEXT );
// ASSERT_HWND_IS_AUTOHIDER( hWndInsertAfter, AFX_IDW_DOCKBAR_RIGHT );
// }
// // get dockbar in next circle (nOwnCircleNo+1) - top
// hWndInsertAfter = ::GetWindow( hWndInsertAfter, GW_HWNDNEXT );
// ASSERT_HWND_IS_DOCKBAR( hWndInsertAfter, AFX_IDW_DOCKBAR_TOP, (nOwnCircleNo+1) );
// // get dockbar in next circle (nOwnCircleNo+1) - bottom
// hWndInsertAfter = ::GetWindow( hWndInsertAfter, GW_HWNDNEXT );
// ASSERT_HWND_IS_DOCKBAR( hWndInsertAfter, AFX_IDW_DOCKBAR_BOTTOM, (nOwnCircleNo+1) );
// }
// break; // case AFX_IDW_DOCKBAR_LEFT
// case AFX_IDW_DOCKBAR_RIGHT:
// {
// if( nOwnCircleNo == 0 && hWndAutoHideArea != NULL )
// {
// // get autohider - top
// hWndInsertAfter = ::GetWindow( hWndInsertAfter, GW_HWNDNEXT );
// ASSERT_HWND_IS_AUTOHIDER( hWndInsertAfter, AFX_IDW_DOCKBAR_TOP );
// // get autohider - bottom
// hWndInsertAfter = ::GetWindow( hWndInsertAfter, GW_HWNDNEXT );
// ASSERT_HWND_IS_AUTOHIDER( hWndInsertAfter, AFX_IDW_DOCKBAR_BOTTOM );
// // get autohider - left
// hWndInsertAfter = ::GetWindow( hWndInsertAfter, GW_HWNDNEXT );
// ASSERT_HWND_IS_AUTOHIDER( hWndInsertAfter, AFX_IDW_DOCKBAR_LEFT );
// // get autohider - right
// hWndInsertAfter = ::GetWindow( hWndInsertAfter, GW_HWNDNEXT );
// ASSERT_HWND_IS_AUTOHIDER( hWndInsertAfter, AFX_IDW_DOCKBAR_RIGHT );
// }
// // get dockbar in next circle (nOwnCircleNo+1) - top
// hWndInsertAfter = ::GetWindow( hWndInsertAfter, GW_HWNDNEXT );
// ASSERT_HWND_IS_DOCKBAR( hWndInsertAfter, AFX_IDW_DOCKBAR_TOP, (nOwnCircleNo+1) );
// // get dockbar in next circle (nOwnCircleNo+1) - bottom
// hWndInsertAfter = ::GetWindow( hWndInsertAfter, GW_HWNDNEXT );
// ASSERT_HWND_IS_DOCKBAR( hWndInsertAfter, AFX_IDW_DOCKBAR_BOTTOM, (nOwnCircleNo+1) );
// // get dockbar in next circle (nOwnCircleNo+1) - left
// hWndInsertAfter = ::GetWindow( hWndInsertAfter, GW_HWNDNEXT );
// ASSERT_HWND_IS_DOCKBAR( hWndInsertAfter, AFX_IDW_DOCKBAR_LEFT, (nOwnCircleNo+1) );
// }
// break; // case AFX_IDW_DOCKBAR_RIGHT
//#ifdef _DEBUG
// default:
// ASSERT( FALSE );
// break;
//#endif // _DEBUG
// } // switch( nOwnID )
//
//
// ASSERT( hWndInsertAfter != NULL );
// return hWndInsertAfter;
//}
CExtDockBar * CExtDockBar::_GetBarByCircleNo( UINT nCircleNo )
{
ASSERT_VALID( this );
if( nCircleNo == m_nCircleNo )
return this;
if( nCircleNo < m_nCircleNo )
{
ASSERT( m_nCircleNo > 0 );
ASSERT( m_pDockBarOuter != NULL );
return m_pDockBarOuter->_GetBarByCircleNo( nCircleNo );
}
if( m_pDockBarInner == NULL )
{
#ifdef _DEBUG
UINT nNewCircle =
#endif // _DEBUG
_CreateInnerCircle();
ASSERT( nNewCircle == (m_nCircleNo + 1) );
}
ASSERT( m_pDockBarInner != NULL );
ASSERT( m_pDockBarInner->m_nCircleNo == (m_nCircleNo + 1) );
return m_pDockBarInner->_GetBarByCircleNo( nCircleNo );
}
LRESULT CExtDockBar::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
{
switch( message )
{
case WM_CREATE:
EnableToolTips();
break;
case WM_DESTROY:
case WM_NCDESTROY:
if( m_pDockBarInner != NULL )
{
ASSERT( m_pDockBarInner->m_pDockBarOuter == this );
m_pDockBarInner->m_pDockBarOuter = NULL;
m_pDockBarInner = NULL;
}
if( m_pDockBarOuter != NULL )
{
ASSERT( m_pDockBarOuter->m_pDockBarInner == this );
m_pDockBarOuter->m_pDockBarInner = NULL;
m_pDockBarOuter = NULL;
}
break;
} // switch( message )
return CControlBar::WindowProc(message, wParam, lParam);
}
void CExtDockBar::_OptimizeCircles()
{
ASSERT_VALID( this );
CFrameWnd * pFrame = GetParentFrame();
ASSERT_VALID( pFrame );
ASSERT( !pFrame->IsKindOf(RUNTIME_CLASS(CMiniFrameWnd)) );
if( !m_bLockedOptimize )
_OptimizeCircles( pFrame );
}
void CExtDockBar::_OptimizeCircles( CFrameWnd * pFrame )
{
ASSERT_VALID( pFrame );
CExtDockBar * vCircle[4];
vCircle[0] = (CExtDockBar*)pFrame->GetControlBar( AFX_IDW_DOCKBAR_TOP );
ASSERT_VALID( vCircle[0] );
ASSERT_KINDOF( CExtDockBar, vCircle[0] );
ASSERT( vCircle[0]->_GetCircleNo() == 0 );
vCircle[1] = (CExtDockBar*)pFrame->GetControlBar( AFX_IDW_DOCKBAR_BOTTOM );
ASSERT_VALID( vCircle[1] );
ASSERT_KINDOF( CExtDockBar, vCircle[1] );
ASSERT( vCircle[1]->_GetCircleNo() == 0 );
vCircle[2] = (CExtDockBar*)pFrame->GetControlBar( AFX_IDW_DOCKBAR_LEFT );
ASSERT_VALID( vCircle[2] );
ASSERT_KINDOF( CExtDockBar, vCircle[2] );
ASSERT( vCircle[2]->_GetCircleNo() == 0 );
vCircle[3] = (CExtDockBar*)pFrame->GetControlBar( AFX_IDW_DOCKBAR_RIGHT );
ASSERT_VALID( vCircle[3] );
ASSERT_KINDOF( CExtDockBar, vCircle[3] );
ASSERT( vCircle[3]->_GetCircleNo() == 0 );
if( vCircle[0]->_GetDockBarInner() == NULL )
return;
vCircle[0] = vCircle[0]->_GetDockBarInner();
ASSERT( vCircle[0] != NULL );
ASSERT_KINDOF( CExtDockBar, vCircle[0] );
ASSERT( vCircle[0]->_GetCircleNo() == 1 );
vCircle[1] = vCircle[1]->_GetDockBarInner();
ASSERT( vCircle[1] != NULL );
ASSERT_KINDOF( CExtDockBar, vCircle[1] );
ASSERT( vCircle[1]->_GetCircleNo() == 1 );
vCircle[2] = vCircle[2]->_GetDockBarInner();
ASSERT( vCircle[2] != NULL );
ASSERT_KINDOF( CExtDockBar, vCircle[2] );
ASSERT( vCircle[2]->_GetCircleNo() == 1 );
vCircle[3] = vCircle[3]->_GetDockBarInner();
ASSERT( vCircle[3] != NULL );
ASSERT_KINDOF( CExtDockBar, vCircle[3] );
ASSERT( vCircle[3]->_GetCircleNo() == 1 );
//bool bCreateInnerCircle = true;
UINT nCircleShift = 0;
#if (!defined __EXT_MFC_NO_TAB_CONTROLBARS)
bool bAutoHidersPassed = false;
#endif // (!defined __EXT_MFC_NO_TAB_CONTROLBARS)
while( vCircle[0] != NULL )
{
ASSERT( vCircle[0] != NULL );
ASSERT_KINDOF( CExtDockBar, vCircle[0] );
ASSERT( vCircle[1] != NULL );
ASSERT_KINDOF( CExtDockBar, vCircle[1] );
ASSERT( vCircle[2] != NULL );
ASSERT_KINDOF( CExtDockBar, vCircle[2] );
ASSERT( vCircle[3] != NULL );
ASSERT_KINDOF( CExtDockBar, vCircle[3] );
ASSERT( vCircle[0]->m_nCircleNo == vCircle[1]->m_nCircleNo );
ASSERT( vCircle[0]->m_nCircleNo == vCircle[2]->m_nCircleNo );
ASSERT( vCircle[0]->m_nCircleNo == vCircle[3]->m_nCircleNo );
#if (!defined __EXT_MFC_NO_TAB_CONTROLBARS)
if( !bAutoHidersPassed )
{
bAutoHidersPassed = true;
if( vCircle[0]->m_pWndAutoHideArea != NULL )
{
vCircle[0]->m_pWndAutoHideArea->AdjustOrder();
vCircle[1]->m_pWndAutoHideArea->AdjustOrder();
vCircle[2]->m_pWndAutoHideArea->AdjustOrder();
vCircle[3]->m_pWndAutoHideArea->AdjustOrder();
}
}
#endif // (!defined __EXT_MFC_NO_TAB_CONTROLBARS)
if( nCircleShift != 0 )
{
ASSERT( vCircle[0]->m_nCircleNo > nCircleShift );
vCircle[0]->m_nCircleNo -= nCircleShift;
vCircle[1]->m_nCircleNo -= nCircleShift;
vCircle[2]->m_nCircleNo -= nCircleShift;
vCircle[3]->m_nCircleNo -= nCircleShift;
}
CExtDockBar * vCircleOptimize[4];
vCircleOptimize[0] = vCircle[0];
vCircleOptimize[1] = vCircle[1];
vCircleOptimize[2] = vCircle[2];
vCircleOptimize[3] = vCircle[3];
// bool bLastCircle =
// ( vCircle[0]->_GetDockBarInner() != NULL ) ? true : false;
vCircle[0] = vCircle[0]->_GetDockBarInner();
vCircle[1] = vCircle[1]->_GetDockBarInner();
vCircle[2] = vCircle[2]->_GetDockBarInner();
vCircle[3] = vCircle[3]->_GetDockBarInner();
if( vCircleOptimize[0]->_CanBeSafeOptimized()
&& vCircleOptimize[1]->_CanBeSafeOptimized()
&& vCircleOptimize[2]->_CanBeSafeOptimized()
&& vCircleOptimize[3]->_CanBeSafeOptimized()
)
{
// if( bLastCircle )
// {
// bCreateInnerCircle = false;
// break;
// }
#ifdef __DEBUG_LOCKING_OPTIMIZATION_ASSERTS__
ASSERT( !vCircleOptimize[0]->m_bLockedOptimize );
ASSERT( !vCircleOptimize[1]->m_bLockedOptimize );
ASSERT( !vCircleOptimize[2]->m_bLockedOptimize );
ASSERT( !vCircleOptimize[3]->m_bLockedOptimize );
#endif // __DEBUG_LOCKING_OPTIMIZATION_ASSERTS__
vCircleOptimize[0]->_SafeOptimizeInnerOuterChain();
vCircleOptimize[1]->_SafeOptimizeInnerOuterChain();
vCircleOptimize[2]->_SafeOptimizeInnerOuterChain();
vCircleOptimize[3]->_SafeOptimizeInnerOuterChain();
nCircleShift++;
}
else
{
#ifdef __DEBUG_LOCKING_OPTIMIZATION_ASSERTS__
ASSERT( !vCircleOptimize[0]->m_bLockedOptimize );
ASSERT( !vCircleOptimize[1]->m_bLockedOptimize );
ASSERT( !vCircleOptimize[2]->m_bLockedOptimize );
ASSERT( !vCircleOptimize[3]->m_bLockedOptimize );
#endif // __DEBUG_LOCKING_OPTIMIZATION_ASSERTS__
vCircleOptimize[0]->OnDynamicLayoutOptimize();
vCircleOptimize[1]->OnDynamicLayoutOptimize();
vCircleOptimize[2]->OnDynamicLayoutOptimize();
vCircleOptimize[3]->OnDynamicLayoutOptimize();
}
} // while( vCircle[0] != NULL )
// if( bCreateInnerCircle )
// _CreateInnerCircle( pFrame );
CArray < HWND, HWND > arrHwndsToDynOptimize;
bool bDeepOptimize = false;
POSITION pos = pFrame->m_listControlBars.GetHeadPosition();
for( ; pos != NULL; )
{
CExtDynControlBar * pBar =
DYNAMIC_DOWNCAST(
CExtDynControlBar,
((CObject *)(pFrame->m_listControlBars.GetNext(pos)))
);
if( pBar == NULL )
continue;
ASSERT( !pBar->IsFixedMode() );
HWND hWnd = pBar->m_pWndDynDocker->GetSafeHwnd();
if( hWnd == NULL
|| ! ::IsWindow( hWnd )
)
continue;
//if( !pBar->IsFloating() )
{
INT nDockedCount =
pBar->m_pWndDynDocker->GetDockedCount();
if( nDockedCount > 0 )
continue;
bDeepOptimize = true;
} // if( !pBar->IsFloating() )
arrHwndsToDynOptimize.Add( hWnd );
}
for( INT nHwndIdx = 0; nHwndIdx < arrHwndsToDynOptimize.GetSize(); nHwndIdx++ )
{
HWND hWnd = arrHwndsToDynOptimize[ nHwndIdx ];
ASSERT( hWnd != NULL );
if( !::IsWindow( hWnd ) )
continue;
CWnd * pWndChild = CWnd::FromHandlePermanent( hWnd );
if( pWndChild == NULL )
continue;
CExtDockDynBar * pDockBar =
DYNAMIC_DOWNCAST(
CExtDockDynBar,
pWndChild
);
if( pDockBar == NULL )
continue;
#ifdef __DEBUG_LOCKING_OPTIMIZATION_ASSERTS__
ASSERT( !pDockBar->m_bLockedOptimize );
#endif // __DEBUG_LOCKING_OPTIMIZATION_ASSERTS__
pDockBar->OnDynamicLayoutOptimize();
}
if( bDeepOptimize )
_OptimizeCircles( pFrame );
}
void CExtDockBar::_SafeOptimizeInnerOuterChain()
{
ASSERT( this != NULL );
ASSERT_KINDOF( CExtDockBar, this );
ASSERT( GetSafeHwnd() != NULL );
ASSERT( ::IsWindow(GetSafeHwnd()) );
if( m_pDockBarInner != NULL )
{
ASSERT( m_pDockBarInner->m_pDockBarOuter == this );
m_pDockBarInner->m_pDockBarOuter = m_pDockBarOuter;
}
if( m_pDockBarOuter != NULL )
{
ASSERT( m_pDockBarOuter->m_pDockBarInner == this );
m_pDockBarOuter->m_pDockBarInner = m_pDockBarInner;
}
m_pDockBarInner = NULL;
m_pDockBarOuter = NULL;
CFrameWnd * pFrame = GetParentFrame();
ASSERT( pFrame != NULL );
ASSERT( !pFrame->IsKindOf(RUNTIME_CLASS(CMiniFrameWnd)) );
POSITION pos = pFrame->m_listControlBars.Find( this );
ASSERT( pos != NULL );
pFrame->m_listControlBars.RemoveAt( pos );
BOOL bAutoDelete = m_bAutoDelete;
DestroyWindow();
if( !bAutoDelete )
delete this;
}
bool CExtDockBar::_CanBeSafeOptimized()
{
ASSERT( this != NULL );
ASSERT_KINDOF( CExtDockBar, this );
for( INT nPos = 0; nPos < m_arrBars.GetSize(); nPos++ )
{
void * pBar = m_arrBars[ nPos ];
if( pBar != NULL ) // placeholer or child control bar
return false;
}
return true;
}
#if (!defined __EXT_MFC_NO_TAB_CONTROLBARS)
CExtDynAutoHideArea * CExtDockBar::_GetAutoHideArea()
{
return m_pWndAutoHideArea;
}
#endif // (!defined __EXT_MFC_NO_TAB_CONTROLBARS)
void CExtDockBar::_HandleDestruction()
{
m_bLockedOptimize = true;
bool bFirstDestroyed = true;
for( int nBar = m_arrBars.GetSize() - 1; nBar > 0 ; nBar-- )
{
ASSERT( m_arrBars[0] == NULL );
CExtControlBar * pBar = (CExtControlBar *)
m_arrBars[ nBar ];
if( bFirstDestroyed )
{
ASSERT( pBar == NULL );
bFirstDestroyed = false;
continue;
}
if( pBar == NULL )
{
m_arrBars.RemoveAt( nBar );
continue;
}
if( __PLACEHODLER_BAR_PTR(pBar) )
{
m_arrBars.RemoveAt( nBar );
continue;
}
ASSERT_VALID( pBar );
ASSERT_KINDOF( CExtControlBar, pBar );
ASSERT_VALID( pBar->m_pDockSite );
ASSERT( pBar->m_pDockContext != NULL );
ASSERT( pBar->m_pDockBar == this );
pBar->m_bUpdatingChain = true;
pBar->m_pDockBar = NULL;
if( pBar->IsKindOf(RUNTIME_CLASS(CExtDynControlBar)) )
{
CExtDockDynBar * pDynDocker =
((CExtDynControlBar*)pBar)->m_pWndDynDocker;
ASSERT_VALID( pDynDocker );
pDynDocker->_HandleDestruction();
}
ASSERT( pBar->m_bUpdatingChain );
if( pBar->GetParent() != pBar->m_pDockSite )
pBar->SetParent( pBar->m_pDockSite );
pBar->m_bUpdatingChain = false;
m_arrBars.RemoveAt( nBar );
}
m_bLockedOptimize = false;
}
void CExtDockBar::OnDestroy()
{
_HandleDestruction();
CDockBar::OnDestroy();
}
BOOL CExtDockBar::DestroyWindow()
{
_HandleDestruction();
return CDockBar::DestroyWindow();
}
/////////////////////////////////////////////////////////////////////////
// CExtDockDynBar window
IMPLEMENT_DYNCREATE(CExtDockDynBar, CExtDockBar);
BEGIN_MESSAGE_MAP(CExtDockDynBar, CExtDockBar)
//{{AFX_MSG_MAP(CExtDockDynBar)
ON_WM_SIZE()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
CExtDockDynBar::CExtDockDynBar(
UINT nCircleNo
)
: CExtDockBar( nCircleNo )
, m_bHelperDockSiteModified( false )
{
m_bAutoDelete = TRUE;
}
/////////////////////////////////////////////////////////////////////////
// CExtDynControlBar window
#if (!defined __EXT_MFC_NO_TAB_CONTROLBARS)
CExtDynAutoHideArea * CExtDockDynBar::_GetAutoHideArea()
{
CExtControlBar * pExtBar =
STATIC_DOWNCAST(
CExtControlBar,
GetParent()
);
ASSERT( pExtBar->m_pDockBar != NULL );
CExtDockBar * pDockBar =
DYNAMIC_DOWNCAST(
CExtDockBar,
pExtBar->m_pDockBar
);
if( pDockBar == NULL )
return NULL;
return pDockBar->_GetAutoHideArea();
}
#endif // (!defined __EXT_MFC_NO_TAB_CONTROLBARS)
void CExtDockDynBar::VisibleLayoutItem_t::_AssignFromOther(
const CExtDockDynBar::VisibleLayoutItem_t & other
)
{
m_vRow.RemoveAll();
INT nSize = other.m_vRow.GetSize();
if( nSize == 0 )
{
m_vRow.FreeExtra();
return;
}
m_vRow.SetSize( nSize );
for( INT nBar = 0; nBar < nSize; nBar++ )
{
CExtControlBar * pExtBar = other.m_vRow[ nBar ];
ASSERT( pExtBar != NULL );
ASSERT( !pExtBar->IsFixedMode() );
#ifdef _DEBUG
if( __PLACEHODLER_BAR_PTR(pExtBar) )
{
ASSERT( FALSE );
}
#endif // _DEBUG
m_vRow.SetAt( nBar, pExtBar );
} // for( INT nBar = 0; nBar < nSize; nBar++ )
}
CExtDockDynBar::VisibleLayoutItem_t::VisibleLayoutItem_t()
: m_nRowMetric( 0 )
, m_nRowMinMetric( 0 )
, m_nRowExtent( 0 )
, m_nRowMinExtent( 0 )
{
}
CExtDockDynBar::VisibleLayoutItem_t::VisibleLayoutItem_t(
const CExtDockDynBar::VisibleLayoutItem_t & other
)
{
_AssignFromOther( other );
}
CExtDockDynBar::VisibleLayoutItem_t::~VisibleLayoutItem_t()
{
}
CExtDockDynBar::VisibleLayoutItem_t &
CExtDockDynBar::VisibleLayoutItem_t::operator=(
const CExtDockDynBar::VisibleLayoutItem_t & other
)
{
_AssignFromOther( other );
return * this;
}
bool CExtDockDynBar::VisibleLayoutItem_t::IsEmpty() const
{
if( m_vRow.GetSize() == 0 )
return true;
return false;
}
bool CExtDockDynBar::VisibleLayoutItem_t::IsRowMinSized() const
{
ASSERT( m_nRowMetric >= m_nRowMinMetric );
return (m_nRowMetric == m_nRowMinMetric ) ? true : false;
}
void CExtDockDynBar::VisibleLayout_t::_Clean()
{
INT nSize = m_vRows.GetSize();
for( INT nRow = 0; nRow < nSize; nRow++ )
{
VisibleLayoutItem_t * pVLI = m_vRows.GetAt( nRow );
ASSERT( pVLI != NULL );
delete pVLI;
}
m_vRows.RemoveAll();
m_vRows.FreeExtra();
}
CExtDockDynBar::VisibleLayout_t::VisibleLayout_t()
: m_nTotalMetric( 0 )
, m_nTotalMinMetric( 0 )
, m_nTotalMinExtent( 0 )
, m_nTotalBarsCount( 0 )
{
}
CExtDockDynBar::VisibleLayout_t::~VisibleLayout_t()
{
_Clean();
}
void CExtDockDynBar::VisibleLayout_t::AddBarPointer(
CExtControlBar * pExtBar
)
{
ASSERT_VALID( pExtBar );
ASSERT( !pExtBar->IsFixedMode() );
if( !pExtBar->IsVisible() )
return;
#ifdef _DEBUG
if( __PLACEHODLER_BAR_PTR(pExtBar) )
{
ASSERT( FALSE );
}
#endif // _DEBUG
VisibleLayoutItem_t * pVLI = NULL;
INT nRowCount = m_vRows.GetSize();
if( nRowCount == 0 )
{
pVLI = new VisibleLayoutItem_t;
m_vRows.Add( pVLI );
}
else
pVLI = m_vRows[ nRowCount - 1 ];
ASSERT( pVLI != NULL );
pVLI->m_vRow.Add( pExtBar );
m_nTotalBarsCount++;
}
void CExtDockDynBar::VisibleLayout_t::MakeNewRow()
{
INT nRowCount = m_vRows.GetSize();
if( nRowCount == 0 )
{
VisibleLayoutItem_t * pVLI = new VisibleLayoutItem_t;
m_vRows.Add( pVLI );
return;
}
VisibleLayoutItem_t * pVLI = m_vRows.GetAt( nRowCount - 1 );
ASSERT( pVLI != NULL );
if( pVLI->IsEmpty() )
return;
pVLI = new VisibleLayoutItem_t;
m_vRows.Add( pVLI );
}
bool CExtDockDynBar::VisibleLayout_t::IsEmpty() const
{
INT nRowCount = m_vRows.GetSize();
if( nRowCount == 0 )
return true;
if( nRowCount == 1 )
{
VisibleLayoutItem_t * pVLI = m_vRows.GetAt( 0 );
if( pVLI->IsEmpty() )
return true;
}
#ifdef _DEBUG
else
{
VisibleLayoutItem_t * pVLI = m_vRows.GetAt( 0 );
ASSERT( !pVLI->IsEmpty() );
}
#endif // _DEBUG
return false;
}
void CExtDockDynBar::_VisibleLayoutBuild(
VisibleLayout_t & _vl
)
{
ASSERT_VALID( this );
ASSERT( _vl.IsEmpty() );
INT nCount = m_arrBars.GetSize();
ASSERT( nCount > 0 );
ASSERT( m_arrBars[0] == NULL );
UINT nOwnID = GetDlgCtrlID();
ASSERT_DOCKBAR_DLGCTRLID_DOCKED( nOwnID );
BOOL bHorz = ( nOwnID == AFX_IDW_DOCKBAR_TOP || nOwnID == AFX_IDW_DOCKBAR_BOTTOM );
ASSERT( m_arrBars[0] == NULL );
for( INT nBar = 1; nBar < nCount; nBar++ )
{
CExtControlBar * pExtBar = (CExtControlBar *) m_arrBars[nBar];
if( pExtBar == NULL )
{
if( nBar == (nCount-1) )
break;
_vl.MakeNewRow();
continue;
}
if( __PLACEHODLER_BAR_PTR(pExtBar) )
continue;
ASSERT_VALID( pExtBar );
ASSERT_KINDOF( CExtControlBar, pExtBar );
ASSERT( !pExtBar->IsFixedMode() );
if( !pExtBar->IsVisible() )
continue;
_vl.AddBarPointer( pExtBar );
} // for( INT nBar = 1; nBar < nCount; nBar++ )
INT nRowsCount = _vl.m_vRows.GetSize();
if( nRowsCount == 0 )
return;
for( INT nRow = 0; nRow < nRowsCount; nRow ++ )
{
VisibleLayoutItem_t * pVLI = _vl.m_vRows[ nRow ];
ASSERT( pVLI != NULL );
INT nRowSize = pVLI->m_vRow.GetSize();
// TO FIX:
if( nRowSize == 0 )
continue;
ASSERT( nRowSize > 0 );
CExtControlBar * pExtBar = pVLI->m_vRow[ 0 ];
ASSERT( pExtBar != NULL );
LONG nMinHW = pExtBar->_CalcDesiredMinHW();
LONG nMinVH = pExtBar->_CalcDesiredMinVH();
pVLI->m_nRowMinMetric = bHorz
? nMinVH
: nMinHW;
pVLI->m_nRowMetric = bHorz
? pExtBar->m_sizeDockedH.cy
: pExtBar->m_sizeDockedV.cx;
_vl.m_nTotalMetric += pVLI->m_nRowMetric;
INT nRowMinMetric = bHorz
? nMinVH
: nMinHW;
INT nRowMinExtent = bHorz
? nMinHW
: nMinVH;
INT nRowExtent = bHorz
? pExtBar->m_sizeDockedH.cx
: pExtBar->m_sizeDockedV.cy;
for( nBar = 1; nBar < nRowSize; nBar++ )
{
pExtBar = pVLI->m_vRow[ nBar ];
ASSERT( pExtBar != NULL );
LONG nMinHW = pExtBar->_CalcDesiredMinHW();
LONG nMinVH = pExtBar->_CalcDesiredMinVH();
INT nBarMinMetric = bHorz
? nMinVH
: nMinHW;
nRowMinMetric =
min( nRowMinMetric, nBarMinMetric );
nRowMinExtent += bHorz
? nMinHW
: nMinVH;
nRowExtent += bHorz
? pExtBar->m_sizeDockedH.cx
: pExtBar->m_sizeDockedV.cy;
}
_vl.m_nTotalMinMetric += nRowMinMetric;
_vl.m_nTotalMinExtent = max( nRowMinExtent, _vl.m_nTotalMinExtent );
pVLI->m_nRowExtent = nRowExtent;
} // for( INT nRow = 0; nRow < nRowsCount; nRow ++ )
}
void CExtDockDynBar::_VisibleLayoutAlign(
VisibleLayout_t & _vl,
CSize _size
)
{
ASSERT_VALID( this );
ASSERT( !_vl.IsEmpty() );
ASSERT( _size.cx > 0 && _size.cy > 0 );
CRect rcDockBarReal;
GetClientRect( &rcDockBarReal );
_size = rcDockBarReal.Size();
if( _size.cx <= 0 || _size.cy <= 0 )
return;
UINT nOwnID = GetDlgCtrlID();
ASSERT_DOCKBAR_DLGCTRLID_DOCKED( nOwnID );
BOOL bHorz = ( nOwnID == AFX_IDW_DOCKBAR_TOP || nOwnID == AFX_IDW_DOCKBAR_BOTTOM );
INT nRowsCount = _vl.m_vRows.GetSize();
ASSERT( nRowsCount > 0 );
INT nDesiredMetric = bHorz ? _size.cy : _size.cx;
INT nIncrement = (_vl.m_nTotalMetric < nDesiredMetric) ? 1 : -1;
INT nDiff = abs(_vl.m_nTotalMetric - nDesiredMetric);
// align direction 1 (row metrics)
bool bResetRowMetrics = true;
while( nDiff != 0 )
{
bResetRowMetrics = false;
ASSERT( nDiff >= 0 );
INT nRowsMinSized = 0;
for( INT nRow = 0; nRow < nRowsCount; nRow ++ )
{
VisibleLayoutItem_t * pVLI = _vl.m_vRows[ nRow ];
ASSERT( pVLI != NULL );
//ASSERT( !pVLI->IsEmpty() );
INT nRowSize = pVLI->m_vRow.GetSize();
// TO FIX:
if( nRowSize == 0 )
continue;
ASSERT( nRowSize > 0 );
if( nIncrement < 0 && pVLI->IsRowMinSized() )
{
nRowsMinSized ++;
if( nRowsCount == nRowsMinSized )
break;
continue;
}
pVLI->m_nRowMetric += nIncrement;
nDiff--;
for( INT nBar = 0; nBar < nRowSize; nBar++ )
{
CExtControlBar * pExtBar = pVLI->m_vRow[ nBar ];
ASSERT( pExtBar != NULL );
LONG & nRowMetricRef = bHorz
? pExtBar->m_sizeDockedH.cy
: pExtBar->m_sizeDockedV.cx;
nRowMetricRef += nIncrement;
} // for( INT nBar = 0; nBar < nRowSize; nBar++ )
if( nDiff == 0 )
break;
} // for( INT nRow = 0; nRow < nRowsCount; nRow ++ )
if( nRowsCount == nRowsMinSized )
break;
} // while( nDiff != 0 )
if( bResetRowMetrics )
{
for( INT nRow = 0; nRow < nRowsCount; nRow ++ )
{
VisibleLayoutItem_t * pVLI = _vl.m_vRows[ nRow ];
ASSERT( pVLI != NULL );
//ASSERT( !pVLI->IsEmpty() );
INT nRowSize = pVLI->m_vRow.GetSize();
// TO FIX:
if( nRowSize == 0 )
continue;
ASSERT( nRowSize > 0 );
for( INT nBar = 0; nBar < nRowSize; nBar++ )
{
CExtControlBar * pExtBar = pVLI->m_vRow[ nBar ];
ASSERT( pExtBar != NULL );
LONG & nRowMetricRef = bHorz
? pExtBar->m_sizeDockedH.cy
: pExtBar->m_sizeDockedV.cx;
nRowMetricRef = pVLI->m_nRowMetric;
} // for( INT nBar = 0; nBar < nRowSize; nBar++ )
} // for( INT nRow = 0; nRow < nRowsCount; nRow ++ )
} // if( bResetRowMetrics )
// align direction 2 (row extents)
nDesiredMetric = bHorz ? _size.cx : _size.cy;
for( INT nRow = 0; nRow < nRowsCount; nRow ++ )
{
VisibleLayoutItem_t * pVLI = _vl.m_vRows[ nRow ];
ASSERT( pVLI != NULL );
//ASSERT( !pVLI->IsEmpty() );
// TO FIX:
if( pVLI->IsEmpty() )
continue;
INT nIncrement =
(pVLI->m_nRowExtent < nDesiredMetric) ? 1 : -1;
INT nDiff = abs( pVLI->m_nRowExtent - nDesiredMetric );
while( nDiff != 0 )
{
ASSERT( nDiff >= 0 );
INT nRowSize = pVLI->m_vRow.GetSize();
// TO FIX:
if( nRowSize == 0 )
continue;
ASSERT( nRowSize > 0 );
INT nBarsMinSized = 0;
for( INT nBar = 0; nBar < nRowSize; nBar++ )
{
CExtControlBar * pExtBar = pVLI->m_vRow[ nBar ];
ASSERT( pExtBar != NULL );
LONG & nBarMetricRef = bHorz
? pExtBar->m_sizeDockedH.cx
: pExtBar->m_sizeDockedV.cy;
if( nIncrement < 0 )
{
LONG nBarMinMetric = bHorz
? pExtBar->_CalcDesiredMinHW()
: pExtBar->_CalcDesiredMinVH();
ASSERT( nBarMetricRef >= nBarMinMetric );
if( nBarMetricRef <= nBarMinMetric )
{
nBarsMinSized ++;
if( nBarsMinSized == nRowSize )
break;
continue;
}
} // if( nIncrement < 0 )
nBarMetricRef += nIncrement;
nDiff --;
if( nDiff == 0 )
break;
} // for( INT nBar = 0; nBar < nRowSize; nBar++ )
if( nBarsMinSized == nRowSize )
break;
} // while( nDiff != 0 )
} // for( INT nRow = 0; nRow < nRowsCount; nRow ++ )
ASSERT( _vl.m_nTotalBarsCount > 0 );
HANDLE hDWP = ::BeginDeferWindowPos( _vl.m_nTotalBarsCount );
ASSERT( hDWP != NULL );
// apply new layout
CPoint ptOffs( 0, 0 );
for( nRow = 0; nRow < nRowsCount; nRow ++ )
{
VisibleLayoutItem_t * pVLI = _vl.m_vRows[ nRow ];
ASSERT( pVLI != NULL );
//ASSERT( !pVLI->IsEmpty() );
INT nRowSize = pVLI->m_vRow.GetSize();
// TO FIX:
if( nRowSize == 0 )
continue;
ASSERT( nRowSize > 0 );
INT nRowOffset = 0;
for( INT nBar = 0; nBar < nRowSize; nBar++ )
{
CExtControlBar * pExtBar = pVLI->m_vRow[ nBar ];
ASSERT( pExtBar != NULL );
if( nBar == 0 )
nRowOffset = bHorz
? pExtBar->m_sizeDockedH.cy
: pExtBar->m_sizeDockedV.cx;
CRect rcBar(
ptOffs,
bHorz
? pExtBar->m_sizeDockedH
: pExtBar->m_sizeDockedV
);
if( hDWP != NULL )
{
hDWP =
::DeferWindowPos(
hDWP,
pExtBar->GetSafeHwnd(),
NULL,
rcBar.left, rcBar.top,
rcBar.Width(), rcBar.Height(),
SWP_NOZORDER|SWP_NOACTIVATE
);
ASSERT( hDWP != NULL );
}
if( hDWP == NULL )
pExtBar->MoveWindow( &rcBar );
if( bHorz )
ptOffs.x += pExtBar->m_sizeDockedH.cx;
else
ptOffs.y += pExtBar->m_sizeDockedV.cy;
} // for( INT nBar = 0; nBar < nRowSize; nBar++ )
if( bHorz )
{
ptOffs.x = 0;
ptOffs.y += nRowOffset;
}
else
{
ptOffs.x += nRowOffset;
ptOffs.y = 0;
}
} // for( nRow = 0; nRow < nRowsCount; nRow ++ )
ASSERT( hDWP != NULL );
if( hDWP != NULL )
::EndDeferWindowPos( hDWP );
}
IMPLEMENT_DYNCREATE(CExtDynControlBar, CExtControlBar);
BEGIN_MESSAGE_MAP(CExtDynControlBar, CExtControlBar)
//{{AFX_MSG_MAP(CExtDynControlBar)
ON_WM_CREATE()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
CExtDynControlBar::CExtDynControlBar()
: m_pWndDynDocker( NULL )
{
m_bAppearInDockSiteControlBarPopupMenu = false;
m_bAutoDelete = TRUE;
}
CExtDockDynBar * CExtDynControlBar::OnCreateDynamicDockBarObject()
{
return ( new CExtDockDynBar( 0 ) );
}
int CExtDynControlBar::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if( CExtControlBar::OnCreate(lpCreateStruct) == -1 )
{
ASSERT( FALSE );
return -1;
}
UINT nOwnID = GetDlgCtrlID();
#if (!defined __EXT_MFC_NO_TAB_CONTROLBARS)
if( IsKindOf( RUNTIME_CLASS(CExtDynTabControlBar) )
&& nOwnID == AFX_IDW_DOCKBAR_FLOAT
)
{
nOwnID = AFX_IDW_DOCKBAR_TOP;
SetDlgCtrlID( nOwnID );
}
#endif // (!defined __EXT_MFC_NO_TAB_CONTROLBARS)
ASSERT_DOCKBAR_DLGCTRLID_DOCKED( nOwnID );
ASSERT( m_pWndDynDocker == NULL );
m_pWndDynDocker = OnCreateDynamicDockBarObject();
ASSERT( m_pWndDynDocker != NULL );
CFrameWnd * pParentFrame =
STATIC_DOWNCAST( CFrameWnd, GetParent() );
ASSERT_VALID( pParentFrame );
if( !m_pWndDynDocker->Create(
pParentFrame,
WS_CHILD|WS_VISIBLE|WS_CLIPSIBLINGS|WS_CLIPCHILDREN
|CBRS_ALIGN_TOP //|CBRS_ALIGN_ANY
|CBRS_BORDER_ANY
,
nOwnID
)
)
{
ASSERT( FALSE );
return -1;
}
m_pWndDynDocker->SetParent( this );
EnableToolTips();
return 0;
}
bool CExtDynControlBar::IsBarWithGripper(
bool * pbGripperAtTop, // = NULL
bool * pbTextOnGripper // = NULL
) const
{
ASSERT_VALID( this );
if( pbGripperAtTop != NULL )
*pbGripperAtTop = false;
if( pbTextOnGripper != NULL )
*pbTextOnGripper = false;
return false;
}
bool CExtDynControlBar::_CanDockToTabbedContainers(
CExtControlBar * pDestBar
) const
{
ASSERT_VALID( this );
if( !CExtControlBar::_CanDockToTabbedContainers(pDestBar) )
return false;
if( m_pWndDynDocker == NULL )
return false;
for( int i = 0; i < m_pWndDynDocker->m_arrBars.GetSize(); i++ )
{
CExtControlBar * pBar = (CExtControlBar *)
m_pWndDynDocker->m_arrBars[i];
if( pBar == NULL )
continue;
if( __PLACEHODLER_BAR_PTR(pBar) )
continue;
ASSERT_VALID( pBar );
ASSERT_KINDOF( CExtControlBar, pBar );
if( !pBar->_CanDockToTabbedContainers(pDestBar) )
return false;
} // for( int i = 0; i < m_pWndDynDocker->m_arrBars.GetSize(); i++ )
return true;
}
#if (!defined __EXT_MFC_NO_TAB_CONTROLBARS)
CExtDynTabControlBar * CExtDynControlBar::_GetNearestTabbedContainer()
{
ASSERT_VALID( this );
return CExtControlBar::_GetNearestTabbedContainer();
}
#endif // (!defined __EXT_MFC_NO_TAB_CONTROLBARS)
CSize CExtDynControlBar::_CalcLayoutMinSize() const
{
ASSERT_VALID( this );
CExtDockDynBar * pDockBar =
STATIC_DOWNCAST( CExtDockDynBar, GetWindow(GW_CHILD) );
ASSERT_VALID( pDockBar );
ASSERT_KINDOF( CExtDockDynBar, pDockBar );
CExtDockDynBar::VisibleLayout_t _vl;
pDockBar->_VisibleLayoutBuild( _vl );
UINT nDockBarID = pDockBar->GetDlgCtrlID();
ASSERT_DOCKBAR_DLGCTRLID_DOCKED( nDockBarID );
BOOL bHorz = ( nDockBarID == AFX_IDW_DOCKBAR_TOP || nDockBarID == AFX_IDW_DOCKBAR_BOTTOM );
CSize _size(
bHorz ? _vl.m_nTotalMinMetric : _vl.m_nTotalMinExtent,
bHorz ? _vl.m_nTotalMinExtent : _vl.m_nTotalMinExtent
);
return _size;
}
INT CExtDynControlBar::_CalcDesiredMinHW() const
{
return _CalcLayoutMinSize().cx;
}
INT CExtDynControlBar::_CalcDesiredMinVH() const
{
return _CalcLayoutMinSize().cy;
}
CSize CExtDynControlBar::_CalcDesiredMinFloatedSize() const
{
return _CalcLayoutMinSize();
}
CSize CExtDynControlBar::CalcDynamicLayout(
int nLength,
DWORD nMode
)
{
CSize _size = CExtControlBar::CalcDynamicLayout( nLength, nMode );
if( m_pDockBar == NULL ) // (+ v.2.23) - shutdown mode
return _size;
ASSERT_VALID( m_pDockBar );
if( ((CExtDockBar *)m_pDockBar)->m_bLayoutQuery )
return _size;
if( m_pWndDynDocker->GetSafeHwnd() == NULL )
return _size;
INT nDockedVisibleCount = m_pWndDynDocker->GetDockedVisibleCount();
if( nDockedVisibleCount == 0 )
{
m_pDockSite->ShowControlBar( this, FALSE, FALSE );
_size.cx = _size.cy = 0;
}
CFrameWnd * pParentFrame = GetParentFrame();
if( pParentFrame->IsKindOf( RUNTIME_CLASS( CMiniFrameWnd ) ) )
{
ASSERT_VALID( m_pWndDynDocker );
ASSERT( ::IsWindow( m_pWndDynDocker->GetSafeHwnd() ) );
//!!//
// m_pWndDynDocker->OnDynamicLayoutUpdate();
// pParentFrame->SetWindowPos(
// NULL, 0, 0, 0, 0,
// SWP_NOSIZE|SWP_NOMOVE|SWP_NOZORDER|SWP_NOACTIVATE
// |SWP_FRAMECHANGED
// );
// pParentFrame->SendMessage( WM_NCPAINT );
ASSERT_VALID( m_pDockBar );
if( ( ! m_pWndDynDocker->m_bLockedOptimize )
&& pParentFrame == m_pDockBar->GetParent()
)
m_pWndDynDocker->OnDynamicLayoutUpdate();
} // if( ....
return _size;
}
void CExtDockDynBar::OnDynamicLayoutUpdate()
{
ASSERT_VALID( this );
ASSERT_KINDOF( CExtDockDynBar, this );
if( m_bLockedOptimize )
return;
if( m_bInDynamicLayoutUpdate )
return;
m_bInDynamicLayoutUpdate = true;
UINT nDockBarID = GetDlgCtrlID();
ASSERT_DOCKBAR_DLGCTRLID_DOCKED( nDockBarID );
BOOL bHorz = ( nDockBarID == AFX_IDW_DOCKBAR_TOP || nDockBarID == AFX_IDW_DOCKBAR_BOTTOM );
CalcFixedLayout( TRUE, bHorz );
m_bInDynamicLayoutUpdate = false;
CExtDockBar::OnDynamicLayoutUpdate();
}
void CExtDockDynBar::OnDynamicLayoutOptimize()
{
ASSERT_VALID( this );
ASSERT_VALID( m_pDockSite );
if( m_bLockedOptimize )
{
#ifdef _DEBUG
#ifdef __DEBUG_LOCKING_OPTIMIZATION_ASSERTS__
INT nDockedCount = GetDockedCount();
ASSERT( nDockedCount != 0 );
#endif // __DEBUG_LOCKING_OPTIMIZATION_ASSERTS__
#endif // _DEBUG
return;
}
bool bOptimizeChilds = false;
INT nSinglePos = -1;
bool bPlaceHolder = false;
ASSERT( m_arrBars.GetSize() >= 1 );
INT nDockedCount = GetDockedCount();
if( nDockedCount != 0 )
{
ASSERT( nDockedCount >= 1 );
for( INT nBar = 1; nBar < m_arrBars.GetSize(); nBar++ )
{
CControlBar * pBar = (CControlBar *)m_arrBars[ nBar ];
if( pBar == NULL )
continue;
if( __PLACEHODLER_BAR_PTR(pBar) )
{
if( nSinglePos >= 0 && !bPlaceHolder )
{
bOptimizeChilds = true;
break;
}
nSinglePos = nBar;
bPlaceHolder = true;
continue;
}
else
{
ASSERT_VALID( pBar );
ASSERT_KINDOF( CControlBar, pBar );
if( nSinglePos >= 0 )
{
bOptimizeChilds = true;
break;
}
nSinglePos = nBar;
}
} // for( INT nBar = 1; nBar < m_arrBars.GetSize(); nBar++ )
} // if( nDockedCount != 0 )
if( bOptimizeChilds )
{
CExtDockBar::OnDynamicLayoutOptimize();
return;
}
CFrameWnd * pDockSite = m_pDockSite;
CMiniFrameWnd * pMiniFrame =
DYNAMIC_DOWNCAST(
CMiniFrameWnd,
GetParentFrame()
);
if( pMiniFrame != NULL )
pMiniFrame->DelayRecalcLayout();
CExtDynControlBar * pDynBar =
STATIC_DOWNCAST( CExtDynControlBar, GetParent() );
ASSERT_VALID( pDynBar );
ASSERT( pDockSite == pDynBar->m_pDockSite );
CDockBar * pDockBarParent =
STATIC_DOWNCAST( CDockBar, pDynBar->GetParent() );
ASSERT_VALID( pDockBarParent );
ASSERT( pDockSite == pDockBarParent->m_pDockSite );
HWND hWndOwn = GetSafeHwnd();
if( nSinglePos == -1 )
{ // optimizing empty dynamic docker
// AfxMessageBox( "Optimizing empty dynamic docker!" );
pDynBar->m_pDockBar = NULL;
// pDockSite->RemoveControlBar( pDynBar );
pDockSite->RemoveControlBar( this );
ASSERT( pDynBar->m_bAutoDelete );
HWND hWndDynBar = pDynBar->GetSafeHwnd();
pDockBarParent->RemoveControlBar( pDynBar );
if( ::IsWindow(hWndDynBar) )
pDynBar->DestroyWindow();
if( pMiniFrame == NULL )
pDockSite->DelayRecalcLayout();
ASSERT( pDockSite->m_listControlBars.Find(pDynBar) == NULL );
if( ! ( ::IsWindow(hWndOwn) ) )
return;
if( pDockBarParent->IsKindOf(RUNTIME_CLASS(CExtDockBar)) )
((CExtDockBar *)pDockBarParent)->OnDynamicLayoutUpdate();
return;
} // optimizing empty dynamic docker
if( bPlaceHolder )
{ // optimizing placeholder dynamic docker
//// AfxMessageBox( "Optimizing placeholder dynamic docker!" );
return;
} // optimizing placeholder dynamic docker
// optimizing singlebar dynamic docker
// AfxMessageBox( "Optimizing singlebar dynamic docker!" );
CExtControlBar * pSingleBar = (CExtControlBar *)m_arrBars[ nSinglePos ];
ASSERT_VALID( pSingleBar );
ASSERT_KINDOF( CExtControlBar, pSingleBar );
ASSERT( !pSingleBar->IsFixedMode() );
CRect wrSingleBar;
pDynBar->GetWindowRect( &wrSingleBar );
CSize sizeSingleBar = wrSingleBar.Size();
INT nDynPos = pDockBarParent->FindBar( pDynBar );
ASSERT( nDynPos > 0 );
pDockBarParent->m_arrBars[ nDynPos ] = pSingleBar;
pSingleBar->m_pDockBar = pDockBarParent;
if( pSingleBar->IsKindOf(RUNTIME_CLASS(CExtControlBar))
&& !((CExtControlBar*)pSingleBar)->IsFixedMode()
)
{
if( pDockBarParent->GetBarStyle() & CBRS_ORIENT_HORZ )
((CExtControlBar*)pSingleBar)->
SetInitDesiredSizeHorizontal( sizeSingleBar );
else
((CExtControlBar*)pSingleBar)->
SetInitDesiredSizeVertical( sizeSingleBar );
DWORD dwStyle = pSingleBar->GetBarStyle();
dwStyle &= ~(CBRS_ALIGN_ANY);
dwStyle |= (pDynBar->m_dwStyle & CBRS_ALIGN_ANY) | CBRS_BORDER_ANY;
pSingleBar->SetBarStyle( dwStyle );
}
m_arrBars.RemoveAll();
m_arrBars.Add( (CControlBar *)NULL );
pSingleBar->SetParent( pDockBarParent );
pSingleBar->m_pDockBar = pDockBarParent;
pDynBar->m_pDockBar = NULL;
// pDockSite->RemoveControlBar( pDynBar );
pDockSite->RemoveControlBar( this );
ASSERT( pDynBar->m_bAutoDelete );
pDynBar->DestroyWindow();
/*
// pSingleBar->m_bUpdatingChain = true;
pDockBarParent->ScreenToClient( &wrSingleBar );
pSingleBar->SetWindowPos(
NULL,
wrSingleBar.left, wrSingleBar.top,
sizeSingleBar.cx, sizeSingleBar.cy,
SWP_NOZORDER|SWP_NOOWNERZORDER
|SWP_NOACTIVATE
|SWP_FRAMECHANGED
//|SWP_NOREDRAW
);
// pSingleBar->m_bUpdatingChain = false;
*/
if( pMiniFrame == NULL )
pDockSite->DelayRecalcLayout();
ASSERT( pDockSite->m_listControlBars.Find(pDynBar) == NULL );
if( pDockBarParent->IsKindOf(RUNTIME_CLASS(CExtDockBar)) )
((CExtDockBar *)pDockBarParent)->OnDynamicLayoutUpdate();
}
CSize CExtDockDynBar::CalcFixedLayout(
BOOL bStretch,
BOOL bHorz
)
{
bHorz;
ASSERT_VALID( this );
ASSERT( !m_bFloating );
VisibleLayout_t _vl;
_VisibleLayoutBuild( _vl );
CRect rect;
GetWindowRect( &rect );
CSize _size = rect.Size();
if( !_vl.IsEmpty()
&& bStretch
&& _size.cx > 0 && _size.cy > 0
)
{
_VisibleLayoutAlign( _vl, _size );
}
return _size;
}
void CExtDockDynBar::CalcOrderedVector(
ExtControlBarVector_t & vBars
)
{
ASSERT_VALID( this );
INT nCount = m_arrBars.GetSize();
ASSERT( nCount > 0 );
ASSERT( m_arrBars[0] == NULL );
for( INT nBar = 1; nBar < nCount; nBar++ )
{
CExtControlBar * pBar = (CExtControlBar *) m_arrBars[nBar];
if( pBar == NULL )
continue;
if( __PLACEHODLER_BAR_PTR( pBar ) )
continue;
ASSERT_VALID( pBar );
ASSERT_KINDOF( CExtControlBar, pBar );
ASSERT( !pBar->IsFixedMode() );
vBars.Add( pBar );
} // for( INT nBar = 1; nBar < nCount; nBar++ )
}
void CExtDockDynBar::OnSize(UINT nType, int cx, int cy)
{
CExtDockBar::OnSize(nType, cx, cy);
if( !m_bHelperDockSiteModified
&& m_pDockSite != NULL
)
{
POSITION pos = m_pDockSite->m_listControlBars.Find( this );
if( pos != NULL )
{
m_pDockSite->m_listControlBars.RemoveAt( pos );
m_bHelperDockSiteModified = true;
}
}
/*
if( nType == SIZE_MINIMIZED )
return;
if( cx <= 0 || cy <= 0 )
return;
OnDynamicLayoutUpdate();
*/
}
/////////////////////////////////////////////////////////////////////////
// CExtDockOuterBar::OuterLayoutItemData
void CExtDockOuterBar::OuterLayoutItemData::_AssignFromOther(
const CExtDockOuterBar::OuterLayoutItemData & other
)
{
m_pBar = other.m_pBar;
m_bVisible = other.m_bVisible;
m_sizeCalcDynamic = other.m_sizeCalcDynamic;
m_sizeBarMin = other.m_sizeBarMin;
m_rcPreCalc = other.m_rcPreCalc;
m_rcReal = other.m_rcReal;
}
CExtDockOuterBar::OuterLayoutItemData::OuterLayoutItemData()
: m_pBar( NULL )
, m_bVisible( false )
, m_sizeCalcDynamic( 0, 0 )
, m_sizeBarMin( 0, 0 )
, m_rcPreCalc( 0, 0, 0, 0 )
, m_rcReal( 0, 0, 0, 0 )
{
}
CExtDockOuterBar::OuterLayoutItemData::OuterLayoutItemData(
CControlBar * pBar,
BOOL bHorz,
const SIZE & sizeMax
)
: m_pBar( pBar )
, m_sizeCalcDynamic( 0, 0 )
, m_sizeBarMin( 0, 0 )
, m_rcPreCalc( 0, 0, 0, 0 )
, m_rcReal( 0, 0, 0, 0 )
{
ASSERT_VALID( m_pBar );
ASSERT_KINDOF( CControlBar, pBar );
m_bVisible = pBar->IsVisible() ? true : false;
// if( m_bVisible
// && (pBar->m_nStateFlags & CControlBar::delayHide) != 0
// )
// m_bVisible = false;
// if( (!m_bVisible)
// && (pBar->m_nStateFlags & CControlBar::delayShow) != 0
// )
// m_bVisible = true;
if( !m_bVisible )
return;
// for _CalcFixedRowLayout
CRect rcBarWin, rcBarClient;
pBar->GetWindowRect( &rcBarWin );
pBar->ScreenToClient( & rcBarWin );
pBar->GetClientRect( &rcBarClient );
m_sizeBarMin = rcBarWin.Size() - rcBarClient.Size();
if( pBar->IsKindOf(RUNTIME_CLASS(CExtControlBar)) )
{
m_sizeBarMin +=
((CExtControlBar *)pBar)->
_CalcDesiredMinOuterSize( bHorz );
} // if( pBar->IsKindOf(RUNTIME_CLASS(CExtControlBar)) )
// get ideal rect for bar
DWORD dwMode = 0;
if( (pBar->m_dwStyle & CBRS_SIZE_DYNAMIC)
&&
(pBar->m_dwStyle & CBRS_FLOATING)
)
dwMode |= LM_HORZ | LM_MRUWIDTH;
else if(pBar->m_dwStyle & CBRS_ORIENT_HORZ)
dwMode |= LM_HORZ | LM_HORZDOCK;
else
dwMode |= LM_VERTDOCK;
m_sizeCalcDynamic = pBar->CalcDynamicLayout(-1, dwMode);
if( pBar->IsKindOf(RUNTIME_CLASS(CExtControlBar))
&& ((CExtControlBar *)pBar)->_GetFullRowMode()
)
{
if(dwMode & LM_HORZDOCK)
m_sizeCalcDynamic.cx = sizeMax.cx;
else if(dwMode & LM_VERTDOCK)
m_sizeCalcDynamic.cy = sizeMax.cy;
}
}
/////////////////////////////////////////////////////////////////////////
// CExtDockOuterBar window
IMPLEMENT_DYNCREATE(CExtDockOuterBar, CExtDockBar);
BEGIN_MESSAGE_MAP(CExtDockOuterBar, CExtDockBar)
//{{AFX_MSG_MAP(CExtDockOuterBar)
ON_WM_TIMER()
//}}AFX_MSG_MAP
ON_WM_SYSCOLORCHANGE()
__EXT_MFC_SAFE_ON_WM_SETTINGCHANGE()
ON_MESSAGE(WM_DISPLAYCHANGE, OnDisplayChange)
ON_MESSAGE(__ExtMfc_WM_THEMECHANGED, OnThemeChanged)
END_MESSAGE_MAP()
CExtDockOuterBar::CExtDockOuterBar()
: CExtDockBar( 0 )
, m_bInDockSiteDelayedRecalc( false )
, m_bDockSiteRecalcIsDelayed( false )
{
}
void CExtDockOuterBar::OnSysColorChange()
{
CExtDockBar::OnSysColorChange();
g_PaintManager.OnSysColorChange( this );
g_CmdManager.OnSysColorChange( this );
}
void CExtDockOuterBar::OnSettingChange(UINT uFlags, __EXT_MFC_SAFE_LPCTSTR lpszSection)
{
CExtDockBar::OnSettingChange( uFlags, lpszSection );
g_PaintManager.OnSettingChange( this, uFlags, lpszSection );
g_CmdManager.OnSettingChange( this, uFlags, lpszSection );
}
LRESULT CExtDockOuterBar::OnDisplayChange( WPARAM wParam, LPARAM lParam )
{
LRESULT lResult = CExtDockBar::OnDisplayChange( wParam, lParam );
g_PaintManager.OnDisplayChange( this, (INT)wParam, CPoint(lParam) );
g_CmdManager.OnDisplayChange( this, (INT)wParam, CPoint(lParam) );
return lResult;
}
LRESULT CExtDockOuterBar::OnThemeChanged( WPARAM wParam, LPARAM lParam )
{
LRESULT lResult = Default();
g_PaintManager.OnThemeChanged( this, wParam, lParam );
g_CmdManager.OnThemeChanged( this, wParam, lParam );
return lResult;
}
void CExtDockOuterBar::OnDynamicLayoutUpdate()
{
CExtDockBar::OnDynamicLayoutUpdate();
}
void CExtDockOuterBar::OnDynamicLayoutOptimize()
{
CExtDockBar::OnDynamicLayoutOptimize();
}
void CExtDockOuterBar::_DelayDockSiteRecalc()
{
ASSERT_VALID( this );
if( m_bDockSiteRecalcIsDelayed )
return;
CExtDockOuterBar * pDocker = this;
if( GetDlgCtrlID() != AFX_IDW_DOCKBAR_TOP )
{
CFrameWnd * pFrame = STATIC_DOWNCAST( CFrameWnd, GetParent() );
ASSERT_VALID( pFrame );
CControlBar * pTempBar = pFrame->GetControlBar( AFX_IDW_DOCKBAR_TOP );
if( pTempBar == NULL )
pTempBar = pFrame->GetControlBar( AFX_IDW_DOCKBAR_BOTTOM );
if( pTempBar == NULL )
pTempBar = pFrame->GetControlBar( AFX_IDW_DOCKBAR_LEFT );
if( pTempBar == NULL )
pTempBar = pFrame->GetControlBar( AFX_IDW_DOCKBAR_RIGHT );
if( pTempBar != NULL )
pDocker = STATIC_DOWNCAST( CExtDockOuterBar, pTempBar );
} // if( GetDlgCtrlID() != AFX_IDW_DOCKBAR_TOP )
pDocker->_DelayDockSiteRecalc_Start();
}
void CExtDockOuterBar::_DelayDockSiteRecalc_Start()
{
ASSERT_VALID( this );
if( m_bDockSiteRecalcIsDelayed )
return;
m_bDockSiteRecalcIsDelayed = true;
if( _DelayDockSiteRecalc_Update() )
{
KillTimer( 901 );
m_bDockSiteRecalcIsDelayed = false;
}
else
SetTimer( 901, 1, NULL );
}
bool CExtDockOuterBar::_DelayDockSiteRecalc_Update()
{
ASSERT_VALID( this );
if( m_bInDockSiteDelayedRecalc )
return false;
CExtControlBar::InternalFriendlyFrameWnd * pFrame =
(CExtControlBar::InternalFriendlyFrameWnd *)
STATIC_DOWNCAST( CFrameWnd, GetParent() );
ASSERT_VALID( pFrame );
if( pFrame->IsInRecalcLayout() )
return false;
m_bInDockSiteDelayedRecalc = true;
pFrame->RecalcLayout();
m_bInDockSiteDelayedRecalc = false;
return true;
}
void CExtDockOuterBar::OnTimer(UINT nIDEvent)
{
if( nIDEvent == 901 )
{
if( _DelayDockSiteRecalc_Update() )
{
KillTimer( 901 );
m_bDockSiteRecalcIsDelayed = false;
}
return;
} // if( nIDEvent == 901 )
CExtDockBar::OnTimer(nIDEvent);
}
void CExtDockOuterBar::_AffixmentBringToTop( CExtControlBar * pBar )
{
ASSERT_VALID( this );
ASSERT_VALID( pBar );
CExtControlBar::InternalAffixmentData * pAffixmentDataSrc =
pBar->_AffixmentGetOuter();
ASSERT( pAffixmentDataSrc != NULL );
ASSERT( FindBar(pBar) >= 0 );
ExtControlBarVector_t vBars;
pBar->_GetRowExtBars( vBars, false );
int nCount = vBars.GetSize();
ASSERT( nCount > 0 );
pAffixmentDataSrc->m_nAffixmentWeight = 1;
/// pAffixmentDataSrc->m_rcAffixment.SetRectEmpty();
if( nCount == 1 )
return;
int nResetWeight = m_arrBars.GetSize() * 4;
for( int nBar = 0; nBar < nCount; )
{
CExtControlBar * pBar2 = vBars[nBar];
ASSERT_VALID( pBar2 );
if( pBar2 == pBar )
{
nBar++;
continue;
}
CExtControlBar::InternalAffixmentData * pAffixmentData2 =
pBar2->_AffixmentGetOuter();
if( pAffixmentData2 == NULL )
{
vBars.RemoveAt(nBar);
nCount--;
continue;
}
if( pAffixmentData2->IsEmpty() )
pAffixmentData2->m_nAffixmentWeight = nResetWeight++;
else
pAffixmentData2->m_nAffixmentWeight++;
nBar++;
} // for( int nBar = 0; nBar < nCount; )
if( nCount <= 1 )
return;
// reset affixment weights
ExtControlBarVector_t vBars2;
for( nBar = 0; nBar < nCount; nBar++ )
{
CExtControlBar * pBarX = vBars[nBar];
int nCount2 = vBars2.GetSize();
if( nCount2 == 0 )
{
vBars2.Add( pBarX );
continue;
}
CExtControlBar::InternalAffixmentData * pAffixmentDataX =
pBarX->_AffixmentGetOuter();
ASSERT( pAffixmentDataX != NULL );
int nWeightX = pAffixmentDataX->m_nAffixmentWeight;
for( int nBar2 = 0; nBar2 < nCount2; nBar2++ )
{
CExtControlBar * pBar2 = vBars2[nBar2];
ASSERT( pBar2 != pBarX );
CExtControlBar::InternalAffixmentData * pAffixmentData2 =
pBar2->_AffixmentGetOuter();
ASSERT( pAffixmentData2 != NULL );
int nWeight2 = pAffixmentData2->m_nAffixmentWeight;
ASSERT( nWeight2 != nWeightX );
if( nWeight2 > nWeightX )
{
vBars2.InsertAt( nBar2, pBarX );
break;
}
if( nBar2 == nCount2-1 )
{
vBars2.Add( pBarX );
break;
}
} // for( int nBar2 = 0; nBar2 < nCount2; nBar2++ )
} // for( nBar = 0; nBar < nCount; nBar++ )
ASSERT( vBars2.GetSize() == nCount );
ASSERT( vBars2[0]->_AffixmentGetOuter()->m_nAffixmentWeight == 1 );
// if( nCount == 2 )
// return;
for( nBar = 1; nBar < nCount; nBar++ )
{
CExtControlBar * pBarX = vBars2[nBar];
CExtControlBar::InternalAffixmentData * pAffixmentDataX =
pBarX->_AffixmentGetOuter();
ASSERT( pAffixmentDataX != NULL );
pAffixmentDataX->m_nAffixmentWeight = nBar + 1;
}
}
//#define __DEBUG_CExtDockOuterBar_CompressSubRow_ASSERT_CRITICAL_MINSIZE
bool CExtDockOuterBar::_CompressSubRow(
CExtDockOuterBar::dockbar_outer_layout_t & dbol,
int nSubRowStartPos,
int nSubRowEndPos,
int nExtentMax,
bool bHorz,
bool & bAdjustWithAffixment,
bool * p_bFullyOccupiedLayout // = NULL
)
{
ASSERT_VALID(this);
ASSERT( dbol.GetSize() > 0 );
ASSERT( nSubRowStartPos <= nSubRowEndPos );
ASSERT( 0 <= nSubRowStartPos && nSubRowStartPos < dbol.GetSize() );
ASSERT( 0 <= nSubRowEndPos && nSubRowEndPos < dbol.GetSize() );
CArray < CRect, CRect > arrRcPreCalc;
int nPossibleBetween = 0;
//int nPossibleCs = 0;
int nExtentReal = 0;
for( int nBar = nSubRowStartPos; nBar <= nSubRowEndPos; nBar++ )
{
OuterLayoutItemData & olid = dbol.ElementAt( nBar );
ASSERT_VALID( olid.m_pBar );
ASSERT_KINDOF( CControlBar, olid.m_pBar );
ASSERT( olid.m_bVisible );
CRect rcPreCalc( olid.m_rcPreCalc );
ASSERT( rcPreCalc.left >= 0 );
ASSERT( rcPreCalc.top >= 0 );
ASSERT( rcPreCalc.left <= rcPreCalc.right );
ASSERT( rcPreCalc.top <= rcPreCalc.bottom );
#ifdef __DEBUG_CExtDockOuterBar_CompressSubRow_ASSERT_CRITICAL_MINSIZE
ASSERT( rcPreCalc.Width() >= olid.m_sizeBarMin.cx );
ASSERT( rcPreCalc.Height() >= olid.m_sizeBarMin.cy );
#endif // __DEBUG_CExtDockOuterBar_CompressSubRow_ASSERT_CRITICAL_MINSIZE
int nBetween = 0;
if( nBar == nSubRowStartPos )
{
nBetween += bHorz
? rcPreCalc.left
: rcPreCalc.top
;
ASSERT( nBetween >= 0 );
} // if( nBar == nSubRowStartPos )
else
{
if( bHorz )
{
nBetween +=
rcPreCalc.left
- arrRcPreCalc.ElementAt(nBar-1-nSubRowStartPos).right
;
ASSERT( nBetween >= 0 );
if( nBar == nSubRowEndPos )
nBetween += nExtentMax - rcPreCalc.right;
} // if( bHorz )
else
{
nBetween +=
rcPreCalc.top
- arrRcPreCalc.ElementAt(nBar-1-nSubRowStartPos).bottom
;
ASSERT( nBetween >= 0 );
if( nBar == nSubRowEndPos )
nBetween += nExtentMax - rcPreCalc.bottom;
} // else from if( bHorz )
} // else from if( nBar == nSubRowStartPos )
// int nCsAvail = bHorz
// ? (rcPreCalc.Width() - olid.m_sizeBarMin.cx)
// : (rcPreCalc.Height() - olid.m_sizeBarMin.cy)
// ;
// ASSERT( nCsAvail >= 0 );
// nPossibleCs += nCsAvail;
nPossibleBetween += nBetween;
arrRcPreCalc.Add( rcPreCalc );
nExtentReal += bHorz
? rcPreCalc.Width()
: rcPreCalc.Height()
;
} // for( int nBar = nSubRowStartPos; nBar <= nSubRowEndPos; nBar++ )
ASSERT( arrRcPreCalc.GetSize() == (nSubRowEndPos-nSubRowStartPos+1) );
//int nPossible = nPossibleBetween + nPossibleCs;
bool bRetVal = false;
int nCsRow = nExtentReal - nExtentMax /*- nPossibleBetween*/; //nPossibleCs;
if( nPossibleBetween > 0 )
nCsRow -= nPossibleBetween;
if( nPossibleBetween > 0 )
{
int nLeftPrev = nExtentMax;
for( nBar = nSubRowEndPos; nBar >= nSubRowStartPos; nBar-- )
{
CRect & rcPreCalc = arrRcPreCalc.ElementAt( nBar-nSubRowStartPos );
int nShift =
nLeftPrev
- (bHorz ? rcPreCalc.right : rcPreCalc.bottom)
;
if( nShift < 0 )
rcPreCalc.OffsetRect(
bHorz ? nShift : 0,
bHorz ? 0 : nShift
);
nLeftPrev = bHorz
? rcPreCalc.left
: rcPreCalc.top
;
} // for( nBar = nSubRowEndPos; nBar >= nSubRowStartPos; nBar-- )
if( nLeftPrev >= 0 )
bRetVal = true;
// else
// nCsRow = -nLeftPrev;
} // if( nPossibleBetween > 0 )
bool bCompressionPassed = false;
if( (!bRetVal) && nCsRow >= 0 )
{
int nLeftPrev = nExtentMax;
for( nBar = nSubRowEndPos; nBar >= nSubRowStartPos; nBar-- )
{
OuterLayoutItemData & olid = dbol.ElementAt( nBar );
CRect & rcPreCalc = arrRcPreCalc.ElementAt( nBar-nSubRowStartPos );
int nCsAvail = bHorz
? (rcPreCalc.Width() - olid.m_sizeBarMin.cx)
: (rcPreCalc.Height() - olid.m_sizeBarMin.cy)
;
if( nCsAvail < 0 )
nCsAvail = 0;
//ASSERT( nCsAvail >= 0 );
if( nCsAvail > nCsRow )
nCsAvail = nCsRow;
bool bAdjust = false;
if( nCsRow > 0 )
{
nCsRow -= nCsAvail;
ASSERT( nCsRow >= 0 );
bAdjust = true;
}
int nShift =
nLeftPrev
- (bHorz ? rcPreCalc.right : rcPreCalc.bottom )
;
//ASSERT( nShift >= 0 );
rcPreCalc.OffsetRect(
bHorz ? nShift : 0,
bHorz ? 0 : nShift
);
//if( nCsRow > 0 )
if( bAdjust )
(bHorz ? rcPreCalc.left : rcPreCalc.top) += nCsAvail;
nLeftPrev = bHorz ? rcPreCalc.left : rcPreCalc.top;
} // for( nBar = nSubRowEndPos; nBar >= nSubRowStartPos; nBar-- )
if( nCsRow == 0 && nLeftPrev >= 0 )
{
bRetVal = true;
if( nLeftPrev == 0
&& (nSubRowStartPos < nSubRowEndPos)
)
{ // if compression passed with full row layout with more than 1 bar
bCompressionPassed = true;
// re-compress with affixment
AffixmentOrderVector_t arrAffixmentOrder;
_CalcAffixmentOrderVector(
bHorz,
arrAffixmentOrder,
dbol,
false,
nSubRowStartPos,
nSubRowEndPos
);
ASSERT( arrAffixmentOrder.GetSize() == (nSubRowEndPos-nSubRowStartPos+1) );
bool bPerformReShift = false;
// last is not reviewed
for( int nOrderT = arrAffixmentOrder.GetSize()-1; nOrderT > 0; nOrderT-- )
{
int nReviewIdx = arrAffixmentOrder[ nOrderT - 1 ];
OuterLayoutItemData & olidReview = dbol.ElementAt( nReviewIdx );
CExtControlBar * pExtBarReview =
DYNAMIC_DOWNCAST(
CExtControlBar,
olidReview.m_pBar
);
if( pExtBarReview == NULL )
continue;
CExtControlBar::InternalAffixmentData * pAffixmentDataReview =
pExtBarReview->_AffixmentGetOuter();
if( pAffixmentDataReview == NULL
|| pAffixmentDataReview->IsEmpty()
)
continue;
CRect & rcPreCalcReview = arrRcPreCalc.ElementAt( nReviewIdx-nSubRowStartPos );
int nExtentBarReview = bHorz
? rcPreCalcReview.Width()
: rcPreCalcReview.Height()
;
int nExtentCompressedAffixmentReview = bHorz
? pAffixmentDataReview->m_sizeCompressed.cx
: pAffixmentDataReview->m_sizeCompressed.cy
;
if( nExtentCompressedAffixmentReview < nExtentBarReview )
continue;
int nCsExt = nExtentCompressedAffixmentReview - nExtentBarReview;
int nCsSrc = nCsExt;
for( int nCmpxIdx = arrAffixmentOrder.GetSize(); nCmpxIdx > nOrderT ; nCmpxIdx-- )
{
int nCmpxIdxEffective = arrAffixmentOrder[ nCmpxIdx - 1 ];
OuterLayoutItemData & olidCmpx = dbol.ElementAt( nCmpxIdxEffective );
CExtControlBar * pExtBarCmpx =
DYNAMIC_DOWNCAST(
CExtControlBar,
olidCmpx.m_pBar
);
if( pExtBarCmpx == NULL )
continue;
CExtControlBar::InternalAffixmentData * pAffixmentDataCmpx =
pExtBarCmpx->_AffixmentGetOuter();
if( pAffixmentDataCmpx == NULL
|| pAffixmentDataCmpx->IsEmpty()
)
continue;
ASSERT( pAffixmentDataReview->m_nAffixmentWeight <= pAffixmentDataCmpx->m_nAffixmentWeight );
CRect & rcPreCalcCmpx = arrRcPreCalc.ElementAt( nCmpxIdxEffective-nSubRowStartPos );
int nCsAvail = bHorz
? (rcPreCalcCmpx.Width() - olidCmpx.m_sizeBarMin.cx)
: (rcPreCalcCmpx.Height() - olidCmpx.m_sizeBarMin.cy)
;
//ASSERT( nCsAvail >= 0 );
if( nCsAvail < 0 )
continue;
nCsAvail = min( nCsAvail, nCsExt );
ASSERT( nCsAvail >= 0 );
if( nCsAvail == 0 )
continue;
(bHorz ? rcPreCalcCmpx.right : rcPreCalcCmpx.bottom ) -=
nCsAvail;
nCsExt -= nCsAvail;
bPerformReShift = true;
ASSERT( nCsExt >= 0 );
if( nCsExt == 0 )
break;
} // for( int nCmpxIdx = arrAffixmentOrder.GetSize(); nCmpxIdx > nOrderT ; nCmpxIdx-- )
ASSERT( 0 <= nCsExt && nCsExt <= nCsSrc );
if( nCsExt == nCsSrc )
continue;
ASSERT( bPerformReShift );
(bHorz ? rcPreCalcReview.right : rcPreCalcReview.bottom ) +=
(nCsSrc - nCsExt);
} // for( int nOrderT = arrAffixmentOrder.GetSize()-1; nOrderT > 0; nOrderT-- )
if( bPerformReShift )
{
int nRightPrev = 0;
for( nBar = nSubRowStartPos; nBar <= nSubRowEndPos; nBar++ )
{
// OuterLayoutItemData & olid = dbol.ElementAt( nBar );
CRect & rcPreCalc = arrRcPreCalc.ElementAt( nBar-nSubRowStartPos );
int nShift =
nRightPrev
- (bHorz ? rcPreCalc.left : rcPreCalc.top )
;
if( nShift != 0 )
rcPreCalc.OffsetRect(
bHorz ? nShift : 0,
bHorz ? 0 : nShift
);
nRightPrev = bHorz ? rcPreCalc.right : rcPreCalc.bottom;
} // for( nBar = nSubRowStartPos; nBar <= nSubRowEndPos; nBar++ )
} // if( bPerformReShift )
} // if compression passed with full row layout with more than 1 bar
} // if( nCsRow == 0 && nLeftPrev >= 0 )
} // if( (!bRetVal) && nCsRow >= 0 )
if( !bRetVal )
{
bAdjustWithAffixment = false;
return false;
} // if( !bRetVal )
bool bCalcFullyOccupiedLayout =
(p_bFullyOccupiedLayout != NULL) ? true : false;
if( bCalcFullyOccupiedLayout
&& (*p_bFullyOccupiedLayout)
)
bCalcFullyOccupiedLayout = false;
if( bCalcFullyOccupiedLayout
&& nSubRowStartPos > 0
&& nSubRowEndPos < (dbol.GetSize() - 1)
)
bCalcFullyOccupiedLayout = false;
if( bCalcFullyOccupiedLayout
&& bCompressionPassed
)
{
bCalcFullyOccupiedLayout = false;
*p_bFullyOccupiedLayout = true;
}
int nPosRightPrev = 0;
for( nBar = nSubRowStartPos; nBar <= nSubRowEndPos; nBar++ )
{
OuterLayoutItemData & olid = dbol.ElementAt( nBar );
olid.m_rcPreCalc = arrRcPreCalc.ElementAt( nBar-nSubRowStartPos );
ASSERT( olid.m_rcPreCalc.left >= 0 );
ASSERT( olid.m_rcPreCalc.right >= 0 );
ASSERT( olid.m_rcPreCalc.left <= olid.m_rcPreCalc.right );
ASSERT( olid.m_rcPreCalc.top <= olid.m_rcPreCalc.bottom );
#ifdef __DEBUG_CExtDockOuterBar_CompressSubRow_ASSERT_CRITICAL_MINSIZE
ASSERT( olid.m_rcPreCalc.Width() >= olid.m_sizeBarMin.cx );
ASSERT( olid.m_rcPreCalc.Height() >= olid.m_sizeBarMin.cy );
#endif // __DEBUG_CExtDockOuterBar_CompressSubRow_ASSERT_CRITICAL_MINSIZE
if( !bCalcFullyOccupiedLayout )
continue;
int nPosLeft = bHorz
? olid.m_rcPreCalc.left
: olid.m_rcPreCalc.top
;
if( nBar == nSubRowStartPos )
{
ASSERT( nPosLeft >= 0 );
if( nPosLeft > 0 )
{
bCalcFullyOccupiedLayout = false;
continue;
}
} // if( nBar == nSubRowStartPos )
ASSERT( nPosLeft >= nPosRightPrev );
if( nPosLeft > nPosRightPrev )
{
bCalcFullyOccupiedLayout = false;
continue;
}
nPosRightPrev = bHorz
? olid.m_rcPreCalc.right
: olid.m_rcPreCalc.bottom
;
if( nBar == nSubRowEndPos )
{
if( nPosRightPrev < nExtentMax )
{
bCalcFullyOccupiedLayout = false;
continue;
}
} // if( nBar == nSubRowEndPos )
} // for( nBar = nSubRowStartPos; nBar <= nSubRowEndPos; nBar++ )
if( bCalcFullyOccupiedLayout )
{
ASSERT( p_bFullyOccupiedLayout != NULL );
*p_bFullyOccupiedLayout = true;
}
return true;
}
void CExtDockOuterBar::_CalcFixedRowLayout(
CSize & sizeFixed,
CSize & sizeMax,
CPoint & pt,
BOOL bHorz,
AFX_SIZEPARENTPARAMS & layout,
CExtDockOuterBar::dockbar_outer_layout_t & dbol,
int * p_nSubRowCount, // = NULL
bool * p_bFullyOccupiedLayout // = NULL
)
{
ASSERT_VALID(this);
if( p_nSubRowCount != NULL )
*p_nSubRowCount = 1;
if( p_bFullyOccupiedLayout != NULL )
*p_bFullyOccupiedLayout = false;
int nCountOfBars = dbol.GetSize();
ASSERT( nCountOfBars > 0 );
// pre-process hidden bars
for( int nBar = 0; nBar < nCountOfBars; )
{
OuterLayoutItemData & olid = dbol.ElementAt( nBar );
ASSERT_VALID( olid.m_pBar );
ASSERT_KINDOF( CControlBar, olid.m_pBar );
if( !olid.m_bVisible )
{
olid.m_pBar->RecalcDelayShow( &layout );
dbol.RemoveAt( nBar );
nCountOfBars--;
continue;
}
olid.m_pBar->GetWindowRect( &olid.m_rcReal );
ScreenToClient( &olid.m_rcReal );
nBar++;
} // for( int nBar = 0; nBar < nCountOfBars; )
// precalc layout (1), move according to affixement
AffixmentOrderVector_t arrAffixmentOrder;
_CalcAffixmentOrderVector(
bHorz ? true : false,
arrAffixmentOrder,
dbol,
true
);
ASSERT( arrAffixmentOrder.GetSize() == nCountOfBars );
// precalc layout (2), split to subrows
int nTotalRowExtent = 0;
int nSubRowStartPos = 0;
bool bAdjustWithAffixment = true;
bool bAlignSubRowAffixmentHW = true;
for( nBar = 0; nBar < nCountOfBars; nBar++ )
{
OuterLayoutItemData & olid = dbol.ElementAt( nBar );
ASSERT_VALID( olid.m_pBar );
ASSERT_KINDOF( CControlBar, olid.m_pBar );
ASSERT( olid.m_bVisible );
olid.m_rcPreCalc = CRect( pt, olid.m_sizeCalcDynamic );
if( bHorz )
{
if( olid.m_rcReal.left > olid.m_rcPreCalc.left
&& (!m_bFloating)
)
olid.m_rcPreCalc.OffsetRect(
olid.m_rcReal.left - olid.m_rcPreCalc.left,
0
);
int nRest = olid.m_rcPreCalc.right - sizeMax.cx;
/// int nRest = sizeMax.cx - olid.m_rcPreCalc.left + olid.m_sizeBarMin.cx;
if( nRest >= 0
&& ( !olid.m_pBar->IsKindOf(RUNTIME_CLASS(CExtControlBar))
|| ( olid.m_pBar->IsKindOf(RUNTIME_CLASS(CExtControlBar))
&& ((CExtControlBar*)olid.m_pBar)->IsFixedMode()
)
)
)
{ // trying to make one multi-row or compress it
if( !_CompressSubRow(
dbol,
nSubRowStartPos,
nBar,
sizeMax.cx,
bHorz ? true : false,
bAdjustWithAffixment,
p_bFullyOccupiedLayout
)
)
{
if( p_nSubRowCount != NULL )
(*p_nSubRowCount)++;
if( p_bFullyOccupiedLayout != NULL )
*p_bFullyOccupiedLayout = true;
// ASSERT( bAlignSubRowAffixmentHW );
bAlignSubRowAffixmentHW = false;
_AlignSubRowAffixmentHW(
bHorz ? true : false,
dbol,
nSubRowStartPos,
nBar
);
bAdjustWithAffixment = false;
nSubRowStartPos = nBar;
_AdjustByTotalRowExtent(
nTotalRowExtent,
sizeFixed,
pt,
bHorz
);
ASSERT( pt.x == 0 );
olid.m_rcPreCalc = CRect( pt, olid.m_sizeCalcDynamic );
}
else
bAlignSubRowAffixmentHW = true;
} // trying to make one multi-row or compress it
pt.x =
//olid.m_rcPreCalc.left + olid.m_sizeCalcDynamic.cx
olid.m_rcPreCalc.right
;
nTotalRowExtent = max( nTotalRowExtent, olid.m_sizeCalcDynamic.cy );
} // if( bHorz )
else
{
// offset calculated rect out to actual
if( olid.m_rcReal.top > olid.m_rcPreCalc.top
&& (!m_bFloating)
)
olid.m_rcPreCalc.OffsetRect(
0,
olid.m_rcReal.top - olid.m_rcPreCalc.top
);
int nRest = olid.m_rcPreCalc.bottom - sizeMax.cy;
/// int nRest = sizeMax.cy - olid.m_rcPreCalc.top + olid.m_sizeBarMin.cy;
if( nRest >= 0
&& ( !olid.m_pBar->IsKindOf(RUNTIME_CLASS(CExtControlBar))
|| ( olid.m_pBar->IsKindOf(RUNTIME_CLASS(CExtControlBar))
&& ((CExtControlBar*)olid.m_pBar)->IsFixedMode()
)
)
)
{ // trying to make one multi-row or compress it
if( !_CompressSubRow(
dbol,
nSubRowStartPos,
nBar,
sizeMax.cy,
bHorz ? true : false,
bAdjustWithAffixment,
p_bFullyOccupiedLayout
)
)
{
if( p_nSubRowCount != NULL )
(*p_nSubRowCount)++;
if( p_bFullyOccupiedLayout != NULL )
*p_bFullyOccupiedLayout = true;
// ASSERT( bAlignSubRowAffixmentHW );
bAlignSubRowAffixmentHW = false;
_AlignSubRowAffixmentHW(
bHorz ? true : false,
dbol,
nSubRowStartPos,
nBar
);
bAdjustWithAffixment = false;
nSubRowStartPos = nBar;
_AdjustByTotalRowExtent(
nTotalRowExtent,
sizeFixed,
pt,
bHorz
);
ASSERT( pt.y == 0 );
olid.m_rcPreCalc = CRect( pt, olid.m_sizeCalcDynamic );
}
else
bAlignSubRowAffixmentHW = true;
} // trying to make one multi-row or compress it
pt.y =
//olid.m_rcPreCalc.top + olid.m_sizeCalcDynamic.cy
olid.m_rcPreCalc.bottom
;
nTotalRowExtent = max( nTotalRowExtent, olid.m_sizeCalcDynamic.cx );
} // else from if( bHorz )
} // for( nBar = 0; nBar < nCountOfBars; nBar++ )
if( bAlignSubRowAffixmentHW && (nCountOfBars > 0) )
{
ASSERT( nBar <= nCountOfBars );
if( nBar == nCountOfBars )
nBar = nCountOfBars - 1;
ASSERT( nSubRowStartPos <= nBar );
_AlignSubRowAffixmentHW(
bHorz ? true : false,
dbol,
nSubRowStartPos,
nBar
);
} // if( bAlignSubRowAffixmentHW && (nCountOfBars > 0) )
/* DEBUG **
*********************************************
*********************************************
int nPosLastTest = 0;
for( nBar = 0; bAdjustWithAffixment && nBar < nCountOfBars; nBar++ )
{
OuterLayoutItemData & olid = dbol.ElementAt( nBar );
ASSERT_VALID( olid.m_pBar );
ASSERT_KINDOF( CControlBar, olid.m_pBar );
ASSERT( olid.m_bVisible );
int nPosCurrTest = bHorz
? olid.m_rcPreCalc.left
: olid.m_rcPreCalc.top
;
ASSERT( nPosLastTest <= nPosCurrTest );
if( nPosLastTest < nPosCurrTest )
break;
nPosLastTest = bHorz
? olid.m_rcPreCalc.right
: olid.m_rcPreCalc.bottom
;
} // for( nBar = 0; bAdjustWithAffixment && nBar < nCountOfBars; nBar++ )
int bMaxTest = bHorz ? sizeMax.cx : sizeMax.cy;
if( nBar == nCountOfBars
&& nPosLastTest >= bMaxTest
)
bAdjustWithAffixment = false;
*********************************************
*********************************************
** DEBUG */
if( bAdjustWithAffixment )
{
// pre adjust affixment
for( int nOrder = nCountOfBars; nOrder > 0; nOrder-- )
{
int nBarAtOrder = arrAffixmentOrder[nOrder-1];
ASSERT( 0 <= nBarAtOrder && nBarAtOrder < nCountOfBars );
OuterLayoutItemData & olid = dbol.ElementAt( nBarAtOrder );
ASSERT_VALID( olid.m_pBar );
ASSERT_KINDOF( CControlBar, olid.m_pBar );
ASSERT( olid.m_bVisible );
CExtControlBar * pExtBar =
DYNAMIC_DOWNCAST(
CExtControlBar,
olid.m_pBar
);
if( pExtBar == NULL )
continue;
CExtControlBar::InternalAffixmentData * pAffixmentData =
pExtBar->_AffixmentGetOuter();
// if( pAffixmentData == NULL )
// continue;
// ASSERT( !pAffixmentData->IsEmpty() );
// ASSERT( !pAffixmentData->m_rcAffixment.IsRectEmpty() );
// if( olid.m_rcPreCalc == pAffixmentData->m_rcAffixment )
// continue;
if( pAffixmentData == NULL
|| pAffixmentData->IsEmpty()
|| pAffixmentData->m_rcAffixment.IsRectEmpty()
|| olid.m_rcPreCalc == pAffixmentData->m_rcAffixment
)
continue;
_PreAdjustWithAffixment(
bHorz ? true : false,
dbol,
olid,
nBarAtOrder,
pAffixmentData,
bHorz ? sizeMax.cx : sizeMax.cy
);
} // for( int nOrder = nCountOfBars; nOrder > 0; nOrder-- )
// post adjust affixment
for( nOrder = nCountOfBars; nOrder > 0; nOrder-- )
{
int nBarAtOrder = arrAffixmentOrder[nOrder-1];
ASSERT( 0 <= nBarAtOrder && nBarAtOrder < nCountOfBars );
OuterLayoutItemData & olid = dbol.ElementAt( nBarAtOrder );
ASSERT_VALID( olid.m_pBar );
ASSERT_KINDOF( CControlBar, olid.m_pBar );
ASSERT( olid.m_bVisible );
CExtControlBar * pExtBar =
DYNAMIC_DOWNCAST(
CExtControlBar,
olid.m_pBar
);
if( pExtBar == NULL )
continue;
CExtControlBar::InternalAffixmentData * pAffixmentData =
pExtBar->_AffixmentGetOuter();
// if( pAffixmentData == NULL )
// continue;
// ASSERT( !pAffixmentData->IsEmpty() );
// ASSERT( !pAffixmentData->m_rcAffixment.IsRectEmpty() );
// if( olid.m_rcPreCalc == pAffixmentData->m_rcAffixment )
// continue;
if( pAffixmentData == NULL
|| pAffixmentData->IsEmpty()
|| pAffixmentData->m_rcAffixment.IsRectEmpty()
|| olid.m_rcPreCalc == pAffixmentData->m_rcAffixment
)
continue;
_PostAdjustWithAffixment(
bHorz ? true : false,
dbol,
olid,
nBarAtOrder,
pAffixmentData,
bHorz ? sizeMax.cx : sizeMax.cy
);
} // for( int nOrder = nCountOfBars; nOrder > 0; nOrder-- )
} // if( bAdjustWithAffixment )
// verify for minimal layouts
for( nBar = 0; nBar < nCountOfBars; nBar++ )
{
OuterLayoutItemData & olid = dbol.ElementAt( nBar );
ASSERT_VALID( olid.m_pBar );
ASSERT_KINDOF( CControlBar, olid.m_pBar );
ASSERT( olid.m_bVisible );
if( bHorz )
{
int nRest = sizeMax.cx - olid.m_rcPreCalc.right;
if( nRest >= 0 )
continue;
olid.m_rcPreCalc.right = sizeMax.cx;
if( olid.m_rcPreCalc.Width() < olid.m_sizeBarMin.cx )
olid.m_rcPreCalc.right = olid.m_rcPreCalc.left + olid.m_sizeBarMin.cx;
} // if( bHorz )
else
{
int nRest = sizeMax.cy - olid.m_rcPreCalc.bottom;
if( nRest >= 0 )
continue;
olid.m_rcPreCalc.bottom = sizeMax.cy;
if( olid.m_rcPreCalc.Height() < olid.m_sizeBarMin.cy )
olid.m_rcPreCalc.bottom = olid.m_rcPreCalc.top + olid.m_sizeBarMin.cy;
} // else from if( bHorz )
}
// apply layout
if( !m_bLayoutQuery )
{
for( nBar = 0; nBar < nCountOfBars; nBar++ )
{
OuterLayoutItemData & olid = dbol.ElementAt( nBar );
ASSERT_VALID( olid.m_pBar );
ASSERT_KINDOF( CControlBar, olid.m_pBar );
ASSERT( olid.m_bVisible );
if( olid.m_rcPreCalc == olid.m_rcReal )
continue;
if( (olid.m_pBar->m_dwStyle & CBRS_FLOATING) == 0 )
olid.m_pBar->m_pDockContext->
m_rectMRUDockPos = olid.m_rcPreCalc;
AfxRepositionWindow(
&layout,
olid.m_pBar->m_hWnd,
&olid.m_rcPreCalc
);
} // for( nBar = 0; nBar < nCountOfBars; nBar++ )
} // if( !m_bLayoutQuery )
_AdjustByTotalRowExtent(
nTotalRowExtent,
sizeFixed,
pt,
bHorz
);
}
void CExtDockOuterBar::_PreAdjustWithAffixment(
bool bHorz,
CExtDockOuterBar::dockbar_outer_layout_t & dbol,
CExtDockOuterBar::OuterLayoutItemData & olidAdjustedSrc,
int nBarAdjustedSrc,
CExtControlBar::InternalAffixmentData * pAffixmentDataAdjustedSrc,
int nExtentMax
)
{
if( nExtentMax <= 0 )
return;
int nCountOfBars = dbol.GetSize();
ASSERT( 0 <= nBarAdjustedSrc && nBarAdjustedSrc < nCountOfBars );
ASSERT( dbol.ElementAt(nBarAdjustedSrc).m_pBar == olidAdjustedSrc.m_pBar );
ASSERT( pAffixmentDataAdjustedSrc != NULL );
ASSERT( !pAffixmentDataAdjustedSrc->IsEmpty() );
int nPosAffixment = bHorz
? pAffixmentDataAdjustedSrc->m_rcAffixment.left
: pAffixmentDataAdjustedSrc->m_rcAffixment.top
;
int nPosPreCalc = bHorz
? olidAdjustedSrc.m_rcPreCalc.left
: olidAdjustedSrc.m_rcPreCalc.top
;
int nAdjustShift = nPosAffixment - nPosPreCalc;
if( nAdjustShift == 0 )
return;
// TRACE3(
// " Bar 0x%08X weight = %d nAdjustShift = %d\n",
// long(olidAdjustedSrc.m_pBar),
// pAffixmentDataAdjustedSrc->m_nAffixmentWeight,
// nAdjustShift
// );
_ShiftSubRowWithAffixment(
bHorz,
dbol,
( nAdjustShift > 0 )
? nBarAdjustedSrc
: 0
,
( nAdjustShift > 0 )
? (nCountOfBars - 1)
: nBarAdjustedSrc
,
nAdjustShift,
nExtentMax
);
}
void CExtDockOuterBar::_PostAdjustWithAffixment(
bool bHorz,
CExtDockOuterBar::dockbar_outer_layout_t & dbol,
CExtDockOuterBar::OuterLayoutItemData & olidAdjustedSrc,
int nBarAdjustedSrc,
CExtControlBar::InternalAffixmentData * pAffixmentDataAdjustedSrc,
int nExtentMax
)
{
if( nExtentMax <= 0 )
return;
int nCountOfBars = dbol.GetSize();
ASSERT( 0 <= nBarAdjustedSrc && nBarAdjustedSrc < nCountOfBars );
ASSERT( dbol.ElementAt(nBarAdjustedSrc).m_pBar == olidAdjustedSrc.m_pBar );
ASSERT( pAffixmentDataAdjustedSrc != NULL );
ASSERT( !pAffixmentDataAdjustedSrc->IsEmpty() );
int nPosAffixment = bHorz
? pAffixmentDataAdjustedSrc->m_rcAffixment.left
: pAffixmentDataAdjustedSrc->m_rcAffixment.top
;
int nPosPreCalc = bHorz
? olidAdjustedSrc.m_rcPreCalc.left
: olidAdjustedSrc.m_rcPreCalc.top
;
int nPosPossibleToFix = nPosPreCalc;
int nAdjustShift = nPosAffixment - nPosPreCalc;
if( nAdjustShift == 0 )
return;
if( nAdjustShift < 0 )
{
if( nBarAdjustedSrc == 0 )
{
nPosPossibleToFix =
max( nPosPossibleToFix, 0 );
} // if( nBarAdjustedSrc == 0 )
else
{
OuterLayoutItemData & olid2 = dbol.ElementAt( nBarAdjustedSrc-1 );
ASSERT_VALID( olid2.m_pBar );
ASSERT_KINDOF( CControlBar, olid2.m_pBar );
ASSERT( olid2.m_bVisible );
nPosPossibleToFix = bHorz
? olid2.m_rcPreCalc.right
: olid2.m_rcPreCalc.bottom
;
} // else from if( nBarAdjustedSrc == 0 )
int nPossibleShift = nPosPossibleToFix - nPosPreCalc;
nAdjustShift = max( nAdjustShift, nPossibleShift );
} // if( nAdjustShift < 0 )
else
{
nPosPreCalc += bHorz
? olidAdjustedSrc.m_rcPreCalc.Width()
: olidAdjustedSrc.m_rcPreCalc.Height()
;
nPosPossibleToFix = nPosPreCalc;
if( nBarAdjustedSrc == (nCountOfBars-1) )
{
nPosPossibleToFix =
min( nPosPossibleToFix, nExtentMax );
} // if( nBarAdjustedSrc == (nCountOfBars-1) )
else
{
OuterLayoutItemData & olid2 = dbol.ElementAt( nBarAdjustedSrc+1 );
ASSERT_VALID( olid2.m_pBar );
ASSERT_KINDOF( CControlBar, olid2.m_pBar );
ASSERT( olid2.m_bVisible );
nPosPossibleToFix = bHorz
? olid2.m_rcPreCalc.left
: olid2.m_rcPreCalc.top
;
} // else from if( nBarAdjustedSrc == (nCountOfBars-1) )
int nPossibleShift = nPosPossibleToFix - nPosPreCalc;
nAdjustShift = min( nAdjustShift, nPossibleShift );
} // else from if( nAdjustShift < 0 )
if( nAdjustShift == 0 )
return;
olidAdjustedSrc.m_rcPreCalc.OffsetRect(
bHorz ? nAdjustShift : 0,
bHorz ? 0 : nAdjustShift
);
}
int CExtDockOuterBar::_ShiftSubRowWithAffixment(
bool bHorz,
CExtDockOuterBar::dockbar_outer_layout_t & dbol,
int nReviewStart,
int nReviewEnd,
int nAdjustShift,
int nExtentMax
)
{
ASSERT( dbol.GetSize() > 0 );
ASSERT( 0 <= nReviewStart && nReviewStart < dbol.GetSize() );
ASSERT( 0 <= nReviewEnd && nReviewEnd < dbol.GetSize() );
ASSERT( nReviewStart <= nReviewEnd );
ASSERT( nAdjustShift != 0 );
ASSERT( nExtentMax > 0 );
if( nReviewStart == nReviewEnd )
{
OuterLayoutItemData & olid = dbol.ElementAt( nReviewStart );
ASSERT_VALID( olid.m_pBar );
ASSERT_KINDOF( CControlBar, olid.m_pBar );
ASSERT( olid.m_bVisible );
int nPosPreCalc = bHorz
? olid.m_rcPreCalc.left
: olid.m_rcPreCalc.top
;
ASSERT( nPosPreCalc >= 0 );
if( nAdjustShift > 0 )
{
ASSERT( nReviewStart == dbol.GetSize()-1 );
nPosPreCalc += bHorz
? olid.m_rcPreCalc.Width()
: olid.m_rcPreCalc.Height()
;
ASSERT( nPosPreCalc >= 0 );
ASSERT( nPosPreCalc <= nExtentMax );
if( nPosPreCalc == nExtentMax )
return 0;
int nRest = nExtentMax - nPosPreCalc;
ASSERT( nRest >= 0 );
nAdjustShift = min( nAdjustShift, nRest );
ASSERT( nAdjustShift >= 0 );
} // if( nAdjustShift > 0 )
else
{
ASSERT( nReviewStart == 0 );
// if( nPosPreCalc == 0 )
// return 0;
//if( nPosPreCalc < 0 )
// return 0;
nAdjustShift = max( (-nPosPreCalc), nAdjustShift );
ASSERT( nAdjustShift <= 0 );
} // else from if( nAdjustShift > 0 )
olid.m_rcPreCalc.OffsetRect(
bHorz ? nAdjustShift : 0,
bHorz ? 0 : nAdjustShift
);
ASSERT( olid.m_rcPreCalc.left >= 0 );
ASSERT( olid.m_rcPreCalc.top >= 0 );
return nAdjustShift;
} // if( nReviewStart == nReviewEnd )
if( nAdjustShift > 0 )
{
OuterLayoutItemData & olid1 = dbol.ElementAt( nReviewStart );
ASSERT_VALID( olid1.m_pBar );
ASSERT_KINDOF( CControlBar, olid1.m_pBar );
ASSERT( olid1.m_bVisible );
ASSERT( olid1.m_rcPreCalc.left >= 0 );
ASSERT( olid1.m_rcPreCalc.top >= 0 );
int nPosPreCalc1 = bHorz
? olid1.m_rcPreCalc.right // (olid1.m_rcPreCalc.left + olid1.m_rcPreCalc.Width())
: olid1.m_rcPreCalc.bottom // (olid1.m_rcPreCalc.top + olid1.m_rcPreCalc.Height())
;
ASSERT( nPosPreCalc1 >= 0 );
OuterLayoutItemData & olid2 = dbol.ElementAt( nReviewStart + 1 );
ASSERT_VALID( olid2.m_pBar );
ASSERT_KINDOF( CControlBar, olid2.m_pBar );
ASSERT( olid2.m_bVisible );
ASSERT( olid2.m_rcPreCalc.left >= 0 );
ASSERT( olid2.m_rcPreCalc.top >= 0 );
int nPosPreCalc2 = bHorz
? olid2.m_rcPreCalc.left
: olid2.m_rcPreCalc.top
;
ASSERT( nPosPreCalc2 >= 0 );
int nDist = nPosPreCalc2 - nPosPreCalc1;
ASSERT( nDist >= 0 );
nDist = min( nAdjustShift, nDist );
ASSERT( nDist <= nAdjustShift );
if( nDist == nAdjustShift )
{
olid1.m_rcPreCalc.OffsetRect(
bHorz ? nAdjustShift : 0,
bHorz ? 0 : nAdjustShift
);
ASSERT( olid1.m_rcPreCalc.left >= 0 );
ASSERT( olid1.m_rcPreCalc.top >= 0 );
return nAdjustShift;
}
int nSpaceToCompress = nAdjustShift - nDist;
ASSERT( nSpaceToCompress > 0 );
int nSpaceReallyCompressed =
_ShiftSubRowWithAffixment(
bHorz,
dbol,
nReviewStart + 1,
nReviewEnd,
nSpaceToCompress,
nExtentMax
);
ASSERT( nSpaceReallyCompressed >= 0 );
ASSERT( nSpaceReallyCompressed <= nSpaceToCompress );
/*?????*/ nAdjustShift = nSpaceReallyCompressed + nDist;
olid1.m_rcPreCalc.OffsetRect(
bHorz ? nAdjustShift : 0,
bHorz ? 0 : nAdjustShift
);
ASSERT( olid1.m_rcPreCalc.left >= 0 );
ASSERT( olid1.m_rcPreCalc.top >= 0 );
} // if( nAdjustShift > 0 )
else
{
OuterLayoutItemData & olid1 = dbol.ElementAt( nReviewEnd );
ASSERT_VALID( olid1.m_pBar );
ASSERT_KINDOF( CControlBar, olid1.m_pBar );
ASSERT( olid1.m_bVisible );
ASSERT( olid1.m_rcPreCalc.left >= 0 );
ASSERT( olid1.m_rcPreCalc.top >= 0 );
int nPosPreCalc1 = bHorz
? olid1.m_rcPreCalc.left
: olid1.m_rcPreCalc.top
;
ASSERT( nPosPreCalc1 >= 0 );
OuterLayoutItemData & olid2 = dbol.ElementAt( nReviewEnd - 1 );
ASSERT_VALID( olid2.m_pBar );
ASSERT_KINDOF( CControlBar, olid2.m_pBar );
ASSERT( olid2.m_bVisible );
ASSERT( olid2.m_rcPreCalc.left >= 0 );
ASSERT( olid2.m_rcPreCalc.top >= 0 );
int nPosPreCalc2 = bHorz
? olid2.m_rcPreCalc.right // (olid2.m_rcPreCalc.left + olid2.m_rcPreCalc.Width())
: olid2.m_rcPreCalc.bottom // (olid2.m_rcPreCalc.top + olid2.m_rcPreCalc.Height())
;
ASSERT( nPosPreCalc2 >= 0 );
int nDist = nPosPreCalc2 - nPosPreCalc1;
ASSERT( nDist <= 0 );
nDist = max( nAdjustShift, nDist );
ASSERT( nDist >= nAdjustShift );
if( nDist == nAdjustShift )
{
olid1.m_rcPreCalc.OffsetRect(
bHorz ? nAdjustShift : 0,
bHorz ? 0 : nAdjustShift
);
ASSERT( olid1.m_rcPreCalc.left >= 0 );
ASSERT( olid1.m_rcPreCalc.top >= 0 );
return nAdjustShift;
}
int nSpaceToCompress = nAdjustShift - nDist;
ASSERT( nSpaceToCompress < 0 );
int nSpaceReallyCompressed =
_ShiftSubRowWithAffixment(
bHorz,
dbol,
nReviewStart,
nReviewEnd - 1,
nSpaceToCompress,
nExtentMax
);
ASSERT( nSpaceReallyCompressed <= 0 );
ASSERT( nSpaceReallyCompressed >= nSpaceToCompress );
/*?????*/ nAdjustShift = nSpaceReallyCompressed + nDist;
olid1.m_rcPreCalc.OffsetRect(
bHorz ? nAdjustShift : 0,
bHorz ? 0 : nAdjustShift
);
ASSERT( olid2.m_rcPreCalc.left >= 0 );
ASSERT( olid2.m_rcPreCalc.top >= 0 );
} // else from if( nAdjustShift > 0 )
return nAdjustShift;
}
void CExtDockOuterBar::_AdjustByTotalRowExtent(
int & nTotalRowExtent,
CSize & sizeFixed,
CPoint & pt,
BOOL bHorz
)
{
if( nTotalRowExtent == 0 )
return;
if( bHorz )
{
pt.y += nTotalRowExtent;
sizeFixed.cx = max(sizeFixed.cx, pt.x);
sizeFixed.cy = max(sizeFixed.cy, pt.y);
pt.x = 0;
sizeFixed.cy--;
} // if( bHorz )
else
{
pt.x += nTotalRowExtent;
sizeFixed.cx = max(sizeFixed.cx, pt.x);
sizeFixed.cy = max(sizeFixed.cy, pt.y);
pt.y = 0;
sizeFixed.cx--;
} // else from if( bHorz )
nTotalRowExtent = 0;
}
CSize CExtDockOuterBar::CalcFixedLayout(BOOL bStretch, BOOL bHorz)
{
ASSERT_VALID(this);
CSize sizeFixed =
CControlBar::CalcFixedLayout( bStretch, bHorz );
CSize sizeMax;
if( !m_rectLayout.IsRectEmpty() )
sizeMax = m_rectLayout.Size();
else
{
CFrameWnd * pFrame = GetParentFrame();
CRect rcFrameWindow;
pFrame->GetClientRect( &rcFrameWindow );
sizeMax = rcFrameWindow.Size();
}
CPoint pt( 0, 0 );
int nCountOfBars = m_arrBars.GetSize();
AFX_SIZEPARENTPARAMS layout;
layout.hDWP =
m_bLayoutQuery
? NULL
: ( ::BeginDeferWindowPos(nCountOfBars) )
;
dockbar_outer_layout_t dbol;
for( int nBar = 0; nBar < nCountOfBars; nBar++ )
{
CControlBar * pBar = (CControlBar *)m_arrBars[nBar];
if( pBar != NULL
&& (!(__PLACEHODLER_BAR_PTR(pBar)))
)
{
ASSERT_VALID( pBar );
ASSERT_KINDOF( CControlBar, pBar );
dbol.Add(
OuterLayoutItemData(
pBar,
bHorz,
sizeMax
)
);
} // if( pBar != NULL && ...
if( pBar == NULL || nBar == (nCountOfBars-1) )
{
if( dbol.GetSize() == 0 )
continue;
_CalcFixedRowLayout(
sizeFixed,
sizeMax,
pt,
bHorz,
layout,
dbol
);
dbol.RemoveAll();
} // if( pBar == NULL || nBar == (nCountOfBars-1) )
} // for( int nBar = 0; nBar < nCountOfBars; nBar++ )
ASSERT( dbol.GetSize() == 0 );
if( !m_bLayoutQuery )
{
ASSERT( layout.hDWP != NULL );
if( layout.hDWP != NULL )
{
VERIFY( ::EndDeferWindowPos(layout.hDWP) );
}
} // if( !m_bLayoutQuery )
// adjust size for borders on the dock bar itself
CRect rc( 0, 0, 0, 0 );
CalcInsideRect(rc, bHorz);
if( (!bStretch || !bHorz) && sizeFixed.cx != 0 )
sizeFixed.cx +=
-rc.right + rc.left
+ g_bControlBarFixSizePixel ? 1 : 0;
if( (!bStretch || bHorz) && sizeFixed.cy != 0 )
sizeFixed.cy +=
-rc.bottom + rc.top
+ g_bControlBarFixSizePixel ? 1 : 0;
if( !m_bLayoutQuery )
OnDynamicLayoutUpdate();
return sizeFixed;
}
void CExtDockOuterBar::_RedockInRow(
CExtControlBar * pBarSlide,
int nShiftDesired,
bool * p_bInplaceResizing // = NULL
)
{
ASSERT_VALID( this );
ASSERT_VALID( pBarSlide );
ASSERT( this == pBarSlide->GetParent() );
if( p_bInplaceResizing != NULL )
*p_bInplaceResizing = false;
if( nShiftDesired == 0 )
return;
int nCountOfBars = m_arrBars.GetSize();
ASSERT( nCountOfBars > 1 );
int nSlideBarPos = FindBar( pBarSlide );
ASSERT( 0 < nSlideBarPos && nSlideBarPos < nCountOfBars );
CControlBar * pFirstBar =
pBarSlide->_GetFirstControlBarInRow(
pBarSlide,
false,
false,
false
);
ASSERT_VALID( pFirstBar );
int nFirstBarPos = FindBar( pFirstBar );
ASSERT( 0 < nFirstBarPos && nFirstBarPos < nCountOfBars );
ASSERT( nFirstBarPos <= nSlideBarPos );
UINT nDockBarID = GetDlgCtrlID();
ASSERT_DOCKBAR_DLGCTRLID_DOCKED( nDockBarID );
BOOL bHorz =
( nDockBarID == AFX_IDW_DOCKBAR_TOP
|| nDockBarID == AFX_IDW_DOCKBAR_BOTTOM )
? TRUE : FALSE;
CRect rcSlideBarWnd;
pBarSlide->GetWindowRect( &rcSlideBarWnd );
ScreenToClient( &rcSlideBarWnd );
CSize sizeMax, sizeFakeFixed( 0, 0 );
if( !m_rectLayout.IsRectEmpty() )
sizeMax = m_rectLayout.Size();
else
{
CFrameWnd * pFrame = GetParentFrame();
CRect rcFrameWindow;
pFrame->GetClientRect( &rcFrameWindow );
sizeMax = rcFrameWindow.Size();
}
CPoint pt( 0, 0 );
if( bHorz )
pt.y = rcSlideBarWnd.top;
else
pt.x = rcSlideBarWnd.left;
CExtControlBar::InternalAffixmentData * pAffixmentData =
pBarSlide->_AffixmentGetOuter();
if( pAffixmentData != NULL )
{
ASSERT( !pAffixmentData->IsEmpty() );
if( pAffixmentData->m_rcAffixment.IsRectEmpty() )
{
pBarSlide->GetWindowRect( &pAffixmentData->m_rcAffixment );
ScreenToClient( &pAffixmentData->m_rcAffixment );
}
pAffixmentData->m_rcAffixment.OffsetRect(
bHorz ? nShiftDesired : 0,
bHorz ? 0 : nShiftDesired
);
if( bHorz )
{
if( pAffixmentData->m_rcAffixment.right >= sizeMax.cx )
pAffixmentData->m_rcAffixment.OffsetRect(
sizeMax.cx - pAffixmentData->m_rcAffixment.right,
0
);
if( pAffixmentData->m_rcAffixment.left < 0 )
pAffixmentData->m_rcAffixment.OffsetRect(
- pAffixmentData->m_rcAffixment.left,
0
);
} // if( bHorz )
else
{
if( pAffixmentData->m_rcAffixment.bottom >= sizeMax.cy )
pAffixmentData->m_rcAffixment.OffsetRect(
0,
sizeMax.cy - pAffixmentData->m_rcAffixment.bottom
);
if( pAffixmentData->m_rcAffixment.top < 0 )
pAffixmentData->m_rcAffixment.OffsetRect(
0,
- pAffixmentData->m_rcAffixment.top
);
} // else from if( bHorz )
}
dockbar_outer_layout_t dbol;
for( int nBar = nFirstBarPos; nBar < nCountOfBars; nBar++ )
{
CControlBar * pBar = (CControlBar *)m_arrBars[nBar];
if( pBar != NULL
&& (!(__PLACEHODLER_BAR_PTR(pBar)))
)
{
ASSERT_VALID( pBar );
ASSERT_KINDOF( CControlBar, pBar );
OuterLayoutItemData olid(
pBar,
bHorz,
sizeMax
);
if( pBar == pBarSlide )
{
if( pAffixmentData == NULL )
olid.m_rcPreCalc.OffsetRect(
bHorz ? nShiftDesired : 0,
bHorz ? 0 : nShiftDesired
);
} // if( pBar == pBarSlide )
dbol.Add( olid );
} // if( pBar != NULL && ...
if( pBar == NULL || nBar == (nCountOfBars-1) )
break;
} // for( int nBar = nFirstBarPos; nBar < nCountOfBars; nBar++ )
ASSERT( dbol.GetSize() != 0 );
int nSubRowCount = 0;
bool bFullyOccupiedLayout = false;
BOOL bLayoutQueryOld = m_bLayoutQuery;
CSize sizeFakeFixedOld( sizeFakeFixed ), sizeMaxOld( sizeMax );
CPoint ptOld( pt );
AFX_SIZEPARENTPARAMS layout;
layout.hDWP = NULL;
_CalcFixedRowLayout(
sizeFakeFixed,
sizeMax,
pt,
bHorz,
layout,
dbol,
&nSubRowCount,
&bFullyOccupiedLayout
);
m_bLayoutQuery = bLayoutQueryOld;
ASSERT( nSubRowCount >= 1 );
if( m_bLayoutQuery )
return;
ASSERT( (nCountOfBars - nFirstBarPos) > 0 );
sizeFakeFixed = sizeFakeFixedOld;
sizeMax = sizeMaxOld;
pt = ptOld;
nCountOfBars = dbol.GetSize();
ASSERT( nCountOfBars > 0 );
layout.hDWP =
::BeginDeferWindowPos(nCountOfBars);
// reasonable row shift offset
const int nRsOffset = 1; //2;
if( nCountOfBars > 1 && pAffixmentData != NULL )
{
int nSlideBarIdxInArray = -1;
for( nBar = 0; nBar < nCountOfBars; nBar++ )
{
OuterLayoutItemData & olid = dbol.ElementAt( nBar );
ASSERT_VALID( olid.m_pBar );
ASSERT_KINDOF( CControlBar, olid.m_pBar );
ASSERT( olid.m_bVisible );
if( olid.m_pBar == pBarSlide )
{
ASSERT( nSlideBarIdxInArray < 0 );
nSlideBarIdxInArray = nBar;
break;
}
} // for( nBar = 0; nBar < nCountOfBars; nBar++ )
ASSERT( 0 <= nSlideBarIdxInArray && nSlideBarIdxInArray < nCountOfBars );
OuterLayoutItemData & olid =
dbol.ElementAt( nSlideBarIdxInArray );
ASSERT_VALID( olid.m_pBar );
ASSERT_KINDOF( CControlBar, olid.m_pBar );
ASSERT( olid.m_bVisible );
bool bTrySwapping = bFullyOccupiedLayout; // true; (+ v.2.22)
bool bUpAffxOnSwapping = true;
if( bFullyOccupiedLayout
&& (nSubRowCount == 1)
)
{ // if can analyze resizing in row
ASSERT( pAffixmentData != NULL );
if( nSlideBarIdxInArray > 0 )
{ // do resizing pre-affixment, do not resize first in row
CSize sizeBarCalc = olid.m_rcPreCalc.Size();
if( nShiftDesired > 0 )
{
//ASSERT( (!bHorz) || sizeBarCalc.cx >= olid.m_sizeBarMin.cx );
//ASSERT( ( bHorz) || sizeBarCalc.cy >= olid.m_sizeBarMin.cy );
int nExtentPossibleByBar = bHorz
? (sizeBarCalc.cx - olid.m_sizeBarMin.cx)
: (sizeBarCalc.cy - olid.m_sizeBarMin.cy)
;
nExtentPossibleByBar =
min( nExtentPossibleByBar, nShiftDesired );
if( nExtentPossibleByBar > 0 )
{
bTrySwapping = false;
if( pAffixmentData->m_nAffixmentWeight != 1 )
_AffixmentBringToTop( pBarSlide );
if( bHorz )
{
int nNewAffixment = sizeBarCalc.cx - nExtentPossibleByBar;
if( nNewAffixment > olid.m_sizeCalcDynamic.cx )
nNewAffixment = olid.m_sizeCalcDynamic.cx;
if( pAffixmentData->m_sizeCompressed.cx != nNewAffixment )
pAffixmentData->m_sizeCompressed.cx = nNewAffixment;
else
bTrySwapping = true;
} // if( bHorz )
else
{
int nNewAffixment = sizeBarCalc.cy - nExtentPossibleByBar;
if( nNewAffixment > olid.m_sizeCalcDynamic.cy )
nNewAffixment = olid.m_sizeCalcDynamic.cy;
if( pAffixmentData->m_sizeCompressed.cy != nNewAffixment )
pAffixmentData->m_sizeCompressed.cy = nNewAffixment;
else
bTrySwapping = true;
} // else from if( bHorz )
} // if( nExtentPossibleByBar > 0 )
} // if( nShiftDesired > 0 )
else
{
//ASSERT( (!bHorz) || sizeBarCalc.cx >= olid.m_sizeBarMin.cx );
//ASSERT( ( bHorz) || sizeBarCalc.cy >= olid.m_sizeBarMin.cy );
int nExtentPossibleByBar = bHorz
? (olid.m_sizeCalcDynamic.cx - sizeBarCalc.cx)
: (olid.m_sizeCalcDynamic.cy - sizeBarCalc.cy)
;
nExtentPossibleByBar =
min( nExtentPossibleByBar, (-nShiftDesired) );
ASSERT( nExtentPossibleByBar >= 0 );
if( nExtentPossibleByBar > 0 )
{
bTrySwapping = false;
if( pAffixmentData->m_nAffixmentWeight != 1 )
_AffixmentBringToTop( pBarSlide );
if( bHorz )
{
int nNewAffixment = sizeBarCalc.cx + nExtentPossibleByBar;
if( nNewAffixment > olid.m_sizeCalcDynamic.cx )
nNewAffixment = olid.m_sizeCalcDynamic.cx;
if( pAffixmentData->m_sizeCompressed.cx != nNewAffixment )
pAffixmentData->m_sizeCompressed.cx = nNewAffixment;
else
bTrySwapping = true;
}
else
{
int nNewAffixment = sizeBarCalc.cy + nExtentPossibleByBar;
if( nNewAffixment > olid.m_sizeCalcDynamic.cy )
nNewAffixment = olid.m_sizeCalcDynamic.cy;
if( pAffixmentData->m_sizeCompressed.cy != nNewAffixment )
pAffixmentData->m_sizeCompressed.cy = nNewAffixment;
else
bTrySwapping = true;
}
} // if( nExtentPossibleByBar > 0 )
} // else from if( nShiftDesired > 0 )
} // do resizing pre-affixment, do not resize first in row
else
bUpAffxOnSwapping = false;
} // if can analyze resizing in row
else if( (!bTrySwapping) && (nSubRowCount == 1) )
{ // analyze left/right free space between bars is available (+ v.2.22)
ASSERT( !bFullyOccupiedLayout );
ASSERT( 0 <= nSlideBarIdxInArray && nSlideBarIdxInArray < nCountOfBars );
int nStartBar = nSlideBarIdxInArray + 1;
int nEndBar = nCountOfBars - 1;
if( nShiftDesired < 0 )
{
nStartBar = 0;
nEndBar = nSlideBarIdxInArray;
}
for( int nBarXSP = nStartBar; nBarXSP <= nEndBar; nBarXSP++ )
{
OuterLayoutItemData & olid = dbol.ElementAt( nBarXSP );
ASSERT_VALID( olid.m_pBar );
ASSERT_KINDOF( CControlBar, olid.m_pBar );
ASSERT( olid.m_bVisible );
int nFreeBefore = 0;
CRect rcBarLocal( olid.m_rcReal );
if( nBarXSP == 0 )
nFreeBefore = bHorz ? rcBarLocal.left : rcBarLocal.top;
else
{
OuterLayoutItemData & olidPrev = dbol.ElementAt( nBarXSP-1 );
ASSERT_VALID( olidPrev.m_pBar );
ASSERT_KINDOF( CControlBar, olidPrev.m_pBar );
ASSERT( olidPrev.m_bVisible );
CRect rcBarLocalPrev( olidPrev.m_rcReal );
nFreeBefore = bHorz
? (rcBarLocal.left - rcBarLocalPrev.right)
: (rcBarLocal.top - rcBarLocalPrev.bottom)
;
} // else from if( nBarXSP == 0 )
if( nFreeBefore < 0 )
nFreeBefore = 0;
if( nShiftDesired < 0 && nFreeBefore == 0 )
{
if( nBarXSP == nEndBar )
{
bTrySwapping = true;
break;
}
continue;
} // if( nShiftDesired < 0 )
if( nShiftDesired > 0 && nFreeBefore > 0 )
break; // no swapping to right/bottom (have some space to slide)
if( nBarXSP == nEndBar && nShiftDesired > 0 )
{
CRect rcThisDocker;
GetClientRect( &rcThisDocker );
ASSERT( rcThisDocker.left == 0 && rcThisDocker.top == 0 );
if( rcThisDocker.right <= 0 || rcThisDocker.bottom <= 0 )
break; // empty space for anything
int nFreeAfter = bHorz
? (rcThisDocker.right - rcBarLocal.right)
: (rcThisDocker.bottom - rcBarLocal.bottom)
;
if( nFreeAfter <= 0 )
{
bTrySwapping = true;
break;
}
} // if( nBarXSP == nEndBar && nShiftDesired > 0 )
} // for( int nBarXSP = nStartBar; nBarXSP <= nEndBar; nBarXSP++ )
} // analyze left/right free space between bars is available (+ v.2.22)
if( bTrySwapping )
{
if( bUpAffxOnSwapping )
_AffixmentBringToTop( pBarSlide );
pAffixmentData->m_rcAffixment = olid.m_rcPreCalc;
if( nShiftDesired > 0 )
{
if( nSlideBarIdxInArray != (nCountOfBars-1) )
{
OuterLayoutItemData & olid2 =
dbol.ElementAt( nSlideBarIdxInArray + 1 );
ASSERT_VALID( olid2.m_pBar );
ASSERT_KINDOF( CControlBar, olid2.m_pBar );
ASSERT( olid2.m_bVisible );
CExtControlBar * pExtBar2 =
DYNAMIC_DOWNCAST(
CExtControlBar,
olid2.m_pBar
);
if( pExtBar2 != NULL )
{
CExtControlBar::InternalAffixmentData * pAffixmentData2 =
pExtBar2->_AffixmentGetOuter();
if( pAffixmentData2 != NULL )
{
int nPosAffx2 = bHorz
? pAffixmentData2->m_rcAffixment.left
: pAffixmentData2->m_rcAffixment.top
;
int nPosReal2 = bHorz
? olid2.m_rcPreCalc.left
: olid2.m_rcPreCalc.top
;
int n1stExtent = bHorz
? olid.m_rcPreCalc.Width()
: olid.m_rcPreCalc.Height()
;
// nPosReal2 += nRsOffset;
// nPosReal2 += nShiftDesired;
if( (nPosReal2 - n1stExtent) > nPosAffx2 )
_SwapInRowWithAffixment(
dbol,
nSlideBarIdxInArray,
nSlideBarIdxInArray + 1
);
else
{
int nPosReal = bHorz
? olid.m_rcPreCalc.left
: olid.m_rcPreCalc.top
;
int n2ndExtent = bHorz
? olid2.m_rcPreCalc.Width()
: olid2.m_rcPreCalc.Height()
;
if( ( (nPosReal2+n2ndExtent)
- (nPosReal+n1stExtent)
- nShiftDesired
- nRsOffset
)
<= 0
)
_SwapInRowWithAffixment(
dbol,
nSlideBarIdxInArray,
nSlideBarIdxInArray + 1
);
}
} // if( pAffixmentData2 != NULL )
} // if( pExtBar2 != NULL )
} // if( nSlideBarIdxInArray != (nCountOfBars-1) )
} // if( nShiftDesired > 0 )
else
{
if( nSlideBarIdxInArray != 0 )
{
OuterLayoutItemData & olid2 =
dbol.ElementAt( nSlideBarIdxInArray - 1 );
ASSERT_VALID( olid2.m_pBar );
ASSERT_KINDOF( CControlBar, olid2.m_pBar );
ASSERT( olid2.m_bVisible );
CExtControlBar * pExtBar2 =
DYNAMIC_DOWNCAST(
CExtControlBar,
olid2.m_pBar
);
if( pExtBar2 != NULL )
{
CExtControlBar::InternalAffixmentData * pAffixmentData2 =
pExtBar2->_AffixmentGetOuter();
if( pAffixmentData2 != NULL )
{
int nPosReal = bHorz
? olid.m_rcPreCalc.left
: olid.m_rcPreCalc.top
;
int nPosAffx2 = bHorz
? pAffixmentData2->m_rcAffixment.left
: pAffixmentData2->m_rcAffixment.top
;
// nPosReal -= nRsOffset;
// nPosReal += nShiftDesired;
if( nPosReal <= nPosAffx2 )
_SwapInRowWithAffixment(
dbol,
nSlideBarIdxInArray - 1,
nSlideBarIdxInArray
);
else
{
int nPosReal2 = bHorz
? olid2.m_rcPreCalc.left
: olid2.m_rcPreCalc.top
;
// int n1stExtent = bHorz
// ? olid.m_rcPreCalc.Width()
// : olid.m_rcPreCalc.Height()
// ;
// int n2ndExtent = bHorz
// ? olid2.m_rcPreCalc.Width()
// : olid2.m_rcPreCalc.Height()
// ;
if( ( (nPosReal /*+n1stExtent*/ )
- (nPosReal2 /*+n2ndExtent*/ )
+ nShiftDesired
- nRsOffset
)
<= 0
)
_SwapInRowWithAffixment(
dbol,
nSlideBarIdxInArray - 1,
nSlideBarIdxInArray
);
}
} // if( pAffixmentData2 != NULL )
} // if( pExtBar2 != NULL )
} // if( nSlideBarIdxInArray != 0 )
} // else from if( nShiftDesired > 0 )
} // if( bTrySwapping )
else
{
if( p_bInplaceResizing != NULL )
*p_bInplaceResizing = bFullyOccupiedLayout; //true; (+ v.2.22)
} // else from if( bTrySwapping )
} // if( nCountOfBars > 1 && pAffixmentData != NULL )
_CalcFixedRowLayout(
sizeFakeFixed,
sizeMax,
pt,
bHorz,
layout,
dbol
);
ASSERT( layout.hDWP != NULL );
if( layout.hDWP != NULL )
{
VERIFY( ::EndDeferWindowPos(layout.hDWP) );
}
for( nBar = 0; nBar < dbol.GetSize(); nBar++ )
{
OuterLayoutItemData & olid =
dbol.ElementAt( nBar );
ASSERT_VALID( olid.m_pBar );
ASSERT_KINDOF( CControlBar, olid.m_pBar );
if( !olid.m_bVisible )
continue;
CExtControlBar * pExtBar =
DYNAMIC_DOWNCAST( CExtControlBar, olid.m_pBar );
if( pExtBar == NULL )
continue;
pExtBar->RedrawWindow(
NULL, NULL,
RDW_INVALIDATE|RDW_UPDATENOW
|RDW_ERASE|RDW_ERASENOW
|RDW_ALLCHILDREN|RDW_NOFRAME
);
} // for( nBar = 0; nBar < dbol.GetSize(); nBar++ )
}
void CExtDockOuterBar::_SwapInRowWithAffixment(
CExtDockOuterBar::dockbar_outer_layout_t & dbol,
int nIdxLess,
int nIdxGreater
)
{
ASSERT( dbol.GetSize() > 1 );
ASSERT( 0 <= nIdxLess && nIdxLess <= dbol.GetSize() );
ASSERT( 0 <= nIdxGreater && nIdxGreater <= dbol.GetSize() );
ASSERT( (nIdxLess+1) == nIdxGreater );
OuterLayoutItemData & olid1 = dbol.ElementAt( nIdxLess );
ASSERT_VALID( olid1.m_pBar );
ASSERT_KINDOF( CControlBar, olid1.m_pBar );
ASSERT( olid1.m_bVisible );
CControlBar * pBar1 = olid1.m_pBar;
int nPosInternal1 = FindBar( pBar1 );
ASSERT( 0 < nPosInternal1 && nPosInternal1 < m_arrBars.GetSize() );
OuterLayoutItemData & olid2 = dbol.ElementAt( nIdxGreater );
ASSERT_VALID( olid2.m_pBar );
ASSERT_KINDOF( CControlBar, olid2.m_pBar );
ASSERT( olid2.m_bVisible );
CControlBar * pBar2 = olid2.m_pBar;
int nPosInternal2 = FindBar( pBar2 );
ASSERT( 0 < nPosInternal2 && nPosInternal2 < m_arrBars.GetSize() );
ASSERT( pBar1 != pBar2 );
ASSERT( nPosInternal1 != nPosInternal2 );
m_arrBars[ nPosInternal1 ] = pBar2;
m_arrBars[ nPosInternal2 ] = pBar1;
OuterLayoutItemData olid = dbol.ElementAt( nIdxGreater );
dbol.RemoveAt( nIdxGreater );
dbol.InsertAt( nIdxLess, olid );
}
bool CExtDockOuterBar::_ReDockToNewRow(
CControlBar * pBarSlide,
MfcControlBarVector_t & vRow,
int nShiftDesired
)
{
ASSERT_VALID( this );
ASSERT_VALID( pBarSlide );
ASSERT( pBarSlide->m_pDockBar == this );
ASSERT( pBarSlide->IsVisible() );
int nCountOfBars = vRow.GetSize();
ASSERT( nCountOfBars > 0 );
UINT nDockBarID = GetDlgCtrlID();
ASSERT_DOCKBAR_DLGCTRLID_DOCKED( nDockBarID );
bool bHorz =
( nDockBarID == AFX_IDW_DOCKBAR_TOP
|| nDockBarID == AFX_IDW_DOCKBAR_BOTTOM )
? TRUE : FALSE;
CRect rcBarSlide, rcBarSlideOrg, rcBarInsertBefore;
pBarSlide->GetWindowRect( &rcBarSlide );
ScreenToClient( &rcBarSlide );
rcBarSlideOrg = rcBarSlide;
int nExtentBarSlideMinPossible = 0;
if( pBarSlide->IsKindOf(RUNTIME_CLASS(CExtControlBar)) )
{
CSize sizeBarSlideMinPossible =
((CExtControlBar*)pBarSlide)->_CalcDesiredMinOuterSize(
bHorz ? TRUE : FALSE );
nExtentBarSlideMinPossible = bHorz
? sizeBarSlideMinPossible.cx
: sizeBarSlideMinPossible.cy
;
} // if( pBarSlide->IsKindOf(RUNTIME_CLASS(CExtControlBar)) )
else
{
CRect rcBar;
pBarSlide->GetWindowRect( &rcBar );
nExtentBarSlideMinPossible = bHorz
? rcBar.Width()
: rcBar.Height()
;
} // else from if( pBarSlide->IsKindOf(RUNTIME_CLASS(CExtControlBar)) )
int nExtentRowMinPossible = 0;
for( int nBar = 0; nBar < nCountOfBars; nBar++ )
{
CControlBar * pBar = vRow[nBar];
ASSERT_VALID( pBar );
ASSERT_KINDOF( CControlBar, pBar );
ASSERT( pBar->IsVisible() );
ASSERT( pBar != pBarSlide );
int nExtentBarMinPossible = 0;
if( pBar->IsKindOf(RUNTIME_CLASS(CExtControlBar)) )
{
CSize sizeBarMinPossible =
((CExtControlBar*)pBar)->_CalcDesiredMinOuterSize(
bHorz ? TRUE : FALSE );
nExtentBarMinPossible = bHorz
? sizeBarMinPossible.cx
: sizeBarMinPossible.cy
;
} // if( pBar->IsKindOf(RUNTIME_CLASS(CExtControlBar)) )
else
{
CRect rcBar;
pBar->GetWindowRect( &rcBar );
nExtentBarMinPossible = bHorz
? rcBar.Width()
: rcBar.Height()
;
} // else from if( pBar->IsKindOf(RUNTIME_CLASS(CExtControlBar)) )
nExtentRowMinPossible += nExtentBarMinPossible;
} // for( int nBar = 0; nBar < nCountOfBars; nBar++ )
CRect rcThisDockerClient;
GetClientRect( &rcThisDockerClient );
int nMaxExtent = bHorz
? rcThisDockerClient.Width()
: rcThisDockerClient.Height()
;
int nExtentRest = nMaxExtent - nExtentRowMinPossible;
if( nExtentRest < nExtentBarSlideMinPossible )
return false;
int nSlidePosStart = bHorz
? rcBarSlide.left
: rcBarSlide.top
;
nSlidePosStart += nShiftDesired;
if( nSlidePosStart < 0 )
{
nShiftDesired += nSlidePosStart;
nSlidePosStart = 0;
}
CControlBar * pBarInsertBefore = NULL;
bool bAppendMode = false;
for( nBar = 0; nBar < nCountOfBars; nBar++ )
{
CControlBar * pBar = vRow[nBar];
ASSERT_VALID( pBar );
ASSERT_KINDOF( CControlBar, pBar );
ASSERT( pBar->IsVisible() );
CRect rcBar;
pBar->GetWindowRect( &rcBar );
ScreenToClient( &rcBar );
int nBarInRowPosStart = bHorz
? rcBar.left
: rcBar.top
;
if( nSlidePosStart <= nBarInRowPosStart )
{
rcBarInsertBefore = rcBar;
pBarInsertBefore = pBar;
} // if( nSlidePosStart <= nBarInRowPosStart )
else
{
int nBarInRowPosEnd = bHorz
? rcBar.right
: rcBar.bottom
;
if( nSlidePosStart <= nBarInRowPosEnd )
{
int nBarInRowPosMid =
(nBarInRowPosEnd + nBarInRowPosStart) / 2;
if( nSlidePosStart <= nBarInRowPosMid )
{
rcBarInsertBefore = rcBar;
pBarInsertBefore = pBar;
break;
}
bAppendMode = true;
break;
} // if( nSlidePosStart <= nBarInRowPosEnd )
else
{
if( pBarInsertBefore != NULL )
break;
bAppendMode = true;
} // else from if( nSlidePosStart <= nBarInRowPosEnd )
} // else from if( nSlidePosStart <= nBarInRowPosStart )
} // for( nBar = 0; nBar < nCountOfBars; nBar++ )
if( pBarInsertBefore == NULL
&& (!bAppendMode)
)
return false;
int nBarPos = FindBar( pBarSlide );
ASSERT( 0 < nBarPos && nBarPos < m_arrBars.GetSize() );
if( m_arrBars[nBarPos-1] == NULL
&& m_arrBars[nBarPos+1] == NULL
)
m_arrBars.RemoveAt( nBarPos+1 );
m_arrBars.RemoveAt( nBarPos );
if( pBarInsertBefore != NULL )
{
if( bHorz )
{
rcBarSlide.OffsetRect(
nShiftDesired,
rcBarInsertBefore.top - rcBarSlide.top
);
if( rcBarInsertBefore.left < rcBarSlide.left )
rcBarSlide.OffsetRect(
rcBarInsertBefore.left - rcBarSlide.left,
0
);
} // if( bHorz )
else
{
rcBarSlide.OffsetRect(
rcBarInsertBefore.left - rcBarSlide.left,
nShiftDesired
);
if( rcBarInsertBefore.top < rcBarSlide.top )
rcBarSlide.OffsetRect(
0,
rcBarInsertBefore.top - rcBarSlide.top
);
} // else from if( bHorz )
nBarPos = FindBar( pBarInsertBefore );
ASSERT( 0 < nBarPos && nBarPos < m_arrBars.GetSize() );
m_arrBars.InsertAt( nBarPos, pBarSlide );
ASSERT_VALID( this );
} // if( pBarInsertBefore != NULL )
else
{
ASSERT( bAppendMode );
pBarInsertBefore = vRow[nCountOfBars-1];
ASSERT_VALID( pBarInsertBefore );
ASSERT_KINDOF( CControlBar, pBarInsertBefore );
ASSERT( pBarInsertBefore->IsVisible() );
pBarInsertBefore->GetWindowRect( &rcBarInsertBefore );
ScreenToClient( &rcBarInsertBefore );
if( bHorz )
{
rcBarSlide.OffsetRect(
nShiftDesired,
rcBarInsertBefore.top - rcBarSlide.top
);
if( rcBarSlide.left < rcBarInsertBefore.right )
rcBarSlide.OffsetRect(
rcBarInsertBefore.right - rcBarSlide.left,
0
);
} // if( bHorz )
else
{
rcBarSlide.OffsetRect(
rcBarInsertBefore.left - rcBarSlide.left,
nShiftDesired
);
if( rcBarSlide.top < rcBarInsertBefore.bottom )
rcBarSlide.OffsetRect(
0,
rcBarInsertBefore.bottom - rcBarSlide.top
);
} // else from if( bHorz )
nBarPos = FindBar( pBarInsertBefore );
ASSERT( 0 < nBarPos && nBarPos < m_arrBars.GetSize() );
m_arrBars.InsertAt( nBarPos+1, pBarSlide );
ASSERT_VALID( this );
} // else from if( pBarInsertBefore != NULL )
if( rcBarSlideOrg != rcBarSlide )
pBarSlide->SetWindowPos(
NULL,
rcBarSlide.left, rcBarSlide.top,
rcBarSlide.Width(), rcBarSlide.Height(),
SWP_NOZORDER|SWP_NOACTIVATE
|SWP_NOSENDCHANGING
|SWP_NOREDRAW|SWP_NOCOPYBITS
);
return true;
}
void CExtDockOuterBar::_AlignSubRowAffixmentHW(
bool bHorz,
CExtDockOuterBar::dockbar_outer_layout_t & dbol,
int nSubRowStartPos,
int nSubRowEndPos
)
{
ASSERT_VALID(this);
ASSERT( dbol.GetSize() > 0 );
ASSERT( nSubRowStartPos <= nSubRowEndPos );
ASSERT( 0 <= nSubRowStartPos && nSubRowStartPos < dbol.GetSize() );
ASSERT( 0 <= nSubRowEndPos && nSubRowEndPos < dbol.GetSize() );
if( nSubRowStartPos == nSubRowEndPos )
return;
int nIdxToAlignFirst = -1;
int nIdxToAlignLast = -1;
int nTotalAffixmentExtentHW = -1;
for( int nBar = nSubRowStartPos; nBar <= nSubRowEndPos; nBar++ )
{
OuterLayoutItemData & olid = dbol.ElementAt( nBar );
ASSERT_VALID( olid.m_pBar );
ASSERT_KINDOF( CControlBar, olid.m_pBar );
ASSERT( olid.m_bVisible );
CExtControlBar * pExtBar =
DYNAMIC_DOWNCAST(
CExtControlBar,
olid.m_pBar
);
if( pExtBar == NULL )
continue;
if( !pExtBar->_AffixmentIsAlignedHW() )
continue;
ASSERT( pExtBar->_AffixmentGetOuter() != NULL );
int nBarAffixmentExtentHW = bHorz
? olid.m_rcPreCalc.Height()
: olid.m_rcPreCalc.Width()
;
nTotalAffixmentExtentHW =
max( nTotalAffixmentExtentHW, nBarAffixmentExtentHW );
if( nIdxToAlignFirst < 0 )
{
ASSERT( nIdxToAlignLast < 0 );
nIdxToAlignFirst = nIdxToAlignLast = nBar;
continue;
}
ASSERT( nIdxToAlignFirst >= nSubRowStartPos );
ASSERT( nIdxToAlignFirst <= nIdxToAlignLast );
nIdxToAlignLast = nBar;
} // for( int nBar = nSubRowStartPos; nBar <= nSubRowEndPos; nBar++ )
ASSERT( nIdxToAlignFirst <= nIdxToAlignLast );
if( nTotalAffixmentExtentHW < 0
|| nIdxToAlignFirst == nIdxToAlignLast
)
return;
ASSERT( nSubRowStartPos <= nIdxToAlignFirst && nIdxToAlignFirst <= nSubRowEndPos );
ASSERT( nSubRowStartPos <= nIdxToAlignLast && nIdxToAlignLast <= nSubRowEndPos );
for( nBar = nIdxToAlignFirst; nBar <= nIdxToAlignLast; nBar++ )
{
OuterLayoutItemData & olid = dbol.ElementAt( nBar );
ASSERT_VALID( olid.m_pBar );
ASSERT_KINDOF( CControlBar, olid.m_pBar );
ASSERT( olid.m_bVisible );
CExtControlBar * pExtBar =
DYNAMIC_DOWNCAST(
CExtControlBar,
olid.m_pBar
);
if( pExtBar == NULL )
continue;
if( !pExtBar->_AffixmentIsAlignedHW() )
continue;
ASSERT( pExtBar->_AffixmentGetOuter() != NULL );
CRect & rcPreCalc = olid.m_rcPreCalc;
if( bHorz )
rcPreCalc.bottom = rcPreCalc.top + nTotalAffixmentExtentHW;
else
rcPreCalc.right = rcPreCalc.left + nTotalAffixmentExtentHW;
} // for( nBar = nIdxToAlignFirst; nBar <= nIdxToAlignLast; nBar++ )
}
void CExtDockOuterBar::_CalcAffixmentOrderVector(
bool bHorz,
AffixmentOrderVector_t & arrAffixmentOrder,
CExtDockOuterBar::dockbar_outer_layout_t & dbol,
bool bResetAffixmentDataIfNeeded, // = false
int nSubRowStartPos, // = 0
int nSubRowEndPos // = -1
)
{
ASSERT_VALID(this);
if( arrAffixmentOrder.GetSize() > 0 )
arrAffixmentOrder.RemoveAll();
if( dbol.GetSize() == 0 )
return;
ASSERT( 0 <= nSubRowStartPos && nSubRowStartPos < dbol.GetSize() );
if( nSubRowEndPos < 0 )
nSubRowEndPos = dbol.GetSize() - 1;
ASSERT( 0 <= nSubRowEndPos && nSubRowEndPos < dbol.GetSize() );
ASSERT( nSubRowStartPos <= nSubRowEndPos );
int nResetAffixmentWeight =
dbol.GetSize() + nSubRowStartPos + 1;
for( int nBar = nSubRowStartPos; nBar <= nSubRowEndPos; nBar++ )
{
OuterLayoutItemData & olid = dbol.ElementAt( nBar );
ASSERT_VALID( olid.m_pBar );
ASSERT_KINDOF( CControlBar, olid.m_pBar );
ASSERT( olid.m_bVisible );
CExtControlBar * pExtBar =
DYNAMIC_DOWNCAST(
CExtControlBar,
olid.m_pBar
);
if( pExtBar == NULL )
{
arrAffixmentOrder.Add( nBar );
continue;
}
CExtControlBar::InternalAffixmentData * pAffixmentData =
pExtBar->_AffixmentGetOuter();
if( pAffixmentData == NULL )
{
arrAffixmentOrder.Add( nBar );
continue;
}
if( pAffixmentData->IsEmpty() )
{
if( bResetAffixmentDataIfNeeded )
pAffixmentData->m_nAffixmentWeight = nResetAffixmentWeight++;
else
{
arrAffixmentOrder.Add( nBar );
continue;
} // else from if( bResetAffixmentDataIfNeeded )
} // if( pAffixmentData->IsEmpty() )
if( pAffixmentData->m_rcAffixment.IsRectEmpty() )
{
if( bResetAffixmentDataIfNeeded )
pAffixmentData->m_rcAffixment = olid.m_rcReal;
else
{
arrAffixmentOrder.Add( nBar );
continue;
} // else from if( bResetAffixmentDataIfNeeded )
} // if( pAffixmentData->m_rcAffixment.IsRectEmpty() )
if( bResetAffixmentDataIfNeeded )
{
if( bHorz )
{
if( pAffixmentData->m_sizeCompressed.cx == 0 )
pAffixmentData->m_sizeCompressed.cx =
olid.m_rcReal.Width();
if( pAffixmentData->m_sizeCompressed.cx > olid.m_sizeCalcDynamic.cx )
pAffixmentData->m_sizeCompressed.cx = olid.m_sizeCalcDynamic.cx;
} // if( bHorz )
else
{
if( pAffixmentData->m_sizeCompressed.cy == 0 )
pAffixmentData->m_sizeCompressed.cy =
olid.m_rcReal.Height();
if( pAffixmentData->m_sizeCompressed.cy > olid.m_sizeCalcDynamic.cy )
pAffixmentData->m_sizeCompressed.cy = olid.m_sizeCalcDynamic.cy;
} // else from if( bHorz )
} // if( bResetAffixmentDataIfNeeded )
if( arrAffixmentOrder.GetSize() == 0 )
{
arrAffixmentOrder.Add( nBar );
continue;
}
int nReviewCount = nBar - nSubRowStartPos;
ASSERT( nReviewCount > 0 );
ASSERT( arrAffixmentOrder.GetSize() == nReviewCount );
for( int nOrder = 0; nOrder < nReviewCount; nOrder++ )
{
int nBarAtOrder = arrAffixmentOrder[nOrder];
ASSERT( nBarAtOrder < nBar );
OuterLayoutItemData & olid2 = dbol.ElementAt( nBarAtOrder );
ASSERT_VALID( olid2.m_pBar );
ASSERT( olid.m_pBar != olid2.m_pBar );
ASSERT_KINDOF( CControlBar, olid2.m_pBar );
ASSERT( olid2.m_bVisible );
CExtControlBar * pExtBar2 =
DYNAMIC_DOWNCAST(
CExtControlBar,
olid2.m_pBar
);
if( pExtBar2 == NULL )
{
arrAffixmentOrder.InsertAt( nOrder, nBar );
break;
}
CExtControlBar::InternalAffixmentData * pAffixmentData2 =
pExtBar2->_AffixmentGetOuter();
if( pAffixmentData2 == NULL )
{
arrAffixmentOrder.InsertAt( nOrder, nBar );
break;
}
ASSERT( !pAffixmentData2->IsEmpty() );
// TO FIX: affixment recalc afrer tooggling docked/floating state
// ASSERT(
// pAffixmentData2->m_nAffixmentWeight
// != pAffixmentData->m_nAffixmentWeight
// );
if( pAffixmentData2->m_nAffixmentWeight
> pAffixmentData->m_nAffixmentWeight
)
{
arrAffixmentOrder.InsertAt( nOrder, nBar );
break;
}
if( nOrder == (nReviewCount - 1) )
{
arrAffixmentOrder.Add( nBar );
break;
}
} // for( int nOrder = 0; nOrder < nReviewCount; nOrder++ )
ASSERT( arrAffixmentOrder.GetSize() == (nReviewCount + 1) );
} // for( int nBar = nSubRowStartPos; nBar <= nSubRowEndPos; nBar++ )
ASSERT( arrAffixmentOrder.GetSize() == (nSubRowEndPos-nSubRowStartPos+1) );
}