Click here to Skip to main content
12,956,234 members (57,867 online)
Click here to Skip to main content

Stats

2.2M views
21.7K downloads
634 bookmarked
Posted 29 May 2002

Professional User Interface Suite

, 13 Jan 2004
MFC extension library enabling software to be provided with a professional UI
Prof-UIS
Bin_600
Bin_700
Bin_710
Include
profuisdll
idd_ext_color_dlg.ico
profuisdll.def
profuisdll_600.dsp
profuisdll_600.dsw
res
black_arrow_bottom.cur
black_arrow_left.cur
black_arrow_right.cur
black_arrow_top.cur
cmd00001.cur
cmd00002.cur
cmd00003.cur
cur_arrow_invert.cur
cur_black_finger.cur
cur_black_hand.cur
cur_hand_like.cur
cur_pan_all.cur
cur_pan_bottom.cur
cur_pan_bottom_left.cur
cur_pan_bottom_right.cur
cur_pan_horz.cur
cur_pan_left.cur
cur_pan_right.cur
cur_pan_top.cur
cur_pan_top_left.cur
cur_pan_top_right.cur
cur_pan_vert.cur
cur_resize_h1.cur
cur_resize_h2.cur
cur_resize_v1.cur
cur_resize_v2.cur
cur00001.cur
cur00002.cur
cur00003.cur
cur00004.cur
hollow_cross_normal.cur
hollow_cross_small.cur
ico00001.ico
id_view_.bmp
idd_ext_.ico
idd_icon.ico
ied_cp.cur
ied_el.cur
ied_fill.cur
ied_line.cur
ied_pen.cur
ied_rect.cur
ied_tool.cur
suppress.cur
suppress_arrow.cur
toolbar_.bmp
zoom_hollow.cur
zoom_minus.cur
zoom_plus.cur
profuislib
profuislib_600.dsp
profuislib_600.dsw
Samples
AviFrames
AviFrames_600.dsp
res
AviFrames.ico
CINEAPK.AVI
IDR_TOOLBAR_PLAYER.bmp
IDR_TOOLBAR_UISTYLE.bmp
Toolbar.bmp
toolbar2.bmp
xptheme.bin
DRAWCLI
DRAWCLI_600.dsp
L.JPN
RES
res
DRAWCLI.ICO
DRAWDOC.ICO
ico00001.ico
ico00002.ico
ico00003.ico
ico00004.ico
ico00005.ico
ico00006.ico
ico00007.ico
ico00008.ico
icon1.ico
id_objec.ico
id_scppv.ico
idr_abou.ico
PENCIL.CUR
TOOLBAR_1_16bit.bmp
TOOLBAR_1_4bit.bmp
TOOLBAR_2_16bit.bmp
TOOLBAR_2_4bit.bmp
FixedSizePanels
FixedSizePanels_600.dsp
res
bitmap_t.bmp
FixedSizePanels.ico
Toolbar.bmp
toolbar2.bmp
FullScreenState
FullScreenState_600.dsp
res
FullScreenState.ico
idr_mdit.ico
Toolbar.bmp
toolbar1.bmp
toolbar2.bmp
toolbar4.bmp
FunnyBars
FunnyBars_600.dsp
res
FunnyBars.ico
Toolbar.bmp
toolbar_16_16_8.bmp
toolbar_44_40_32.bmp
winXP.manifest
GLViews
GLViews_600.dsp
res
bitmap_i.bmp
bitmap_s.bmp
bitmap_t.bmp
bmp00001.bmp
btpnlane.bmp
CINEAPK.AVI
cur00001.cur
cur00002.cur
cursor_g.cur
earth.bmp
GLViews.ico
moon.bmp
ProfUisCubeSideOrange.bmp
ProfUisCubeSideWhite.bmp
ring.bmp
Toolbar.bmp
toolbar_.bmp
toolbar2.bmp
wndavipl.bmp
wndmirror.bmp
res_html
bodytop.gif
book_close.gif
book_open.gif
MDI
MDI_600.dsp
res
idr_mdit.ico
MDI.ico
Toolbar.bmp
toolbar2.bmp
MDI_InnerOuterBars
MDI_InnerOuterBars_600.dsp
res
bmp00001.bmp
idr_mdit.ico
MDI_InnerOuterBars.ico
Toolbar.bmp
toolbar_.bmp
toolbar2.bmp
MDIDOCVIEW
MDIDOCVIEW_600.dsp
res
MDIDOCVIEW.ico
MDIDOCVIEWDoc.ico
Toolbar.bmp
MthOutput
MthOutput_600.dsp
res
idr_mdit.ico
MthOutput.ico
Toolbar.bmp
toolbar1.bmp
toolbar2.bmp
ProfUIS_Controls
ProfUIS_Controls_600.dsp
res
bitmap1.bmp
bitmap2.bmp
icon1.ico
ProfUIS_Controls.ico
tab_imag.bmp
toolbar1.bmp
ResizableChildSheet
res
idr_chil.ico
ResizableChildSheet.ico
Toolbar.bmp
ResizableChildSheet_600.dsp
ResizablePropertySheet
res
bitmap1.bmp
bitmap2.bmp
ResizablePropertySheet.ico
ResizablePropertySheet_600.dsp
SDI
res
SDI.ico
Toolbar.bmp
toolbar2.bmp
SDI_600.dsp
SDIDOCVIEW
res
SDIDOCVIEW.ico
SDIDOCVIEWDoc.ico
Toolbar.bmp
SDIDOCVIEW_600.dsp
StateInFile
res
StateInFile.ico
Toolbar.bmp
StateInFile_600.dsp
StatusPanes
res
download.avi
StatusPanes.ico
Toolbar.bmp
toolbar2.bmp
StatusPanes_600.dsp
Src
Workspace
ProfUIS_600.dsw
Include
profuisdll
idd_ext_color_dlg.ico
profuisdll.def
profuisdll.dsp
res
profuislib
profuislib.dsp
Samples
DRAWCLI
MDI
MDIDOCVIEW
MDI_InnerOuterBars
ProfUIS_Controls
ResizablePropertySheet
SDI
SDIDOCVIEW
StateInFile
DRAWCLI.dsp
L.JPN
res
RES
DRAWCLI.ICO
DRAWDOC.ICO
ico00001.ico
ico00002.ico
icon1.ico
id_objec.ico
PENCIL.CUR
TOOLBAR.BMP
MDI.dsp
res
idr_mdit.ico
MDI.ico
Toolbar.bmp
toolbar2.bmp
MDIDOCVIEW.dsp
res
MDIDOCVIEW.ico
MDIDOCVIEWDoc.ico
Toolbar.bmp
MDI_InnerOuterBars.dsp
res
bmp00001.bmp
idr_mdit.ico
MDI_InnerOuterBars.ico
Toolbar.bmp
toolbar2.bmp
toolbar_.bmp
ProfUIS_Controls.dsp
res
bitmap1.bmp
bitmap2.bmp
icon1.ico
ProfUIS_Controls.ico
tab_imag.bmp
toolbar1.bmp
res
ResizablePropertySheet.dsp
ResizablePropertySheet.ico
res
SDI.dsp
SDI.ico
Toolbar.bmp
toolbar2.bmp
res
SDIDOCVIEW.dsp
SDIDOCVIEW.ico
SDIDOCVIEWDoc.ico
Toolbar.bmp
res
StateInFile.dsp
StateInFile.ico
Toolbar.bmp
Src
Workspace
ProfUIS.dsw
ProfUIS.suo
Bin
MDI.exe
ProfUIS21.dll
ProfUIS_Controls.exe
SDI.exe
StateInFile.exe
idd_ext_color_dlg.ico
profuisdll.aps
profuisdll.clw
profuisdll.def
profuisdll.dep
profuisdll.dsp
profuisdll.mak
profuisdll.plg
MDI.APS
MDI.clw
MDI.dep
MDI.dsp
MDI.mak
MDI.plg
idr_mdit.ico
MDI.ico
Toolbar.bmp
toolbar2.bmp
ProfUIS_Controls.aps
ProfUIS_Controls.clw
ProfUIS_Controls.dep
ProfUIS_Controls.dsp
ProfUIS_Controls.mak
ProfUIS_Controls.ico
toolbar1.bmp
SDI.APS
SDI.clw
SDI.dep
SDI.dsp
SDI.mak
SDI.plg
SDI.ico
Toolbar.bmp
toolbar2.bmp
StateInFile.aps
StateInFile.clw
StateInFile.dep
StateInFile.dsp
StateInFile.mak
StateInFile.plg
StateInFile.ico
Toolbar.bmp
ProfUIS.dsw
ProfUIS.ncb
ProfUIS.opt
// 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.

// extcontrolbar.cpp : implementation file
//

#include "stdafx.h"

//
// Many thanks to Paul DiLascia & Cristi Posea, their works
// were a powerful incentive to learn more about pretty
// complicated MFC docking windows mechanism
//

#if (!defined __EXT_CONTROLBAR_H)
	#include <ExtControlBar.h>
#endif

#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( !defined __EXTMINIDOCKFRAMEWND_H)
	#include "ExtMiniDockFrameWnd.h"
#endif

#if (!defined __ExtCmdManager_H)
	#include <ExtCmdManager.h>
#endif

#if (!defined __EXT_MEMORY_DC_H)
	#include <../Src/ExtMemoryDC.h>
#endif

#if (!defined __EXT_LOCALIZATION_H)
	#include <../Src/ExtLocalization.h>
#endif

#include <../profuisdll/resource.h>

#if (!defined __AFXPRIV_H__)
	#include <AfxPriv.h>
#endif 

#if _MFC_VER < 0x700
	#include <../src/AfxImpl.h>
#else
	#ifndef __AFXSTATE_H__
		#include <../src/mfc/afxstat_.h>
	#endif
	#include <../src/mfc/AfxImpl.h>
#endif

#ifndef __AFXOLE_H__
	#include <AfxOle.h>
#endif 

#if (!defined __EXT_MFC_NO_CUSTOMIZE)
	#if (!defined __EXTCUSTOMIZE_H)
		#include <ExtCustomize.h>
	#endif
#endif // (!defined __EXT_MFC_NO_CUSTOMIZE)

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

#define __DOCKSITE_DCX_FLAGS \
	( DCX_WINDOW \
		|DCX_CACHE \
		|DCX_LOCKWINDOWUPDATE \
		|DCX_CLIPSIBLINGS \
	)

#define __PLACEHODLER_BAR_PTR( __CB__ ) \
	( (HIWORD(__CB__) ) == 0 )

#define __BAR_NC_GAP_X 1 //afxData.cxBorder2
#define __BAR_NC_GAP_Y 1 //afxData.cyBorder2

#define __DOCKING_SIDE_GAP 10

static HCURSOR g_hCursorArrow	= ::LoadCursor(NULL,IDC_ARROW);
static HCURSOR g_hCursorDrag	= ::LoadCursor(NULL,IDC_SIZEALL);
static HCURSOR g_hCursorResizeV	= ::LoadCursor(NULL,IDC_SIZENS);
static HCURSOR g_hCursorResizeH	= ::LoadCursor(NULL,IDC_SIZEWE);

/////////////////////////////////////////////////////////////////////////////
// CExtControlBar::FriendlyDockBarHack

class CExtControlBar::FriendlyDockBarHack
	: CDockBar
{
public:
	friend class CExtControlBar;
	friend class CExtControlBar::InternalDraggingState_t;

	INT GetCalcExtentMax( BOOL bHorz )
	{
		ASSERT( this != NULL );
		ASSERT_VALID( this );
		ASSERT( m_pDockSite != NULL );
		ASSERT_VALID( m_pDockSite );
		ASSERT_KINDOF( CDockBar, this );
		INT nCalcExtentMax = bHorz
			? m_rectLayout.Width()
			: m_rectLayout.Height();
		ASSERT( nCalcExtentMax >= 0 );
		if( nCalcExtentMax == 0
			|| m_rectLayout.IsRectEmpty()
			)
		{
			CRect rcDock;
			GetClientRect( &rcDock );
			//m_pDockSite->GetClientRect( &rcDock );
			nCalcExtentMax = bHorz
				? rcDock.Width()  // + 2
				: rcDock.Height() // - 2
				;
			//ASSERT( nCalcExtentMax >= 0 );
			if( nCalcExtentMax <= 0 )
				return 3; // dummy choice
		} // if( nCalcExtentMax == 0 )
		return nCalcExtentMax;
	}

	void _InsertBar( INT nPos, CControlBar * pBar )
	{
		ASSERT_VALID( this );
		ASSERT( nPos >= 0 && nPos < m_arrBars.GetSize() );
		m_arrBars.InsertAt( nPos, pBar );
		ASSERT_VALID( this );
#ifdef _DEBUG
		if( pBar != NULL )
		{
			ASSERT_BAR_LOCATION_IN_ROW( this, pBar );
		}
#endif // _DEBUG
	}
	
	void _InsertRowSplitter( INT nPos )
	{
		ASSERT_VALID( this );
		_InsertBar( nPos, NULL );
		ASSERT_VALID( this );
	}

}; // class CExtControlBar::FriendlyDockBarHack

/////////////////////////////////////////////////////////////////////////////
// CExtControlBar::POPUP_MENU_EVENT_DATA

CExtControlBar::POPUP_MENU_EVENT_DATA::POPUP_MENU_EVENT_DATA(
	SHORT nHelperNotificationType,
	CExtPopupMenuWnd * pPopupMenuWnd,
	CWnd * pWndEventSrc,
	const POINT & ptScreen,
	UINT nMsgID, // = WM_NULL
	CObject * pObjectSrc // = NULL
	)
	: m_nHelperNotificationType( nHelperNotificationType )
	, m_pPopupMenuWnd( pPopupMenuWnd )
	, m_pWndEventSrc( pWndEventSrc )
	, m_ptScreen( ptScreen )
	, m_nMsgID( nMsgID )
	, m_pObjectSrc( pObjectSrc )
	, m_pWndInitialTarget( NULL )
	, m_bPostNotification( false )
{
	ASSERT_VALID( m_pPopupMenuWnd );
	ASSERT_VALID( m_pWndEventSrc );
	ASSERT( m_pWndEventSrc->GetSafeHwnd() != NULL );
	ASSERT( ::IsWindow(m_pWndEventSrc->GetSafeHwnd()) );
	if( m_ptScreen.x < 0 || m_ptScreen.y < 0 )
	{
		if( ! ::GetCursorPos( &m_ptScreen ) )
			m_ptScreen.x = m_ptScreen.y = 0;
	}
}

CExtControlBar::POPUP_MENU_EVENT_DATA::~POPUP_MENU_EVENT_DATA()
{
}

bool CExtControlBar::POPUP_MENU_EVENT_DATA::IsControlBarMenuListNotification() const
{
	switch( m_nHelperNotificationType )
	{
	case __PMED_DOCKBAR_CTX:
	case __PMED_CONTROLBAR_CTX:
	case __PMED_CONTROLBAR_NC_CTX:
	case __PMED_STATUSBAR_CTX:
	case __PMED_AUTOHIDESLIDER_CTX:
	case __PMED_MINIFRAME_NC_CTX:
	case __PMED_MDICLIAREA_CTX:
	case __PMED_CONTROLBAR_NCBTNMENU_BARS:
	case __PMED_CTXEXPBTN_BARS:
		return true;
	} // switch( m_nHelperNotificationType )
	return false;
}

CExtControlBar::POPUP_MENU_EVENT_DATA::operator WPARAM() const
{
	return ( (WPARAM) this );
}

CExtControlBar::POPUP_MENU_EVENT_DATA *
	CExtControlBar::POPUP_MENU_EVENT_DATA::FromWParam( WPARAM wParam )
{
	return ( (POPUP_MENU_EVENT_DATA *) wParam );
}

CExtControlBar::POPUP_MENU_EVENT_DATA *
	CExtControlBar::POPUP_MENU_EVENT_DATA::FromMSG( MSG * pMSG )
{
	ASSERT( pMSG != NULL );
	ASSERT( pMSG->message == CExtControlBar::g_nMsgConstructPopupMenu );
	return FromWParam( pMSG->wParam );
}

bool CExtControlBar::POPUP_MENU_EVENT_DATA::NotifyTarget(
	bool bPostNotification
	)
{
	ASSERT_VALID( m_pPopupMenuWnd );
	ASSERT_VALID( m_pWndEventSrc );
	ASSERT( m_pWndEventSrc->GetSafeHwnd() != NULL );
	ASSERT( ::IsWindow(m_pWndEventSrc->GetSafeHwnd()) );
	m_bPostNotification = bPostNotification;
CControlBar * pBar = DYNAMIC_DOWNCAST( CControlBar, m_pWndEventSrc );
	if( pBar != NULL )
		m_pWndInitialTarget = pBar->m_pDockSite;
	if( m_pWndInitialTarget == NULL )
	{
		m_pWndInitialTarget =  m_pWndEventSrc->GetParentFrame();
		if( m_pWndInitialTarget == NULL )
		{
			m_pWndInitialTarget = m_pWndEventSrc->GetParent();
			ASSERT_VALID( m_pWndInitialTarget );
		}
		else if( m_pWndInitialTarget->IsKindOf(RUNTIME_CLASS(CMiniDockFrameWnd)) )
		{
			m_pWndInitialTarget = m_pWndInitialTarget->GetParentFrame();
			ASSERT_VALID( m_pWndInitialTarget );
			ASSERT( ! m_pWndInitialTarget->IsKindOf(RUNTIME_CLASS(CMiniDockFrameWnd)) );
		}
	}
	ASSERT_VALID( m_pWndInitialTarget );
	ASSERT( m_pWndInitialTarget->GetSafeHwnd() != NULL );
	ASSERT( ::IsWindow(m_pWndInitialTarget->GetSafeHwnd()) );
LRESULT lResult =
		m_pWndInitialTarget->SendMessage(
			CExtControlBar::g_nMsgConstructPopupMenu,
			*this
			);
	return (lResult != 0) ? true : false;
}


/////////////////////////////////////////////////////////////////////////////
// CExtControlBar

IMPLEMENT_DYNCREATE( CExtControlBar, CControlBar )

CCriticalSection CExtControlBar::g_csCB;
ExtControlBarVector_t CExtControlBar::g_AllBars;
CExtControlBar::InternalDockBarInfo_t CExtControlBar::g_DockBarInfo;
bool CExtControlBar::g_bEnableOnIdleCalls = false;

#if (!defined __EXT_MFC_NO_TAB_CONTROLBARS)
bool CExtControlBar::g_bAllowAutohideTabsOleDropTarget = true;
bool CExtControlBar::g_bAllowDynamicTabsOleDropTarget = true;
#endif // (!defined __EXT_MFC_NO_TAB_CONTROLBARS)

const UINT CExtControlBar::g_nMsgQueryRepositionCalcEffect =
	::RegisterWindowMessage(
		_T("CExtControlBar::g_nMsgQueryRepositionCalcEffect")
		);
const UINT CExtControlBar::g_nMsgQueryIcon =
	::RegisterWindowMessage(
		_T("CExtControlBar::g_nMsgQueryIcon")
		);
const UINT CExtControlBar::g_nMsgPutToPopupMenu =
	::RegisterWindowMessage(
		_T("CExtControlBar::g_nMsgPutToPopupMenu")
		);
const UINT CExtControlBar::g_nMsgConstructPopupMenu =
	::RegisterWindowMessage(
		_T("CExtControlBar::g_nMsgConstructPopupMenu")
		);
#if (!defined __EXT_MFC_NO_TAB_CONTROLBARS)
const UINT CExtControlBar::g_nMsgCreateTabbedBar =
	::RegisterWindowMessage(
		_T("CExtControlBar::g_nMsgCreateTabbedBar")
		);
#endif // (!defined __EXT_MFC_NO_TAB_CONTROLBARS)


static CExtSafeString productsection2regkeypath(
	__EXT_MFC_SAFE_LPCTSTR sProfileName,
	__EXT_MFC_SAFE_LPCTSTR sSectionNameCompany, // under HKEY_CURRENT_USER\Software
	__EXT_MFC_SAFE_LPCTSTR sSectionNameProduct // under HKEY_CURRENT_USER\Software\%sSectionNameCompany%
	)
{
	return CExtCmdManager::GetSubSystemRegKeyPath(
		__PROF_UIS_REG_CONTROL_BAR,
		sProfileName,
		sSectionNameCompany,
		sSectionNameProduct
		);
}

CExtControlBar::InternalDockBarInfo_t::InternalDockBarInfo_t()
{
	m_mapDockBarInfo.SetAt(
		AFX_IDW_DOCKBAR_TOP,
		CBRS_TOP
		);
	m_mapDockBarInfo.SetAt(
		AFX_IDW_DOCKBAR_BOTTOM,
		CBRS_BOTTOM
		);
	m_mapDockBarInfo.SetAt(
		AFX_IDW_DOCKBAR_LEFT,
		CBRS_LEFT
		);
	m_mapDockBarInfo.SetAt(
		AFX_IDW_DOCKBAR_RIGHT,
		CBRS_RIGHT
		);
}

DWORD CExtControlBar::InternalDockBarInfo_t::operator[]( UINT nDockBarID )
{
	DWORD dwStyle = 0;
	VERIFY( m_mapDockBarInfo.Lookup(nDockBarID,dwStyle) );
	return dwStyle;
}

bool CExtControlBar::InternalDockBarInfo_t::ReplaceFrameDockBar(
	UINT nDockBarID,
	DWORD dwDockStyle,
	CFrameWnd * pFrame
	)
{
	ASSERT_VALID(pFrame);

	ASSERT((dwDockStyle & ~(CBRS_ALIGN_ANY|CBRS_FLOAT_MULTI)) == 0);

DWORD dwDockBarStyle = (*this)[nDockBarID];
	if( (dwDockBarStyle&dwDockStyle&CBRS_ALIGN_ANY) == 0 )
		return false;
	
CDockBar * pDockBar = (CDockBar*)
		pFrame->GetControlBar(nDockBarID);
	ASSERT_VALID( pDockBar );
	ASSERT_KINDOF( CDockBar, pDockBar );
	if( pDockBar->IsKindOf(
			RUNTIME_CLASS(CExtDockOuterBar)
			)
		)
		return true;

BOOL bExplicitDelete = !pDockBar->m_bAutoDelete;
	pDockBar->m_pDockSite->RemoveControlBar( pDockBar );
	pDockBar->m_pDockSite = NULL;
	pDockBar->DestroyWindow();
	if( bExplicitDelete )
		delete pDockBar;
	pDockBar = new CExtDockOuterBar();
	DWORD dwStyle =
		WS_CHILD|WS_VISIBLE|WS_CLIPSIBLINGS|WS_CLIPCHILDREN
		|dwDockBarStyle;
	if(	!pDockBar->Create( pFrame, dwStyle, nDockBarID ) )
	{
		ASSERT( FALSE );
		return false;
	}

	return true;
}

CExtControlBar::CExtControlBar()
	: m_bGripperStaticallyAtTop( true )
	, m_bAllowContractExpand( true )
	, m_bDoNotEraseClientBackground( false )
	, m_bPresubclassDialogMode( false )
	, m_bReflectParentSizing( true )
	, m_bInCustomModeUpdateCmdUI( false )
	, m_bFixedMode( false )
	, m_bAppearInDockSiteControlBarPopupMenu( true )
	, m_nGripHeightAtTop( ::GetSystemMetrics(SM_CYSMCAPTION)+1 )
	, m_nGripWidthAtLeft( ::GetSystemMetrics(SM_CYSMCAPTION)+1 )
	, m_nSeparatorHeight( min( 4, ::GetSystemMetrics(SM_CYSIZEFRAME) ) )
	, m_nSeparatorWidth(  min( 4, ::GetSystemMetrics(SM_CXSIZEFRAME) ) )
	, m_nMinHW( ::GetSystemMetrics(SM_CYSMCAPTION)+1 + m_nSeparatorHeight )
	, m_nMinVH( ::GetSystemMetrics(SM_CYSMCAPTION)+1 + m_nSeparatorHeight )
	, m_nTrackerOffset( 0 )
	, m_nMetricOffset( 0 )
	, m_sizeDockedH( 200, 150 )
	, m_sizeDockedV( 150, 200 )
	, m_sizeFloated( 200, 200 )
	, m_bRowResizing( false )
	, m_bRowRecalcing( false )
	, m_bDragging( false )
	, m_bReposSingleChildMode( true )
	, m_ptHelperDragOffsetFloated( 0, 0 )
	, m_ptHelperDragOffsetDockedH( 0, 0 )
	, m_ptHelperDragOffsetDockedV( 0, 0 )
	, m_ptFloatHelper( 0, 0 )
	, m_bWindowActive( false )
	, m_bTopRecalcing( false )
	, m_bNcAreaBtnTracking( false )
#if (!defined __EXT_MFC_NO_TAB_CONTROLBARS)
	, m_bAutoHideMode( false )
#endif // (!defined __EXT_MFC_NO_TAB_CONTROLBARS)
	, m_ptDraggingLast( -1, -1 )
	, m_bUpdatingChain( false )
	, m_nDelayedRowUpdateMetric( 0 )
#if (!defined __EXT_MFC_NO_CUSTOMIZE)
	, m_bVisibleInCustomizeListBox( false )
#endif // (!defined __EXT_MFC_NO_CUSTOMIZE)
{
	VERIFY( RegisterControlBarClass() );

CSingleLock _slCsCB( &g_csCB );
	_slCsCB.Lock();
	g_AllBars.Add( this );
	_slCsCB.Unlock();
}

CExtControlBar::~CExtControlBar()
{
CSingleLock _slCsCB( &g_csCB );
	_slCsCB.Lock();
INT nCountOfExtBars = g_AllBars.GetSize();
	for( INT nExtBar = 0; nExtBar < nCountOfExtBars; nExtBar++ )
	{
		CExtControlBar * pBar = g_AllBars[ nExtBar ];
		ASSERT( pBar != NULL );
		if( pBar == this )
		{
			g_AllBars.RemoveAt( nExtBar );
			break;
		}
	} // for( INT nExtBar = 0; nExtBar < nCountOfExtBars; nExtBar++ )
	_slCsCB.Unlock();

	NcButtons_RemoveAll();
}


BEGIN_MESSAGE_MAP(CExtControlBar, CControlBar)
	//{{AFX_MSG_MAP(CExtControlBar)
	ON_WM_NCHITTEST()
	ON_WM_NCCALCSIZE()
	ON_WM_NCPAINT()
	ON_WM_CANCELMODE()
	ON_WM_CAPTURECHANGED()
	ON_WM_MOUSEMOVE()
	ON_WM_NCLBUTTONDOWN()
	ON_WM_NCLBUTTONUP()
    ON_WM_LBUTTONDOWN()
	ON_WM_LBUTTONUP()
    ON_WM_LBUTTONDBLCLK()
	ON_WM_RBUTTONUP()
	ON_WM_SIZE()
	ON_WM_NCLBUTTONDBLCLK()
	ON_WM_NCRBUTTONUP()
	ON_WM_SHOWWINDOW()
	ON_WM_SETFOCUS()
	//}}AFX_MSG_MAP
    ON_MESSAGE(WM_SETTEXT, OnSetText)
	ON_MESSAGE(WM_SIZEPARENT, OnSizeParent)
	ON_MESSAGE(WM_HELPHITTEST, OnHelpHitTest)
	ON_WM_SYSCOLORCHANGE()
	__EXT_MFC_SAFE_ON_WM_SETTINGCHANGE()
	ON_MESSAGE(WM_DISPLAYCHANGE, OnDisplayChange)
	ON_MESSAGE(__ExtMfc_WM_THEMECHANGED, OnThemeChanged)
END_MESSAGE_MAP()


BOOL CExtControlBar::Create(
	__EXT_MFC_SAFE_LPCTSTR lpszWindowName,
	CWnd * pParentWnd,
    UINT nID, // = AFX_IDW_DIALOGBAR
	DWORD dwStyle // =
		//WS_CHILD|WS_VISIBLE
		//|CBRS_TOP|CBRS_GRIPPER|CBRS_TOOLTIPS
		//|CBRS_FLYBY|CBRS_SIZE_DYNAMIC
		//|CBRS_HIDE_INPLACE
	)
{
    ASSERT_VALID( pParentWnd );
 
	if( !RegisterControlBarClass() )
	{
		ASSERT( FALSE );
		return FALSE;
	}
	
	ASSERT(
		!((dwStyle & CBRS_SIZE_FIXED)
		&&
        (dwStyle & CBRS_SIZE_DYNAMIC))
		);
    m_dwStyle = dwStyle & CBRS_ALL;

CExtSafeString sWindowName(
		(lpszWindowName != NULL)
			? lpszWindowName : _T("")
		);
	if( lpszWindowName == NULL && nID != 0 && nID != UINT(-1) )
	{
		CExtCmdItem * pCmdItem =
			g_CmdManager->CmdGetPtr(
				g_CmdManager->ProfileNameFromWnd( pParentWnd->GetSafeHwnd() ),
				nID
				);
		if( pCmdItem != NULL )
		{
			sWindowName = pCmdItem->m_sMenuText;
			sWindowName.Replace( _T("&"), _T("") );
		}
		else
		{
			if( !sWindowName.LoadString(nID	) )
				sWindowName = _T("");
		}
	}
	if( !sWindowName.IsEmpty() )
	{
		int nNlPos = sWindowName.Find( _T('\n') );
		if( nNlPos >= 0 )
			sWindowName = sWindowName.Left( nNlPos );
	}
    
	dwStyle &= ~CBRS_ALL;
    dwStyle |= WS_CLIPCHILDREN;
CExtSafeString sWndClassName(
		::AfxRegisterWndClass(
			CS_DBLCLKS,
			g_hCursorArrow,
			g_PaintManager->GetBrush( COLOR_BTNFACE ),
			0
			)
		);

	if(	!CWnd::Create(
			sWndClassName,
			sWindowName.IsEmpty() ? _T("") : sWindowName,
			dwStyle,
			CRect( 0, 0, 0, 0 ),
			pParentWnd,
			nID
			)
		)
	{
		ASSERT( FALSE );
        return FALSE;
	}
    return TRUE;
}

bool CExtControlBar::_SetupFloatingFrameWndImpl(
	CFrameWnd * pFrame
	)	
{
	ASSERT( pFrame != NULL );
	return
		((CExtControlBar::InternalFriendlyFrameWnd *)pFrame)->
			SetupSmilyFrameWnd();
}

bool CExtControlBar::_FrameEnableDockingImpl(
	CFrameWnd * pFrame,
	DWORD dwDockStyle, // = CBRS_ALIGN_ANY
	bool bReplaceFloatingWnd // = true
	) 
{
	// NOTE: this rule is specific for current implementation
	ASSERT( dwDockStyle == CBRS_ALIGN_ANY );

	ASSERT_VALID(pFrame);
	ASSERT((dwDockStyle & ~(CBRS_ALIGN_ANY|CBRS_FLOAT_MULTI)) == 0);

	pFrame->EnableDocking( dwDockStyle );
	
	if(	!g_DockBarInfo.ReplaceFrameDockBar(
			AFX_IDW_DOCKBAR_TOP,
			dwDockStyle,
			pFrame
			)
		)
	{
		ASSERT( FALSE );
		return false;
	}
	if(	!g_DockBarInfo.ReplaceFrameDockBar(
			AFX_IDW_DOCKBAR_BOTTOM,
			dwDockStyle,
			pFrame
			)
		)
	{
		ASSERT( FALSE );
		return false;
	}
	if(	!g_DockBarInfo.ReplaceFrameDockBar(
			AFX_IDW_DOCKBAR_LEFT,
			dwDockStyle,
			pFrame
			)
		)
	{
		ASSERT( FALSE );
		return false;
	}
	if(	!g_DockBarInfo.ReplaceFrameDockBar(
			AFX_IDW_DOCKBAR_RIGHT,
			dwDockStyle,
			pFrame
			)
		)
	{
		ASSERT( FALSE );
		return false;
	}

	if( bReplaceFloatingWnd )
	{
		if( !_SetupFloatingFrameWndImpl( pFrame ) )
		{
			ASSERT( FALSE );
			return false;
		}
	}

	return true;
}

bool CExtControlBar::FrameEnableDocking(
	CFrameWnd * pFrame,
	DWORD dwDockStyle, // = CBRS_ALIGN_ANY
	bool bReplaceFloatingWnd // = true
	) 
{
	return
		_FrameEnableDockingImpl(
			pFrame,
			dwDockStyle,
			bReplaceFloatingWnd
			);
}

#if (!defined __EXT_MFC_NO_TAB_CONTROLBARS)
bool CExtControlBar::FrameInjectAutoHideAreas(
	CFrameWnd * pFrame
	) 
{
	return _FrameInjectAutoHideAreasImpl( pFrame );
}

bool CExtControlBar::_FrameInjectAutoHideAreasImpl(
	CFrameWnd * pFrame
	) 
{
	ASSERT_VALID( pFrame );
	ASSERT( pFrame->GetSafeHwnd() != NULL );
	ASSERT( ::IsWindow(pFrame->GetSafeHwnd()) );

CExtDynAutoHideSlider * pWndSlider = new CExtDynAutoHideSlider;
	if(	!pWndSlider->Create( pFrame ) )
	{
		ASSERT( FALSE );
		return false;
	}

CExtDynAutoHideArea * pWndAutoHideArea =
		new CExtDynAutoHideArea();
	if(	!pWndAutoHideArea->Create(
			pFrame,
			pWndSlider,
			AFX_IDW_DOCKBAR_TOP
			)
		)
	{
		ASSERT( FALSE );
		return false;
	}

	pWndAutoHideArea =
		new CExtDynAutoHideArea();
	if(	!pWndAutoHideArea->Create(
			pFrame,
			pWndSlider,
			AFX_IDW_DOCKBAR_BOTTOM
			)
		)
	{
		ASSERT( FALSE );
		return false;
	}
	
	pWndAutoHideArea =
		new CExtDynAutoHideArea();
	if(	!pWndAutoHideArea->Create(
			pFrame,
			pWndSlider,
			AFX_IDW_DOCKBAR_LEFT
			)
		)
	{
		ASSERT( FALSE );
		return false;
	}
	
	pWndAutoHideArea =
		new CExtDynAutoHideArea();
	if(	!pWndAutoHideArea->Create(
			pFrame,
			pWndSlider,
			AFX_IDW_DOCKBAR_RIGHT
			)
		)
	{
		ASSERT( FALSE );
		return false;
	}

	pFrame->DelayRecalcLayout();
	return true;
}
#endif // (!defined __EXT_MFC_NO_TAB_CONTROLBARS)

bool CExtControlBar::IsFixedMode() const
{
	return m_bFixedMode;
}

bool CExtControlBar::IsFixedDockStyle() const
{
	return IsFixedMode();
}

bool CExtControlBar::ProfileBarStateLoad(
	CFrameWnd * pFrame,
	__EXT_MFC_SAFE_LPCTSTR sSectionNameCompany, // under HKEY_CURRENT_USER\Software
	__EXT_MFC_SAFE_LPCTSTR sSectionNameProduct, // under HKEY_CURRENT_USER\Software\%sSectionNameCompany%
	__EXT_MFC_SAFE_LPCTSTR sSectionNameProfile, // under HKEY_CURRENT_USER\Software\%sSectionNameCompany%\%sSectionNameProfile%
	LPWINDOWPLACEMENT pFrameWp // = NULL // need serialize frame's WP
	)
{
	ASSERT( sSectionNameCompany != NULL );
	ASSERT( sSectionNameProduct != NULL );
	ASSERT( sSectionNameProfile != NULL );
	ASSERT_VALID( pFrame );

__EXT_MFC_SAFE_LPCTSTR strProfileName =
		g_CmdManager->ProfileNameFromWnd(
			pFrame->GetSafeHwnd()
			);
	if( pFrame == NULL
		|| strProfileName == NULL
		|| strProfileName[0] == _T('\0')
		)
	{
		ASSERT( FALSE );
		return false;
	}
	ASSERT_VALID( pFrame );

//__EXT_MFC_SAFE_LPCTSTR lpszProfileName =
//		AfxGetApp()->m_pszProfileName;
//	ASSERT( lpszProfileName != NULL );
//	ASSERT( lpszProfileName[0] != _T('\0') );

CExtSafeString sRegKeyPath=
		productsection2regkeypath(
			sSectionNameProfile,
			sSectionNameCompany,
			sSectionNameProduct
			);

bool bRetVal = false;
	try
	{
		// prepare memory file and archive,
		// get information from registry
		CMemFile _file;
		if( !CExtCmdManager::FileObjFromRegistry(
				_file,
				sRegKeyPath
				)
			)
		{
			// win xp fix - begin
			WINDOWPLACEMENT _wpf;
			::memset( &_wpf, 0, sizeof(WINDOWPLACEMENT) );
			_wpf.length = sizeof(WINDOWPLACEMENT);
			if( pFrame->GetWindowPlacement(&_wpf) )
			{
				_wpf.ptMinPosition.x = _wpf.ptMinPosition.y = 0;
				_wpf.ptMaxPosition.x = _wpf.ptMaxPosition.y = 0;
				_wpf.showCmd = 
					(pFrame->GetStyle() & WS_VISIBLE)
						? SW_SHOWNA
						: SW_HIDE;
				pFrame->SetWindowPlacement(&_wpf);
			} // if( pFrame->GetWindowPlacement(&_wpf) )
			// win xp fix - end
			return false;
		}
		CArchive ar(
			&_file,
			CArchive::load
			);
		// do serialization
		bRetVal =
			ProfileBarStateSerialize(
				ar,
				pFrame,
				pFrameWp
				);
	} // try
	catch( CException * pXept )
	{
		pXept->Delete();
		ASSERT( FALSE );
	} // catch( CException * pXept )
	catch( ... )
	{
		ASSERT( FALSE );
	} // catch( ... )
	return bRetVal;
}

bool CExtControlBar::ProfileBarStateSave(
	CFrameWnd * pFrame,
	__EXT_MFC_SAFE_LPCTSTR sSectionNameCompany, // under HKEY_CURRENT_USER\Software
	__EXT_MFC_SAFE_LPCTSTR sSectionNameProduct, // under HKEY_CURRENT_USER\Software\%sSectionNameCompany%
	__EXT_MFC_SAFE_LPCTSTR sSectionNameProfile, // under HKEY_CURRENT_USER\Software\%sSectionNameCompany%\%sSectionNameProfile%\%sSectionNameProfile%
	LPWINDOWPLACEMENT pFrameWp // = NULL // need serialize frame's WP
	)
{
	ASSERT( sSectionNameCompany != NULL );
	ASSERT( sSectionNameProduct != NULL );
	ASSERT( sSectionNameProfile != NULL );
	ASSERT_VALID( pFrame );

__EXT_MFC_SAFE_LPCTSTR strProfileName =
		g_CmdManager->ProfileNameFromWnd(
			pFrame->GetSafeHwnd()
			);
	if( pFrame == NULL
		|| strProfileName == NULL
		|| strProfileName[0] == _T('\0')
		)
	{
		ASSERT( FALSE );
		return false;
	}
	ASSERT_VALID( pFrame );

//__EXT_MFC_SAFE_LPCTSTR lpszProfileName =
//		AfxGetApp()->m_pszProfileName;
//	ASSERT( lpszProfileName != NULL );
//	ASSERT( lpszProfileName[0] != _T('\0') );
CExtSafeString sRegKeyPath =
		productsection2regkeypath(
			sSectionNameProfile,
			sSectionNameCompany,
			sSectionNameProduct
			);

bool bRetVal = false;
	try
	{
		// prepare memory file and archive
		CMemFile _file;
		CArchive ar(
			&_file,
			CArchive::store
			);
		// do serialization
		ProfileBarStateSerialize(
			ar,
			pFrame,
			pFrameWp
			);
		// OK, serialization passed
		ar.Flush();
		ar.Close();
		// put information to registry
		bRetVal =
			CExtCmdManager::FileObjToRegistry(
				_file,
				sRegKeyPath
				);
	} // try
	catch( CException * pXept )
	{
		pXept->Delete();
		ASSERT( FALSE );
	} // catch( CException * pXept )
	catch( ... )
	{
		ASSERT( FALSE );
	} // catch( ... )

	return bRetVal;
}

bool CExtControlBar::InternalFriendlyFrameWnd::SetupSmilyFrameWnd(void)
{
	m_pFloatingFrameClass =
		RUNTIME_CLASS(CExtMiniDockFrameWnd);

	return true;
}

void CExtControlBar::InternalFriendlyFrameWnd::SetOuterDockState(
	const CDockState & state,
	const CExtControlBar::OuterPropsArr_t & arrOuterProps
	)
{
	// first pass through barinfo's sets the m_pBar member correctly
	// creating floating frames if necessary
	for( int i = 0; i < state.m_arrBarInfo.GetSize(); i++ )
	{
		CControlBarInfo * pInfo = (CControlBarInfo *)
			state.m_arrBarInfo[i];
		ASSERT( pInfo != NULL );
		if( pInfo->m_bFloating )
		{
			// need to create floating frame to match
			CMiniDockFrameWnd * pDockFrame =
				CreateFloatingFrame(
					pInfo->m_bHorz ?
						CBRS_ALIGN_TOP : CBRS_ALIGN_LEFT
					);
			ASSERT( pDockFrame != NULL) ;
			CRect rcWnd( pInfo->m_pointPos, CSize(10, 10) );
			pDockFrame->CalcWindowRect( &rcWnd );
			pDockFrame->SetWindowPos(
				NULL,
				rcWnd.left, rcWnd.top, 0, 0,
				SWP_NOSIZE|SWP_NOZORDER|SWP_NOACTIVATE
				);
			CDockBar * pDockBar = (CDockBar *)
				pDockFrame->GetDlgItem( AFX_IDW_DOCKBAR_FLOAT );
			ASSERT( pDockBar != NULL );
			ASSERT_KINDOF( CDockBar, pDockBar );
			pInfo->m_pBar = pDockBar;
		} // if( pInfo->m_bFloating )
		else // regular dock bar or toolbar
		{
			pInfo->m_pBar = GetControlBar( pInfo->m_nBarID );
			if( pInfo->m_pBar == NULL )
				continue;
		} // else from if( pInfo->m_bFloating )
		pInfo->m_pBar->m_nMRUWidth = pInfo->m_nMRUWidth;
	} // for( int i = 0; i < state.m_arrBarInfo.GetSize(); i++ )

	// update new outer props
	for( i = 0; i < arrOuterProps.GetSize(); i++ )
	{
		OuterItemData_t _oid = arrOuterProps[i];
		CExtControlBar * pExtBar =
			STATIC_DOWNCAST(
				CExtControlBar,
				GetControlBar( _oid.m_nBarID )
				);
		pExtBar->m_ptFloatHelper = _oid.m_ptFloatHelper;
		pExtBar->m_sizeDockedH = _oid.m_sizeDockedH;
		pExtBar->m_sizeDockedV = _oid.m_sizeDockedV;
		pExtBar->m_sizeFloated = _oid.m_sizeFloated;
		pExtBar->_AffixmentSetOuter( &_oid.m_AffixmentData );
	} // for( i = 0; i < arrOuterProps.GetSize(); i++ )

	// the second pass will actually dock all of the control bars and
	// set everything correctly
	for( i = 0; i < state.m_arrBarInfo.GetSize(); i++ )
	{
		CControlBarInfo * pInfo = (CControlBarInfo *)
			state.m_arrBarInfo[i];
		ASSERT( pInfo != NULL );
		if( pInfo->m_pBar == NULL )
			continue;
		if( pInfo->m_pBar->m_pDockContext != NULL
			&& pInfo->m_pBar->IsKindOf(RUNTIME_CLASS(CExtControlBar))
			)
			((CExtControlBar*)(pInfo->m_pBar))->m_ptFloatHelper
				= pInfo->m_ptMRUFloatPos;
		pInfo->m_pBar->SetBarInfo( pInfo, this );
	} // for( i = 0; i < state.m_arrBarInfo.GetSize(); i++ )

	// the third pass will move independent floating bars
	// into valid positions
	for( i = 0; i < arrOuterProps.GetSize(); i++ )
	{
		OuterItemData_t _oid = arrOuterProps[i];
		CExtControlBar * pExtBar =
			STATIC_DOWNCAST(
				CExtControlBar,
				GetControlBar( _oid.m_nBarID )
				);
		if( !_oid.m_bFloating )
			continue;
		CRect rcFrameInitial( _oid.m_ptFloatHelper, _oid.m_sizeFloated );
		CRect rcFrameNew =
			CExtPaintManager::stat_AlignWndRectToMonitor(
				rcFrameInitial
				);
		CExtMiniDockFrameWnd * pMiniFrame =
			DYNAMIC_DOWNCAST(
				CExtMiniDockFrameWnd,
				pExtBar->GetParentFrame()
				);
		if( pMiniFrame != NULL )
		{
			ASSERT_VALID( pMiniFrame );
			CRect rcFrameReal;
			pMiniFrame->GetWindowRect( rcFrameReal );
			if( rcFrameReal == rcFrameNew )
				continue;
			pMiniFrame->MoveWindow( &rcFrameNew, FALSE );
			pMiniFrame->DelayRecalcLayout();
		} // if( pMiniFrame != NULL )
		else
			pExtBar->FloatControlBar( rcFrameNew.TopLeft() );
	} // for( i = 0; i < arrOuterProps.GetSize(); i++ )

	// last pass shows all the floating windows that were previously shown
	for( i = 0; i < state.m_arrBarInfo.GetSize(); i++ )
	{
		CControlBarInfo * pInfo = (CControlBarInfo *)
			state.m_arrBarInfo[i];
		ASSERT( pInfo != NULL );
		if( pInfo->m_pBar == NULL )
			continue;
		if( !pInfo->m_bFloating )
			continue;
		CFrameWnd * pFrameWnd =
			pInfo->m_pBar->GetParentFrame();
		CDockBar * pDockBar = (CDockBar *) pInfo->m_pBar;
		ASSERT_KINDOF( CDockBar, pDockBar );
		if( pDockBar->GetDockedVisibleCount() > 0 )
		{
			pFrameWnd->RecalcLayout();
			pFrameWnd->ShowWindow( SW_SHOWNA );
			for( INT nBar = 1; nBar < pDockBar->m_arrBars.GetSize(); nBar ++ )
			{
				ASSERT( pDockBar->m_arrBars[0] == NULL );
				CControlBar * pBar = (CControlBar *)
					pDockBar->m_arrBars[nBar];
				if( pBar == NULL )
					continue;
				if( __PLACEHODLER_BAR_PTR(pBar) )
					continue;
				CExtControlBar * pExtBar =
					DYNAMIC_DOWNCAST(
						CExtControlBar,
						pBar
						);
				if( pExtBar == NULL
					|| pExtBar->IsFixedMode()
					)
					continue;
				pExtBar->_RecalcNcArea();
			}
		} // if( pDockBar->GetDockedVisibleCount() > 0 )
	} // for( i = 0; i < state.m_arrBarInfo.GetSize(); i++ )
}

void CExtControlBar::InternalFriendlyFrameWnd::GetOuterDockState(
	CDockState & state,
	CExtControlBar::OuterPropsArr_t & arrOuterProps
	) const
{
	state.Clear(); //make sure dockstate is empty
	arrOuterProps.RemoveAll();

	for(	POSITION pos = m_listControlBars.GetHeadPosition();
			pos != NULL;
		)
	{ // get state info for each bar
		CControlBar * pBar = (CControlBar *)
			m_listControlBars.GetNext( pos );
		ASSERT( pBar != NULL );

		if(		pBar->IsKindOf(RUNTIME_CLASS(CExtDynControlBar))
			||	pBar->IsKindOf(RUNTIME_CLASS(CExtDockDynBar))
			)
			continue;

		if(		pBar->m_pDockBar != NULL
			&&	pBar->m_pDockBar->IsKindOf(RUNTIME_CLASS(CExtDockDynBar))
			)
			continue;

		if( pBar->IsDockBar() )
		{
			UINT nID = pBar->GetDlgCtrlID();
			ASSERT_DOCKBAR_DLGCTRLID( nID );
			if( nID == AFX_IDW_DOCKBAR_FLOAT )
			{
				CControlBar * pBarChild =
					STATIC_DOWNCAST(
						CControlBar,
						pBar->GetWindow(GW_CHILD)
						);
				if( pBarChild->IsKindOf(RUNTIME_CLASS(CExtDynControlBar)) )
					continue;
			}
			if(		pBar->IsKindOf(RUNTIME_CLASS(CExtDockBar))
				&&	((CExtDockBar *)pBar)->_GetCircleNo() != 0
				)
				continue;
		} // if( pBar->IsDockBar() )
#ifdef _DEBUG
		else
		{
			ASSERT( !pBar->IsKindOf(RUNTIME_CLASS(CDockBar)) );
		} // else from if( pBar->IsDockBar() )
#endif // _DEBUG

		CSize sizeReset( -1, -1 );
		if( pBar->IsKindOf(RUNTIME_CLASS(CExtControlBar)) )
		{
			if( pBar->IsKindOf(RUNTIME_CLASS(CExtDynControlBar)) )
				continue;

			if(		(! ((CExtControlBar*)pBar)->IsFixedMode() )
				&&	(! pBar->IsFloating() )
				)
			{
				if( pBar->m_pDockBar == NULL )
					continue;
				CExtDockBar * pDockBar =
					STATIC_DOWNCAST(
						CExtDockBar,
						pBar->m_pDockBar
						);
				ASSERT( !pDockBar->IsKindOf(RUNTIME_CLASS(CExtDockDynBar)) );
				if( pDockBar->_GetCircleNo() > 0 )
					continue;
			}
			OuterItemData_t _oid;
			_oid.m_nBarID = pBar->GetDlgCtrlID();
			_oid.m_ptFloatHelper = ((CExtControlBar*)pBar)->m_ptFloatHelper;
			_oid.m_sizeDockedH = ((CExtControlBar*)pBar)->m_sizeDockedH;
			_oid.m_sizeDockedV = ((CExtControlBar*)pBar)->m_sizeDockedV;
			_oid.m_sizeFloated = ((CExtControlBar*)pBar)->m_sizeFloated;
			ASSERT( _oid.m_AffixmentData.IsEmpty() );
			InternalAffixmentData * pAffixmentData =
				((CExtControlBar*)pBar)->_AffixmentGetOuter();
			if( pAffixmentData != NULL )
				_oid.m_AffixmentData = *pAffixmentData;
	
			ASSERT( !_oid.m_bFloating );
			if( pBar->IsFloating() )
			{
				CRect rcBarWnd;
				CRect rcFraweWnd;
				pBar->GetWindowRect( &rcBarWnd );
				CExtMiniDockFrameWnd * pMiniFrame =
					STATIC_DOWNCAST(
						CExtMiniDockFrameWnd,
						pBar->GetParentFrame()
						);
				pMiniFrame->GetWindowRect( &rcFraweWnd );
				CSize sizeBarWnd = rcBarWnd.Size();
				CSize sizeFraweWnd = rcFraweWnd.Size();
				CSize sizeDiff = sizeFraweWnd - sizeBarWnd;
				_oid.m_ptFloatHelper = rcFraweWnd.TopLeft();
				if( ((CExtControlBar*)pBar)->IsFixedMode() )
				{
					_oid.m_sizeFloated += sizeDiff;
					sizeReset = _oid.m_sizeFloated;
				} // if( ((CExtControlBar*)pBar)->IsFixedMode() )
				_oid.m_bFloating = true;
			} // if( pBar->IsFloating() )

			arrOuterProps.Add( _oid );
		} // if( pBar->IsKindOf(RUNTIME_CLASS(CExtControlBar)) )

		CControlBarInfo* pInfo = new CControlBarInfo;
		pBar->GetBarInfo( pInfo );
		if( pInfo->m_pBar == NULL )
			continue;

		if( sizeReset.cx > 0 && sizeReset.cy > 0 )
			pInfo->m_nMRUWidth = sizeReset.cx;

		state.m_arrBarInfo.Add(pInfo);
	} // get state info for each bar
}

void CExtControlBar::InternalFriendlyFrameWnd::SetDockState(
	const CExtControlBar::InternalDockStateSite & state,
	bool bPresetWP
	)
{
	state.StateSet( bPresetWP );
}

void CExtControlBar::InternalFriendlyFrameWnd::GetDockState(
	CExtControlBar::InternalDockStateSite & state
	) const
{
	state.StateGet();
}

CExtControlBar::InternalDockStateSite::InternalDockStateSite(
	CFrameWnd * pDockSite
	)
	: m_pDockSite( pDockSite )
	, m_pOuterState( NULL )
{
	ASSERT_VALID( m_pDockSite );
	ASSERT_KINDOF( CFrameWnd, m_pDockSite );
	ASSERT( !m_pDockSite->IsKindOf(RUNTIME_CLASS(CMiniFrameWnd)) );
	::memset( &m_wp, 0, sizeof(WINDOWPLACEMENT) );
	m_pOuterState = new CDockState;
}

CExtControlBar::InternalDockStateSite::~InternalDockStateSite()
{
	Clear();
	if( m_pOuterState != NULL )
		delete m_pOuterState;
}

void CExtControlBar::InternalDockStateSite::Clear()
{
	ASSERT_VALID( this );
	ASSERT( m_pOuterState != NULL );
	::memset( &m_wp, 0, sizeof(WINDOWPLACEMENT) );
	m_wp.length = sizeof(WINDOWPLACEMENT);

	m_pOuterState->Clear();

INT nCount = m_arrBarStates.GetSize();
	for( INT i = 0; i < nCount; i++ )
	{
		InternalDockStateBar * pState =
			m_arrBarStates[i];
		ASSERT_VALID( pState );
		pState->Clear();
		delete pState;
	}
	m_arrBarStates.RemoveAll();

#if (!defined __EXT_MFC_NO_TAB_CONTROLBARS)
	m_arrAutoHideOrder.RemoveAll();
#endif // (!defined __EXT_MFC_NO_TAB_CONTROLBARS)

	m_arrOuterProps.RemoveAll();
}

void CExtControlBar::InternalDockStateSite::Serialize( CArchive & ar )
{
	ASSERT_VALID( this );

INT i, nCount;
DWORD dwApiVer0 = g_CmdManager.GetVersionDWORD( false );
DWORD dwApiVer1 = g_CmdManager.GetVersionDWORD( true );
DWORD dwReserved = 0;

	if( ar.IsStoring() )
	{

		// serialize version info
		CExtSafeString sTmpBuffer;
		CExtSafeString sFriendlyVer;
		sFriendlyVer.Format(
			_T("Prof-UIS (v. %s) control bar state"),
			g_CmdManager.GetVersionString( sTmpBuffer )
			);
		ar << sFriendlyVer;
		ar << dwApiVer0;
		ar << dwApiVer1;
		ar << dwReserved;
		ar << dwReserved;
		ar << dwReserved;
		ar << dwReserved;

		// serialize frame position
		CExtSafeString sFrameWp;
		sFrameWp.Format(
			_T("%d,%d,%d,%d,%d,%d"),
			m_wp.rcNormalPosition.left,
			m_wp.rcNormalPosition.top,
			m_wp.rcNormalPosition.right,
			m_wp.rcNormalPosition.bottom,
			m_wp.showCmd,
			m_wp.flags
			);
		ar << sFrameWp;

		m_pOuterState->Serialize( ar );

		nCount = m_arrOuterProps.GetSize();
		ar << nCount;
		for( i = 0; i < nCount; i++ )
			m_arrOuterProps.ElementAt(i).Serialize( ar );

		nCount = m_arrBarStates.GetSize();
		ar << nCount;
		for( i = 0; i < nCount; i++ )
		{
			InternalDockStateBar * pState =
				m_arrBarStates[i];
			ASSERT_VALID( pState );
			pState->Serialize( ar );
		}

#if (!defined __EXT_MFC_NO_TAB_CONTROLBARS)
		nCount = m_arrAutoHideOrder.GetSize();
		ar << nCount;
		for( i = 0; i < nCount; i++ )
		{
			UINT nBarID = m_arrAutoHideOrder[ i ];
			ar << nBarID;
		}
#endif // (!defined __EXT_MFC_NO_TAB_CONTROLBARS)
		
	} // if( ar.IsStoring() )
	else
	{
		Clear();

		// serialize version info
		DWORD dwApiVer0a = 0, dwApiVer1a = 0;
		CExtSafeString sFriendlyVer;
		ar >> sFriendlyVer;
		ar >> dwApiVer0a;
		ar >> dwApiVer1a;
		ar >> dwReserved;
		ar >> dwReserved;
		ar >> dwReserved;
		ar >> dwReserved;
		if( dwApiVer1 != dwApiVer1a )
		{
			ASSERT( FALSE );
			::AfxThrowArchiveException(
				CArchiveException::generic,
				NULL
				);
		}

		CExtSafeString sFrameWp;
		ar >> sFrameWp;
		ASSERT( !sFrameWp.IsEmpty() );
		::memset( &m_wp, 0, sizeof(WINDOWPLACEMENT) );
		m_wp.length = sizeof(WINDOWPLACEMENT);
		VERIFY( m_pDockSite->GetWindowPlacement(&m_wp)  );
		m_wp.ptMinPosition.x = m_wp.ptMinPosition.y = 0;
		m_wp.ptMaxPosition.x = m_wp.ptMaxPosition.y = 0;

		if(	_stscanf(
				sFrameWp,
				_T("%d,%d,%d,%d,%d,%d"),
				&m_wp.rcNormalPosition.left,
				&m_wp.rcNormalPosition.top,
				&m_wp.rcNormalPosition.right,
				&m_wp.rcNormalPosition.bottom,
				&m_wp.showCmd,
				&m_wp.flags
				) != 6
			)
		{
			ASSERT( FALSE );
			::memset( &m_wp, 0, sizeof(WINDOWPLACEMENT) );
			m_wp.length = sizeof(WINDOWPLACEMENT);
			m_wp.showCmd = SW_HIDE;
			//return false;
			::AfxThrowArchiveException(
				CArchiveException::generic,
				NULL
				);
		}

		m_pOuterState->Serialize( ar );

		ar >> nCount;
		for( i = 0; i < nCount; i++ )
		{
			OuterItemData_t _oid;
			_oid.Serialize( ar );
			m_arrOuterProps.Add( _oid );
		}

		ar >> nCount;
		for( i = 0; i < nCount; i++ )
		{
			InternalDockStateBar * pState =
				new InternalDockStateBar;
			pState->Serialize( ar );
			ASSERT_VALID( pState );
			m_arrBarStates.Add( pState );
		}
		
#if (!defined __EXT_MFC_NO_TAB_CONTROLBARS)
		ar >> nCount;
		for( i = 0; i < nCount; i++ )
		{
			UINT nBarID;
			ar >> nBarID;
			m_arrAutoHideOrder.Add( nBarID );
		}
#endif // (!defined __EXT_MFC_NO_TAB_CONTROLBARS)

	} // else from if( ar.IsStoring() )
}

void CExtControlBar::InternalDockStateSite::StateGet()
{
	ASSERT_VALID( this );
	ASSERT( m_pOuterState != NULL );
	ASSERT_VALID( m_pDockSite );

	Clear();

	CExtDockBar::_OptimizeCircles( m_pDockSite );

	VERIFY( m_pDockSite->GetWindowPlacement(&m_wp) );

POSITION pos = m_pDockSite->m_listControlBars.GetHeadPosition();
	for( ; pos != NULL; )
	{
		CControlBar * pBar = (CControlBar *)
			m_pDockSite->m_listControlBars.GetNext( pos );
		ASSERT_VALID( pBar );
		
		if( pBar->IsFloating() )
		{
			if( pBar->IsDockBar() )
				continue;
			if( pBar->IsKindOf(RUNTIME_CLASS(CExtDynControlBar)) )
			{
				CExtMiniDockFrameWnd * pFrame =
					STATIC_DOWNCAST(
						CExtMiniDockFrameWnd,
						pBar->GetParentFrame()
						);
				ASSERT_VALID( pBar->m_pDockBar );
				ASSERT_KINDOF( CDockBar, pBar->m_pDockBar );
				ASSERT( !pBar->m_pDockBar->IsKindOf(RUNTIME_CLASS(CExtDockBar)) );
				ASSERT( pBar->m_pDockBar->GetDlgCtrlID() == AFX_IDW_DOCKBAR_FLOAT );
				ASSERT( pBar->m_pDockBar->GetParent() == pFrame );
				AppendFloatingLayout(
					STATIC_DOWNCAST(
						CExtMiniDockFrameWnd,
						pFrame
						)
					);
			} // if( pBar->IsKindOf(RUNTIME_CLASS(CExtDynControlBar)) )
			continue;
		} // if( pBar->IsFloating() )
		
		if( !pBar->IsDockBar() )
			continue;

		ASSERT_KINDOF( CDockBar, pBar );
		if( !pBar->IsKindOf(RUNTIME_CLASS(CExtDockBar)) )
			continue;

		CFrameWnd * pFrame = pBar->GetParentFrame();
		ASSERT_VALID( pFrame );
		if( pFrame->IsKindOf(RUNTIME_CLASS(CMiniFrameWnd)) )
		{
			ASSERT_KINDOF( CExtMiniDockFrameWnd, pFrame );
			continue;
		}

		ASSERT(
			!pBar->GetParentFrame()->IsKindOf(
				RUNTIME_CLASS( CMiniFrameWnd )
				)
			);
		
		CExtDockBar * pDockBar =
			STATIC_DOWNCAST(
				CExtDockBar,
				pBar
				);

		UINT nCircleNo = pDockBar->_GetCircleNo();
		if( nCircleNo == 0 )
			continue;

		AppendDockBarAtSideLayout( pDockBar );
	}

#if (!defined __EXT_MFC_NO_TAB_CONTROLBARS)
CExtDynAutoHideArea * arrAutoHiders[4] =
{
	NULL, NULL, NULL, NULL
};
static const UINT arrSideMap[4] =
{
	AFX_IDW_DOCKBAR_TOP,
	AFX_IDW_DOCKBAR_BOTTOM,
	AFX_IDW_DOCKBAR_LEFT,
	AFX_IDW_DOCKBAR_RIGHT,
};
	for( INT nSide = 0; nSide < 4; nSide++ )
	{
		UINT nDockBarID = arrSideMap[ nSide ];
		CExtDockBar * pDockBar = (CExtDockBar *)
			m_pDockSite->GetControlBar( nDockBarID );
		ASSERT_VALID( pDockBar );
		ASSERT_KINDOF( CExtDockBar, pDockBar );
		ASSERT( pDockBar->_GetCircleNo() == 0 );
		arrAutoHiders[ nSide ] = pDockBar->_GetAutoHideArea();
		if( arrAutoHiders[ nSide ] == NULL )
		{
			ASSERT( nSide == 0 );
			break;
		}
		ASSERT_VALID( arrAutoHiders[ nSide ] );
		ASSERT(
			UINT( arrAutoHiders[ nSide ]->GetDlgCtrlID() )
				== arrSideMap[nSide]
				);
	} // for( INT nSide = 0; nSide < 4; nSide++ )

	if( arrAutoHiders[0] != NULL )
	{
		for( nSide = 0; nSide < 4; nSide++ )
		{
			ASSERT_VALID( arrAutoHiders[nSide] );
			INT nCount = arrAutoHiders[nSide]->ItemGetCount();
			for( INT nItem = 0; nItem < nCount; nItem++ )
			{
				CExtTabWnd::TAB_ITEM_INFO * pTII =
					arrAutoHiders[nSide]->ItemGet( nItem );
				ASSERT_VALID( pTII );
				if( (pTII->GetItemStyle() & __ETWI_IN_GROUP_ACTIVE) == 0 )
					continue;
				CExtControlBar * pBar =
					reinterpret_cast < CExtControlBar * >
						( pTII->LParamGet() );
				ASSERT_VALID( pBar );
				ASSERT_KINDOF( CExtControlBar, pBar );
				ASSERT( !pBar->IsKindOf(RUNTIME_CLASS(CExtDynControlBar)) );
				ASSERT( !pBar->IsFixedMode() );
				ASSERT( m_pDockSite->m_listControlBars.Find(pBar) != NULL );
				ASSERT( pBar->AutoHideModeGet() );
				UINT nBarID = (UINT) pBar->GetDlgCtrlID();
				m_arrAutoHideOrder.Add( nBarID );
			} // for( INT nItem = 0; nItem < nCount; nItem++ )
		} // for( nSide = 0; nSide < 4; nSide++ )
	} // if( arrAutoHiders[0] != NULL )
#endif // (!defined __EXT_MFC_NO_TAB_CONTROLBARS)

	((InternalFriendlyFrameWnd *)m_pDockSite)->GetOuterDockState(
		*m_pOuterState,
		m_arrOuterProps
		);
}

CExtControlBar::InternalAffixmentData::InternalAffixmentData()
	: m_nAffixmentWeight( 0 )
	, m_rcAffixment( 0, 0, 0, 0 )
	, m_sizeCompressed( 0, 0 )
	, m_dwAffixmentFlags( __EAFF_FIXED_MODE_INITIAL_RECALC )
{
}

CExtControlBar::InternalAffixmentData::InternalAffixmentData(
	const CExtControlBar::InternalAffixmentData & other
	)
{
	_AssignFromOther( other );
}

CExtControlBar::InternalAffixmentData::~InternalAffixmentData()
{
}

void CExtControlBar::InternalAffixmentData::_AssignFromOther(
	const CExtControlBar::InternalAffixmentData & other
	)
{
	m_nAffixmentWeight = other.m_nAffixmentWeight;
	m_rcAffixment = other.m_rcAffixment;
	m_sizeCompressed = other.m_sizeCompressed;
	m_dwAffixmentFlags = other.m_dwAffixmentFlags;
}

bool CExtControlBar::InternalAffixmentData::IsEmpty() const
{
	return (m_nAffixmentWeight==0) ? true : false;
}

void CExtControlBar::InternalAffixmentData::Empty()
{
	m_nAffixmentWeight = 0;
	m_rcAffixment.SetRectEmpty();
	ASSERT(
			m_rcAffixment.left == 0
		&&	m_rcAffixment.right == 0
		&&	m_rcAffixment.top == 0
		&&	m_rcAffixment.bottom == 0
		);
	m_sizeCompressed.cx = m_sizeCompressed.cy = 0;
	m_dwAffixmentFlags = __EAFF_FIXED_MODE_INITIAL_RECALC;
}

int CExtControlBar::InternalAffixmentData::CompareAffixment(
	const CExtControlBar::InternalAffixmentData & other
	) const
{
	if( !IsEmpty() )
	{
		if( other.IsEmpty() )
			return 1;
		if( m_nAffixmentWeight > other.m_nAffixmentWeight )
			return 1;
		if( m_nAffixmentWeight < other.m_nAffixmentWeight )
			return -1;
	} // if( !IsEmpty() )
	else
	{
		if( !other.IsEmpty() )
			return -1;
	} // else from if( !IsEmpty() )
	return 0;
}

void CExtControlBar::InternalAffixmentData::Serialize( CArchive & ar )
{
	ASSERT( sizeof(m_nAffixmentWeight) == (sizeof(BYTE)*4) );
SHORT nHelperFlags = 0x0000;
	if( ar.IsStoring() )
	{
		if( IsEmpty() )
			nHelperFlags |= 0x0001;
		ar.Write( &nHelperFlags, sizeof(nHelperFlags) );
		if( nHelperFlags & 0x0001 )
			return;
		ar << m_nAffixmentWeight;
		ar << m_rcAffixment;
		ar << m_sizeCompressed;
		ar << m_dwAffixmentFlags;
	} // if( ar.IsStoring() )
	else
	{
		Empty();
		ar.Read( &nHelperFlags, sizeof(nHelperFlags) );
		if( nHelperFlags & 0x0001 )
			return;
		ar >> m_nAffixmentWeight;
		ar >> m_rcAffixment;
		ar >> m_sizeCompressed;
		ar >> m_dwAffixmentFlags;
	} // else from if( ar.IsStoring() )
}

CExtControlBar::InternalDockStateBar *
	CExtControlBar::InternalDockStateSite::AppendFloatingLayout(
		CExtMiniDockFrameWnd * pMiniFrame
		)
{
	ASSERT_VALID( this );
	ASSERT_VALID( pMiniFrame );
	ASSERT_KINDOF( CExtMiniDockFrameWnd, pMiniFrame );

CDockBar * pFloatDocker =
		STATIC_DOWNCAST(
			CDockBar,
			pMiniFrame->GetWindow( GW_CHILD )
			);
	ASSERT_VALID( pFloatDocker );
	ASSERT( pFloatDocker->IsDockBar() );
	ASSERT_KINDOF( CDockBar, pFloatDocker );
	ASSERT( !pFloatDocker->IsKindOf(RUNTIME_CLASS(CExtDockBar)) );
	ASSERT( pFloatDocker->GetDlgCtrlID() == AFX_IDW_DOCKBAR_FLOAT );
CExtDynControlBar * pDynDocker =
		STATIC_DOWNCAST(
			CExtDynControlBar,
			pFloatDocker->GetWindow( GW_CHILD )
			);
	ASSERT_VALID( pDynDocker );

InternalDockStateBar * _idsb =
		new InternalDockStateBar;
	_idsb->StateGet( pDynDocker, NULL );
	ASSERT( _idsb->m_dwDockStateFlags & InternalDockStateBar::__STATE_FLOATING );
	m_arrBarStates.Add( _idsb );

	return _idsb;
}

CExtControlBar::InternalDockStateBar *
	CExtControlBar::InternalDockStateSite::AppendDockBarAtSideLayout(
		CExtDockBar * pDockBar
		)
{
	ASSERT_VALID( this );
	ASSERT_VALID( pDockBar );
	ASSERT_KINDOF( CExtDockBar, pDockBar );
	ASSERT( !pDockBar->IsKindOf(RUNTIME_CLASS(CExtDockDynBar)) );
	ASSERT( pDockBar->_GetCircleNo() > 0 );

	ASSERT( pDockBar->m_arrBars[0] == NULL );
bool bNewRow = false;
INT nCount = pDockBar->m_arrBars.GetSize();
InternalDockStateBar * pLastState = NULL;
	for( INT nBar = 1; nBar < nCount; nBar ++ )
	{
		CExtControlBar * pBar = (CExtControlBar *)
			pDockBar->m_arrBars[nBar];
		if( pBar == NULL )
		{
			bNewRow = true;
			continue;
		}
		if( __PLACEHODLER_BAR_PTR(pBar) )
			continue;
		ASSERT_KINDOF( CExtControlBar, pBar );
		ASSERT( !pBar->IsFixedMode() );

//		if( pBar->IsKindOf(RUNTIME_CLASS(CExtDynControlBar)) )
//		{
//			if( ((CExtDynControlBar*)pBar)->m_pWndDynDocker->GetDockedCount() == 0 )
//				continue;
//		}

		InternalDockStateBar * _idsb =
			new InternalDockStateBar;
		_idsb->StateGet( pBar, NULL );
		if( bNewRow )
			_idsb->m_dwDockStateFlags |= InternalDockStateBar::__STATE_NEW_ROW;
		m_arrBarStates.Add( _idsb );
		bNewRow = false;
		pLastState = _idsb;
	}
	return pLastState;
}

void CExtControlBar::InternalDockStateSite::StateSet( bool bPresetWP ) const
{
	ASSERT_VALID( this );
	ASSERT( m_pOuterState != NULL );
	ASSERT_VALID( m_pDockSite );

	if( bPresetWP )
	{
		//WINDOWPLACEMENT _wp;
		//::memcpy( &_wp, &m_wp, sizeof(WINDOWPLACEMENT) );
		//VERIFY( m_pDockSite->SetWindowPlacement( &_wp ) );

		CRect rcDockSiteWnd;
		if(		m_wp.showCmd == SW_SHOWMAXIMIZED
			||	m_wp.showCmd == SW_SHOWMINIMIZED
			||	m_wp.showCmd == SW_SHOWMINNOACTIVE
			||	m_wp.showCmd == SW_HIDE
			||	m_wp.showCmd == SW_FORCEMINIMIZE
			)
		{
			CExtPaintManager::monitor_parms_t _mp;
			CExtPaintManager::stat_GetMonitorParms( _mp, m_wp.rcNormalPosition );
			rcDockSiteWnd = _mp.m_rcWorkArea;
		}
		else
		{
			rcDockSiteWnd =  m_wp.rcNormalPosition;
		}
		m_pDockSite->SetWindowPos(
			NULL,
			rcDockSiteWnd.left, rcDockSiteWnd.top,
			rcDockSiteWnd.Width(), rcDockSiteWnd.Height(),
			SWP_NOZORDER|SWP_NOOWNERZORDER|SWP_NOACTIVATE
				|SWP_NOREDRAW|SWP_NOSENDCHANGING 
			);
	} // if( bPresetWP )

POSITION pos;
INT i, nCount;

ExtControlBarVector_t vRedockBars;
	for(	pos =
				m_pDockSite->m_listControlBars.GetHeadPosition();
			pos != NULL;
			)
	{
		CControlBar * pBar = (CControlBar *)
			m_pDockSite->m_listControlBars.GetNext( pos );
		ASSERT_VALID( pBar );
		
		if( pBar->GetParentFrame()->IsKindOf(RUNTIME_CLASS(CMiniFrameWnd)) )
		{
			if(		pBar->IsKindOf(RUNTIME_CLASS(CExtControlBar))
				&&	!pBar->IsKindOf(RUNTIME_CLASS(CExtDynControlBar))
				)
				vRedockBars.Add( (CExtControlBar *)pBar );
			continue;
		}

		if( pBar->IsDockBar() )
			continue;
		if(		pBar->m_pDockSite == NULL
			||	pBar->m_pDockContext == NULL
			)
			continue;
		if( pBar->m_pDockBar == NULL )
		{
			m_pDockSite->DockControlBar( pBar );
			m_pDockSite->ShowControlBar( pBar, FALSE, TRUE );
			continue;
		}
		if(		!pBar->IsKindOf(RUNTIME_CLASS(CExtControlBar))
			||	pBar->IsKindOf(RUNTIME_CLASS(CExtDynControlBar))
			||	((CExtControlBar *)pBar)->IsFixedMode()
			)
			continue;

		ASSERT_KINDOF( CExtDockBar, pBar->m_pDockBar );
		if( ((CExtDockBar*)pBar->m_pDockBar)->_GetCircleNo() == 0
			&& (! pBar->m_pDockBar->IsKindOf(RUNTIME_CLASS(CExtDockDynBar)) )
			)
			continue;
		
#if (!defined __EXT_MFC_NO_TAB_CONTROLBARS)
		if( ((CExtControlBar *)pBar)->AutoHideModeGet() )
			((CExtControlBar *)pBar)->AutoHideModeSet(
				false, false, false, true );
#endif // (!defined __EXT_MFC_NO_TAB_CONTROLBARS)

		m_pDockSite->ShowControlBar( pBar, FALSE, TRUE );
	}

	nCount = vRedockBars.GetSize();
	for( i = 0; i < nCount; i++ )
	{
		CExtControlBar * pBar = vRedockBars[i];
		DWORD dwBarStyle = pBar->GetBarStyle();
		UINT nBarDockerID = AFX_IDW_DOCKBAR_TOP;
		if( dwBarStyle & CBRS_ALIGN_BOTTOM )
			nBarDockerID = AFX_IDW_DOCKBAR_BOTTOM;
		else if( dwBarStyle & CBRS_ALIGN_LEFT )
			nBarDockerID = AFX_IDW_DOCKBAR_LEFT;
		else if( dwBarStyle & CBRS_ALIGN_RIGHT )
			nBarDockerID = AFX_IDW_DOCKBAR_RIGHT;
		if( pBar->IsFixedMode() )
		{
			bool bFloating = pBar->IsFloating();
			if( bFloating )
				m_pDockSite->ShowControlBar( pBar, FALSE, FALSE );
			m_pDockSite->DockControlBar(
				pBar,
				nBarDockerID
				);
			m_pDockSite->ShowControlBar( pBar, FALSE, TRUE );
		}
		else
		{
			((CExtControlBar *)pBar)->DockControlBar(
				nBarDockerID,
				1,
				m_pDockSite,
				false
				);
			m_pDockSite->ShowControlBar( pBar, FALSE, TRUE );
		}
	}

	CExtDockBar::_OptimizeCircles( m_pDockSite );
	m_pDockSite->RecalcLayout();

	nCount = m_arrBarStates.GetSize();
	for( i = 0; i < nCount; i++ )
	{
		InternalDockStateBar * pState =
			m_arrBarStates[i];
		ASSERT_VALID( pState );
		pState->StateSet( m_pDockSite, NULL );
	}

#if (!defined __EXT_MFC_NO_TAB_CONTROLBARS)
	nCount = m_arrAutoHideOrder.GetSize();
	for( i = 0; i < nCount; i++ )
	{
		UINT nBarID = m_arrAutoHideOrder[ i ];
		CExtControlBar * pBar =
			STATIC_DOWNCAST(
				CExtControlBar,
				m_pDockSite->GetControlBar( nBarID )
				);
		ASSERT_VALID( pBar );
		ASSERT_KINDOF( CExtControlBar, pBar );
		ASSERT( !pBar->IsKindOf(RUNTIME_CLASS(CExtDynControlBar)) );
		ASSERT( !pBar->IsFixedMode() );
		ASSERT( !pBar->AutoHideModeGet() );
		ASSERT( !pBar->IsFloating() );
		ASSERT( !pBar->GetParentFrame()->IsKindOf(RUNTIME_CLASS(CMiniFrameWnd)) );
		pBar->AutoHideModeSet( true, false, false, true );
		
		ASSERT_KINDOF( CExtDockBar, pBar->m_pDockBar );
		
		CWnd * pWndParent = pBar->m_pDockBar;
		for( ; true ;  )
		{
			ASSERT_VALID( pWndParent );
			if( pWndParent->IsKindOf(RUNTIME_CLASS(CExtDockBar)) )
			{
				if( !pWndParent->IsKindOf(RUNTIME_CLASS(CExtDockDynBar)) )
				{
					ASSERT( pWndParent->GetParent() == m_pDockSite );
					break;
				}
			}
			pWndParent = pWndParent->GetParent();
		}
		ASSERT_KINDOF( CExtDockBar, pWndParent );
		ASSERT( ((CExtDockBar*)pWndParent)->_GetCircleNo() > 0 );
		UINT nTopDockBarID = pWndParent->GetDlgCtrlID();
		ASSERT_DOCKBAR_DLGCTRLID_DOCKED( nTopDockBarID );
		CExtDockBar * pOuterDocker =
			STATIC_DOWNCAST(
				CExtDockBar,
				m_pDockSite->GetControlBar( nTopDockBarID )
				);
		ASSERT_VALID( pOuterDocker );
		ASSERT( UINT(pOuterDocker->GetDlgCtrlID()) == nTopDockBarID );
		
		CExtDynAutoHideArea * pAutoHideArea =
			pOuterDocker->_GetAutoHideArea();
		ASSERT_VALID( pAutoHideArea );
		ASSERT( UINT(pAutoHideArea->GetDlgCtrlID()) == nTopDockBarID );
		LONG nPos = pAutoHideArea->FindControlBar( pBar );
		ASSERT( nPos >= 0 );
		
		CExtTabWnd::TAB_ITEM_INFO * pTII =
			pAutoHideArea->ItemGet( nPos );
		pTII->ModifyItemStyle( 0, __ETWI_IN_GROUP_ACTIVE );

	} // for( i = 0; i < nCount; i++ )
#endif // (!defined __EXT_MFC_NO_TAB_CONTROLBARS)

	((InternalFriendlyFrameWnd *)m_pDockSite)->SetOuterDockState(
		*m_pOuterState,
		m_arrOuterProps
		);

	nCount = m_arrBarStates.GetSize();
	for( i = 0; i< nCount; i++ )
	{
		InternalDockStateBar * pState =
			m_arrBarStates[i];
		ASSERT_VALID( pState );
		pState->PreSyncAttributes( m_pDockSite, NULL );
	}

#ifdef _DEBUG
	for(	pos =
				m_pDockSite->m_listControlBars.GetHeadPosition();
			pos != NULL;
			)
	{
		CControlBar * pBar = (CControlBar *)
			m_pDockSite->m_listControlBars.GetNext( pos );
		ASSERT_VALID( pBar );
		CExtDockBar * pExtDocker =
			DYNAMIC_DOWNCAST( CExtDockBar, pBar );
		if( pExtDocker != NULL )
		{
			ASSERT( !pExtDocker->m_bLockedOptimize );
		}
	}
#endif // _DEBUG

	m_pDockSite->RecalcLayout();

	nCount = m_arrBarStates.GetSize();
	for( i = 0; i < nCount; i++ )
	{
		InternalDockStateBar * pState =
			m_arrBarStates[i];
		ASSERT_VALID( pState );
		pState->PostSyncAttributes( m_pDockSite, NULL );
		if( pState->m_dwDockStateFlags & InternalDockStateBar::__STATE_FLOATING )
		{
			ASSERT_VALID( pState->m_pHelperBar );
			CExtMiniDockFrameWnd * pMiniFrame =
				STATIC_DOWNCAST(
					CExtMiniDockFrameWnd,
					pState->m_pHelperBar->GetParentFrame()
					);
			pState->m_pHelperBar->_RecalcNcArea();
			pState->m_pHelperBar->OnRepositionSingleChild();
			pMiniFrame->RecalcLayout();
		}
	}

	for(	pos =
				m_pDockSite->m_listControlBars.GetHeadPosition();
			pos != NULL;
			)
	{
		CControlBar * pBar = (CControlBar *)
			m_pDockSite->m_listControlBars.GetNext( pos );
		ASSERT_VALID( pBar );
		if( pBar->IsDockBar() )
			continue;
		if(		(!pBar->IsKindOf(RUNTIME_CLASS(CExtControlBar)))
			||	pBar->IsKindOf(RUNTIME_CLASS(CExtDynControlBar))
			)
			continue;
		if( !((CExtControlBar *)pBar)->IsFixedMode() )
			continue;
		((CExtControlBar *)pBar)->_RecalcNcArea();
		if( !pBar->IsFloating() )
			continue;
		ASSERT_KINDOF(
			CMiniDockFrameWnd,
			pBar->GetParentFrame()
			);
		((CExtControlBar *)pBar)->_RecalcLayoutImpl();
	}

/*
bool bRecalcLayout = false;
	for(	pos =
				m_pDockSite->m_listControlBars.GetHeadPosition();
			pos != NULL;
			)
	{
		CControlBar * pBar = (CControlBar *)m_pDockSite->m_listControlBars.GetNext(pos);
		ASSERT_VALID( pBar );
		ASSERT_KINDOF( CControlBar, pBar );
		ASSERT( pBar->GetSafeHwnd() != NULL );
		ASSERT( ::IsWindow( pBar->GetSafeHwnd() ) );
		if(		pBar->IsDockBar()
			||	(!pBar->IsVisible())
			||	pBar->GetParentFrame() != m_pDockSite
			)
			continue;
		bRecalcLayout = true;
		pBar->SetWindowPos(
			NULL, 0,0,0,0,
			SWP_NOMOVE|SWP_NOSIZE
				|SWP_NOZORDER|SWP_NOOWNERZORDER
				|SWP_FRAMECHANGED
			);
	}
	if( bRecalcLayout )
		m_pDockSite->RecalcLayout();
*/
	m_pDockSite->SendMessageToDescendants(
		WM_IDLEUPDATECMDUI,
		(WPARAM)TRUE,
		0
		);
	m_pDockSite->SendMessageToDescendants(
		WM_IDLEUPDATECMDUI,
		(WPARAM)TRUE,
		0,
		TRUE,
		TRUE
		);
	m_pDockSite->SendMessage(
		WM_SETMESSAGESTRING,
		AFX_IDS_IDLEMESSAGE
		);
}

CExtControlBar::InternalDockStateBar::InternalDockStateBar()
{
	InitMembers();
}

CExtControlBar::InternalDockStateBar::~InternalDockStateBar()
{
	Clear();
}

void CExtControlBar::InternalDockStateBar::Serialize( CArchive & ar )
{
	ASSERT_VALID( this );

INT i, nCount;

	if( ar.IsStoring() )
	{
		ar << m_nBarID;
		ar << m_nDockBarID;
		ar << m_nCircleNo;
		ar << m_nMRUWidth;
		ar << m_dwBarFlags;
		ar << m_dwDockStateFlags;
		ar << m_dwMRUFloatStyle;
		ar << m_ptFloatPos;
		ar << m_ptMRUFloatPos;
		ar << m_rcMRUDockPos;
		ar << m_rcFloatingFrame;
		ar << m_dwFloatingFrameCreateStyle;
		ar << m_nDelayedRowUpdateMetric;
		ar << m_rcBar;
		ar << m_sizeDockedH;
		ar << m_sizeDockedV;
		ar << m_sizeFloated;

		nCount = m_arrChildStates.GetSize();
		ar << nCount;
		for( i = 0; i < nCount; i++ )
		{
			InternalDockStateBar * pState = m_arrChildStates[i];
			ASSERT_VALID( pState );
			pState->Serialize( ar );
		}

	} // if( ar.IsStoring() )
	else
	{
		Clear();
		
		ar >> m_nBarID;
		ar >> m_nDockBarID;
		ar >> m_nCircleNo;
		ar >> m_nMRUWidth;
		ar >> m_dwBarFlags;
		ar >> m_dwDockStateFlags;
		ar >> m_dwMRUFloatStyle;
		ar >> m_ptFloatPos;
		ar >> m_ptMRUFloatPos;
		ar >> m_rcMRUDockPos;
		ar >> m_rcFloatingFrame;
		ar >> m_dwFloatingFrameCreateStyle;
		ar >> m_nDelayedRowUpdateMetric;
		ar >> m_rcBar;
		ar >> m_sizeDockedH;
		ar >> m_sizeDockedV;
		ar >> m_sizeFloated;

		ar >> nCount;
		for( i = 0; i < nCount; i++ )
		{
			InternalDockStateBar * pState = new InternalDockStateBar;
			pState->Serialize( ar );
			ASSERT_VALID( pState );
			m_arrChildStates.Add( pState );
		}

	} // else from if( ar.IsStoring() )
}

void CExtControlBar::InternalDockStateBar::Clear()
{
	ASSERT_VALID( this );
	InitMembers();

INT i, nCount;

	nCount = m_arrChildStates.GetSize();
	for( i = 0; i < nCount; i++ )
	{
		InternalDockStateBar * pState = m_arrChildStates[i];
		ASSERT_VALID( pState );
		pState->Clear();
		delete pState;
	}
	m_arrChildStates.RemoveAll();

}

void CExtControlBar::InternalDockStateBar::InitMembers()
{
	ASSERT( this != NULL );
	m_nBarID = m_nDockBarID = AFX_IDW_DOCKBAR_FLOAT;
	m_nCircleNo = 0;
	m_nMRUWidth = 50;
	m_ptFloatPos.x = m_ptFloatPos.y = 0;
	m_rcMRUDockPos.SetRectEmpty();
	m_rcFloatingFrame.SetRect( 0, 0, 200, 200 );
	m_dwFloatingFrameCreateStyle = WS_CHILD;
	m_nDelayedRowUpdateMetric = 0;
	m_rcBar.SetRect( 0, 0, 200, 200 );
	m_dwMRUFloatStyle = 0;
	m_ptMRUFloatPos.x = m_ptMRUFloatPos.y;
	m_sizeDockedH.cx = m_sizeDockedH.cy = 200;
	m_sizeDockedV.cx = m_sizeDockedV.cy = 200;
	m_sizeFloated.cx = m_sizeFloated.cy = 200;

	m_dwDockStateFlags = 0;

	m_nHelperAciveTabChildIndex = -1;
	m_pHelperBar = NULL;
}

void CExtControlBar::InternalDockStateBar::StateGet(
	CExtControlBar * pBar,
	CExtControlBar::InternalDockStateBar * pParentState
	)
{
	pParentState;
	ASSERT_VALID( this );
	ASSERT_VALID( pBar );
	ASSERT( !pBar->IsFixedMode() );
	ASSERT_VALID( pBar->m_pDockBar );
	ASSERT( pBar->m_pDockContext != NULL );
#ifdef _DEBUG
	if( pBar->IsFloating() )
	{
		ASSERT_KINDOF( CDockBar, pBar->m_pDockBar );
		ASSERT( !pBar->m_pDockBar->IsKindOf(RUNTIME_CLASS(CExtDockBar)) );
	}
	else
	{
		ASSERT_KINDOF( CExtDockBar, pBar->m_pDockBar );
	}
#endif // _DEBUG

	Clear();

	m_nBarID = pBar->GetDlgCtrlID();
	m_nDockBarID = pBar->m_pDockBar->GetDlgCtrlID();
	m_nCircleNo = 0;
	if( !pBar->IsFloating() )
	{

		ASSERT_KINDOF( CExtDockBar, pBar->m_pDockBar );
		m_nCircleNo = ((CExtDockBar *)pBar->m_pDockBar)->_GetCircleNo();

#ifdef _DEBUG
		CFrameWnd * pParentFrame = pBar->GetParentFrame();
		if( pParentFrame->IsKindOf(RUNTIME_CLASS(CMiniFrameWnd)) )
		{
			ASSERT_KINDOF( CExtMiniDockFrameWnd, pParentFrame );
			ASSERT( m_nCircleNo == 0 );
		}
		else
		{
			//ASSERT( m_nCircleNo > 0 );
			ASSERT( pParentFrame == pBar->m_pDockSite );
		}
#endif // _DEBUG

	}

	if( pBar->IsVisible() )
		m_dwDockStateFlags |= __STATE_VISIBLE;
	
#if (!defined __EXT_MFC_NO_TAB_CONTROLBARS)
	if( pBar->AutoHideModeGet() )
	{
		CExtDockDynTabBar * pTabbedDocker =
			DYNAMIC_DOWNCAST(
				CExtDockDynTabBar,
				pBar->m_pDockBar
				);
		if( pTabbedDocker == NULL )
		{
			if( !pBar->IsKindOf(RUNTIME_CLASS(CExtDynTabControlBar)) )
				m_dwDockStateFlags |= __STATE_AUTOHIDDEN;
		}
		else
		{
			ASSERT_VALID( pParentState );
			ASSERT_KINDOF( CExtDynTabControlBar, pTabbedDocker->GetParent() );
			pParentState->m_dwDockStateFlags |= __STATE_AUTOHIDDEN;
		} // else from if( pTabbedDocker == NULL )
	} // if( pBar->AutoHideModeGet() )
#endif // (!defined __EXT_MFC_NO_TAB_CONTROLBARS)
	
	m_nMRUWidth = pBar->m_nMRUWidth;

CRect m_rcBar;
	pBar->GetWindowRect( &m_rcBar );
//CRect rcBarClient;
//	pBar->GetClientRect( &rcBarClient );
//CSize sizeBarWnd = m_rcBar.Size();
//CSize sizeBarClient = rcBarClient.Size();
//CSize sizeNcArea = sizeBarWnd - sizeBarClient;
	pBar->m_pDockBar->ScreenToClient( &m_rcBar );

	m_ptFloatPos = pBar->m_ptFloatHelper;
	m_sizeDockedH = pBar->m_sizeDockedH; // + sizeNcArea;
	m_sizeDockedV = pBar->m_sizeDockedV; // + sizeNcArea;
	m_sizeFloated = pBar->m_sizeFloated;

	m_nDelayedRowUpdateMetric = pBar->m_nDelayedRowUpdateMetric;

	m_rcMRUDockPos = pBar->m_pDockContext->m_rectMRUDockPos;
	m_dwMRUFloatStyle = pBar->m_pDockContext->m_dwMRUFloatStyle;
	m_ptMRUFloatPos = pBar->m_pDockContext->m_ptMRUFloatPos;

	m_dwBarFlags = pBar->m_dwStyle;

#if (!defined __EXT_MFC_NO_TAB_CONTROLBARS)
	if( pBar->IsKindOf(RUNTIME_CLASS(CExtDynTabControlBar)) )
	{ // if tabbed container
		m_dwDockStateFlags |= InternalDockStateBar::__DOCK_DYNAMIC_TABBED;

		CExtDynTabControlBar * pTabbedBar =
			STATIC_DOWNCAST(
				CExtDynTabControlBar,
				pBar
				);
		
		CExtDockDynTabBar * pTabbedDocker =
			STATIC_DOWNCAST(
				CExtDockDynTabBar,
				pTabbedBar->m_pWndDynDocker //  GetWindow( GW_CHILD )
				);

		ASSERT( pTabbedDocker->m_arrBars.GetSize() > 1 );
		ASSERT( pTabbedDocker->m_arrBars[0] == NULL );

		LONG nSel = -1;
		if( pBar->GetStyle() & WS_VISIBLE )
			nSel = pTabbedBar->GetSwitcherSelection();

		ExtControlBarVector_t vBars;
		pTabbedDocker->CalcOrderedVector( vBars );
		LONG nCount = vBars.GetSize();
		//ASSERT( nCount > 1 );
#ifdef _DEBUG
		INT nRealDockedCount = pTabbedDocker->GetDockedCount();
		ASSERT( nCount == nRealDockedCount );
#endif // _DEBUG
		for( LONG nBar = 0; nBar < nCount; nBar++ )
		{
			CExtControlBar * pChildBar = vBars[ nBar ];
			ASSERT_VALID( pChildBar );
			ASSERT_KINDOF( CExtControlBar, pChildBar );
			ASSERT( !pChildBar->IsFixedMode() );

			InternalDockStateBar * _idsb =
				new InternalDockStateBar;
			_idsb->StateGet( pChildBar, this );
			_idsb->m_dwDockStateFlags |= InternalDockStateBar::__STATE_DYNAMIC_CHILD;
			_idsb->m_dwDockStateFlags |= InternalDockStateBar::__STATE_TAB_CHILD;
			if( nSel == nBar )
				_idsb->m_dwDockStateFlags |= InternalDockStateBar::__STATE_TAB_ACTIVE;
			m_arrChildStates.Add( _idsb );
		}
		ASSERT( m_arrChildStates.GetSize() == nRealDockedCount );

		if( pBar->IsFloating() )
		{
			m_dwDockStateFlags |= InternalDockStateBar::__STATE_FLOATING;
			CExtMiniDockFrameWnd * pMiniFrame =
				STATIC_DOWNCAST(
					CExtMiniDockFrameWnd,
					pBar->GetParentFrame()
					);
			pMiniFrame->GetWindowRect( &m_rcFloatingFrame );
			m_dwFloatingFrameCreateStyle = pMiniFrame->GetStyle();
		}

	} // if tabbed container
	else
#endif // (!defined __EXT_MFC_NO_TAB_CONTROLBARS)
		if( pBar->IsKindOf(RUNTIME_CLASS(CExtDynControlBar)) )
	{ // if dynamic half-split container
		m_dwDockStateFlags |= InternalDockStateBar::__DOCK_DYNAMIC_HALF_SPLIT;
		
		CExtDockDynBar * pDynDocker =
			STATIC_DOWNCAST(
				CExtDockDynBar,
				pBar->GetWindow( GW_CHILD )
				);

		INT nCount = pDynDocker->m_arrBars.GetSize();
		ASSERT( nCount > 1 );
		ASSERT( pDynDocker->m_arrBars[0] == NULL );

		bool bNewRow = false;
		for( INT nBar = 1; nBar < nCount; nBar++ )
		{
			CExtControlBar * pChildBar = (CExtControlBar *)
				pDynDocker->m_arrBars[nBar];
			if( pChildBar == NULL )
			{
				bNewRow = true;
				continue;
			}
			if( __PLACEHODLER_BAR_PTR(pChildBar) )
				continue;
			ASSERT_KINDOF( CExtControlBar, pChildBar );
			ASSERT( !pChildBar->IsFixedMode() );

//			if( pChildBar->IsKindOf(RUNTIME_CLASS(CExtDynControlBar)) )
//			{
//				if( ((CExtDynControlBar*)pChildBar)->m_pWndDynDocker->GetDockedCount() == 0 )
//					continue;
//			}

			InternalDockStateBar * _idsb =
				new InternalDockStateBar;
			_idsb->StateGet( pChildBar, this );
			if( bNewRow )
				_idsb->m_dwDockStateFlags |= InternalDockStateBar::__STATE_NEW_ROW;
			_idsb->m_dwDockStateFlags |= InternalDockStateBar::__STATE_DYNAMIC_CHILD;
			m_arrChildStates.Add( _idsb );

			bNewRow = false;
		}
#ifdef _DEBUG
		INT nRealDockedCount = pDynDocker->GetDockedCount();
		ASSERT( nRealDockedCount > 0 );
		ASSERT( m_arrChildStates.GetSize() == nRealDockedCount );
#endif // _DEBUG

		if( pBar->IsFloating() )
		{
			m_dwDockStateFlags |= InternalDockStateBar::__STATE_FLOATING;
			CExtMiniDockFrameWnd * pMiniFrame =
				STATIC_DOWNCAST(
					CExtMiniDockFrameWnd,
					pBar->GetParentFrame()
					);
			pMiniFrame->GetWindowRect( &m_rcFloatingFrame );
			m_dwFloatingFrameCreateStyle = pMiniFrame->GetStyle();
		}

	} // if dynamic half-split container
	else
	{ // if bar at side
		m_dwDockStateFlags |= InternalDockStateBar::__DOCK_AT_SIDE;
		ASSERT( !pBar->IsFloating() );
	} // if bar at side

}

void CExtControlBar::InternalDockStateBar::StateSet(
	CFrameWnd * pDockSite,
	CExtControlBar::InternalDockStateBar * pParentState
	)
{
	ASSERT_VALID( this );
	ASSERT_VALID( pDockSite );

	m_pHelperBar = NULL;

	switch( (m_dwDockStateFlags & __DOCK_AT_MASK) )
	{
	case __DOCK_AT_NOWHERE:
	break; // case __DOCK_AT_NOWHERE
	case __DOCK_AT_SIDE:
	{
		ASSERT_DOCKBAR_DLGCTRLID_DOCKED( m_nDockBarID );
		ASSERT( (m_dwDockStateFlags & InternalDockStateBar::__STATE_FLOATING) == 0 );
		
		m_pHelperBar = (CExtControlBar *)
			pDockSite->GetControlBar( m_nBarID );
		ASSERT_VALID( m_pHelperBar );
		ASSERT_KINDOF( CExtControlBar, m_pHelperBar );
		ASSERT( !m_pHelperBar->IsFixedMode() );

		if( (m_dwDockStateFlags & InternalDockStateBar::__STATE_DYNAMIC_CHILD) != 0 )
		{
			ASSERT_VALID( pParentState );
			ASSERT_VALID( pParentState->m_pHelperBar );
			ASSERT_KINDOF( CExtDynControlBar, pParentState->m_pHelperBar );

			CExtDockDynBar * pDockBar =
				STATIC_DOWNCAST(
					CExtDockDynBar,
					(	STATIC_DOWNCAST(
							CExtDynControlBar,
							pParentState->m_pHelperBar
							)
						)->m_pWndDynDocker
					);

			pDockBar->_LockSequenceOptimization( true );
			
			m_pHelperBar->m_bUpdatingChain = true;

#if (!defined __EXT_MFC_NO_TAB_CONTROLBARS)
			if( (m_dwDockStateFlags & InternalDockStateBar::__STATE_TAB_CHILD) != 0 )
			{
				ASSERT_KINDOF( CExtDynTabControlBar, pParentState->m_pHelperBar );
				((CExtDynTabControlBar*)pParentState->m_pHelperBar)
					-> InsertBar(
						m_pHelperBar,
						-1,
						false
						);
			} // if( (m_dwDockStateFlags & InternalDockStateBar::__STATE_TAB_CHILD) != 0 )
			else
#endif // (!defined __EXT_MFC_NO_TAB_CONTROLBARS)
			{
				pDockBar->DockControlBar( m_pHelperBar );
			} // else from if( (m_dwDockStateFlags & InternalDockStateBar::__STATE_TAB_CHILD) != 0 )
			
			m_pHelperBar->MoveWindow( &m_rcBar, FALSE );
			m_pHelperBar->m_bUpdatingChain = false;
			
			pDockBar->_LockSequenceOptimization( false );

			INT nBarPos = 
				pDockBar->FindBar( m_pHelperBar );
			ASSERT( nBarPos >= 1 );
			if( nBarPos > 1 )
			{
				if( (m_dwDockStateFlags & __STATE_NEW_ROW) != 0 )
				{
					if( pDockBar->m_arrBars[nBarPos-1] != NULL  )
						pDockBar->m_arrBars.InsertAt(
							nBarPos,
							(CControlBar *)NULL
							);
				} // if( (m_dwDockStateFlags & __STATE_NEW_ROW) != 0 )
				else
				{
					if( pDockBar->m_arrBars[nBarPos-1] == NULL  )
						pDockBar->m_arrBars.RemoveAt( nBarPos-1 );
				} // else from if( (m_dwDockStateFlags & __STATE_NEW_ROW) != 0 )
			} // if( nBarPos > 1 )
		} // if( (m_dwDockStateFlags & InternalDockStateBar::__STATE_DYNAMIC_CHILD) != 0 )
		else
		{
			ASSERT( m_nCircleNo > 0 );

			ASSERT_VALID( m_pHelperBar->m_pDockBar );
			ASSERT( m_pHelperBar->m_pDockContext != NULL );
			ASSERT_KINDOF( CExtDockBar, m_pHelperBar->m_pDockBar );

			CExtDockBar * pDockBar =
				STATIC_DOWNCAST(
					CExtDockBar,
					pDockSite->GetControlBar( m_nDockBarID )
					);
			pDockBar =
				pDockBar->_GetBarByCircleNo( m_nCircleNo );

			pDockBar->_LockSequenceOptimization( true );
			pDockBar->DockControlBar( m_pHelperBar );
			pDockBar->_LockSequenceOptimization( false );

			INT nBarPos = 
				pDockBar->FindBar( m_pHelperBar );
			ASSERT( nBarPos >= 1 );
			if( nBarPos > 1 )
			{
				if( (m_dwDockStateFlags & __STATE_NEW_ROW) != 0 )
				{
					if( pDockBar->m_arrBars[nBarPos-1] != NULL  )
						pDockBar->m_arrBars.InsertAt(
							nBarPos,
							(CControlBar *)NULL
							);
				} // if( (m_dwDockStateFlags & __STATE_NEW_ROW) != 0 )
				else
				{
					if( pDockBar->m_arrBars[nBarPos-1] == NULL  )
						pDockBar->m_arrBars.RemoveAt( nBarPos-1 );
				} // else from if( (m_dwDockStateFlags & __STATE_NEW_ROW) != 0 )
			} // if( nBarPos > 1 )
		} // else from if( (m_dwDockStateFlags & InternalDockStateBar::__STATE_DYNAMIC_CHILD) != 0 )
	}
	break; // case __DOCK_AT_SIDE
	case __DOCK_DYNAMIC_HALF_SPLIT:
	{
		CFrameWnd * pParentFrame = pDockSite;
		if( (m_dwDockStateFlags & InternalDockStateBar::__STATE_FLOATING) != 0 )
		{
			CExtMiniDockFrameWnd * pMiniFrame =
				new CExtMiniDockFrameWnd;
			if( !pMiniFrame->Create(
					pDockSite,
					m_dwFloatingFrameCreateStyle
					)
				)
			{
				ASSERT( FALSE );
				AfxThrowResourceException();
			}
			pParentFrame = pMiniFrame;
			CRect rcFrameAdjusted =
				CExtPaintManager::stat_AlignWndRectToMonitor(
					m_rcFloatingFrame
					);
			pMiniFrame->MoveWindow( &rcFrameAdjusted, FALSE );
			pMiniFrame->DelayRecalcLayout();
		} // if( (m_dwDockStateFlags & InternalDockStateBar::__STATE_FLOATING) != 0 )

		m_pHelperBar = new CExtDynControlBar;

		DWORD dwDynStyle =
				WS_CHILD
				| (m_dwDockStateFlags & CBRS_ALIGN_ANY)
				;
		dwDynStyle |= CBRS_BORDER_ANY;
		dwDynStyle &= ~( CBRS_FLOATING | CBRS_GRIPPER );
		dwDynStyle |= CBRS_TOOLTIPS;

		m_pHelperBar->SetInitDesiredSizeHorizontal( m_sizeDockedH );
		m_pHelperBar->SetInitDesiredSizeVertical( m_sizeDockedV );
		m_pHelperBar->SetInitDesiredSizeFloating( m_sizeFloated );
		if(	!m_pHelperBar->Create(
				NULL,
				pDockSite, // pParentFrame
				m_nBarID,
				dwDynStyle
				)
			)
		{
			ASSERT( FALSE );
			return;
		}
		ASSERT( ((CExtDynControlBar *)m_pHelperBar)->m_pWndDynDocker != NULL );
		ASSERT( ((CExtDynControlBar *)m_pHelperBar)->m_pWndDynDocker->GetSafeHwnd() != NULL );
		ASSERT( ::IsWindow(((CExtDynControlBar *)m_pHelperBar)->m_pWndDynDocker->GetSafeHwnd()) );
		m_pHelperBar->m_pDockSite = pDockSite;
		((CExtDynControlBar *)m_pHelperBar)->m_pWndDynDocker->m_pDockSite = pDockSite;
		m_pHelperBar->m_hWndOwner = pDockSite->GetSafeHwnd();
		m_pHelperBar->EnableDocking( CBRS_ALIGN_ANY );
		ASSERT( m_pHelperBar->m_pDockContext != NULL );
		ASSERT( m_pHelperBar->m_pDockContext->m_pDockSite == pDockSite );
		ASSERT_VALID( m_pHelperBar );

		if( pDockSite->m_listControlBars.Find(m_pHelperBar) == NULL )
			pDockSite->m_listControlBars.AddTail( m_pHelperBar );

		if( (m_dwDockStateFlags & InternalDockStateBar::__STATE_FLOATING) != 0 )
		{
			CExtMiniDockFrameWnd * pMiniFrame =
				STATIC_DOWNCAST(
					CExtMiniDockFrameWnd,
					pParentFrame
					);
			CDockBar * pFloatingDocker =
				STATIC_DOWNCAST(
					CDockBar,
					pMiniFrame->GetWindow(GW_CHILD)
					);
			ASSERT( !pFloatingDocker->IsKindOf(RUNTIME_CLASS(CExtDockBar)) );
			ASSERT( pFloatingDocker->GetDlgCtrlID() == AFX_IDW_DOCKBAR_FLOAT );
			m_pHelperBar->SetParent( pFloatingDocker );
		} // if( (m_dwDockStateFlags & InternalDockStateBar::__STATE_FLOATING) != 0 )

		if( !((CExtDynControlBar *)m_pHelperBar)->m_pWndDynDocker->m_bHelperDockSiteModified )
		{
			POSITION posToRemove =
				pDockSite->m_listControlBars.Find(
					((CExtDynControlBar *)m_pHelperBar)->m_pWndDynDocker
					);
			if( posToRemove != NULL )
			{
				pDockSite->m_listControlBars.RemoveAt( posToRemove );
				((CExtDynControlBar *)m_pHelperBar)->m_pWndDynDocker->m_bHelperDockSiteModified = true;
			} // if( posToRemove != NULL )
		} // if( !((CExtDynControlBar *)m_pHelperBar)->m_pWndDynDocker->m_bHelperDockSiteModified )

		if( (m_dwDockStateFlags & InternalDockStateBar::__STATE_FLOATING) != 0 )
		{
			CDockBar * pDockBar =
				STATIC_DOWNCAST(
					CDockBar,
					pParentFrame->GetWindow( GW_CHILD )
					);
			ASSERT_KINDOF( CDockBar, pDockBar );
			ASSERT( !pDockBar->IsKindOf(RUNTIME_CLASS(CExtDockBar)) );
			ASSERT( pDockBar->GetDlgCtrlID() ==	AFX_IDW_DOCKBAR_FLOAT );
			((CExtDockBar*)pDockBar)->DockControlBar( m_pHelperBar );
			ASSERT( pDockBar->IsFloating() );
			ASSERT( m_pHelperBar->IsFloating() );
			
			m_pHelperBar->m_bUpdatingChain = true;
			m_pHelperBar->MoveWindow( &m_rcBar, FALSE );
			m_pHelperBar->m_bUpdatingChain = false;
		} // if( (m_dwDockStateFlags & InternalDockStateBar::__STATE_FLOATING) != 0 )
		else if( (m_dwDockStateFlags & InternalDockStateBar::__STATE_DYNAMIC_CHILD) != 0 )
		{
			ASSERT_VALID( pParentState );
			ASSERT_VALID( pParentState->m_pHelperBar );
			ASSERT_KINDOF( CExtDynControlBar, m_pHelperBar );

			CExtDockBar * pDockBar =
				STATIC_DOWNCAST(
					CExtDockBar,
					(	STATIC_DOWNCAST(
							CExtDynControlBar,
							pParentState->m_pHelperBar
							)
						)->m_pWndDynDocker
					);

			pDockBar->_LockSequenceOptimization( true );

			pDockBar->DockControlBar( m_pHelperBar );
			
			m_pHelperBar->m_bUpdatingChain = true;
			m_pHelperBar->MoveWindow( &m_rcBar, FALSE );
			m_pHelperBar->m_bUpdatingChain = false;
			
			pDockBar->_LockSequenceOptimization( false );

			INT nBarPos = 
				pDockBar->FindBar( m_pHelperBar );
			ASSERT( nBarPos >= 1 );
			if( nBarPos > 1 )
			{
				if( (m_dwDockStateFlags & __STATE_NEW_ROW) != 0 )
				{
					if( pDockBar->m_arrBars[nBarPos-1] != NULL  )
						pDockBar->m_arrBars.InsertAt(
							nBarPos,
							(CControlBar *)NULL
							);
				} // if( (m_dwDockStateFlags & __STATE_NEW_ROW) != 0 )
				else
				{
					if( pDockBar->m_arrBars[nBarPos-1] == NULL  )
						pDockBar->m_arrBars.RemoveAt( nBarPos-1 );
				} // else from if( (m_dwDockStateFlags & __STATE_NEW_ROW) != 0 )
			} // if( nBarPos > 1 )
		} // else if( (m_dwDockStateFlags & InternalDockStateBar::__STATE_DYNAMIC_CHILD) != 0 )
		else
		{
			ASSERT( m_nCircleNo > 0 );
			ASSERT( m_pHelperBar->m_pDockContext != NULL );

			CExtDockBar * pDockBar =
				STATIC_DOWNCAST(
					CExtDockBar,
					pDockSite->GetControlBar( m_nDockBarID )
					);
			pDockBar =
				pDockBar->_GetBarByCircleNo( m_nCircleNo );

			pDockBar->_LockSequenceOptimization( true );
			
			pDockBar->DockControlBar( m_pHelperBar );
			
			m_pHelperBar->m_bUpdatingChain = true;
			m_pHelperBar->MoveWindow( &m_rcBar, FALSE );
			m_pHelperBar->m_bUpdatingChain = false;
			
			pDockBar->_LockSequenceOptimization( false );

			INT nBarPos = 
				pDockBar->FindBar( m_pHelperBar );
			ASSERT( nBarPos >= 1 );
			if( nBarPos > 1 )
			{
				if( (m_dwDockStateFlags & __STATE_NEW_ROW) != 0 )
				{
					if( pDockBar->m_arrBars[nBarPos-1] != NULL  )
						pDockBar->m_arrBars.InsertAt(
							nBarPos,
							(CControlBar *)NULL
							);
				} // if( (m_dwDockStateFlags & __STATE_NEW_ROW) != 0 )
				else
				{
					if( pDockBar->m_arrBars[nBarPos-1] == NULL  )
						pDockBar->m_arrBars.RemoveAt( nBarPos-1 );
				} // else from if( (m_dwDockStateFlags & __STATE_NEW_ROW) != 0 )
			} // if( nBarPos > 1 )
		} // else from if( (m_dwDockStateFlags & InternalDockStateBar::__STATE_DYNAMIC_CHILD) != 0 )

		INT nCount = m_arrChildStates.GetSize();
		for( INT nBar = 0; nBar < nCount; nBar ++ )
		{
			InternalDockStateBar * pState = m_arrChildStates[nBar];
			ASSERT_VALID( pState );
			pState->StateSet( pDockSite, this );
		}
	
#ifdef _DEBUG
		INT nRealDockedCount =
			((CExtDynControlBar *)m_pHelperBar)
				-> m_pWndDynDocker
				-> GetDockedCount();
		ASSERT( nRealDockedCount == nCount );
#endif // _DEBUG

	}
	break; // case __DOCK_DYNAMIC_HALF_SPLIT
	
#if (!defined __EXT_MFC_NO_TAB_CONTROLBARS)
	case __DOCK_DYNAMIC_TABBED:
	{
		CFrameWnd * pParentFrame = pDockSite;
		if( (m_dwDockStateFlags & InternalDockStateBar::__STATE_FLOATING) != 0 )
		{
			CExtMiniDockFrameWnd * pMiniFrame =
				new CExtMiniDockFrameWnd;
			if( !pMiniFrame->Create(
					pDockSite,
					m_dwFloatingFrameCreateStyle
					)
				)
			{
				ASSERT( FALSE );
				AfxThrowResourceException();
			}
			CRect rcFrameAdjusted =
				CExtPaintManager::stat_AlignWndRectToMonitor(
					m_rcFloatingFrame
					);
			pMiniFrame->MoveWindow( &rcFrameAdjusted, FALSE );
			pMiniFrame->DelayRecalcLayout();
			pParentFrame = pMiniFrame;
		} // if( (m_dwDockStateFlags & InternalDockStateBar::__STATE_FLOATING) != 0 )

		DWORD dwDynStyle =
				WS_CHILD
				| (m_dwDockStateFlags & CBRS_ALIGN_ANY)
				;
		dwDynStyle |= CBRS_BORDER_ANY;
		dwDynStyle &= ~( CBRS_FLOATING | CBRS_GRIPPER );
		dwDynStyle |= CBRS_TOOLTIPS;

		m_pHelperBar = NULL;
		pDockSite->SendMessage(
			g_nMsgCreateTabbedBar,
			WPARAM( &m_pHelperBar )
			);
#ifdef _DEBUG
		if( m_pHelperBar != NULL )
		{
			ASSERT_VALID( m_pHelperBar );
			ASSERT_KINDOF( CExtDynTabControlBar, m_pHelperBar );
		} // if( m_pHelperBar != NULL )
#endif // _DEBUG
		if( m_pHelperBar == NULL )
			m_pHelperBar = new CExtDynTabControlBar;
		m_pHelperBar->SetInitDesiredSizeHorizontal( m_sizeDockedH );
		m_pHelperBar->SetInitDesiredSizeVertical( m_sizeDockedV );
		m_pHelperBar->SetInitDesiredSizeFloating( m_sizeFloated );
		if(	!m_pHelperBar->Create(
				NULL,
				pDockSite, // pParentFrame
				m_nBarID,
				dwDynStyle
				)
			)
		{
			ASSERT( FALSE );
			return;
		}
		ASSERT( ((CExtDynControlBar *)m_pHelperBar)->m_pWndDynDocker != NULL );
		ASSERT( ((CExtDynControlBar *)m_pHelperBar)->m_pWndDynDocker->GetSafeHwnd() != NULL );
		ASSERT( ::IsWindow(((CExtDynControlBar *)m_pHelperBar)->m_pWndDynDocker->GetSafeHwnd()) );
		m_pHelperBar->m_pDockSite = pDockSite;
		((CExtDynControlBar *)m_pHelperBar)->m_pWndDynDocker->m_pDockSite = pDockSite;
		m_pHelperBar->m_hWndOwner = pDockSite->GetSafeHwnd();
		m_pHelperBar->EnableDocking( CBRS_ALIGN_ANY );
		ASSERT( m_pHelperBar->m_pDockContext != NULL );
		ASSERT( m_pHelperBar->m_pDockContext->m_pDockSite == pDockSite );
		ASSERT_VALID( m_pHelperBar );

		if( pDockSite->m_listControlBars.Find(m_pHelperBar) == NULL )
			pDockSite->m_listControlBars.AddTail( m_pHelperBar );

		if( (m_dwDockStateFlags & InternalDockStateBar::__STATE_FLOATING) != 0 )
		{
			CExtMiniDockFrameWnd * pMiniFrame =
				STATIC_DOWNCAST(
					CExtMiniDockFrameWnd,
					pParentFrame
					);
			CDockBar * pFloatingDocker =
				STATIC_DOWNCAST(
					CDockBar,
					pMiniFrame->GetWindow(GW_CHILD)
					);
			ASSERT( !pFloatingDocker->IsKindOf(RUNTIME_CLASS(CExtDockBar)) );
			ASSERT( pFloatingDocker->GetDlgCtrlID() == AFX_IDW_DOCKBAR_FLOAT );
			m_pHelperBar->SetParent( pFloatingDocker );
		} // if( (m_dwDockStateFlags & InternalDockStateBar::__STATE_FLOATING) != 0 )

		if( !((CExtDynControlBar *)m_pHelperBar)->m_pWndDynDocker->m_bHelperDockSiteModified )
		{
			POSITION posToRemove =
				pDockSite->m_listControlBars.Find(
					((CExtDynControlBar *)m_pHelperBar)->m_pWndDynDocker
					);
			if( posToRemove != NULL )
			{
				pDockSite->m_listControlBars.RemoveAt( posToRemove );
				((CExtDynControlBar *)m_pHelperBar)->m_pWndDynDocker->m_bHelperDockSiteModified = true;
			} // if( posToRemove != NULL )
		} // if( !((CExtDynControlBar *)m_pHelperBar)->m_pWndDynDocker->m_bHelperDockSiteModified )

		if( (m_dwDockStateFlags & InternalDockStateBar::__STATE_FLOATING) != 0 )
		{
			CDockBar * pDockBar =
				STATIC_DOWNCAST(
					CDockBar,
					pParentFrame->GetWindow( GW_CHILD )
					);
			ASSERT_KINDOF( CDockBar, pDockBar );
			ASSERT( !pDockBar->IsKindOf(RUNTIME_CLASS(CExtDockBar)) );
			ASSERT( pDockBar->GetDlgCtrlID() ==	AFX_IDW_DOCKBAR_FLOAT );
			((CExtDockBar*)pDockBar)->DockControlBar( m_pHelperBar );
			ASSERT( pDockBar->IsFloating() );
			ASSERT( m_pHelperBar->IsFloating() );
			
			m_pHelperBar->m_bUpdatingChain = true;
			m_pHelperBar->MoveWindow( &m_rcBar, FALSE );
			m_pHelperBar->m_bUpdatingChain = false;
		} // if( (m_dwDockStateFlags & InternalDockStateBar::__STATE_FLOATING) != 0 )
		else if( (m_dwDockStateFlags & InternalDockStateBar::__STATE_DYNAMIC_CHILD) != 0 )
		{
			ASSERT_VALID( pParentState );
			ASSERT_VALID( pParentState->m_pHelperBar );
			ASSERT_KINDOF( CExtDynControlBar, m_pHelperBar );

			CExtDockBar * pDockBar =
				STATIC_DOWNCAST(
					CExtDockBar,
					(	STATIC_DOWNCAST(
							CExtDynControlBar,
							pParentState->m_pHelperBar
							)
						)->m_pWndDynDocker
					);

			pDockBar->_LockSequenceOptimization( true );
			
			pDockBar->DockControlBar( m_pHelperBar );
			
			m_pHelperBar->m_bUpdatingChain = true;
			m_pHelperBar->MoveWindow( &m_rcBar, FALSE );
			m_pHelperBar->m_bUpdatingChain = false;
			
			pDockBar->_LockSequenceOptimization( false );

			INT nBarPos = 
				pDockBar->FindBar( m_pHelperBar );
			ASSERT( nBarPos >= 1 );
			if( nBarPos > 1 )
			{
				if( (m_dwDockStateFlags & __STATE_NEW_ROW) != 0 )
				{
					if( pDockBar->m_arrBars[nBarPos-1] != NULL  )
						pDockBar->m_arrBars.InsertAt(
							nBarPos,
							(CControlBar *)NULL
							);
				} // if( (m_dwDockStateFlags & __STATE_NEW_ROW) != 0 )
				else
				{
					if( pDockBar->m_arrBars[nBarPos-1] == NULL  )
						pDockBar->m_arrBars.RemoveAt( nBarPos-1 );
				} // else from if( (m_dwDockStateFlags & __STATE_NEW_ROW) != 0 )
			} // if( nBarPos > 1 )
		} // else if( (m_dwDockStateFlags & InternalDockStateBar::__STATE_DYNAMIC_CHILD) != 0 )
		else
		{
			ASSERT( m_nCircleNo > 0 );
			ASSERT( m_pHelperBar->m_pDockContext != NULL );

			CExtDockBar * pDockBar =
				STATIC_DOWNCAST(
					CExtDockBar,
					pDockSite->GetControlBar( m_nDockBarID )
					);
			pDockBar =
				pDockBar->_GetBarByCircleNo( m_nCircleNo );

			pDockBar->_LockSequenceOptimization( true );
			
			pDockBar->DockControlBar( m_pHelperBar );
			
			m_pHelperBar->m_bUpdatingChain = true;
			m_pHelperBar->MoveWindow( &m_rcBar, FALSE );
			m_pHelperBar->m_bUpdatingChain = false;
			
			pDockBar->_LockSequenceOptimization( false );

			INT nBarPos = 
				pDockBar->FindBar( m_pHelperBar );
			ASSERT( nBarPos >= 1 );
			if( nBarPos > 1 )
			{
				if( (m_dwDockStateFlags & __STATE_NEW_ROW) != 0 )
				{
					if( pDockBar->m_arrBars[nBarPos-1] != NULL  )
						pDockBar->m_arrBars.InsertAt(
							nBarPos,
							(CControlBar *)NULL
							);
				} // if( (m_dwDockStateFlags & __STATE_NEW_ROW) != 0 )
				else
				{
					if( pDockBar->m_arrBars[nBarPos-1] == NULL  )
						pDockBar->m_arrBars.RemoveAt( nBarPos-1 );
				} // else from if( (m_dwDockStateFlags & __STATE_NEW_ROW) != 0 )
			} // if( nBarPos > 1 )
		} // else from if( (m_dwDockStateFlags & InternalDockStateBar::__STATE_DYNAMIC_CHILD) != 0 )

		INT nCount = m_arrChildStates.GetSize();
		//ASSERT( nCount > 1 );
		m_nHelperAciveTabChildIndex = -1;
		for( INT nBar = 0; nBar < nCount; nBar ++ )
		{
			InternalDockStateBar * pState = m_arrChildStates[nBar];
			ASSERT_VALID( pState );
			if( (pState->m_dwDockStateFlags & InternalDockStateBar::__STATE_TAB_ACTIVE) != 0 )
			{
				if( (pState->m_dwDockStateFlags & InternalDockStateBar::__STATE_VISIBLE) != 0 )
				{
					ASSERT( m_nHelperAciveTabChildIndex == -1 );
					m_nHelperAciveTabChildIndex = nBar;
				}
			}
			pState->StateSet( pDockSite, this );
		}

#ifdef _DEBUG
		INT nRealDockedCount =
			((CExtDynTabControlBar *)m_pHelperBar)
				-> m_pWndDynDocker
				-> GetDockedCount();
		ASSERT( nRealDockedCount == nCount );
#endif // _DEBUG

	}
	break; // case __DOCK_DYNAMIC_TABBED
#endif // (!defined __EXT_MFC_NO_TAB_CONTROLBARS)

#ifdef _DEBUG
	default:
	{
		ASSERT( FALSE );
	}
	break;
#endif // _DEBUG
	} // switch( (m_dwDockStateFlags & __DOCK_AT_MASK) )

	ASSERT_VALID( m_pHelperBar );

//bool bBarWndVisible = ( ( m_pHelperBar->GetStyle() & WS_VISIBLE ) != 0 ) ? true : false;
//	if( (m_dwDockStateFlags & __STATE_VISIBLE) != 0 )
//	{
//		if( !bBarWndVisible )
//			pDockSite->ShowControlBar( m_pHelperBar, TRUE, TRUE );
//	} // if( (m_dwDockStateFlags & __STATE_VISIBLE) != 0 )
//	else
//	{
//		if( bBarWndVisible )
//			pDockSite->ShowControlBar( m_pHelperBar, FALSE, TRUE );
//	} // else from if( (m_dwDockStateFlags & __STATE_VISIBLE) != 0 )

	pDockSite->ShowControlBar(
		m_pHelperBar,
		(m_dwDockStateFlags & __STATE_VISIBLE) ? TRUE : FALSE,
		TRUE
		);

CExtMiniDockFrameWnd * pMiniFrame =
		DYNAMIC_DOWNCAST(
			CExtMiniDockFrameWnd,
			m_pHelperBar->GetParentFrame()
			);
	if( pMiniFrame != NULL )
	{
		ASSERT_VALID( pMiniFrame );
		INT nCount = pMiniFrame->m_listControlBars.GetCount();
		if( nCount != 0 )
		{
			ASSERT( nCount == 1 );
			pMiniFrame->m_listControlBars.RemoveAll();
		}

		CRect rcFrameInitial;
		pMiniFrame->GetWindowRect( &rcFrameInitial );
		CRect rcFrameAdjusted =
			CExtPaintManager::stat_AlignWndRectToMonitor(
				rcFrameInitial
				);
		if( rcFrameAdjusted != rcFrameInitial )
		{
			pMiniFrame->MoveWindow( &rcFrameAdjusted, FALSE );
			pMiniFrame->DelayRecalcLayout();
		} // if( rcFrameAdjusted != rcFrameInitial )
	} // if( pMiniFrame != NULL )


	m_pHelperBar->m_dwStyle = m_dwBarFlags;

	m_pHelperBar->m_ptFloatHelper = m_ptFloatPos;

	m_pHelperBar->m_sizeDockedH = m_sizeDockedH;
	m_pHelperBar->m_sizeDockedV = m_sizeDockedV;
	m_pHelperBar->m_sizeFloated = m_sizeFloated;

	m_pHelperBar->m_nDelayedRowUpdateMetric = m_nDelayedRowUpdateMetric;

	m_pHelperBar->m_nMRUWidth = m_nMRUWidth;

	m_pHelperBar->m_pDockContext->m_rectMRUDockPos = m_rcMRUDockPos;
	m_pHelperBar->m_pDockContext->m_dwMRUFloatStyle = m_dwMRUFloatStyle;
	m_pHelperBar->m_pDockContext->m_ptMRUFloatPos = m_ptMRUFloatPos;

//	if( m_dwDockStateFlags & __STATE_AUTOHIDDEN
//		&& !m_pHelperBar->AutoHideModeGet()
//		)
//	{
//		VERIFY(
//			m_pHelperBar->AutoHideModeSet(
//				true,
//				false,
//				false,
//				false
//				)
//			);
//	}
}

void CExtControlBar::InternalDockStateBar::PreSyncAttributes(
	CFrameWnd * pDockSite,
	CExtControlBar::InternalDockStateBar * pParentState
	)
{
	ASSERT_VALID( this );
	ASSERT_VALID( m_pHelperBar );
	pParentState;

	m_pHelperBar->m_ptFloatHelper = m_ptFloatPos;

	m_pHelperBar->m_sizeDockedH = m_sizeDockedH;
	m_pHelperBar->m_sizeDockedV = m_sizeDockedV;
	m_pHelperBar->m_sizeFloated = m_sizeFloated;

	m_pHelperBar->m_nDelayedRowUpdateMetric = m_nDelayedRowUpdateMetric;

	m_pHelperBar->m_nMRUWidth = m_nMRUWidth;

	m_pHelperBar->m_pDockContext->m_rectMRUDockPos = m_rcMRUDockPos;
	m_pHelperBar->m_pDockContext->m_dwMRUFloatStyle = m_dwMRUFloatStyle;
	m_pHelperBar->m_pDockContext->m_ptMRUFloatPos = m_ptMRUFloatPos;

	INT nCount = m_arrChildStates.GetSize();
	for( INT nBar = 0; nBar < nCount; nBar++ )
	{
		InternalDockStateBar * pState = m_arrChildStates[nBar];
		ASSERT_VALID( pState );
		pState->PreSyncAttributes( pDockSite, this );
	}
}

void CExtControlBar::InternalDockStateBar::PostSyncAttributes(
	CFrameWnd * pDockSite,
	CExtControlBar::InternalDockStateBar * pParentState
	)
{
	ASSERT_VALID( this );
	ASSERT_VALID( m_pHelperBar );
	pParentState;

bool bWalkChild = false;
	switch( (m_dwDockStateFlags & __DOCK_AT_MASK) )
	{
	case __DOCK_AT_NOWHERE:
	{
	}
	break; // case __DOCK_AT_NOWHERE
	case __DOCK_AT_SIDE:
	{
	}
	break; // case __DOCK_AT_SIDE
	case __DOCK_DYNAMIC_HALF_SPLIT:
	{
		bWalkChild = true;
		ASSERT_KINDOF( CExtDynControlBar, m_pHelperBar );
#if (!defined __EXT_MFC_NO_TAB_CONTROLBARS)
		ASSERT( !m_pHelperBar->IsKindOf(RUNTIME_CLASS(CExtDynTabControlBar)) );
#endif // (!defined __EXT_MFC_NO_TAB_CONTROLBARS)

		if( !((CExtDynControlBar *)m_pHelperBar)->m_pWndDynDocker->m_bHelperDockSiteModified )
		{
			POSITION posToRemove =
				pDockSite->m_listControlBars.Find(
					((CExtDynControlBar *)m_pHelperBar)->m_pWndDynDocker
					);
			if( posToRemove != NULL )
			{
				pDockSite->m_listControlBars.RemoveAt( posToRemove );
				((CExtDynControlBar *)m_pHelperBar)->m_pWndDynDocker->m_bHelperDockSiteModified = true;
			} // if( posToRemove != NULL )
		} // if( !((CExtDynControlBar *)m_pHelperBar)->m_pWndDynDocker->m_bHelperDockSiteModified )

		if( (m_dwDockStateFlags & InternalDockStateBar::__STATE_FLOATING) != 0 )
		{
			CExtMiniDockFrameWnd * pParentFrame =
				STATIC_DOWNCAST(
					CExtMiniDockFrameWnd,
					m_pHelperBar->GetParentFrame()
					);
			pParentFrame->RecalcLayout();
		}

#ifdef _DEBUG
		INT nChildsCount = m_arrChildStates.GetSize();
		INT nRealDockedCount =
			((CExtDynControlBar *)m_pHelperBar)
				-> m_pWndDynDocker
				-> GetDockedCount();
		ASSERT( nRealDockedCount == nChildsCount );
#endif // _DEBUG
	}
	break; // case __DOCK_DYNAMIC_HALF_SPLIT
	
#if (!defined __EXT_MFC_NO_TAB_CONTROLBARS)
	case __DOCK_DYNAMIC_TABBED:
	{
		bWalkChild = true;
		ASSERT_KINDOF( CExtDynTabControlBar, m_pHelperBar );

		if( !((CExtDynControlBar *)m_pHelperBar)->m_pWndDynDocker->m_bHelperDockSiteModified )
		{
			POSITION posToRemove =
				pDockSite->m_listControlBars.Find(
					((CExtDynControlBar *)m_pHelperBar)->m_pWndDynDocker
					);
			if( posToRemove != NULL )
			{
				pDockSite->m_listControlBars.RemoveAt( posToRemove );
				((CExtDynControlBar *)m_pHelperBar)->m_pWndDynDocker->m_bHelperDockSiteModified = true;
			} // if( posToRemove != NULL )
		} // if( !((CExtDynControlBar *)m_pHelperBar)->m_pWndDynDocker->m_bHelperDockSiteModified )

		if( (m_dwDockStateFlags & InternalDockStateBar::__STATE_FLOATING) != 0 )
		{
			CExtMiniDockFrameWnd * pParentFrame =
				STATIC_DOWNCAST(
					CExtMiniDockFrameWnd,
					m_pHelperBar->GetParentFrame()
					);
			pParentFrame->RecalcLayout();
		}

		if( m_nHelperAciveTabChildIndex >= 0 )
		{
			//ASSERT( m_pHelperBar->GetStyle() & WS_VISIBLE );
			if( (m_pHelperBar->GetStyle() & WS_VISIBLE) == 0 )
				m_pHelperBar->ShowWindow( SW_SHOWNA );

			CExtDynTabControlBar * pTabbedBar =
				STATIC_DOWNCAST(
					CExtDynTabControlBar,
					m_pHelperBar
					);
			LONG nSel = 
				pTabbedBar->GetSwitcherSelection();
			if(		nSel != m_nHelperAciveTabChildIndex
				&&	m_nHelperAciveTabChildIndex >= 0
				&&	pTabbedBar->GetBarAt(m_nHelperAciveTabChildIndex,true)->IsVisible()
				)
				pTabbedBar->SetSwitcherSelection(
					m_nHelperAciveTabChildIndex,
					true,
					true
					);
		}
	
#ifdef _DEBUG
		INT nChildsCount = m_arrChildStates.GetSize();
		INT nRealDockedCount =
			((CExtDynTabControlBar *)m_pHelperBar)
				-> m_pWndDynDocker
				-> GetDockedCount();
		ASSERT( nRealDockedCount == nChildsCount );
#endif // _DEBUG
	}
	break; // case __DOCK_DYNAMIC_TABBED
#endif // (!defined __EXT_MFC_NO_TAB_CONTROLBARS)

#ifdef _DEBUG
	default:
	{
		ASSERT( FALSE );
	}
	break;
#endif // _DEBUG
	} // switch( (m_dwDockStateFlags & __DOCK_AT_MASK) )

	if( bWalkChild )
	{
		INT nCount = m_arrChildStates.GetSize();
		ASSERT( nCount > 0 );
		for( INT nBar = 0; nBar < nCount; nBar++ )
		{
			InternalDockStateBar * pState = m_arrChildStates[nBar];
			ASSERT_VALID( pState );
			pState->PostSyncAttributes( pDockSite, this );
		}
	}





	m_pHelperBar->m_ptFloatHelper = m_ptFloatPos;

	m_pHelperBar->m_sizeDockedH = m_sizeDockedH;
	m_pHelperBar->m_sizeDockedV = m_sizeDockedV;
	m_pHelperBar->m_sizeFloated = m_sizeFloated;

	m_pHelperBar->m_nDelayedRowUpdateMetric = m_nDelayedRowUpdateMetric;

	m_pHelperBar->m_nMRUWidth = m_nMRUWidth;

	m_pHelperBar->m_pDockContext->m_rectMRUDockPos = m_rcMRUDockPos;
	m_pHelperBar->m_pDockContext->m_dwMRUFloatStyle = m_dwMRUFloatStyle;
	m_pHelperBar->m_pDockContext->m_ptMRUFloatPos = m_ptMRUFloatPos;
}

bool CExtControlBar::ProfileBarStateSerialize(
	CArchive & ar,
	CFrameWnd * pFrame,
	LPWINDOWPLACEMENT pFrameWp // = NULL // need serialize frame's WP
	)
{
	ASSERT( pFrame != NULL );
	ASSERT(
		::IsWindow( pFrame->GetSafeHwnd() )
		);
	ASSERT_VALID( pFrame );

bool bRetVal = false;
	try
	{
		InternalDockStateSite state( pFrame );

		if( ar.IsStoring() )
		{
			((InternalFriendlyFrameWnd *)pFrame)->
				GetDockState(
					state
					);
			state.Serialize( ar );
		} // if( ar.IsStoring() )
		else
		{
			// win xp fix - begin
			WINDOWPLACEMENT _wpf;
			::memset( &_wpf, 0, sizeof(WINDOWPLACEMENT) );
			_wpf.length = sizeof(WINDOWPLACEMENT);
			if( pFrame->GetWindowPlacement(&_wpf) )
			{
				_wpf.ptMinPosition.x = _wpf.ptMinPosition.y = 0;
				_wpf.ptMaxPosition.x = _wpf.ptMaxPosition.y = 0;
				_wpf.showCmd = 
					(pFrame->GetStyle() & WS_VISIBLE)
						? SW_SHOWNA
						: SW_HIDE;
				pFrame->SetWindowPlacement(&_wpf);
			} // if( pFrame->GetWindowPlacement(&_wpf) )
			// win xp fix - end
			bool bPresetWP =
				( pFrameWp != NULL ) ? true : false;
			state.Serialize( ar );
			((InternalFriendlyFrameWnd *)pFrame)->SetDockState(
				state,
				bPresetWP
				);
		} // else from if( ar.IsStoring() )

		if( pFrameWp != NULL )
			::memcpy(
				pFrameWp,
				&state.m_wp,
				sizeof(WINDOWPLACEMENT)
				);
		// almost OK
		bRetVal = true;
	} // try
	catch( CException * pXept )
	{
		pXept->Delete();
		ASSERT( FALSE );
	} // catch( CException * pXept )
	catch( ... )
	{
		ASSERT( FALSE );
	} // catch( ... )

	return bRetVal;
}

LRESULT CExtControlBar::OnSetText(WPARAM wParam, LPARAM lParam)
{
    wParam;
LRESULT lResult = CWnd::Default();
	if(	IsFloating() )
	{
		CFrameWnd * pFrame = GetParentFrame();
		if(		pFrame != NULL
			&&	pFrame->IsKindOf(RUNTIME_CLASS(CMiniDockFrameWnd))
			)
		{
			m_pDockBar->SetWindowText( (LPTSTR) lParam );
			pFrame->SetWindowText( (LPTSTR) lParam );
			pFrame->DelayRecalcLayout();
			pFrame->SendMessage( WM_NCPAINT );
		}
	}

bool bTextOnGripper = false;
	if( IsBarWithGripper( NULL, &bTextOnGripper ) )
	{
		if( bTextOnGripper )
			SendMessage( WM_NCPAINT );
	}
	return lResult;
}

static void stat_AddUnique(
	ExtControlBarVector_t & vBars,
	CExtControlBar * pBar
	)
{
	ASSERT( pBar != NULL );
INT nCount = vBars.GetSize();
	for( INT nBar = 0; nBar < nCount; nBar++ )
	{
		CExtControlBar * pAddedBar = vBars[ nBar ];
		ASSERT( pAddedBar != NULL );
		if( pAddedBar == pBar )
			return;
	}
#if (!defined __EXT_MFC_NO_TAB_CONTROLBARS)
	if( pBar->m_pDockBar != NULL )
	{
		if( pBar->m_pDockBar->IsKindOf( RUNTIME_CLASS(CExtDockDynTabBar) ) )
		{
			CExtDynTabControlBar * pTabbedBar =
				STATIC_DOWNCAST(
					CExtDynTabControlBar,
					pBar->m_pDockBar->GetParent()
					);
			stat_AddUnique( vBars, pTabbedBar );
			return;
		}
	}
#endif // (!defined __EXT_MFC_NO_TAB_CONTROLBARS)
	vBars.Add( pBar );
}

void CExtControlBar::_GetFrameControlBars(
	CFrameWnd * pFrame,
	ExtControlBarVector_t & vBars,
	DWORD dwCallOpt, // = ((DWORD)__GFECB_ALL_NONRESTRICT)
	CPoint ptRestrict // = CPoint( -1000, -1000 )
	)
{
	ASSERT( pFrame != NULL );
	ASSERT( pFrame->GetSafeHwnd() != NULL );
	ASSERT( ::IsWindow( pFrame->GetSafeHwnd() ) );
	ASSERT_VALID( pFrame );
	vBars.RemoveAll();
	if( ( dwCallOpt & 
			( DWORD(__GFECB_FIXED) | DWORD(__GFECB_NONFIXED) )
			) == 0
		)
		return; // empty query
	if( ( dwCallOpt & 
			( DWORD(__GFECB_BAR_VISIBLE) | DWORD(__GFECB_BAR_INVISIBLE) )
			) == 0
		)
		return; // empty query
	if( ( dwCallOpt & 
			( DWORD(__GFECB_WND_VISIBLE) | DWORD(__GFECB_WND_INVISIBLE) )
			) == 0
		)
		return; // empty query
CSingleLock _slCsCB( &g_csCB );
	_slCsCB.Lock();
int nAllBarsCount = g_AllBars.GetSize();
	for( INT nBar = 0; nBar < nAllBarsCount; nBar++ )
	{
		CExtControlBar * pBar = g_AllBars[nBar];
		ASSERT_KINDOF( CExtControlBar, pBar );
		if( pBar->GetSafeHwnd() == NULL )
			continue;
		if( !(::IsWindow(pBar->GetSafeHwnd())) )
			continue;
		if( pBar->IsKindOf(RUNTIME_CLASS(CExtDynControlBar))
#if (!defined __EXT_MFC_NO_TAB_CONTROLBARS)
			&& ( !pBar->IsKindOf(RUNTIME_CLASS(CExtDynTabControlBar)) )
#endif // (!defined __EXT_MFC_NO_TAB_CONTROLBARS)
			)
			continue;
		if( pBar->m_bPresubclassDialogMode )
			continue;
		CFrameWnd * pBarFrame =
			_GetDockingFrameImpl( pBar );
		ASSERT( pBarFrame != NULL );
		ASSERT( pBarFrame->GetSafeHwnd() != NULL );
		ASSERT( ::IsWindow( pBarFrame->GetSafeHwnd() ) );
		ASSERT_VALID( pBarFrame );
		if( pBarFrame != pFrame )
			continue;
		if( dwCallOpt == ((DWORD)__GFECB_ALL_NONRESTRICT) )
		{
			//stat_AddUnique( vBars, pBar );
			vBars.Add( pBar );
			continue;
		}
		if( (dwCallOpt&((DWORD)__GFECB_FIXED)) == 0 )
		{
			if( pBar->IsFixedMode() )
				continue;
		}
		if( !pBar->IsFixedMode() )
		{
			if( (dwCallOpt&((DWORD)__GFECB_NONFIXED)) == 0 )
				continue;
			bool bMinOnRow = pBar->IsMinimizedOnRow();
			if( (dwCallOpt&((DWORD)__GFECB_NONFIXED_MIN)) == 0 )
			{
				if( bMinOnRow )
					continue;
			}
			if( (dwCallOpt&((DWORD)__GFECB_NONFIXED_NONMIN)) == 0 )
			{
				if( !bMinOnRow )
					continue;
			}
		}
		if( pBar->IsVisible() )
		{
			if( (dwCallOpt&((DWORD)__GFECB_BAR_VISIBLE)) == 0 )
				continue;
		}
		else
		{
			if( (dwCallOpt&((DWORD)__GFECB_BAR_INVISIBLE)) == 0 )
				continue;
		}
		if( pBar->IsWindowVisible() )
		{
			if( (dwCallOpt&((DWORD)__GFECB_WND_VISIBLE)) == 0 )
				continue;
		}
		else
		{
			if( (dwCallOpt&((DWORD)__GFECB_WND_INVISIBLE)) == 0 )
				continue;
		}

		if( pBar->IsFloating() )
		{
			if( (dwCallOpt&((DWORD)__GFECB_FLOATED)) == 0 )
				continue;
		} // if( pBar->IsFloating() )
		else
		{
			if( (dwCallOpt&((DWORD)__GFECB_DOCKED)) == 0 )
				continue;
			if( (dwCallOpt&((DWORD)__GFECB_DOCKED)) !=
					((DWORD)__GFECB_DOCKED)
				)
			{ // if not all docked bars
				UINT nDockBarID = pBar->GetSafeDockBarDlgCtrlID();
				switch( nDockBarID )
				{
				case AFX_IDW_DOCKBAR_TOP:
					if( (dwCallOpt&((DWORD)__GFECB_DOCKED_TOP)) == 0 )
						continue;
				break;
				case AFX_IDW_DOCKBAR_BOTTOM:
					if( (dwCallOpt&((DWORD)__GFECB_DOCKED_BOTTOM)) == 0 )
						continue;
				break;
				case AFX_IDW_DOCKBAR_LEFT:
					if( (dwCallOpt&((DWORD)__GFECB_DOCKED_LEFT)) == 0 )
						continue;
				break;
				case AFX_IDW_DOCKBAR_RIGHT:
					if( (dwCallOpt&((DWORD)__GFECB_DOCKED_RIGHT)) == 0 )
						continue;
				break;
#ifdef _DEBUG
				default:
					ASSERT( FALSE );
				break;
#endif // _DEBUG
				} // switch( nDockBarID )
			} // if not all docked bars
		} // else from if( pBar->IsFloating() )

		// restriction by point
		if( (dwCallOpt&((DWORD)__GFECB_BYPT_ALL)) != 0 )
		{ // if restriction by point
			CRect rcWnd;
			CWnd * pWndNcTest = pBar;
			if( pBar->IsFloating() )
			{
				pWndNcTest = pBar->GetDockingFrame();
				ASSERT( pWndNcTest != NULL );
				ASSERT( pWndNcTest->GetSafeHwnd() != NULL );
				ASSERT( ::IsWindow( pWndNcTest->GetSafeHwnd() ) );
				ASSERT_VALID( pWndNcTest );
				ASSERT_KINDOF( CMiniDockFrameWnd, pWndNcTest );
			}
			pWndNcTest->GetWindowRect( &rcWnd );
			BOOL bInsideWndArea =
				rcWnd.PtInRect( ptRestrict );
			if( !bInsideWndArea )
				continue;
			
			if( (dwCallOpt&((DWORD)__GFECB_BYPT_ONLY_WND)) != 0 )
			{
				stat_AddUnique( vBars, pBar );
				//continue;
				_slCsCB.Unlock();
				return;
			}
			
			if( (dwCallOpt&((DWORD)__GFECB_BYPT_NCGRIP)) != 0 )
			{
				if( pBar->m_rcGrip.IsRectEmpty() )
					continue;
				CPoint ptWnd( ptRestrict );
				ptWnd -= rcWnd.TopLeft();
				if( !pBar->m_rcGrip.PtInRect(ptWnd) )
					continue;
			}

			if( (dwCallOpt&((DWORD)__GFECB_BYPT_CLIENT)) != 0 )
			{
				CRect rcClient;
				pBar->GetClientRect( &rcClient );
				pBar->ClientToScreen( &rcClient );
				if( !rcClient.PtInRect( ptRestrict ) )
					continue;
			}

			if( (dwCallOpt&((DWORD)__GFECB_BYPT_NC)) != 0 )
			{ // if any nc hit test restriction
				UINT nHitTest =
					pWndNcTest->SendMessage(
						WM_NCHITTEST,
						WPARAM(0),
						MAKELPARAM(ptRestrict.x,ptRestrict.y)
						);
				if( (dwCallOpt&((DWORD)__GFECB_BYPT_HTLEFT)) != 0 )
				{
					if( nHitTest != HTLEFT )
						continue;
				}
				if( (dwCallOpt&((DWORD)__GFECB_BYPT_HTRIGHT)) != 0 )
				{
					if( nHitTest != HTRIGHT )
						continue;
				}
				if( (dwCallOpt&((DWORD)__GFECB_BYPT_HTTOP)) != 0 )
				{
					if( nHitTest != HTTOP )
						continue;
				}
				if( (dwCallOpt&((DWORD)__GFECB_BYPT_HTBOTTOM)) != 0 )
				{
					if( nHitTest != HTBOTTOM )
						continue;
				}

				if( (dwCallOpt&((DWORD)__GFECB_BYPT_HTTOPLEFT)) != 0 )
				{
					if( nHitTest != HTTOPLEFT )
						continue;
				}
				if( (dwCallOpt&((DWORD)__GFECB_BYPT_HTTOPRIGHT)) != 0 )
				{
					if( nHitTest != HTTOPRIGHT )
						continue;
				}
				if( (dwCallOpt&((DWORD)__GFECB_BYPT_HTBOTTOMLEFT)) != 0 )
				{
					if( nHitTest != HTBOTTOMLEFT )
						continue;
				}
				if( (dwCallOpt&((DWORD)__GFECB_BYPT_HTBOTTOMRIGHT)) != 0 )
				{
					if( nHitTest != HTBOTTOMRIGHT )
						continue;
				}

				if( (dwCallOpt&((DWORD)__GFECB_BYPT_HTNOWHERE)) != 0 )
				{
					if( nHitTest != HTNOWHERE )
						continue;
				}
				
				if( (dwCallOpt&((DWORD)__GFECB_BYPT_HTSYSMENU)) != 0 )
				{
					if( nHitTest != HTSYSMENU )
						continue;
				}
				
				if( (dwCallOpt&((DWORD)__GFECB_BYPT_HTGROWBOX)) != 0 )
				{
					if( nHitTest != HTGROWBOX )
						continue;
				}
				
				if( (dwCallOpt&((DWORD)__GFECB_BYPT_HTMINBUTTON)) != 0 )
				{
					if( nHitTest != HTMINBUTTON )
						continue;
				}
				
				if( (dwCallOpt&((DWORD)__GFECB_BYPT_HTMAXBUTTON)) != 0 )
				{
					if( nHitTest != HTMAXBUTTON )
						continue;
				}

				if( (dwCallOpt&((DWORD)__GFECB_BYPT_HTCLIENT)) != 0 )
				{
					if( nHitTest != HTCLIENT )
						continue;
				}
				
			} // if any nc hit test restriction
		} // if restriction by point

		stat_AddUnique( vBars, pBar );
	} // for( INT nBar = 0; nBar < nAllBarsCount; nBar++ )

	_slCsCB.Unlock();
}

void CExtControlBar::_GetFrameControlBars(
	ExtControlBarVector_t & vBars,
	DWORD dwCallOpt, // = ((DWORD)__GFECB_ALL_NONRESTRICT)
	CPoint ptRestrict // = CPoint( -1000, -1000 )
	) const
{
CFrameWnd * pFrame = _GetDockingFrameImpl();
	_GetFrameControlBars(
		pFrame,
		vBars,
		dwCallOpt,
		ptRestrict
		);
}

CControlBar * CExtControlBar::_GetNextControlBarInRow(
	CControlBar * pBar,
	bool bNext, // = true // next or previous
	bool bExtBar, // = false
	bool bNonFixed // = false
	)
{
	ASSERT( pBar != NULL );
	ASSERT( pBar->GetSafeHwnd() != NULL );
	ASSERT_VALID( pBar );
	ASSERT( !pBar->IsFloating() );
	ASSERT_VALID( pBar->m_pDockBar );
INT nPos = pBar->m_pDockBar->FindBar( pBar );
	ASSERT( nPos >= 0 );
	if( nPos == 0 && !bNext )
		return NULL; // first in first row
INT nCountOfSideBars = pBar->m_pDockBar->m_arrBars.GetSize();
	ASSERT( nPos < nCountOfSideBars );
	if( nPos == (nCountOfSideBars-1) && bNext )
		return NULL; // last in last row
	if( bNext )
	{
		for( nPos++; nPos < nCountOfSideBars; nPos++ )
		{
			CControlBar * pExamineBar = (CControlBar *)
				pBar->m_pDockBar->m_arrBars[ nPos ];
			ASSERT( pExamineBar != pBar );
			if( pExamineBar == NULL )
				return NULL; // row separator
			if( __PLACEHODLER_BAR_PTR(pExamineBar) )
				continue;
			if( bExtBar )
			{
				if( !pBar->IsKindOf(RUNTIME_CLASS(CExtControlBar)) )
					continue;
				if( bNonFixed )
				{
					if( ((CExtControlBar *)pBar)->IsFixedMode() )
						continue;
				}
			}
			return pExamineBar;
		} // for( nPos++; nPos < nCountOfSideBars; nPos++ )
	} // if( bNext )
	else
	{
		for( nPos--; nPos >= 0; nPos-- )
		{
			CControlBar * pExamineBar = (CControlBar *)
				pBar->m_pDockBar->m_arrBars[ nPos ];
			ASSERT( pExamineBar != pBar );
			if( pExamineBar == NULL )
				return NULL; // row separator
			if( __PLACEHODLER_BAR_PTR(pExamineBar) )
				continue;
			if( bExtBar )
			{
				if( !pBar->IsKindOf(RUNTIME_CLASS(CExtControlBar)) )
					continue;
				if( bNonFixed )
				{
					if( ((CExtControlBar *)pBar)->IsFixedMode() )
						continue;
				}
			}
			return pExamineBar;
		} // for( nPos--; nPos >= 0; nPos-- )
	} // else from if( bNext )
	return NULL;
}

CControlBar * CExtControlBar::_GetFirstControlBarInRow(
	CControlBar * pBar,
	bool bNext, // = false // last or first
	bool bExtBar, // = false
	bool bNonFixed // = false
	)
{
	ASSERT( pBar != NULL );
	ASSERT( pBar->GetSafeHwnd() != NULL );
	ASSERT_VALID( pBar );
	ASSERT( !pBar->IsFloating() );
	ASSERT_VALID( pBar->m_pDockBar );
INT nPos = pBar->m_pDockBar->FindBar( pBar );
	ASSERT( nPos > 0 );
	if( nPos == 1 && !bNext )
	{
		// first in first row
		if( bExtBar )
		{
			if( !pBar->IsKindOf(RUNTIME_CLASS(CExtControlBar)) )
			{
				CControlBar * pBar2 =
					_GetNextControlBarInRow(
						pBar,true,bExtBar,bNonFixed );
				return ( pBar2 == NULL ) ? pBar : pBar2;
			}
			if( bNonFixed
				&& ((CExtControlBar *)pBar)->IsFixedMode()
				)
			{
				CControlBar * pBar2 =
					_GetNextControlBarInRow(
						pBar,true,bExtBar,bNonFixed );
				return ( pBar2 == NULL ) ? pBar : pBar2;
			}
		}
		return pBar;
	} // if( nPos == 1 && !bNext )
INT nCountOfSideBars = pBar->m_pDockBar->m_arrBars.GetSize();
	ASSERT( nPos <= nCountOfSideBars );
	if( nPos == (nCountOfSideBars-1) && bNext )
	{
		// last in last row
		if( bExtBar )
		{
			if( !pBar->IsKindOf(RUNTIME_CLASS(CExtControlBar)) )
			{
				CControlBar * pBar2 =
					_GetNextControlBarInRow(
						pBar,false,bExtBar,bNonFixed );
				return ( pBar2 == NULL ) ? pBar : pBar2;
			}
			if( bNonFixed
				&& ((CExtControlBar *)pBar)->IsFixedMode()
				)
			{
				CControlBar * pBar2 =
					_GetNextControlBarInRow(
						pBar,false,bExtBar,bNonFixed );
				return ( pBar2 == NULL ) ? pBar : pBar2;
			}
		}
		return pBar;
	}
CControlBar * pPrevBar = pBar;
	if( bNext )
	{
		for( nPos++; nPos < nCountOfSideBars; nPos++ )
		{
			CControlBar * pExamineBar = (CControlBar *)
				pBar->m_pDockBar->m_arrBars[ nPos ];
			ASSERT( pExamineBar != pBar );
			if( pExamineBar == NULL )
				return pPrevBar; // row separator
			if( __PLACEHODLER_BAR_PTR(pExamineBar) )
				continue;
			if( bExtBar )
			{
				if( !pBar->IsKindOf(RUNTIME_CLASS(CExtControlBar)) )
					continue;
				if( bNonFixed )
				{
					if( ((CExtControlBar *)pBar)->IsFixedMode() )
						continue;
				}
			}
			pPrevBar = pExamineBar;
		} // for( nPos++; nPos < nCountOfSideBars; nPos++ )
	} // if( bNext )
	else
	{
		for( nPos--; nPos >= 0; nPos-- )
		{
			CControlBar * pExamineBar = (CControlBar *)
				pBar->m_pDockBar->m_arrBars[ nPos ];
			ASSERT( pExamineBar != pBar );
			if( pExamineBar == NULL )
				return pPrevBar; // row separator
			if( __PLACEHODLER_BAR_PTR(pExamineBar) )
				continue;
			if( bExtBar )
			{
				if( !pBar->IsKindOf(RUNTIME_CLASS(CExtControlBar)) )
					continue;
				if( bNonFixed )
				{
					if( ((CExtControlBar *)pBar)->IsFixedMode() )
						continue;
				}
			}
			pPrevBar = pExamineBar;
		} // for( nPos--; nPos >= 0; nPos-- )
	} // else from if( bNext )
	return pPrevBar;
}

void CExtControlBar::_GetNextRowBars(
	bool bNextRow,
	MfcControlBarVector_t & vBars,
	CRect * pRcAllBars, // = NULL
	INT * p_nOwnPos, // = NULL
	bool * p_bRowMaxSized, // = NULL // row with resizable bars?
	bool * p_bRowFullSized // = NULL // row with menu-like bar?
	) const
{
	ASSERT_VALID( this );
	if( pRcAllBars != NULL )
		pRcAllBars->SetRect( 0, 0, 0, 0 );
	if( p_nOwnPos != NULL )
		*p_nOwnPos = -1;
	if( p_bRowMaxSized != NULL )
		*p_bRowMaxSized = false;
	if( p_bRowFullSized != NULL )
		*p_bRowFullSized = false;
    vBars.RemoveAll();
	if( m_pDockBar == NULL )
		return;
	ASSERT_VALID( m_pDockBar );
INT nOwnIdx = m_pDockBar->FindBar( (CControlBar *)this );
	ASSERT( nOwnIdx >= 0 );
	if( nOwnIdx < 0 )
		return;
	if( p_nOwnPos != NULL )
		*p_nOwnPos = nOwnIdx;
INT nTotalDockCount = m_pDockBar->m_arrBars.GetSize();
INT nFirstToReview = -1;
INT nIncrement = bNextRow ? 1 : -1;
	for( INT nBar = nOwnIdx+nIncrement; true; nBar += nIncrement )
	{
		if( nBar == 0 || nBar == nTotalDockCount )
			return;
		CControlBar * pBar = (CControlBar *)
			m_pDockBar->m_arrBars[ nBar ];
		if( pBar == NULL )
		{
			nFirstToReview = nBar + nIncrement;
			if( nFirstToReview >= nTotalDockCount )
				return;
			break;
		}
#ifdef _DEBUG
		if( __PLACEHODLER_BAR_PTR(pBar) )
			continue;
		ASSERT_VALID( pBar );
		ASSERT_KINDOF( CControlBar, pBar );
#endif // _DEBUG
	} // for( INT nBar = nOwnIdx+nIncrement; true; nBar += nIncrement )
	
	if( nFirstToReview <= 0 )
		return;
//	ASSERT( 0 < nFirstToReview && nFirstToReview < nTotalDockCount );
	ASSERT( 0 <= nFirstToReview && nFirstToReview < nTotalDockCount );

INT nBarWidth = 0;
bool bHorz = IsDockedHorizontally();

	for( nBar = nFirstToReview; true; nBar += nIncrement )
	{
		if( nBar < 0 || nBar >= nTotalDockCount )
			break;
		CControlBar * pBar = (CControlBar *)
			m_pDockBar->m_arrBars[ nBar ];
		if( pBar == NULL )
		{
			if( vBars.GetSize() == 0 )
			{
				nBarWidth = 0;
				if( pRcAllBars != NULL )
					pRcAllBars->SetRect( 0, 0, 0, 0 );
				if( p_bRowMaxSized != NULL )
					*p_bRowMaxSized = false;
				if( p_bRowFullSized != NULL )
					*p_bRowFullSized = false;
				continue; // skip invisible or placeholder's row
			}
			break;
		}
		if( __PLACEHODLER_BAR_PTR(pBar) )
			continue;
		ASSERT_VALID( pBar );
		ASSERT_KINDOF( CControlBar, pBar );
		ASSERT( pBar != (CControlBar *)this );

		if( !pBar->IsVisible() )
			continue;
		
		if( pRcAllBars != NULL )
		{
			if( vBars.GetSize() == 0 )
				pBar->GetWindowRect( pRcAllBars );
			else
			{
				CRect rcWndBar;
				pBar->GetWindowRect( &rcWndBar );
				pRcAllBars->left =
					min( pRcAllBars->left, rcWndBar.left );
				pRcAllBars->top =
					min( pRcAllBars->top, rcWndBar.top );
				pRcAllBars->right =
					max( pRcAllBars->right, rcWndBar.right );
				pRcAllBars->bottom =
					max( pRcAllBars->bottom, rcWndBar.bottom );
			}
		} // if( pRcAllBars != NULL )

		if( (p_bRowMaxSized != NULL || p_bRowFullSized != NULL)
			&& pBar->IsKindOf(RUNTIME_CLASS(CExtControlBar))
			)
		{
			if( p_bRowMaxSized != NULL
				&& ( ! (*p_bRowMaxSized) )
				&& !((CExtControlBar*)pBar)->IsFixedMode()
				)
				*p_bRowMaxSized = true;
			if(	p_bRowFullSized != NULL
				&& ( ! (*p_bRowFullSized) )
				&& pBar->IsKindOf(RUNTIME_CLASS(CExtControlBar))
				&& ((CExtControlBar *)pBar)->_GetFullRowMode()
				)
				*p_bRowFullSized = true;
			if( p_bRowFullSized != NULL
				&& ( ! (*p_bRowFullSized) )
				)
			{
				CRect rcBarWnd;
				pBar->GetWindowRect( &rcBarWnd );
				nBarWidth +=
					bHorz ? rcBarWnd.Width() : rcBarWnd.Height();
			}
		}
		vBars.Add( pBar );
	} // for( nBar = nFirstToReview; true; nBar += nIncrement )

	if( p_bRowFullSized != NULL
		&& ( ! (*p_bRowFullSized) )
		)
	{
		ASSERT_VALID( m_pDockBar );
		CRect rcDockBarWnd;
		m_pDockBar->GetWindowRect( &rcDockBarWnd );
		INT nDockBarWidth = bHorz ? rcDockBarWnd.Width() : rcDockBarWnd.Height();
		nDockBarWidth --;
		if( nBarWidth >= nDockBarWidth )
			*p_bRowFullSized = true;
	}
}

void CExtControlBar::_GetRowBars(
	MfcControlBarVector_t & vBars,
	CRect * pRcAllBars, // = NULL
	INT * p_nOwnPos, // = NULL
	bool * p_bRowMaxSized, // = NULL // row with resizable bars?
	bool * p_bRowFullSized // = NULL // row with menu-like bar?
	) const
{
	ASSERT_VALID( this );
	if( pRcAllBars != NULL )
		pRcAllBars->SetRect( 0, 0, 0, 0 );
	if( p_nOwnPos != NULL )
		*p_nOwnPos = -1;
	if( p_bRowMaxSized != NULL )
		*p_bRowMaxSized = false;
	if( p_bRowFullSized != NULL )
		*p_bRowFullSized = false;
    vBars.RemoveAll();
bool bEmptyRowCalc = true;
	if( m_pDockBar == NULL )
		return;
	ASSERT_VALID( m_pDockBar );
INT nBarWidth = 0;
bool bHorz = IsDockedHorizontally();
INT nTotalDockCount = m_pDockBar->m_arrBars.GetSize();
bool bThisFound = false;
	for( INT nBar = 0; nBar < nTotalDockCount; nBar++ )
	{
		CControlBar * pBar = (CControlBar *)
			m_pDockBar->m_arrBars[ nBar ];
		if( pBar == NULL )
		{
			if( bThisFound )
				break;
			vBars.RemoveAll();
			bEmptyRowCalc = true;
			nBarWidth = 0;
			if( pRcAllBars != NULL )
				pRcAllBars->SetRect( 0, 0, 0, 0 );
			if( p_bRowMaxSized != NULL )
				*p_bRowMaxSized = false;
			if( p_bRowFullSized != NULL )
				*p_bRowFullSized = false;
			continue;
		}
		if( __PLACEHODLER_BAR_PTR( pBar ) )
			continue;
		ASSERT_KINDOF( CControlBar, pBar );
		
		if( pBar == (CControlBar *)this )
		{
			bThisFound = true;
			if( p_nOwnPos != NULL )
				*p_nOwnPos = vBars.GetSize();
		}

		if( !pBar->IsVisible() )
			continue;
		
		if( pRcAllBars != NULL )
		{
			if( bEmptyRowCalc )
			{
				bEmptyRowCalc = false;
				pBar->GetWindowRect( pRcAllBars );
			} // if( bEmptyRowCalc )
			else
			{
				CRect rcWndBar;
				pBar->GetWindowRect( &rcWndBar );
				pRcAllBars->left =
					min( pRcAllBars->left, rcWndBar.left );
				pRcAllBars->top =
					min( pRcAllBars->top, rcWndBar.top );
				pRcAllBars->right =
					max( pRcAllBars->right, rcWndBar.right );
				pRcAllBars->bottom =
					max( pRcAllBars->bottom, rcWndBar.bottom );
			} // else from if( bEmptyRowCalc )
		} // if( pRcAllBars != NULL )

		if( (p_bRowMaxSized != NULL || p_bRowFullSized != NULL)
			&& pBar->IsKindOf(RUNTIME_CLASS(CExtControlBar))
			)
		{
			if( p_bRowMaxSized != NULL
				&& ( ! (*p_bRowMaxSized) )
				&& !((CExtControlBar*)pBar)->IsFixedMode()
				)
				*p_bRowMaxSized = true;
			if( p_bRowFullSized != NULL
				&& ( ! (*p_bRowFullSized) )
				&& pBar->IsKindOf(RUNTIME_CLASS(CExtControlBar))
				&& ((CExtControlBar *)pBar)->_GetFullRowMode()
				)
				*p_bRowFullSized = true;
			if( p_bRowFullSized != NULL
				&& ( ! (*p_bRowFullSized) )
				)
			{
				CRect rcBarWnd;
				pBar->GetWindowRect( &rcBarWnd );
				nBarWidth +=
					bHorz ? rcBarWnd.Width() : rcBarWnd.Height();
			}
		}

		vBars.Add( pBar );
	} // for( INT nBar = 0; nBar < nTotalDockCount; nBar++ )

	if( p_bRowFullSized != NULL
		&& ( ! (*p_bRowFullSized) )
		)
	{
		ASSERT_VALID( m_pDockBar );
		CRect rcDockBarWnd;
		m_pDockBar->GetWindowRect( &rcDockBarWnd );
		INT nDockBarWidth = bHorz ? rcDockBarWnd.Width() : rcDockBarWnd.Height();
		nDockBarWidth --;
		if( nBarWidth >= nDockBarWidth )
			*p_bRowFullSized = true;
	}

#ifdef _DEBUG
	if( p_nOwnPos != NULL )
	{
		INT nCount = vBars.GetSize();
		ASSERT( nCount > 0 );
		ASSERT( 0 <= (*p_nOwnPos) && (*p_nOwnPos) < nCount );
		for( INT nBar = 0; nBar < nTotalDockCount; nBar++ )
		{
			CControlBar * pBar = (CControlBar *)
				m_pDockBar->m_arrBars[ nBar ];
			pBar;
		}
	}
#endif // _DEBUG
}

void CExtControlBar::_GetRowExtBars(
	ExtControlBarVector_t & vBars,
	bool bNonFixedOnly, // = true
	CRect * pRcAllBars, // = NULL
	INT * p_nOwnPos, // = NULL
	bool * p_bRowMaxSized, // = NULL // row with resizable bars?
	bool * p_bRowFullSized // = NULL // row with menu-like bar?
	) const
{
	ASSERT_VALID( this );
	if( pRcAllBars != NULL )
		pRcAllBars->SetRect( 0, 0, 0, 0 );
	if( p_nOwnPos != NULL )
		*p_nOwnPos = -1;
	if( p_bRowMaxSized != NULL )
		*p_bRowMaxSized = false;
	if( p_bRowFullSized != NULL )
		*p_bRowFullSized = false;
    vBars.RemoveAll();
bool bEmptyRowCalc = true;
	if( m_pDockBar == NULL )
		return;
	ASSERT_VALID( m_pDockBar );
INT nBarWidth = 0;
bool bHorz = IsDockedHorizontally();
INT nTotalDockCount = m_pDockBar->m_arrBars.GetSize();
bool bThisFound = false;
	for( INT nBar = 0; nBar < nTotalDockCount; nBar++ )
	{
		CControlBar * pBar = (CControlBar *)
			m_pDockBar->m_arrBars[ nBar ];
		if( pBar == NULL )
		{
			if( bThisFound )
				break;
			vBars.RemoveAll();
			bEmptyRowCalc = true;
			nBarWidth = 0;
			if( pRcAllBars != NULL )
				pRcAllBars->SetRect( 0, 0, 0, 0 );
			if( p_bRowMaxSized != NULL )
				*p_bRowMaxSized = false;
			if( p_bRowFullSized != NULL )
				*p_bRowFullSized = false;
			continue;
		}
		if( __PLACEHODLER_BAR_PTR( pBar ) )
			continue;
		ASSERT_KINDOF( CControlBar, pBar );

		if( pBar == (CControlBar *)this )
		{
			bThisFound = true;
			if( p_nOwnPos != NULL )
				*p_nOwnPos = vBars.GetSize();
		}

		if( pBar->IsKindOf(RUNTIME_CLASS(CExtControlBar)) )
		{
			if( ( !((CExtControlBar *)pBar)->IsFixedMode() )
				|| (! bNonFixedOnly )
				)
				vBars.Add( (CExtControlBar *)pBar );
		
			if( p_bRowMaxSized != NULL || p_bRowFullSized != NULL )
			{
				if( p_bRowMaxSized != NULL
					&& ( ! (*p_bRowMaxSized) )
					&& !((CExtControlBar*)pBar)->IsFixedMode()
					)
					*p_bRowMaxSized = true;
				if( p_bRowFullSized != NULL
					&& ( ! (*p_bRowFullSized) )
					&& pBar->IsKindOf(RUNTIME_CLASS(CExtControlBar))
					&& ((CExtControlBar *)pBar)->_GetFullRowMode()
					)
					*p_bRowFullSized = true;
			}
		}
		if( p_bRowFullSized != NULL
			&& ( ! (*p_bRowFullSized) )
			)
		{
			CRect rcBarWnd;
			pBar->GetWindowRect( &rcBarWnd );
			nBarWidth +=
				bHorz ? rcBarWnd.Width() : rcBarWnd.Height();
		}

		if( pRcAllBars != NULL )
		{
			if( bEmptyRowCalc )
			{
				bEmptyRowCalc = false;
				pBar->GetWindowRect( pRcAllBars );
			} // if( bEmptyRowCalc )
			else
			{
				CRect rcWndBar;
				pBar->GetWindowRect( &rcWndBar );
				pRcAllBars->left =
					min( pRcAllBars->left, rcWndBar.left );
				pRcAllBars->top =
					min( pRcAllBars->top, rcWndBar.top );
				pRcAllBars->right =
					max( pRcAllBars->right, rcWndBar.right );
				pRcAllBars->bottom =
					max( pRcAllBars->bottom, rcWndBar.bottom );
			} // if( bEmptyRowCalc )
		} // if( pRcAllBars != NULL )
	} // for( INT nBar = 0; nBar < nTotalDockCount; nBar++ )

	if( p_bRowFullSized != NULL
		&& ( ! (*p_bRowFullSized) )
		)
	{
		ASSERT_VALID( m_pDockBar );
		CRect rcDockBarWnd;
		m_pDockBar->GetWindowRect( &rcDockBarWnd );
		INT nDockBarWidth = bHorz ? rcDockBarWnd.Width() : rcDockBarWnd.Height();
		nDockBarWidth --;
		if( nBarWidth >= nDockBarWidth )
			*p_bRowFullSized = true;
	}

#ifdef _DEBUG
	if( p_nOwnPos != NULL )
	{
		INT nCount = vBars.GetSize();
		ASSERT( nCount > 0 );
		ASSERT( 0 <= (*p_nOwnPos) && (*p_nOwnPos) < nCount );
	}
#endif // _DEBUG
}

bool CExtControlBar::_IsFirstBarInRow( bool bExtBar ) const
{
	if( m_pDockBar == NULL )
		return false;
	ASSERT_VALID( m_pDockBar );
INT nRowCount = 0;
INT nTotalDockCount = m_pDockBar->m_arrBars.GetSize();
	for( INT nBar = 0; nBar < nTotalDockCount; nBar++ )
	{
		CControlBar * pBar = (CControlBar *)
			m_pDockBar->m_arrBars[ nBar ];
		if( pBar == NULL )
		{
			nRowCount = 0;
			continue;
		}
		if( __PLACEHODLER_BAR_PTR( pBar ) )
			continue;
		ASSERT_KINDOF( CControlBar, pBar );
		if( bExtBar )
		{
			CExtControlBar * pExtBar = 
				DYNAMIC_DOWNCAST( CExtControlBar, pBar );
			if( pExtBar == NULL )
				return false;
			if( pExtBar->IsFixedMode() )
				return false;
		}
		if( pBar == (CControlBar *)this )
		{
			return (nRowCount == 0) ? true : false;
		}
		nRowCount++;
	} // for( INT nBar = 0; nBar < nTotalDockCount; nBar++ )
	ASSERT( FALSE );
	return false;
}

bool CExtControlBar::_IsLastBarInRow( bool bExtBar ) const
{
	ASSERT( !IsFloating() );
	if( bExtBar )
	{
		ExtControlBarVector_t vBars;
		_GetRowExtBars( vBars );
		INT nCountOfBars = vBars.GetSize();
		ASSERT( nCountOfBars > 0 );
		if( vBars[nCountOfBars-1] == (CExtControlBar *)this )
			return true;
		return false;
	}
MfcControlBarVector_t vBars;
    _GetRowBars( vBars );
INT nCountOfBars = vBars.GetSize();
	ASSERT( nCountOfBars > 0 );
	if( vBars[nCountOfBars-1] == (CControlBar *)this )
		return true;
	return false;
}

CFrameWnd * CExtControlBar::_GetDockingFrameImpl(
	CControlBar * pBar
	)
{
	ASSERT_VALID( pBar );
	ASSERT( pBar->GetSafeHwnd() != NULL );

	if( pBar->m_pDockSite != NULL )
	{
		ASSERT_VALID( pBar->m_pDockSite );
		ASSERT( pBar->m_pDockSite->GetSafeHwnd() != NULL );
		ASSERT_KINDOF( CFrameWnd, pBar->m_pDockSite );
		return pBar->m_pDockSite;
	}

CFrameWnd * pFrame = pBar->GetParentFrame();
	if( pFrame == NULL )
		return NULL;

	ASSERT_VALID( pFrame );
	ASSERT_KINDOF( CFrameWnd, pFrame );
	if( pFrame->IsKindOf(RUNTIME_CLASS(CMiniDockFrameWnd)) )
	{
		pFrame = pFrame->GetParentFrame();
		ASSERT_VALID( pFrame );
		ASSERT( !pFrame->IsKindOf(RUNTIME_CLASS(CMiniDockFrameWnd)) );
	}
	return pFrame;
}

CFrameWnd * CExtControlBar::_GetDockingFrameImpl() const
{
	return _GetDockingFrameImpl( (CControlBar *)this );
}

UINT CExtControlBar::GetSafeDockBarDlgCtrlID() const
{
	ASSERT_VALID( this );
	ASSERT( GetSafeHwnd() != NULL );
	ASSERT( ::IsWindow( GetSafeHwnd() ) );

CWnd * pParentWnd =
		(m_pDockBar != NULL) ? m_pDockBar : GetParent();
	if( pParentWnd->GetSafeHwnd() == NULL
		|| !::IsWindow( pParentWnd->GetSafeHwnd() )
		|| !pParentWnd->IsKindOf( RUNTIME_CLASS(CDockBar) )
		)
		return AFX_IDW_DOCKBAR_FLOAT; // IDC_STATIC

UINT nDlgCtrlID = pParentWnd->GetDlgCtrlID();
	ASSERT_DOCKBAR_DLGCTRLID( nDlgCtrlID );
	return nDlgCtrlID;
}

bool CExtControlBar::IsDockedAtTop() const
{
	if( m_pDockSite == NULL )
		return (m_dwStyle & CBRS_TOP) ? true : false;
	return GetSafeDockBarDlgCtrlID() == AFX_IDW_DOCKBAR_TOP;
}

bool CExtControlBar::IsDockedAtBottom() const
{
	if( m_pDockSite == NULL )
		return (m_dwStyle & CBRS_BOTTOM) ? true : false;
	return GetSafeDockBarDlgCtrlID() == AFX_IDW_DOCKBAR_BOTTOM;
}

bool CExtControlBar::IsDockedAtLeft() const
{
	if( m_pDockSite == NULL )
		return (m_dwStyle & CBRS_LEFT) ? true : false;
	return GetSafeDockBarDlgCtrlID() == AFX_IDW_DOCKBAR_LEFT;
}

bool CExtControlBar::IsDockedAtRight() const
{
	if( m_pDockSite == NULL )
		return (m_dwStyle & CBRS_RIGHT) ? true : false;
	return GetSafeDockBarDlgCtrlID() == AFX_IDW_DOCKBAR_RIGHT;
}

bool CExtControlBar::IsDockedHorizontally() const
{
	if( m_pDockSite == NULL )
		return (m_dwStyle & (CBRS_TOP|CBRS_BOTTOM)) ? true : false;
UINT nDockBarDlgCtrlID = GetSafeDockBarDlgCtrlID();
	return	nDockBarDlgCtrlID == AFX_IDW_DOCKBAR_TOP
		||	nDockBarDlgCtrlID == AFX_IDW_DOCKBAR_BOTTOM;
}

bool CExtControlBar::IsDockedVertically() const
{
	if( m_pDockSite == NULL )
		return (m_dwStyle & (CBRS_LEFT|CBRS_RIGHT)) ? true : false;
UINT nDockBarDlgCtrlID = GetSafeDockBarDlgCtrlID();
	return	nDockBarDlgCtrlID == AFX_IDW_DOCKBAR_LEFT
		||	nDockBarDlgCtrlID == AFX_IDW_DOCKBAR_RIGHT;
}

bool CExtControlBar::IsDocked() const
{
	if( m_pDockSite == NULL )
		return true;
UINT nDockBarDlgCtrlID = GetSafeDockBarDlgCtrlID();
	return	nDockBarDlgCtrlID == AFX_IDW_DOCKBAR_TOP
		||	nDockBarDlgCtrlID == AFX_IDW_DOCKBAR_BOTTOM
		||	nDockBarDlgCtrlID == AFX_IDW_DOCKBAR_LEFT
		||	nDockBarDlgCtrlID == AFX_IDW_DOCKBAR_RIGHT;
}

bool CExtControlBar::IsFloating() const
{
	if( !IsDocked() )
	{
		if( GetParentFrame() != NULL )
			return true;
	}
	return false;
}

bool CExtControlBar::_IsSingleVisibleInFloatingPalette()
{
	if(		m_pDockSite == NULL
		||	!IsVisible()
		||	IsFixedMode()
//		||	m_bUpdatingChain
		)
		return false;
CFrameWnd * pFrame = GetParentFrame();
	if( pFrame == NULL )
		return false;
	if( !pFrame->IsKindOf(RUNTIME_CLASS(CMiniFrameWnd)) )
		return false;
	ASSERT_KINDOF( CExtMiniDockFrameWnd, pFrame );
	ASSERT( m_pDockSite != pFrame );
POSITION pos = m_pDockSite->m_listControlBars.GetHeadPosition();
	for( ; pos != NULL; )
	{
		CExtControlBar * pBar =
			DYNAMIC_DOWNCAST(
				CExtControlBar,
				((CControlBar *)(m_pDockSite->m_listControlBars.GetNext(pos)))
				);
		if(		pBar == NULL
			||	pBar == this
			||	pBar->m_pDockSite == NULL
			||	pBar->m_pDockBar == NULL
			||	pBar->IsFixedMode()
			||	(	pBar->IsKindOf(RUNTIME_CLASS(CExtDynControlBar))
#if (!defined __EXT_MFC_NO_TAB_CONTROLBARS)
					&& !pBar->IsKindOf(RUNTIME_CLASS(CExtDynTabControlBar))
#endif // (!defined __EXT_MFC_NO_TAB_CONTROLBARS)
				)
			||	pBar->GetParentFrame() != pFrame
			)
			continue;
		HWND hWndDockBar = pBar->m_pDockBar->GetSafeHwnd();
		if(		hWndDockBar == NULL // by Guillaume Provost advice
			||	(! ::IsWindow(hWndDockBar) )
			)
			continue;
		ASSERT( pBar->m_pDockBar != NULL );
		if( 
#if (!defined __EXT_MFC_NO_TAB_CONTROLBARS)
			pBar->m_pDockBar->IsKindOf(RUNTIME_CLASS(CExtDockDynTabBar))
			||
#endif // (!defined __EXT_MFC_NO_TAB_CONTROLBARS)
			!pBar->m_pDockBar->IsKindOf(RUNTIME_CLASS(CExtDockBar))
			)
			continue;
		if( pBar->IsVisible() )
			return false;
	}
	return true;
}

bool CExtControlBar::IsBarWithGripper(
	bool * pbGripperAtTop, // = NULL
	bool * pbTextOnGripper // = NULL
	) const
{
	ASSERT_VALID( this );
	if( pbGripperAtTop != NULL )
		*pbGripperAtTop = false;
	if( pbTextOnGripper != NULL )
		*pbTextOnGripper = false;
	if( ! ::IsWindow(GetSafeHwnd()) )
		return false;
	if( (m_dwStyle & CBRS_GRIPPER) == 0
		|| IsFloating()
		)
		return false;

CFrameWnd * pParentFrame = GetParentFrame();
	if(		pParentFrame != NULL
		&&	pParentFrame->IsKindOf(RUNTIME_CLASS(CExtMiniDockFrameWnd))
		)
	{
		if( ((CExtControlBar *)this)->_IsSingleVisibleInFloatingPalette() )
			return false;
	}

#if (!defined __EXT_MFC_NO_TAB_CONTROLBARS)
	if( m_pDockBar != NULL
		&& !AutoHideModeGet()
		)
	{
		if( m_pDockBar->IsKindOf( RUNTIME_CLASS(CExtDockDynTabBar) ) )
		{
			if( pbGripperAtTop != NULL )
				*pbGripperAtTop = false;
			if( pbTextOnGripper != NULL )
				*pbTextOnGripper = false;
			return false;
		}
	}
#endif // (!defined __EXT_MFC_NO_TAB_CONTROLBARS)

	if( pbGripperAtTop != NULL
		&&	( m_bGripperStaticallyAtTop || IsDockedVertically() )
		)
		*pbGripperAtTop = true;
	if( pbTextOnGripper != NULL )
		*pbTextOnGripper = true;
    return true;
}

CSize CExtControlBar::CalcFixedLayout(
	BOOL bStretch,
	BOOL bHorz
	)
{
	bStretch;
	return _CalcDesiredLayout( bHorz );
}

CSize CExtControlBar::CalcDynamicLayout(
	int nLength,
	DWORD nMode
	)
{
	// MSDN for LM_HORZDOCK and LM_VERTDOCK: ... return
	// horizontal/vertical docked dimensions ...

	if( ((nMode & (LM_HORZDOCK | LM_VERTDOCK)) == 0)
		|| IsFloating()
		)
	{ // if going to floated state or already floated
		
		if( nLength > 0 )
		{
			// MSDN for nLength: ... The requested dimension of the
			// control bar, either horizontal or vertical,
			// depending on dwMode ...

			// MSDN for LM_LENGTHY: ... Set if nLength indicates
			// height (Y-direction) instead of width.
			if( nMode & LM_LENGTHY ) 
				m_sizeFloated.cy = nLength;
			else
				m_sizeFloated.cx = nLength;
		} // if( nLength > 0 )

		// MSDN for LM_MRUWIDTH: ... Most Recently Used Dynamic Width.
		// Ignores nLength parameter and uses the remembered most
		// recently used width.

		// MSDN for LM_COMMIT: ... Resets LM_MRUWIDTH to current
		// width of floating control bar.
		if( nMode & ( LM_MRUWIDTH | LM_COMMIT ) )
			return m_sizeFloated;

		return _CalcDesiredLayout( nMode & LM_HORZ );

	} // if going to floated state or already floated

	if( nLength >= 0 )
		return _CalcDesiredLayout( nMode & LM_HORZ );

	ASSERT_VALID( m_pDockBar );
	if( ((CExtDockBar *)m_pDockBar)->m_bLayoutQuery )
		return _CalcDesiredLayout( nMode & LM_HORZ );

    ASSERT_VALID( m_pDockBar );
INT nCalcExtentMax = 
		((FriendlyDockBarHack*)m_pDockBar)->
			GetCalcExtentMax( nMode & LM_HORZ );
	ASSERT( nCalcExtentMax >= 0 );
	if( nCalcExtentMax == 0 )
		return _CalcDesiredLayout( nMode & LM_HORZ );
INT nCalcExtentDiff = 0;
INT nCalcExtentMin =
		(nMode & LM_HORZ) ? afxData.cyBorder2 : afxData.cxBorder2;
INT nCalcExtentReal = 0, nMaxWidth = 0;
INT nCountOfBarsAtSide = m_pDockBar->m_arrBars.GetSize();
	ASSERT( nCountOfBarsAtSide > 0 );
INT nThisIdx = -1, nReviewStart = -1, nReviewStop = -1;
INT nCountInRowReal = 0, nCountExtBarsInRowReal = 0;
INT nCountOfMinSizedBars = 0;
	for( INT nBarAtSide = 0; nBarAtSide < nCountOfBarsAtSide ; nBarAtSide++ )
	{
		CControlBar * pBar =  (CControlBar *)
			m_pDockBar->m_arrBars[ nBarAtSide ];
		if( pBar == NULL )
		{
			if( nThisIdx >= 0 )
			{
				nReviewStop = nBarAtSide - 1;
				break;
			}
			nCountInRowReal = 0;
			nCountExtBarsInRowReal = 0;
			nMaxWidth = 0;
			nReviewStop = -1;
			nReviewStart = nBarAtSide + 1;
			continue;
		} // if( pBar == NULL )
		if( __PLACEHODLER_BAR_PTR(pBar) )
			continue;
		ASSERT_VALID( pBar );
		ASSERT(
			pBar->GetSafeHwnd() != NULL
			&& ::IsWindow(pBar->GetSafeHwnd())
			);
        if( !pBar->IsVisible() )
			continue;
		ASSERT(
			pBar->GetSafeHwnd() != NULL
			&& ::IsWindow( pBar->GetSafeHwnd() )
			);
		if( pBar == this )
		{
			if( nCountExtBarsInRowReal > 0 )
				//goto __Align_Mutually_Row__;
				return _CalcDesiredLayout( nMode & LM_HORZ );
			nThisIdx = nBarAtSide;
			//nReviewStart = nThisIdx;
		}
		CRect rcBarWnd;
		pBar->GetWindowRect( &rcBarWnd );
		CExtControlBar * pExtBar =
			DYNAMIC_DOWNCAST( CExtControlBar, pBar );
		if( pExtBar!=NULL && pExtBar->IsFixedMode() )
			pExtBar = NULL;
//		INT nCalcExtentStep =
//			(nMode & LM_HORZ) ? rcBarWnd.Width() : rcBarWnd.Height();
		if( pExtBar != NULL )
		{
			nCountExtBarsInRowReal++;
			nMaxWidth =
				max(
					nMaxWidth,
					(nMode & LM_HORZ)
						? pExtBar->m_sizeDockedH.cy
						: pExtBar->m_sizeDockedV.cx
					);
		} // if( pExtBar != NULL )
		nCountInRowReal++;
	} // for( int nBarAtSide = 0; nBarAtSide < nCountOfBarsAtSide ; nBarAtSide++ )

	ASSERT( nReviewStart <= nReviewStop );
	ASSERT( nReviewStart <= nThisIdx && nThisIdx <= nReviewStop );

	if( nCountInRowReal == 1 )
	{
        if( nMode & LM_HORZ )
            m_sizeDockedH.cx =
				max( _CalcDesiredMinHW(), nCalcExtentMax );
        else
            m_sizeDockedV.cy =
				max( _CalcDesiredMinVH(), nCalcExtentMax );
		goto __Align_Mutually_Row__;
	}

    for( nBarAtSide = nReviewStart; nBarAtSide <= nReviewStop; nBarAtSide++ )
    {
        CControlBar * pBar = (CControlBar*)
			m_pDockBar->m_arrBars[ nBarAtSide ];
        if( __PLACEHODLER_BAR_PTR(pBar) )
			continue;
		ASSERT_VALID( pBar );
		ASSERT(
			pBar->GetSafeHwnd() != NULL
			&& ::IsWindow(pBar->GetSafeHwnd())
			);
        if( !pBar->IsVisible() )
			continue;
		CExtControlBar * pExtBar =
			DYNAMIC_DOWNCAST( CExtControlBar, pBar );
		if( pExtBar!=NULL && pExtBar->IsFixedMode() )
			pExtBar = NULL;

        INT nCalcExtentBar = 0;
        if( pExtBar == NULL )
        {
            CRect rcBar;
            pBar->GetWindowRect( &rcBar );
            nCalcExtentBar =
				(nMode & LM_HORZ) ?
					rcBar.Width() : rcBar.Height();
        } // if( pExtBar == NULL )
        else
		{
			nCalcExtentBar =
				(nMode & LM_HORZ)
					? pExtBar->_CalcDesiredMinHW()
					: pExtBar->_CalcDesiredMinVH()
					;
			LONG & ref_nCalcExtentBar =
				(nMode & LM_HORZ)
					? pExtBar->m_sizeDockedH.cx
					: pExtBar->m_sizeDockedV.cy
					;
			if( ref_nCalcExtentBar < nCalcExtentBar )
				ref_nCalcExtentBar = nCalcExtentBar;
		}
        nCalcExtentMin += nCalcExtentBar;
		if( nCalcExtentMin <= nCalcExtentMax )
		{
			if( pExtBar == NULL )
			{
				nCalcExtentMax -= nCalcExtentBar;
				continue;
			}
			nCalcExtentReal +=
				(nMode & LM_HORZ)
					? pExtBar->m_sizeDockedH.cx
					: pExtBar->m_sizeDockedV.cy ;
			continue;
		} // if( nCalcExtentMin <= nCalcExtentMax )
        
        if( nBarAtSide < nThisIdx )
        {
			ASSERT( pBar != this );
			((FriendlyDockBarHack*)m_pDockBar)->
				_InsertRowSplitter( nBarAtSide + 1 );
			return _CalcDesiredLayout( nMode & LM_HORZ );
        }
        if( nBarAtSide == nThisIdx )
        {
			ASSERT( pBar == this );
			if( nMode & LM_HORZ )
				m_sizeDockedH.cx =
					max( _CalcDesiredMinHW(), nCalcExtentMax );
			else
				m_sizeDockedV.cy =
					max( _CalcDesiredMinVH(), nCalcExtentMax );
			break;
        }
		ASSERT( pBar != this );
		((FriendlyDockBarHack*)m_pDockBar)->
			_InsertRowSplitter( nBarAtSide );
        nReviewStop = nBarAtSide - 1;
		ASSERT( nReviewStart <= nReviewStop );
		ASSERT( nReviewStart <= nThisIdx && nThisIdx <= nReviewStop );
        break;
    } // for( nBarAtSide = nReviewStart; nBarAtSide <= nReviewStop; nBarAtSide++ )

	nCountOfMinSizedBars = 0;
	for( nBarAtSide = nReviewStart; nBarAtSide <= nReviewStop; nBarAtSide++ )
	{
        CControlBar * pBar = (CControlBar*)
			m_pDockBar->m_arrBars[ nBarAtSide ];
        if( __PLACEHODLER_BAR_PTR(pBar) )
			continue;
		ASSERT_VALID( pBar );
		ASSERT(
			pBar->GetSafeHwnd() != NULL
			&& ::IsWindow(pBar->GetSafeHwnd())
			);
        if( !pBar->IsVisible() )
			continue;
		CExtControlBar * pExtBar =
			DYNAMIC_DOWNCAST( CExtControlBar, pBar );
		if( pExtBar!=NULL && pExtBar->IsFixedMode() )
			pExtBar = NULL;
		if( pExtBar == NULL )
			continue;
        LONG nMinMetric =
			(nMode & LM_HORZ)
				? pExtBar->_CalcDesiredMinHW()
				: pExtBar->_CalcDesiredMinVH()
				;
        LONG nCalcExtentBar =
			(nMode & LM_HORZ)
				? pExtBar->m_sizeDockedH.cx
				: pExtBar->m_sizeDockedV.cy
				;
		ASSERT( nCalcExtentBar >= nMinMetric );
		//
		if( nMinMetric == nCalcExtentBar )
			nCountOfMinSizedBars++;
	} // for( nBarAtSide = nReviewStart; nBarAtSide <= nReviewStop; nBarAtSide++ )
	ASSERT( nCountOfMinSizedBars <= nCountExtBarsInRowReal );

	nCalcExtentDiff = nCalcExtentMax - nCalcExtentReal;
	if( nCountOfMinSizedBars != nCountExtBarsInRowReal )
	{
//		INT nCalcStep =
//			nCalcExtentDiff /
//				(nCountExtBarsInRowReal - nCountOfMinSizedBars);
		INT nCalcStep = (nCalcExtentDiff > 0) ? 1 : -1;
		INT nPass = 0;
		INT nPassMax = abs(nCalcExtentDiff)*2;
		for(	nBarAtSide = nReviewStart;
				// nBarAtSide < nReviewStop &&
				nCalcExtentDiff != 0
				&& nCountOfMinSizedBars != nCountExtBarsInRowReal		
				&& nPass < nPassMax
				;
				)
		{
			ASSERT( nBarAtSide <= nReviewStop+1 );
			if( nBarAtSide == nReviewStop+1 )
			{
				nPass++;
				nBarAtSide = nReviewStart;
			}
			
			CControlBar * pBar = (CControlBar*)
				m_pDockBar->m_arrBars[ nBarAtSide ];
			if( pBar == NULL )
			{
				nBarAtSide++;
				continue;
			}
			if( __PLACEHODLER_BAR_PTR(pBar) )
			{
				nBarAtSide++;
				continue;
			}
			ASSERT_VALID( pBar );
			ASSERT(
				pBar->GetSafeHwnd() != NULL
				&& ::IsWindow(pBar->GetSafeHwnd())
				);
			if( !pBar->IsVisible() )
			{
				nBarAtSide++;
				continue;
			}
			CExtControlBar * pExtBar =
				DYNAMIC_DOWNCAST( CExtControlBar, pBar );
			if( pExtBar == NULL
				|| pExtBar->IsFixedMode()
				)
			{
				nBarAtSide++;
				continue;
			}

			if( nMode & LM_HORZ )
				pExtBar->m_sizeDockedH.cy = nMaxWidth;
			else
				pExtBar->m_sizeDockedV.cx = nMaxWidth;
			
			ASSERT( nCalcExtentDiff != 0 );

			LONG nMinMetric =
				(nMode & LM_HORZ)
					? pExtBar->_CalcDesiredMinHW()
					: pExtBar->_CalcDesiredMinVH()
					;
			LONG & ref_nCalcExtentBar =
				(nMode & LM_HORZ)
					? pExtBar->m_sizeDockedH.cx
					: pExtBar->m_sizeDockedV.cy
					;
			ASSERT( ref_nCalcExtentBar >= nMinMetric );
			if( ref_nCalcExtentBar == nMinMetric )
			{
				nBarAtSide++;
				continue;
			}

			ASSERT( ref_nCalcExtentBar > nMinMetric );
			ref_nCalcExtentBar += nCalcStep;
			nCalcExtentDiff -= nCalcStep;
			if( ref_nCalcExtentBar == nMinMetric )
				nCountOfMinSizedBars++;
			
			ASSERT( ref_nCalcExtentBar >= nMinMetric );
			nBarAtSide++;
		} // for( nBarAtSide = nReviewStart; ...

		ASSERT( nCalcExtentDiff == 0 || nPass == nPassMax );

	} // if( nCountOfMinSizedBars != nCountExtBarsInRowReal )
	else
	{
		CExtControlBar * pLastBar = (CExtControlBar *)
			_GetFirstControlBarInRow(
				this, true, true, true
				);
		ASSERT( pLastBar != NULL );
		while( !pLastBar->IsVisible() )
		{
			CExtControlBar * pLastBar2 = (CExtControlBar *)
				_GetNextControlBarInRow(
					pLastBar, false, true, true
					);
			if( pLastBar2 == NULL )
				break;
			pLastBar = pLastBar2;
		}
		ASSERT( pLastBar != NULL );
		LONG & ref_nCalcExtentBar =
			(nMode & LM_HORZ) ?
				pLastBar->m_sizeDockedH.cx : pLastBar->m_sizeDockedV.cy;
		ref_nCalcExtentBar += nCalcExtentDiff;
		nCalcExtentReal = nCalcExtentMax;
	} // else from if( nCountOfMinSizedBars != nCountExtBarsInRowReal )

__Align_Mutually_Row__:

	ASSERT_VALID( m_pDockBar );
//	if( ((CExtDockBar *)m_pDockBar)->m_bLayoutQuery )
//		return _CalcDesiredLayout( nMode & LM_HORZ );

//bool bAtTop = IsDockedAtTop();
CRect rcWndDockBar;
	m_pDockBar->GetWindowRect( &rcWndDockBar );
CPoint ptDevOffset = -rcWndDockBar.TopLeft();
INT nCalcBarOffset = 0;	

INT nHdwpCount = nReviewStop - nReviewStart + 1;
	ASSERT( nHdwpCount > 0 );
HANDLE hDWP = ::BeginDeferWindowPos( nHdwpCount );
	ASSERT( hDWP != NULL );
static const UINT nDwpFlags =
		SWP_NOZORDER|SWP_NOOWNERZORDER|SWP_NOACTIVATE
		//|SWP_NOSENDCHANGING|SWP_NOREDRAW
		;

	for( nBarAtSide = nReviewStart; nBarAtSide <= nReviewStop; nBarAtSide++ )
	{
		CControlBar * pBar = (CControlBar*)
			m_pDockBar->m_arrBars[ nBarAtSide ];
		if( __PLACEHODLER_BAR_PTR(pBar) )
			continue;
		ASSERT_VALID( pBar );
		ASSERT(
			pBar->GetSafeHwnd() != NULL
			&& ::IsWindow(pBar->GetSafeHwnd())
			);
        if( !pBar->IsVisible() )
			continue;

		CExtControlBar * pExtBar =
			DYNAMIC_DOWNCAST( CExtControlBar, pBar );
		if( pExtBar != NULL && pExtBar->IsFixedMode() )
			pExtBar = NULL;
		CRect rcWndBarOrg;
		pBar->GetWindowRect( &rcWndBarOrg );
		CRect rcWndBar( rcWndBarOrg );
		rcWndBar.OffsetRect( ptDevOffset );
		
		if( pExtBar != NULL )
            rcWndBar =
				CRect(
					rcWndBar.TopLeft(),
					(nMode & LM_HORZ)
						? pExtBar->m_sizeDockedH
						: pExtBar->m_sizeDockedV
					);
		INT nBarRealOffset =
			(nMode & LM_HORZ) ? rcWndBar.left : rcWndBar.top;
        if( nBarRealOffset != nCalcBarOffset )
        {
            if( !(nMode & LM_HORZ) )
                rcWndBar.OffsetRect(
					0,
					nCalcBarOffset - rcWndBar.top
					);
//            else if( bAtTop )
//                rcWndBar.OffsetRect(
//					nCalcBarOffset - rcWndBar.left,
//					-2
//					);
            else
            	rcWndBar.OffsetRect(
					nCalcBarOffset - rcWndBar.left,
					0
					);
			
		} // if( nBarRealOffset != nCalcBarOffset )
		
		if( rcWndBar != rcWndBarOrg )
		{
			hDWP = ::DeferWindowPos(
				hDWP,
				pBar->GetSafeHwnd(),
				NULL,
				rcWndBar.left, rcWndBar.top,
				rcWndBar.Width(), rcWndBar.Height(),
				nDwpFlags
				);
			ASSERT( hDWP != NULL );
		} // if( rcWndBar != rcWndBarOrg )
			

        nCalcBarOffset += (nMode & LM_HORZ)
			? rcWndBar.Width() : rcWndBar.Height();
	} // for( nBarAtSide = nReviewStart; nBarAtSide <= nReviewStop; nBarAtSide++ )

	VERIFY( ::EndDeferWindowPos( hDWP ) );

	return _CalcDesiredLayout( nMode & LM_HORZ );
}

bool CExtControlBar::_GetFullRowMode() const
{
	ASSERT_VALID( this );
	return false;
}

INT CExtControlBar::_CalcDesiredMinHW() const
{
INT nCalcVal = m_nMinHW + m_rcRowRecalcUp.Width();
	if( m_bGripperStaticallyAtTop )
	{
//		int nResizers =
//			m_rcRowRecalc.Width()
//			+ m_rcRowRecalcUp.Width();
//		int nMinMetric =
//			1
//			+ ::GetSystemMetrics(SM_CYSMCAPTION)+2
//			+ nResizers;
//		if( IsBarWithGripper() && !m_rcGrip.IsRectEmpty() )
//		{
//			int nMinFriendly = m_rcGrip.Height() + nResizers;
//			if( nMinMetric < nMinFriendly )
//				nMinMetric = nMinFriendly;
//		}
//		if( nCalcVal < nMinMetric  )
//			nCalcVal = nMinMetric;
		
		nCalcVal = max( nCalcVal, 10 );
	}
	return nCalcVal;
}

INT CExtControlBar::_CalcDesiredMinVH() const
{
INT nCalcVal = m_nMinVH + m_rcRowRecalcUp.Height();
	return nCalcVal;
}

CSize CExtControlBar::_CalcDesiredMinOuterSize( BOOL bHorz )
{
	bHorz;
	return CSize( _CalcDesiredMinHW(), _CalcDesiredMinVH() );
}

CSize CExtControlBar::_CalcDesiredMinFloatedSize() const
{
	// for nonfixed bars only
	return CSize( 80, 60 );
}

CSize CExtControlBar::_CalcDesiredLayout(
	BOOL bHorz,
	BOOL bForceFullRow // = FALSE
	)
{
	if( IsFloating() )
		return m_sizeFloated;
	
	if( bHorz )
	{
		if( bForceFullRow )
			return CSize( MAXSHORT, m_sizeDockedH.cy );
		if( m_sizeDockedH.cy < _CalcDesiredMinHW() )
			m_sizeDockedH.cy = _CalcDesiredMinHW();
		return m_sizeDockedH;
	} // if( bHorz )
	else
	{
		if( bForceFullRow )
			return CSize( m_sizeDockedH.cx, MAXSHORT );
		if( m_sizeDockedV.cx < _CalcDesiredMinVH() )
			m_sizeDockedV.cx = _CalcDesiredMinVH();
		return m_sizeDockedV;
	} // else from if( bHorz )
}

CExtControlBar::InternalAffixmentData *
	CExtControlBar::_AffixmentGetOuter()
{
	ASSERT_VALID( this );
	return NULL;
}

void CExtControlBar::_AffixmentSetOuter(
	CExtControlBar::InternalAffixmentData * pAffixmentData
	)
{
	ASSERT_VALID( this );
	ASSERT( pAffixmentData != NULL );
	pAffixmentData;
}

CExtControlBar::InternalAffixmentData *
	CExtControlBar::_AffixmentGetOuter(
		CControlBar * pBar
		)
{
	ASSERT_VALID( pBar );
CExtControlBar * pExtBar =
		DYNAMIC_DOWNCAST( CExtControlBar, pBar );
	if( pExtBar == NULL )
		return NULL;
	return pExtBar->_AffixmentGetOuter();
}

int CExtControlBar::_AffixmentCompareOuter(
	CControlBar * pBar1,
	CControlBar * pBar2
	)
{
	ASSERT_VALID( pBar1 );
	ASSERT_VALID( pBar2 );
InternalAffixmentData * pAffixmentData1 =
		_AffixmentGetOuter( pBar1 );
InternalAffixmentData * pAffixmentData2 =
		_AffixmentGetOuter( pBar2 );
	if( pAffixmentData1 != NULL )
	{
		if( pAffixmentData2 != NULL )
			return pAffixmentData1->CompareAffixment( *pAffixmentData2 );
	} // if( pAffixmentData1 != NULL )
	else
	{
		if( pAffixmentData2 != NULL )
			return -1;
	} // else from if( pAffixmentData1 != NULL )
	return 0;
}

void CExtControlBar::_AffixmentRecalcOuter()
{
	ASSERT_VALID( this );
	ASSERT_VALID( m_pDockBar );
	ASSERT_KINDOF( CExtDockBar, m_pDockBar );
	ASSERT_VALID( m_pDockSite );
	ASSERT( !IsFloating() );
	ASSERT( GetParentFrame() == m_pDockSite );
	ASSERT( (! GetParentFrame()->IsKindOf(RUNTIME_CLASS(CMiniFrameWnd)) ) );
	ASSERT( GetSafeDockBarDlgCtrlID() != AFX_IDW_DOCKBAR_FLOAT );
InternalAffixmentData * pAffixmentData =
		_AffixmentGetOuter();
	if( pAffixmentData == NULL )
		return;
CExtDockOuterBar * pDockBar =
		DYNAMIC_DOWNCAST(CExtDockOuterBar, m_pDockBar );
	if( pDockBar == NULL )
		return;
	pDockBar->_AffixmentBringToTop( this );
}

void CExtControlBar::_AffixmentSafeClearOuter()
{
	ASSERT_VALID( this );
	ASSERT_VALID( m_pDockSite );
InternalAffixmentData * pAffixmentData =
		_AffixmentGetOuter();
	if( pAffixmentData == NULL )
		return;
	pAffixmentData->Empty();
}

bool CExtControlBar::_AffixmentIsAlignedHW() const
{
	ASSERT_VALID( this );
	return false;
}

void CExtControlBar::DoPaint( CDC* pDC )
{
#if (defined __DEBUG_PAINTING_AREAS_EXTRESIZABLEBAR__)

//	CControlBar::DoPaint( pDC );
	ASSERT( pDC->GetSafeHdc() != NULL );
CRect rcBarClient;
	GetClientRect( &rcBarClient );
	pDC->FillSolidRect( &rcBarClient, g_PaintManager->GetColor(COLOR_INFOBK) );

CRect rcDummy( rcBarClient );
	rcDummy.DeflateRect( 4, 4 );
	pDC->DrawFocusRect( &rcDummy );

#else // __DEBUG_PAINTING_AREAS_EXTRESIZABLEBAR__

	ASSERT( pDC->GetSafeHdc() != NULL );
CRect rcClient;
	GetClientRect( &rcClient );
	if( rcClient.IsRectEmpty()
		|| !pDC->RectVisible( &rcClient )
		)
		return;
	CExtPaintManager::stat_ExcludeChildAreas(
		*pDC,
		*this
		);
CExtMemoryDC dc( pDC, &rcClient );
	ASSERT( dc.GetSafeHdc() != NULL );
	if( dc.GetSafeHdc() != NULL )
		pDC = &dc;
	DoEraseBk( pDC, &rcClient );

	g_PaintManager->OnPaintSessionComplete( this );
#endif // ! __DEBUG_PAINTING_AREAS_EXTRESIZABLEBAR__
}

void CExtControlBar::DoEraseBk( CDC* pDC, LPCRECT pRectBk )
{
	ASSERT( pDC->GetSafeHdc() != NULL );
	ASSERT( pRectBk != NULL );
	g_PaintManager->PaintControlBarClientArea(
		*pDC,
		*pRectBk,
		this
		);
}

BOOL CExtControlBar::DoCustomModePreTranslateMessage(
	CWnd * pWndPretranslateSrc,
	MSG * pMsg
	)
{
	ASSERT( pWndPretranslateSrc != NULL );
	ASSERT( pMsg != NULL );

HWND hWndPretranslateSrc = pWndPretranslateSrc->GetSafeHwnd();
	if(	hWndPretranslateSrc == NULL
		|| ( ! ::IsWindow(hWndPretranslateSrc) )
		)
		return FALSE;

	for(	HWND hWndChild = ::GetWindow( hWndPretranslateSrc, GW_CHILD );
			hWndChild != NULL && ::IsWindow( hWndPretranslateSrc );
			hWndChild = ::GetWindow( hWndChild, GW_HWNDNEXT )
		)
	{
		CWnd * pWndChild = CWnd::FromHandlePermanent( hWndChild );
		if( pWndChild == NULL )
			continue;
		CExtControlBar * pExtBar =
			DYNAMIC_DOWNCAST( CExtControlBar, pWndChild );
		if( pExtBar == NULL )
			continue;
		if( pExtBar->PreTranslateMessage(pMsg) )
			return TRUE;
	}
	return FALSE;
}

void CExtControlBar::DoCustomModeUpdateControlBars(
	CWnd * pWndParentTarget,
	BOOL bDisableIfNoHndler // = TRUE
	)
{
	ASSERT_VALID( pWndParentTarget );

HWND hWndUpdateTarget = pWndParentTarget->GetSafeHwnd();
	if( hWndUpdateTarget == NULL )
		return;

	ASSERT( ::IsWindow( hWndUpdateTarget ) );
	for(	HWND hWndChild = ::GetWindow( hWndUpdateTarget, GW_CHILD );
			hWndChild != NULL && ::IsWindow( hWndUpdateTarget );
			hWndChild = ::GetWindow( hWndChild, GW_HWNDNEXT )
		)
	{
		CWnd * pWndChild = CWnd::FromHandlePermanent( hWndChild );
		if( pWndChild == NULL )
			continue;
		CExtControlBar * pExtBar =
			DYNAMIC_DOWNCAST( CExtControlBar, pWndChild );
		if( pExtBar == NULL )
			continue;
		pExtBar->DoCustomModeUpdateCmdUI(
			bDisableIfNoHndler
			);
	}
}

bool CExtControlBar::DoCustomModeUpdateCmdUI(
	BOOL bDisableIfNoHndler // = TRUE
	)
{
	ASSERT_VALID( this );

	if( m_bInCustomModeUpdateCmdUI )
		return true;

HWND hWndOwn = GetSafeHwnd();
	if( hWndOwn == NULL
		|| ( ! ::IsWindow( hWndOwn ) )
		)
		return false;

	m_bInCustomModeUpdateCmdUI = true;

CFrameWnd * pWndUpdateTarget = NULL;
	
	if( !m_bPresubclassDialogMode )
	{
		pWndUpdateTarget = _GetDockingFrameImpl();
		ASSERT_VALID( pWndUpdateTarget );
		ASSERT_KINDOF( CFrameWnd, pWndUpdateTarget );
	}
	
	OnUpdateCmdUI(
		pWndUpdateTarget,
		bDisableIfNoHndler
		);
	
	m_bInCustomModeUpdateCmdUI = false;

	return true;
}

void CExtControlBar::OnUpdateCmdUI(
	CFrameWnd * pTarget,
	BOOL bDisableIfNoHndler
	)
{
	if(	m_bPresubclassDialogMode
		|| m_bDragging || m_bRowRecalcing || m_bRowResizing
		|| (CExtControlBar::_DraggingGetBar() != NULL)
		)
		return;

	pTarget;
	bDisableIfNoHndler;

	if( (GetStyle() & WS_VISIBLE) == 0 )
		return;

CPoint ptScreen;
	if( ! ::GetCursorPos( &ptScreen ) )
		return;
bool bNeedRepaint = false;

UINT nHT = NcButtons_HitTest( ptScreen );
	if( nHT == HTCLIENT )
	{
		if( m_bNcAreaBtnTracking )
			bNeedRepaint = true;
		m_bNcAreaBtnTracking = false;
	} // if( nHT == HTCLIENT )
	else
	{
		if( !m_bNcAreaBtnTracking )
			bNeedRepaint = true;
		m_bNcAreaBtnTracking = true;
	} // else from if( nHT == HTCLIENT )

HWND hTmpWndFocus = ::GetFocus();
bool bWindowActiveOldVal = m_bWindowActive;
	m_bWindowActive =
		( hTmpWndFocus != NULL
		&& (  GetSafeHwnd() == hTmpWndFocus
			  || ::IsChild( GetSafeHwnd(), hTmpWndFocus )
			)
		);
	if( bWindowActiveOldVal != m_bWindowActive )
		bNeedRepaint = true;

	if( bNeedRepaint )
	{
		SendMessage( WM_NCPAINT );
		GetParent()->SendMessage( WM_NCPAINT );
	}
}

void CExtControlBar::_RecalcNcArea()
{
	if( !IsVisible() )
		return;
	SetWindowPos(
		NULL, 0, 0, 0, 0,
		SWP_NOSIZE|SWP_NOMOVE
			|SWP_NOZORDER|SWP_NOOWNERZORDER
			|SWP_NOREPOSITION
			|SWP_FRAMECHANGED
		);
}

void CExtControlBar::_RecalcLayoutImpl()
{
	if( !m_bReflectParentSizing )
		return;
	if( m_bPresubclassDialogMode )
		return;
CWnd * pWndParent = GetParentFrame();
	if( pWndParent == NULL ||
		pWndParent->GetSafeHwnd() == NULL
		)
		return;
WINDOWPLACEMENT wp;
	ZeroMemory( &wp, sizeof(WINDOWPLACEMENT) );
	wp.length = sizeof(WINDOWPLACEMENT);
	pWndParent->GetWindowPlacement( &wp );
	if( wp.showCmd == SW_SHOWMINIMIZED )
		return;
InternalFriendlyFrameWnd * pFrame = (InternalFriendlyFrameWnd *)
		( DYNAMIC_DOWNCAST( CFrameWnd, pWndParent ) );
	if(		pFrame == NULL
		||	pFrame->IsInRecalcLayout()
		)
		return;
	if( IsFixedMode() && IsFloating() )
		pFrame->RecalcLayout();
	else
		pFrame->DelayRecalcLayout();
}

LRESULT CExtControlBar::WindowProc(UINT message, WPARAM wParam, LPARAM lParam) 
{
	switch( message )
	{
	case WM_CLOSE:

		// emulate for disabling update in user non-frame mode
		m_bInCustomModeUpdateCmdUI = true;

		return 0;

	case WM_DESTROY:
		
		// emulate for disabling update in user non-frame mode
		m_bInCustomModeUpdateCmdUI = true;
		
		break;
	case WM_NCDESTROY:

		// emulate for disabling update in user non-frame mode
		m_bInCustomModeUpdateCmdUI = true;

		NcButtons_RemoveAll();
		break;
	case WM_SETFOCUS:
		{
			LRESULT lResult =
				CControlBar::WindowProc(message, wParam, lParam);
			if( IsMinimizedOnRow() )
				MaximizeOnRow();
			if( !IsFixedMode() )
			{
				CWnd* pWnd = GetWindow(GW_CHILD);
				if(pWnd != NULL)
				{
					pWnd->SetFocus();
#if (!defined __EXT_MFC_NO_TAB_CONTROLBARS)
					ASSERT(
						pWnd->GetWindow(GW_HWNDNEXT) == NULL
						|| IsKindOf(RUNTIME_CLASS(CExtDynTabControlBar))
						);
#else
					ASSERT(
						pWnd->GetWindow(GW_HWNDNEXT) == NULL
						);
#endif // else from (!defined __EXT_MFC_NO_TAB_CONTROLBARS)
				}
			} // if( !IsFixedMode() )
			return lResult;
		}
	case WM_ERASEBKGND:
		if( !m_bDoNotEraseClientBackground )
			return !0;
		CExtPaintManager::stat_ExcludeChildAreas(
			(HDC)wParam,
			*this
			);
		return CControlBar::WindowProc(message, wParam, lParam);;
	case WM_CREATE:
		{
			if( (!m_bPresubclassDialogMode) && (!IsFixedMode()) )
			{
				ASSERT( GetSafeHwnd() != NULL );
				ASSERT( ::IsWindow(GetSafeHwnd()) );
				HWND hWndParent = ::GetParent( GetSafeHwnd() );
				CFrameWnd * pFrame = NULL;
				do
				{
					ASSERT( hWndParent != NULL );
					ASSERT( ::IsWindow(hWndParent) );
					CWnd * pWnd = CWnd::FromHandle( hWndParent );
					if( pWnd->IsKindOf(RUNTIME_CLASS(CFrameWnd)) )
					{
						pFrame = (CFrameWnd *)pWnd;
						break;
					}
				} while( pFrame == NULL );
				ASSERT( pFrame != NULL );
				ASSERT_VALID( pFrame );
				if( pFrame->IsKindOf(RUNTIME_CLASS(CMiniFrameWnd)) )
				{
					pFrame = pFrame->GetParentFrame();
					ASSERT( pFrame != NULL );
					ASSERT_VALID( pFrame );
					ASSERT( !pFrame->IsKindOf(RUNTIME_CLASS(CMiniFrameWnd)) );
				}
				VERIFY( _FrameEnableDockingImpl( pFrame ) );
			} // if( (!m_bPresubclassDialogMode) && (!IsFixedMode()) )
		}
		break;
	case WM_WINDOWPOSCHANGED:
		{
#if (!defined __EXT_MFC_NO_CUSTOMIZE)
			CExtCustomizeSite * pSite =
				CExtCustomizeSite::GetCustomizeSite( m_hWnd );
			if( pSite != NULL )
				pSite->OnBarStateChanged( this );
#endif // (!defined __EXT_MFC_NO_CUSTOMIZE)
			
			if( m_pDockBar == NULL && (!m_bPresubclassDialogMode) )
				break; // on destruction

			LPWINDOWPOS lpWindowPos = 
				reinterpret_cast < LPWINDOWPOS > (lParam);
			ASSERT( lpWindowPos != NULL );

			if( !IsFixedMode() )
				_UpdateVisibilityInChain();
			
			if( (lpWindowPos->flags & SWP_FRAMECHANGED) == 0 )
			{
				_RecalcNcArea();
			}
			else
			{
				//NcButtons_RemoveAll();
				//OnNcAreaButtonsReinitialize();
				OnNcAreaButtonsReposition();
//				CFrameWnd * pFrame = GetParentFrame();
//				if( pFrame != NULL
//					&& pFrame->IsKindOf(RUNTIME_CLASS(CMiniFrameWnd))
//					)
//					pFrame->SendMessage( WM_NCPAINT );
			}

			if(		(	_IsShowContentWhenDragging()
					||	_IsShowContentWhenRowRecalcing()
					||	_IsShowContentWhenRowResizing()
					)
				&&	(GetStyle() & WS_VISIBLE) != 0
				&&	g_PaintManager->GetCb2DbTransparentMode(this)
				)
			{
				SendMessage( WM_NCPAINT );
				RedrawWindow(
					NULL, NULL,
					RDW_ERASE|RDW_INVALIDATE|RDW_UPDATENOW|RDW_ERASENOW
						|RDW_ALLCHILDREN
						|RDW_NOFRAME
					);
				if(		m_pDockBar != NULL
					&&	m_pDockBar->IsKindOf( RUNTIME_CLASS(CExtDockBar) )
					)
				{
					m_pDockBar->Invalidate();
					if( _DraggingGetBar() == this )
						m_pDockBar->UpdateWindow();
				}
			}

			break;
		}
	case WM_WINDOWPOSCHANGING:
		{
			if( m_pDockBar == NULL && (!m_bPresubclassDialogMode) )
				break; // on destruction

			LPWINDOWPOS lpWindowPos = 
				reinterpret_cast < LPWINDOWPOS > (lParam);
			ASSERT( lpWindowPos != NULL );
			lpWindowPos->flags |= SWP_FRAMECHANGED;
			break;
		}
	} // switch( message )
	
	return CControlBar::WindowProc(message, wParam, lParam);
}

/////////////////////////////////////////////////////////////////////////////
// CExtControlBar message handlers

void CExtControlBar::NcButtons_Paint( CDC & dc )
{
	ASSERT( dc.GetSafeHdc() != NULL );
INT nCountOfNcButtons = NcButtons_GetCount();
	for( INT nBtn = 0; nBtn < nCountOfNcButtons; nBtn++ )
	{
		CExtBarNcAreaButton * pBtn =
			NcButtons_GetAt( nBtn );
		if( !pBtn->OnQueryVisibility() )
			continue;
		pBtn->OnNcAreaDraw( dc );
	} // for( INT nBtn = 0; nBtn < nCountOfNcButtons; nBtn++ )
}

CRect & CExtControlBar::NcButtons_CalcGripperTextLocation(
	CRect & rcPreCalcText
	)
{
INT nCountOfNcButtons = NcButtons_GetCount();
	if( nCountOfNcButtons == 0 )
		return rcPreCalcText; 

bool bHorz = false;
bool bGripperAtTop = true;
	if( !IsFloating() )
	{
		if( !IsBarWithGripper( &bGripperAtTop ) )
			return rcPreCalcText;
		bHorz = IsDockedHorizontally();
	}


	// find last visible at right or at bottom
CExtBarNcAreaButton * pBtn = NULL;
	for( INT nBtnIdx = nCountOfNcButtons; nBtnIdx > 0 ; nBtnIdx-- )
	{
		CExtBarNcAreaButton * pBtnExamine =
				NcButtons_GetAt( nBtnIdx - 1 );
		ASSERT_VALID( pBtnExamine );
		if( pBtnExamine->OnQueryVisibility() )
		{
			pBtn = pBtnExamine;
			break;
		}
	} // for( INT nBtnIdx = nCountOfNcButtons; nBtnIdx > 0 ; nBtnIdx-- )
	if( pBtn == NULL )
		return rcPreCalcText;

	// adjust caption text rect
const CRect & rcBtn = *pBtn;
	if( bHorz && !bGripperAtTop )
	{
		rcPreCalcText.top = rcBtn.bottom + 1;
		if( rcPreCalcText.top > rcPreCalcText.bottom )
			rcPreCalcText.top = rcPreCalcText.bottom;
	}
	else
	{
		rcPreCalcText.right = rcBtn.left - 1;
		if( rcPreCalcText.left > rcPreCalcText.right )
			rcPreCalcText.left = rcPreCalcText.right;
	}

	return rcPreCalcText;
}


UINT CExtControlBar::NcButtons_HitTest(
	CPoint point,
	CExtBarNcAreaButton ** ppBtn // = NULL
	)
{
	if( ppBtn != NULL )
		*ppBtn = NULL;

bool bNeedRepaint = false;

CWnd * pWndNcRepaint = this;
CRect rcBarWnd;
	if( IsFloating() )
	{
		CExtMiniDockFrameWnd * pFrame =
			DYNAMIC_DOWNCAST(
				CExtMiniDockFrameWnd,
				GetParentFrame()
				);
		if( pFrame == NULL )
			return HTCLIENT;
		pFrame->GetWindowRect( &rcBarWnd );
		pWndNcRepaint = pFrame;
	} // if( IsFloating() )
	else
	{
#if (!defined __EXT_MFC_NO_TAB_CONTROLBARS)
		if( AutoHideModeGet() )
		{
			ASSERT_VALID( m_pDockBar );
			ASSERT_KINDOF( CExtDockBar, m_pDockBar );
			CExtDynAutoHideArea * pWndAutoHideArea =
				((CExtDockBar*)m_pDockBar)->_GetAutoHideArea();
			ASSERT_VALID( pWndAutoHideArea );
			ASSERT_VALID( pWndAutoHideArea->m_pWndSlider );
			if( pWndAutoHideArea->m_pWndSlider->m_pBar != this
				|| ((pWndAutoHideArea->m_pWndSlider->GetStyle() & WS_VISIBLE) == 0)
				)
				return HTCLIENT;
			pWndAutoHideArea->m_pWndSlider->
				GetWindowRect( &rcBarWnd );
		}
		else
#endif // (!defined __EXT_MFC_NO_TAB_CONTROLBARS)
			GetWindowRect( &rcBarWnd );
	} // else from if( IsFloating() )
CPoint ptDevOffset = -rcBarWnd.TopLeft();
CPoint ptWnd( point + ptDevOffset );

bool bDragging = m_bDragging;
	if( !bDragging )
		bDragging = (_DraggingGetBar() != NULL) ? true : false;

UINT nFirstHT = HTCLIENT;
	if(		_DraggingGetBar() == NULL
		&& (!CExtPopupMenuWnd::IsMenuTracking())
		)
	{
		INT nCountOfNcButtons = NcButtons_GetCount();
		for( INT nBtn = 0; nBtn < nCountOfNcButtons; nBtn++ )
		{
			CExtBarNcAreaButton * pBtn =
				NcButtons_GetAt( nBtn );
			if( !pBtn->OnQueryVisibility() )
				continue;
			
			if( (pBtn->m_bHover || pBtn->m_bPushed)
				&& ppBtn == NULL
				)
			{
				bNeedRepaint = true;
				if( bDragging || m_bRowRecalcing || m_bRowResizing )
				{
					pBtn->m_bHover = false;
					pBtn->m_bPushed = false;
					continue;
				}
			}
			UINT nHT =
				pBtn->OnNcAreaHitTest( ptWnd );
			if( nHT != HTCLIENT )
			{
				if( ppBtn != NULL )
				{
					*ppBtn = pBtn;
					return nHT;
				}
				// TO FIX: ASSERT( nFirstHT == HTCLIENT );
				nFirstHT = nHT;
				bNeedRepaint = true;
			}
		} // for( INT nBtn = 0; nBtn < nCountOfNcButtons; nBtn++ )
	}

	if( bNeedRepaint )
		pWndNcRepaint->SendMessage( WM_NCPAINT );
	
	return nFirstHT;
}

UINT CExtControlBar::OnNcHitTest(CPoint point) 
{
UINT nHT = NcButtons_HitTest( point );
	if( nHT != HTCLIENT )
	{
		m_bNcAreaBtnTracking = true;
		return nHT;
	}
	else
	{
		if( m_bNcAreaBtnTracking )
			PostMessage( WM_NCPAINT );
		m_bNcAreaBtnTracking = false;
	}

	if( IsFixedMode() || IsFloating() )
		return HTCLIENT;

CRect rcBarWnd;
	GetWindowRect( &rcBarWnd );
CPoint ptDevOffset = -rcBarWnd.TopLeft();
CRect rcBarClient;
	GetClientRect( &rcBarClient );
	ClientToScreen( &rcBarClient );
	if( rcBarWnd == rcBarClient )
		return HTCLIENT;
//	rcBarWnd.OffsetRect( ptDevOffset );
//	rcBarClient.OffsetRect( ptDevOffset );

	point += ptDevOffset;

bool bHorz = IsDockedHorizontally();
	if( !m_rcRowResize.IsRectEmpty()
		&& m_rcRowResize.PtInRect( point )
		)
	{
		return bHorz ? HTBOTTOM : HTRIGHT;
	}	
	if( !m_rcRowRecalc.IsRectEmpty()
		&& m_rcRowRecalc.PtInRect( point )
		)
	{
		if( _IsLastBarInRow( true ) )
			return HTCLIENT;
		if( !_RowRecalcing_IsBottomEnabled() )
			return HTCLIENT;
		return bHorz ? HTRIGHT : HTBOTTOM;
	}	
	if( !m_rcRowRecalcUp.IsRectEmpty()
		&& m_rcRowRecalcUp.PtInRect( point )
		)
	{
		if( _IsFirstBarInRow( true ) )
			return HTCLIENT;
		if( !_RowRecalcing_IsTopEnabled() )
			return HTCLIENT;
		return bHorz ? HTLEFT : HTTOP;
	}	
	return HTCLIENT;
}

void CExtControlBar::_GetDeepNcModeMetrics(
	bool & bEnableResizerLeft,
	bool & bEnableResizerTop,
	bool & bEnableResizerRight,
	bool & bEnableResizerBottom
	)
{
	bEnableResizerLeft = true;
	bEnableResizerTop = true;
	bEnableResizerRight = true;
	bEnableResizerBottom = true;

	if( IsFixedMode() )
		return;

	if( !IsVisible() )
		return;

	if( m_pDockSite == NULL || m_pDockBar == NULL )
		return;
	ASSERT_VALID( m_pDockSite );
	ASSERT_VALID( m_pDockBar );

	if( !m_pDockBar->IsKindOf(RUNTIME_CLASS(CExtDockBar)) )
		return;

#if (!defined __EXT_MFC_NO_TAB_CONTROLBARS)
	if( m_pDockBar->IsKindOf(RUNTIME_CLASS(CExtDockDynTabBar)) )
	{
		bEnableResizerLeft = false;
		bEnableResizerTop = false;
		bEnableResizerRight = false;
		bEnableResizerBottom = false;
		return;
	}
#endif // (!defined __EXT_MFC_NO_TAB_CONTROLBARS)

CExtDockBar * pDockBar = (CExtDockBar *) m_pDockBar;
UINT nDockBarID = pDockBar->GetDlgCtrlID();
	ASSERT_DOCKBAR_DLGCTRLID_DOCKED( nDockBarID );

BOOL bHorz = ( nDockBarID == AFX_IDW_DOCKBAR_TOP || nDockBarID == AFX_IDW_DOCKBAR_BOTTOM );

INT nCount = pDockBar->m_arrBars.GetSize();
	ASSERT( nCount >= 1 );
	if( nCount == 1 )
		return;

INT nOwnIdx = pDockBar->FindBar( this );
	if( nOwnIdx == -1 )
		return; // destruction
	ASSERT( nOwnIdx > 0 && nOwnIdx < nCount );

bool bPrevRowExist = false;
bool bFirstVisibleOnRow = true;
	for( INT nBar = nOwnIdx-1; nBar > 0; nBar-- )
	{
		CControlBar * pBar = (CControlBar *) pDockBar->m_arrBars[nBar];
		if( pBar == NULL )
		{
			if( nBar > 0 )
				bPrevRowExist = true;
			break;
		}
		if( __PLACEHODLER_BAR_PTR( pBar ) )
			continue;
		ASSERT_VALID( pBar );
		ASSERT_KINDOF( CControlBar, pBar );
		if( pBar->IsVisible() )
			bFirstVisibleOnRow = false;
	}
bool bPrevVisibleRowExist = false;
	if( bPrevRowExist )
	{
		for( nBar--; nBar > 0; nBar-- )
		{
			CControlBar * pBar = (CControlBar *) pDockBar->m_arrBars[nBar];
			if( pBar == NULL )
				continue;
			if( __PLACEHODLER_BAR_PTR( pBar ) )
				continue;
			ASSERT_VALID( pBar );
			ASSERT_KINDOF( CControlBar, pBar );
			if( pBar->IsVisible() )
			{
				bPrevVisibleRowExist = true;
				break;
			}
		}
	}

bool bNextRowExist = false;
bool bLastVisibleOnRow = true;
	for( nBar = nOwnIdx+1; nBar < nCount; nBar++ )
	{
		CControlBar * pBar = (CControlBar *) pDockBar->m_arrBars[nBar];
		if( pBar == NULL )
		{
			if( nBar < (nCount-1) )
				bNextRowExist = true;
			break;
		}
		if( __PLACEHODLER_BAR_PTR( pBar ) )
			continue;
		ASSERT_VALID( pBar );
		ASSERT_KINDOF( CControlBar, pBar );
		if( pBar->IsVisible() )
			bLastVisibleOnRow = false;
	}
bool bNextVisibleRowExist = false;
	if( bNextRowExist )
	{
		for( nBar++; nBar < nCount; nBar++ )
		{
			CControlBar * pBar = (CControlBar *) pDockBar->m_arrBars[nBar];
			if( pBar == NULL )
				continue;
			if( __PLACEHODLER_BAR_PTR( pBar ) )
				continue;
			ASSERT_VALID( pBar );
			ASSERT_KINDOF( CControlBar, pBar );
			if( pBar->IsVisible() )
			{
				bNextVisibleRowExist = true;
				break;
			}
		}
	}

	if( m_pDockBar->IsKindOf(RUNTIME_CLASS(CExtDockDynBar)) )
	{ // if dockbar is dynamic docker
		if( bHorz )
		{
			if( !bPrevVisibleRowExist )
				bEnableResizerTop = false;
/**/		if( !bNextVisibleRowExist )
/**/			bEnableResizerBottom = false;
			if( bFirstVisibleOnRow )
				bEnableResizerLeft = false;
			if( bLastVisibleOnRow )
				bEnableResizerRight = false;
		} // if( bHorz )
		else
		{
			if( !bPrevVisibleRowExist )
				bEnableResizerLeft = false;
/**/		if( !bNextVisibleRowExist )
/**/			bEnableResizerRight = false;
			if( bFirstVisibleOnRow )
				bEnableResizerTop = false;
			if( bLastVisibleOnRow )
				bEnableResizerBottom = false;
		} // else from if( bHorz )

	} // if dockbar is dynamic docker
	else
	{ // if dockbar is static docker
		
		INT nOwnCircleNo = GetDockBarCircleNo();
		if( nOwnCircleNo > 0 )
		{
			switch( nDockBarID )
			{
			case AFX_IDW_DOCKBAR_TOP:
				if( !bPrevVisibleRowExist )
					bEnableResizerTop = false;
//				if( !bNextVisibleRowExist )
//					bEnableResizerBottom = false;
				if( bFirstVisibleOnRow )
					bEnableResizerLeft = false;
				if( bLastVisibleOnRow )
					bEnableResizerRight = false;
				break;
			case AFX_IDW_DOCKBAR_BOTTOM:
//				if( !bPrevVisibleRowExist )
//					bEnableResizerTop = false;
				if( !bNextVisibleRowExist )
					bEnableResizerBottom = false;
				if( bFirstVisibleOnRow )
					bEnableResizerLeft = false;
				if( bLastVisibleOnRow )
					bEnableResizerRight = false;
				break;
			case AFX_IDW_DOCKBAR_LEFT:
				if( !bPrevVisibleRowExist )
					bEnableResizerLeft = false;
//				if( !bNextVisibleRowExist )
//					bEnableResizerRight = false;
				if( bFirstVisibleOnRow )
					bEnableResizerTop = false;
				if( bLastVisibleOnRow )
					bEnableResizerBottom = false;
				break;
			case AFX_IDW_DOCKBAR_RIGHT:
//				if( !bPrevVisibleRowExist )
//					bEnableResizerLeft = false;
				if( !bNextVisibleRowExist )
					bEnableResizerRight = false;
				if( bFirstVisibleOnRow )
					bEnableResizerTop = false;
				if( bLastVisibleOnRow )
					bEnableResizerBottom = false;
				break;
#ifdef _DEBUG
			default:
				ASSERT( FALSE );
				break;
#endif // _DEBUG
			} // switch( nDockBarID )
		} // if( nOwnCircleNo > 0 )

	} // if dockbar is static docker

}

void CExtControlBar::OnNcCalcSize(BOOL bCalcValidRects, NCCALCSIZE_PARAMS FAR* lpncsp) 
{
	bCalcValidRects;

	if( m_pDockBar == NULL && (!m_bPresubclassDialogMode) )
		return; // on destruction

	if( IsFloating() ) // (+ v.2.22)
	{
		if( !IsFixedMode() ) // (+ v.2.23)
		{
			CRect & rcClientLoc =
				reinterpret_cast < CRect & > ( lpncsp->rgrc[0] );
			rcClientLoc.DeflateRect( 1, 1 );
			return;
		}
		CRect & rcClientLoc =
			reinterpret_cast < CRect & > ( lpncsp->rgrc[0] );
		rcClientLoc.OffsetRect( -rcClientLoc.TopLeft() );
		return;
	}

bool bEnableResizerLeft = true;
bool bEnableResizerTop = true;
bool bEnableResizerRight = true;
bool bEnableResizerBottom = true;
	_GetDeepNcModeMetrics(
		bEnableResizerLeft,
		bEnableResizerTop,
		bEnableResizerRight,
		bEnableResizerBottom
		);

CRect & rcClientLoc =
		reinterpret_cast < CRect & > ( lpncsp->rgrc[0] );
CRect rcDevOrg( rcClientLoc );

	m_rcGrip.SetRectEmpty();
	m_rcRowResize.SetRectEmpty();
	m_rcRowRecalc.SetRectEmpty();
	m_rcRowRecalcUp.SetRectEmpty();

	m_nMinHW = m_nSeparatorWidth;
	m_nMinVH = m_nSeparatorHeight;

bool bGripperAtTop = false;
bool bGripperExists = IsBarWithGripper( &bGripperAtTop );

#ifdef _DEBUG
	if( IsKindOf( RUNTIME_CLASS( CExtDynControlBar ) ) )
	{
#if (!defined __EXT_MFC_NO_TAB_CONTROLBARS)
		if( !IsKindOf( RUNTIME_CLASS( CExtDynTabControlBar ) ) )
#endif // (!defined __EXT_MFC_NO_TAB_CONTROLBARS)
		{
			ASSERT( !bGripperExists );
		}
	}
#endif // _DEBUG
	
CPoint ptGripOffset( 0, 0 );
UINT nDockBarDlgCtrlID = GetSafeDockBarDlgCtrlID();

	if( !IsFixedMode() )
	{
		MfcControlBarVector_t vBars;
		_GetRowBars( vBars );
		int nCountOfnBars = vBars.GetSize();
		INT nLastFixedIdx = -1;
		CExtControlBar * pLastExtBar = NULL;
		bool bAddTopRecalc = false;
		for( INT nBar = 0; nBar < nCountOfnBars ; nBar++ )
		{
			CControlBar * pBar = vBars[ nBar ];
			ASSERT_VALID( pBar );
			if( !pBar->IsVisible() )
				continue;
			CExtControlBar * pExtBar =
				DYNAMIC_DOWNCAST( CExtControlBar, pBar );
			if( pExtBar != NULL && pExtBar->IsFixedMode() )
				pExtBar = NULL;
			if( pExtBar != NULL )
			{
				if( pExtBar == this
					&& pLastExtBar != NULL
					&& nLastFixedIdx == (nBar-1)
					)
				{
					bAddTopRecalc = true;
					break;
				}
				pLastExtBar = pExtBar;
			}
			else
				nLastFixedIdx = nBar;
		} // for( INT nBar = 0; nBar < nCountOfnBars ; nBar++ )
		switch( nDockBarDlgCtrlID )
		{
		case AFX_IDW_DOCKBAR_TOP:
			if( bEnableResizerRight )
			{
				m_rcRowRecalc = rcClientLoc;
				m_rcRowRecalc.OffsetRect( -rcClientLoc.left, -rcClientLoc.top );
				m_rcRowRecalc.left = m_rcRowRecalc.right - m_nSeparatorWidth;
				rcClientLoc.right -= m_nSeparatorWidth;
			}
			
			if( bEnableResizerBottom )
			{
				rcClientLoc.DeflateRect( 0, 0, 0, m_nSeparatorHeight );
				m_rcRowResize = rcClientLoc;
				m_rcRowResize.OffsetRect( -rcClientLoc.left, -rcClientLoc.top );
				m_rcRowResize.top = m_rcRowResize.bottom;
				m_rcRowResize.bottom += m_nSeparatorHeight;
				m_rcRowResize.right = m_rcRowResize.left + rcDevOrg.Width();
			}

			if( bAddTopRecalc )
			{
				m_rcRowRecalcUp = rcClientLoc;
				m_rcRowRecalcUp.OffsetRect( -rcClientLoc.left, -rcClientLoc.top );
				m_rcRowRecalcUp.right = m_rcRowRecalcUp.left + m_nSeparatorWidth;
				if( bGripperExists )
					ptGripOffset.x += m_nSeparatorWidth;
				rcClientLoc.DeflateRect( m_nSeparatorWidth, 0, 0, 0 );
			} // if( bAddTopRecalc )
		break;
		case AFX_IDW_DOCKBAR_BOTTOM:
			if( bEnableResizerRight )
			{
				m_rcRowRecalc = rcClientLoc;
				m_rcRowRecalc.OffsetRect( -rcClientLoc.left, -rcClientLoc.top );
				m_rcRowRecalc.left = m_rcRowRecalc.right - m_nSeparatorWidth;
				rcClientLoc.right -= m_nSeparatorWidth;
			}
			
			if( bEnableResizerTop )
			{
				rcClientLoc.DeflateRect( 0, m_nSeparatorHeight, 0, 0 );
				m_rcRowResize = rcClientLoc;
				m_rcRowResize.OffsetRect( -rcClientLoc.left, -rcClientLoc.top );
				m_rcRowResize.bottom = m_rcRowResize.top + m_nSeparatorHeight;
				m_rcRowResize.right = m_rcRowResize.left + rcDevOrg.Width();
				if( bGripperExists )
					ptGripOffset.y += m_nSeparatorHeight;
			}

			if( bAddTopRecalc )
			{
				m_rcRowRecalcUp = rcClientLoc;
				m_rcRowRecalcUp.OffsetRect( -rcClientLoc.left, -rcClientLoc.top );
				m_rcRowRecalcUp.right = m_rcRowRecalcUp.left + m_nSeparatorWidth;
				if( bGripperExists )
					ptGripOffset.x += m_nSeparatorWidth;
				rcClientLoc.DeflateRect( m_nSeparatorWidth, 0, 0, 0 );
			} // if( bAddTopRecalc )
		break;
		case AFX_IDW_DOCKBAR_LEFT:
			if( bEnableResizerBottom )
			{
				m_rcRowRecalc = rcClientLoc;
				m_rcRowRecalc.OffsetRect( -rcClientLoc.left, -rcClientLoc.top );
				m_rcRowRecalc.top = m_rcRowRecalc.bottom - m_nSeparatorHeight;
rcClientLoc.DeflateRect( 0, 0, 0, m_nSeparatorHeight );
			}
			
			if( bEnableResizerRight )
			{
				//rcClientLoc.DeflateRect( 0, 0, m_nSeparatorWidth, m_nSeparatorHeight );
				rcClientLoc.DeflateRect( 0, 0, m_nSeparatorHeight, 0 );
				m_rcRowResize = rcClientLoc;
				m_rcRowResize.OffsetRect( -rcClientLoc.left, -rcClientLoc.top );
				m_rcRowResize.left = m_rcRowResize.right;
				m_rcRowResize.right += m_nSeparatorWidth;
				m_rcRowResize.bottom = m_rcRowResize.top + rcDevOrg.Height();
			}

			if( bAddTopRecalc )
			{
				m_rcRowRecalcUp = rcClientLoc;
				m_rcRowRecalcUp.OffsetRect( -rcClientLoc.left, -rcClientLoc.top );
				m_rcRowRecalcUp.bottom = m_rcRowRecalcUp.top + m_nSeparatorWidth;
				if( bGripperExists )
					ptGripOffset.y += m_nSeparatorHeight;
				rcClientLoc.DeflateRect( 0, m_nSeparatorHeight, 0, 0 );
			} // if( bAddTopRecalc )
		break;
		case AFX_IDW_DOCKBAR_RIGHT:
			if( bEnableResizerBottom )
			{
				m_rcRowRecalc = rcClientLoc;
				m_rcRowRecalc.OffsetRect( -rcClientLoc.left, -rcClientLoc.top );
				m_rcRowRecalc.top = m_rcRowRecalc.bottom - m_nSeparatorHeight;
rcClientLoc.DeflateRect( 0, 0, 0, m_nSeparatorHeight );
			}
			
			if( bEnableResizerLeft )
			{
				//rcClientLoc.DeflateRect( m_nSeparatorWidth, 0, 0, m_nSeparatorHeight );
				rcClientLoc.DeflateRect( m_nSeparatorHeight, 0, 0, 0 );
				m_rcRowResize = rcClientLoc;
				m_rcRowResize.OffsetRect( -rcClientLoc.left, -rcClientLoc.top );
				m_rcRowResize.right = m_rcRowResize.left + m_nSeparatorWidth;
				m_rcRowResize.bottom = m_rcRowResize.top + rcDevOrg.Height();
				if( bGripperExists )
					ptGripOffset.x += m_nSeparatorWidth;
			}

			if( bAddTopRecalc )
			{
				m_rcRowRecalcUp = rcClientLoc;
				m_rcRowRecalcUp.OffsetRect( -rcClientLoc.left, -rcClientLoc.top );
				m_rcRowRecalcUp.bottom = m_rcRowRecalcUp.top + m_nSeparatorWidth;
				if( bGripperExists )
					ptGripOffset.y += m_nSeparatorHeight;
				rcClientLoc.DeflateRect( 0, m_nSeparatorHeight, 0, 0 );
			} // if( bAddTopRecalc )
		break;
		} // switch( nDockBarDlgCtrlID )
	} // if( !IsFixedMode() )
	else
	{
		g_PaintManager->FixedBar_AdjustClientRect(
			this,
			rcClientLoc
			);
	} // else from if( !IsFixedMode() )

	if( bGripperExists )
	{
		m_rcGrip = rcClientLoc;
		m_rcGrip.OffsetRect( -rcClientLoc.left, -rcClientLoc.top );
		if( bGripperAtTop )
		{
			m_rcGrip.bottom = m_rcGrip.top + m_nGripHeightAtTop;
			m_nMinVH += m_rcGrip.Height();
			if( IsFixedMode() )
				m_rcGrip.DeflateRect( __BAR_NC_GAP_X, 0 );
		} // if( bGripperAtTop )
		else
		{
			m_rcGrip.right = m_rcGrip.left + m_nGripHeightAtTop;
			m_nMinHW += m_rcGrip.Width();
			if( IsFixedMode() )
				m_rcGrip.DeflateRect( 0, __BAR_NC_GAP_Y );
		} // else from if( bGripperAtTop )
		m_rcGrip.OffsetRect( ptGripOffset );

		if( IsFixedMode() )
			m_rcGrip.DeflateRect(
				(nDockBarDlgCtrlID == AFX_IDW_DOCKBAR_LEFT)   ? __BAR_NC_GAP_X : 0,
				(nDockBarDlgCtrlID == AFX_IDW_DOCKBAR_TOP)    ? __BAR_NC_GAP_X : 0,
				(nDockBarDlgCtrlID == AFX_IDW_DOCKBAR_RIGHT)  ? __BAR_NC_GAP_X : 0,
				(nDockBarDlgCtrlID == AFX_IDW_DOCKBAR_BOTTOM) ? __BAR_NC_GAP_X : 0
				);
	} // if( bGripperExists )

	OnNcAreaButtonsReinitialize();
	OnNcAreaButtonsReposition();

	if( bGripperExists )
		rcClientLoc.DeflateRect(
			bGripperAtTop
				? 0
				: m_nGripWidthAtLeft  + __BAR_NC_GAP_X
				,
			bGripperAtTop
				? m_nGripHeightAtTop  + __BAR_NC_GAP_Y
				: 0
				,
			0,
			0
			);

//	if( !IsKindOf(RUNTIME_CLASS(CExtDynControlBar)) )
//		rcClientLoc.DeflateRect( __BAR_NC_GAP_X, __BAR_NC_GAP_Y );

	if( rcClientLoc.bottom < rcClientLoc.top )
		rcClientLoc.bottom = rcClientLoc.top;
	if( rcClientLoc.right < rcClientLoc.left )
		rcClientLoc.right = rcClientLoc.left;
}

void CExtControlBar::OnNcPaint() 
{
	if( m_pDockBar == NULL && (!m_bPresubclassDialogMode) )
		return; // on destruction

#if (defined __DEBUG_PAINTING_AREAS_EXTRESIZABLEBAR__)

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 );

CDC & dc = dcBarWnd;
	dc.FillSolidRect( &rcBarWnd, g_PaintManager->GetColor(COLOR_3DFACE) );

bool bGripperAtTop = false;
bool bGripperExists = IsBarWithGripper( &bGripperAtTop );

	if( bGripperExists )
	{
		ASSERT( !m_rcGrip.IsRectEmpty() );
		CString sWndText;
		GetWindowText( sWndText );
		dc.FillSolidRect( &m_rcGrip, g_PaintManager->GetColor(COLOR_HIGHLIGHT) );
		if( !sWndText.IsEmpty() )
		{
			CRect rcGripText( m_rcGrip );
			rcGripText.DeflateRect( 2, 2 );
			HFONT hOldFont = (HFONT)
				::SelectObject(
					dc.GetSafeHdc(),
					::GetStockObject(DEFAULT_GUI_FONT)
					);
			COLORREF clrTextOld =
				dc.SetTextColor( g_PaintManager->GetColor(COLOR_HIGHLIGHTTEXT) );
			int nOldBkMode = dc.SetBkMode( TRANSPARENT );
			dc.DrawText(
				sWndText,
				&rcGripText,
				DT_LEFT|DT_VCENTER|DT_END_ELLIPSIS
				);
			dc.SetBkMode( nOldBkMode );
			dc.SetTextColor( clrTextOld );
			::SelectObject(
				dc.GetSafeHdc(),
				hOldFont
				);
		}
	} // if( bGripperExists )

	if( !m_rcRowResize.IsRectEmpty() )
		dc.FillSolidRect( &m_rcRowResize, RGB(255,0,0) );
	if( !m_rcRowRecalc.IsRectEmpty() )
		dc.FillSolidRect( &m_rcRowRecalc, RGB(0,255,0) );
	if( !m_rcRowRecalcUp.IsRectEmpty() )
		dc.FillSolidRect( &m_rcRowRecalcUp, RGB(0,0,255) );

	if( IsBarWithGripper() && !IsFloating() )
		NcButtons_Paint( dc );

#else // __DEBUG_PAINTING_AREAS_EXTRESIZABLEBAR__

CWindowDC dc( this );
CRect rcClient, rcBar;
	GetClientRect( rcClient );
	ClientToScreen( rcClient );
	GetWindowRect( rcBar );
	rcClient.OffsetRect( -rcBar.TopLeft() );
	rcBar.OffsetRect( -rcBar.TopLeft() );
	dc.ExcludeClipRect(rcClient);
CExtMemoryDC mdc( &dc, &rcBar );
CExtPaintManager::PAINTDOCKINGFRAMEDATA _pdfd(
		this,
		rcBar,
		rcClient,
		IsFloating() ? true : false,
		!IsFixedMode(),
		!IsFixedMode()
		);
	g_PaintManager->PaintDockingFrame( mdc, _pdfd );
bool bGripperAtTop = false;
	if( IsBarWithGripper(&bGripperAtTop) && !IsFloating() )
	{
		CRect rcGrip( m_rcGrip );
		bool bHorz = IsDockedHorizontally();
		CRect rcText( rcGrip );
		if( bHorz && !bGripperAtTop )
		{
			rcText.DeflateRect( 0, 2 );
			rcText.OffsetRect( -2, 0 );
		}
		else
			rcText.DeflateRect( 2, 0 );
		NcButtons_CalcGripperTextLocation( rcText );
		CString sCaption;
		GetWindowText( sCaption.GetBuffer(1024), 1024 );
		sCaption.ReleaseBuffer();
		CRgn rgnExclude;
		if( rgnExclude.CreateRectRgnIndirect( &rcGrip ) )
			mdc.SelectClipRgn( &rgnExclude );
		CExtPaintManager::PAINTGRIPPERDATA _pgd(
			this,
			rcGrip,
			rcText,
			m_bWindowActive,
			false,
			bHorz && !bGripperAtTop,
			!IsFixedMode(),
			sCaption.IsEmpty() ? LPCTSTR( NULL ) : sCaption
			);
		g_PaintManager->PaintGripper( mdc, _pgd );
		NcButtons_Paint( mdc );
		mdc.SelectClipRgn( NULL );
	} // if( IsBarWithGripper(&bGripperAtTop) && !IsFloating() )
	mdc.__Flush();
	ReleaseDC( &dc );

	g_PaintManager->OnPaintSessionComplete( this );

#endif // ! __DEBUG_PAINTING_AREAS_EXTRESIZABLEBAR__
}

void CExtControlBar::OnSysColorChange() 
{
	CControlBar::OnSysColorChange();
	g_PaintManager.OnSysColorChange( this );
	g_CmdManager.OnSysColorChange( this );
	_RecalcLayoutImpl();
}

void CExtControlBar::OnSettingChange(UINT uFlags, __EXT_MFC_SAFE_LPCTSTR lpszSection) 
{
    CControlBar::OnSettingChange(uFlags, lpszSection);
//	m_nGripHeightAtTop = ::GetSystemMetrics(SM_CYSMCAPTION)+1;
//	m_nGripWidthAtLeft = ::GetSystemMetrics(SM_CYSMCAPTION)+1;
//	m_nSeparatorHeight = min( 4, ::GetSystemMetrics(SM_CYSIZEFRAME) );
//	m_nSeparatorWidth = min( 4, ::GetSystemMetrics(SM_CXSIZEFRAME) );
//	m_nMinHW = ::GetSystemMetrics(SM_CYSMCAPTION)+1 + m_nSeparatorHeight;
//	m_nMinVH = ::GetSystemMetrics(SM_CYSMCAPTION)+1 + m_nSeparatorHeight;
	g_PaintManager.OnSettingChange( this, uFlags, lpszSection );
	g_CmdManager.OnSettingChange( this, uFlags, lpszSection );
	_RecalcLayoutImpl();
}

LRESULT CExtControlBar::OnDisplayChange( WPARAM wParam, LPARAM lParam )
{
LRESULT lResult = CControlBar::OnDisplayChange( wParam, lParam );
	g_PaintManager.OnDisplayChange( this, (INT)wParam, CPoint(lParam) );
	g_CmdManager.OnDisplayChange( this, (INT)wParam, CPoint(lParam) );
	return lResult;
}

LRESULT CExtControlBar::OnThemeChanged( WPARAM wParam, LPARAM lParam )
{
LRESULT lResult = Default();
	g_PaintManager.OnThemeChanged( this, wParam, lParam );
	g_CmdManager.OnThemeChanged( this, wParam, lParam );
	return lResult;
}

void CExtControlBar::OnCancelMode() 
{
	if( m_bRowResizing )
		_RowResizingStop( true );
	if( m_bRowRecalcing )
		_RowRecalcingStop( true );
	if( m_bDragging )
		_DraggingStop( true );
	CExtPopupMenuWnd::CancelMenuTracking();
	CWnd::CancelToolTips();
//	ASSERT( !CExtPopupMenuWnd::IsMenuTracking() );
	if( m_bNcAreaBtnTracking )
	{
		m_bNcAreaBtnTracking = false;
		PostMessage( WM_NCPAINT );
	}
	CControlBar::OnCancelMode();
}

void CExtControlBar::OnCaptureChanged(CWnd *pWnd) 
{
	if( m_bRowResizing )
		_RowResizingStop( true );
	if( m_bRowRecalcing )
		_RowRecalcingStop( true );
//	if( m_bDragging )
//		_DraggingStop( true );
	CControlBar::OnCaptureChanged(pWnd);
}

bool CExtControlBar::_OnMouseMoveMsg(UINT nFlags, CPoint point)
{
	nFlags;
	_SetCursor( point );
	if( m_bNcAreaBtnTracking )
		return true;
	if( m_bRowResizing )
	{
		_RowResizingUpdateState();
		return true;
	}
	if( m_bRowRecalcing )
	{
		_RowRecalcingUpdateState();
		return true;
	}
	if( m_bDragging )
	{
		CPoint ptScreen( point );
		ClientToScreen( &ptScreen );
		_DraggingUpdateState( ptScreen, false );
		return true;
	}
	if( IsFloating()
		&&
		CExtMiniDockFrameWnd::g_bAutoMakeTopmostOnMouseEvent
		&& (!CExtPopupMenuWnd::IsMenuTracking())
		)
	{
		CFrameWnd * pParentFrame = GetParentFrame();
		if( pParentFrame != NULL )
			pParentFrame->BringWindowToTop();
	}
	return false;
}

void CExtControlBar::OnMouseMove(UINT nFlags, CPoint point) 
{
	if( _OnMouseMoveMsg(nFlags,point) )
		return;
	CControlBar::OnMouseMove(nFlags,point);
}

bool CExtControlBar::_RowRecalcing_IsBottomEnabled()
{
	// prev or next extbar should not be minimized
ExtControlBarVector_t vBars;
	_GetRowExtBars( vBars );
INT nCountOfBars = vBars.GetSize();
bool bThisPassed = false;
CExtControlBar * pBarPrev = NULL, * pBarNext = NULL;
	for( INT nBar = 0; nBar < nCountOfBars; nBar++ )
	{
		CExtControlBar * pBar = vBars[ nBar ];
		ASSERT_VALID( pBar );
		if( !pBar->IsVisible() )
			continue;
		if( !bThisPassed )
			pBarPrev = pBar;
		else
		{
			pBarNext = pBar;
			break;
		}
		if( pBar == this )
		{
			bThisPassed = true;
			continue;
		}
	} // for( INT nBar = 0; nBar < nCountOfBars; nBar++ )
bool bMinimizedPrev = true, bMinimizedNext = true;
	if( pBarPrev != NULL )
		bMinimizedPrev = pBarPrev->IsMinimizedOnRow();
	if( pBarNext != NULL )
		bMinimizedNext = pBarNext->IsMinimizedOnRow();
	if( bMinimizedPrev && bMinimizedNext )
		return false;
	return true;
}

bool CExtControlBar::_RowRecalcing_IsTopEnabled()
{
	// this or next extbar should not be minimized
ExtControlBarVector_t vBars;
	_GetRowExtBars( vBars );
INT nCountOfBars = vBars.GetSize();
CExtControlBar * pBarNext = NULL;
	for( INT nBar = 0; nBar < nCountOfBars; nBar++ )
	{
		CExtControlBar * pBar = vBars[ nCountOfBars - nBar - 1 ];
		ASSERT_VALID( pBar );
		if( !pBar->IsVisible() )
			continue;
		if( pBar == this )
			break;
		pBarNext = pBar;
	} // for( INT nBar = 0; nBar < nCountOfBars; nBar++ )
bool bMinimizedNext = true;
	if( pBarNext != NULL )
		bMinimizedNext = pBarNext->IsMinimizedOnRow();
	if( bMinimizedNext && IsMinimizedOnRow() )
		return false;
	return true;
}

void CExtControlBar::OnNcLButtonDown(UINT nHitTest, CPoint point) 
{
#if (!defined __EXT_MFC_NO_CUSTOMIZE)
CExtCustomizeSite * pSite =
		CExtCustomizeSite::GetCustomizeSite( m_hWnd );
	if(		pSite != NULL
		&&	pSite->IsCustomizeMode()
		)
		pSite->DropTargetPopupCancel();
#endif // (!defined __EXT_MFC_NO_CUSTOMIZE)

	if( IsFixedMode() || IsFloating() )
		return;

	switch( nHitTest )
	{
	case HTLEFT:
	case HTBOTTOM:
		break; // case HTLEFT & HTBOTTOM
	default:
		if(		( !IsFixedMode() )
			&&	( !IsMinimizedOnRow() )
			)
		{
			CPoint ptScreen( point );
			//ClientToScreen( &ptScreen );
			CExtBarNcAreaButton * pBtn = NULL;
			( const_cast < CExtControlBar * > ( this ) ) ->
				NcButtons_HitTest( ptScreen, &pBtn );
			if( pBtn == NULL ) // (+ v.2.23)
				SetFocus();
		}
		//return;
		break;
	} // switch( nHitTest )

	ASSERT( !m_bRowRecalcing );
	ASSERT( !m_bRowResizing );

CRect rcBarWnd, rcBarClient;
	GetWindowRect( &rcBarWnd );
	GetClientRect( &rcBarClient );
	ClientToScreen( &rcBarClient );
	if( rcBarWnd == rcBarClient )
		return;
CPoint ptDevOffset = -rcBarWnd.TopLeft();
//	rcBarWnd.OffsetRect( ptDevOffset );
//	rcBarClient.OffsetRect( ptDevOffset );

	point += ptDevOffset;

bool bHorz = IsDockedHorizontally();
	if( !m_rcRowResize.IsRectEmpty()
		&& m_rcRowResize.PtInRect( point )
		)
	{
		ASSERT( (INT)nHitTest == (bHorz ? HTBOTTOM : HTRIGHT) );
		_RowResizingStart();
		return;
	}	
	if( !m_rcRowRecalc.IsRectEmpty()
		&& m_rcRowRecalc.PtInRect( point )
		)
	{
		ASSERT( !_IsLastBarInRow( true ) );
		ASSERT( (INT)nHitTest == (bHorz ? HTRIGHT : HTBOTTOM) );
		m_bTopRecalcing = false;
		
		if( !_RowRecalcing_IsBottomEnabled() )
			return;
		
		_RowRecalcingStart();
		return;
	}	
	if( !m_rcRowRecalcUp.IsRectEmpty()
		&& m_rcRowRecalcUp.PtInRect( point )
		)
	{
		ASSERT( !_IsFirstBarInRow( true ) );
		ASSERT( (INT)nHitTest == (bHorz ? HTLEFT : HTTOP) );

		if( !_RowRecalcing_IsTopEnabled() )
			return;
		
		m_bTopRecalcing = true;
		_RowRecalcingStart();
		return;
	}
}

void CExtControlBar::OnNcLButtonUp(UINT nHitTest, CPoint point) 
{
	if( m_bNcAreaBtnTracking )
	{
		CRect rcBarWnd;
		GetWindowRect( &rcBarWnd );
		CPoint ptDevOffset = -rcBarWnd.TopLeft();
		CPoint ptWnd( point + ptDevOffset );
		INT nCountOfNcButtons = NcButtons_GetCount();
		for( INT nBtn = 0; nBtn < nCountOfNcButtons; nBtn++ )
		{
			CExtBarNcAreaButton * pBtn =
				NcButtons_GetAt( nBtn );
			if( !pBtn->OnQueryVisibility() )
				continue;
			if( pBtn->OnNcAreaClicked( ptWnd ) )
				return;
		} // for( INT nBtn = 0; nBtn < nCountOfNcButtons; nBtn++ )
		return;
	}

	if( m_bRowResizing )
	{
		_RowResizingStop( false );
		return;
	}
	
	if( m_bRowRecalcing )
	{
		_RowRecalcingStop( false );
		return;
	}
	
	if( m_bDragging )
	{
		//_DraggingStop( false );
		return;
	}

	CControlBar::OnNcLButtonUp(nHitTest, point);
}

void CExtControlBar::OnLButtonDown(UINT nFlags, CPoint point) 
{
    if( m_pDockBar == NULL || CExtPopupMenuWnd::IsMenuTracking() )
	{
        CWnd::OnLButtonDown(nFlags, point);
		return;
	}

	// start dragging
	ASSERT_VALID( m_pDockBar );
    ASSERT( m_pDockContext != NULL );

    ClientToScreen( &point );
	
bool bExtendedDragging = _IsShowContentWhenDragging();
	if( !bExtendedDragging && IsFixedMode() )
	{
		m_pDockContext->StartDrag( point );
		return;
	}

	if( m_pDockBar != NULL && (!IsFloating()) )
	{
		if( !m_pDockBar->IsKindOf(
				RUNTIME_CLASS(CExtDockBar)
				)
			)
			bExtendedDragging = false;
	}

	if( IsFloating() )
	{
		CMiniDockFrameWnd * pMiniFrame =
			DYNAMIC_DOWNCAST(
				CMiniDockFrameWnd,
				GetDockingFrame()
				);
		ASSERT_VALID( pMiniFrame );

		CExtMiniDockFrameWnd * pExtMiniFrame =
			DYNAMIC_DOWNCAST(
				CExtMiniDockFrameWnd,
				GetDockingFrame()
				);
		if( pExtMiniFrame != NULL )
		{
			pExtMiniFrame->OnNcLButtonDown(
				HTCAPTION,
				point
				);
			return;
		}
	} // if( IsFloating() )

	if( !IsFixedMode() )
		SetFocus();

CPoint ptOffset( point );
CRect rcWnd;
	GetWindowRect( &rcWnd );
	ptOffset -= rcWnd.TopLeft();

	_DraggingStart( point, ptOffset );
}

void CExtControlBar::OnLButtonUp(UINT nFlags, CPoint point) 
{
	if( m_bRowResizing )
	{
		_RowResizingStop( false );
		return;
	}
	if( m_bRowRecalcing )
	{
		_RowRecalcingStop( false );
		return;
	}
	if( m_bDragging )
	{
		_DraggingStop( false );
		return;
	}
	CControlBar::OnLButtonUp(nFlags, point);
}

void CExtControlBar::OnRButtonUp(UINT nFlags, CPoint point) 
{
	nFlags;

//	if( m_bRowResizing )
//		_RowResizingStop();
//	if( m_bRowRecalcing )
//		_RowRecalcingStop();
//	if( m_bDragging )
//		_DraggingStop( false );
//	CControlBar::OnRButtonUp(nFlags, point);

#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(		m_bPresubclassDialogMode
		||	_GetDockingFrameImpl() == NULL
		||	CExtControlBar::FindHelpMode( this )
		)
	{
		CControlBar::OnRButtonUp( nFlags, point );
		return;
	}

CFrameWnd * pFrame = _GetDockingFrameImpl();
	ASSERT_VALID( pFrame );
	if( ! ::GetCursorPos(&point) )
		return;
HWND hWndTrack = GetOwner()->GetSafeHwnd();
	ASSERT( hWndTrack != NULL && ::IsWindow(hWndTrack) );
CExtPopupMenuWnd * pPopup = new CExtPopupMenuWnd;
	VERIFY( pPopup->CreatePopupMenu(hWndTrack) );
	if(	! CExtDockBar::_ConstructDockSiteControlBarPopupMenu(
			pFrame,
			pPopup,
			CExtControlBar::POPUP_MENU_EVENT_DATA::__PMED_CONTROLBAR_CTX,
			this,
			WM_RBUTTONUP,
			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 CExtControlBar::OnNcRButtonUp(UINT nHitTest, CPoint point)
{
#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(		m_bPresubclassDialogMode
		||	_GetDockingFrameImpl() == NULL
		||	CExtControlBar::FindHelpMode( this )
		)
	{
		CControlBar::OnNcRButtonUp( nHitTest, point );
		return;
	}

CFrameWnd * pFrame = _GetDockingFrameImpl();
	ASSERT_VALID( pFrame );
	if( ! ::GetCursorPos(&point) )
		return;
HWND hWndTrack = GetOwner()->GetSafeHwnd();
	ASSERT( hWndTrack != NULL && ::IsWindow(hWndTrack) );
CExtPopupMenuWnd * pPopup = new CExtPopupMenuWnd;
	VERIFY( pPopup->CreatePopupMenu(hWndTrack) );
	if(	! CExtDockBar::_ConstructDockSiteControlBarPopupMenu(
			pFrame,
			pPopup,
			CExtControlBar::POPUP_MENU_EVENT_DATA::__PMED_CONTROLBAR_NC_CTX,
			this,
			WM_RBUTTONUP,
			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 CExtControlBar::OnLButtonDblClk(UINT nFlags, CPoint point)
{
    if( m_pDockBar == NULL )
	{
        CWnd::OnLButtonDblClk(nFlags, point);
		return;
	}
	ToggleDocking();
}

void CExtControlBar::OnNcLButtonDblClk(UINT nHitTest, CPoint point) 
{
    if( m_pDockBar == NULL || nHitTest != HTCAPTION )
	{
        CWnd::OnNcLButtonDblClk(nHitTest, point);
		return;
	}
	ToggleDocking();
}

bool CExtControlBar::_IsShowContentWhenDragging() const
{
//BOOL bDragShowContent = FALSE;
//    ::SystemParametersInfo(
//		SPI_GETDRAGFULLWINDOWS,
//		0,
//        &bDragShowContent,
//		0
//		);
//	return bDragShowContent ? true : false;

	return false;
}

bool CExtControlBar::_IsShowContentWhenRowResizing() const
{
	return _IsShowContentWhenDragging();
}

bool CExtControlBar::_IsShowContentWhenRowRecalcing() const
{
	return _IsShowContentWhenDragging();
}

void CExtControlBar::_RowResizingStart()
{
	ASSERT( !m_bRowRecalcing );
	ASSERT( !m_bRowResizing );
	CWnd::CancelToolTips();
	m_bRowResizing = true;
	CExtMouseCaptureSink::SetCapture( GetSafeHwnd() );
	ASSERT_VALID( m_pDockSite );
	ASSERT( !IsFloating() );
	m_nMetricOffset = IsDockedHorizontally() ?
		m_sizeDockedH.cy : m_sizeDockedV.cx;
	if( !_IsShowContentWhenRowResizing() )
	{
		CPoint ptCursorScreen( 0, 0 );
		::GetCursorPos( &ptCursorScreen );
		m_nTrackerOffset =
			IsDockedHorizontally()
				? ptCursorScreen.y : ptCursorScreen.x;
		_DrawResizingTracker();
	} // if( !_IsShowContentWhenRowResizing() )

	while( m_bRowResizing )
	{
		::WaitMessage();
		MSG msg;
		// Process all the messages in the message queue
		while( PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE) )
		{
			bool bStop = false;
			switch( msg.message )
			{
			case WM_ACTIVATEAPP:
			case WM_CANCELMODE:
//			case WM_LBUTTONUP:
			case WM_RBUTTONDOWN:
			case WM_NCLBUTTONUP:
//			case WM_NCLBUTTONDOWN:
			case WM_NCRBUTTONUP:
			case WM_NCRBUTTONDOWN:
			case WM_MBUTTONDOWN:
			case WM_MBUTTONUP:
			case WM_NCMBUTTONDOWN:
			case WM_NCMBUTTONUP:
			case WM_CONTEXTMENU:
				bStop = true;
			break;
			default:
				if(	WM_KEYFIRST <= msg.message
					&& msg.message <= WM_KEYLAST
					)
					bStop = true;
//				else
//				{
//					if( CExtMouseCaptureSink::GetCapture() != GetSafeHwnd() )
//						bStop = true;
//					else
//					{
//						if(	(!CExtPopupMenuWnd::
//								IsKeyPressed(VK_LBUTTON))
//							|| CExtPopupMenuWnd::
//								IsKeyPressed(VK_RBUTTON)
//							|| CExtPopupMenuWnd::
//								IsKeyPressed(VK_MBUTTON)
//							)
//							bStop = true;
//					}
//				}
			break;
			} // switch( msg.message )
			if( bStop )
			{
				_RowResizingStop( true );
				break;
			}
			if( !AfxGetThread()->PumpMessage() )
			{
				PostQuitMessage(0);
				break; // Signal WM_QUIT received
			} // if( !AfxGetThread()->PumpMessage() )
		} // while( PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE) )
		if( m_bRowResizing && CExtControlBar::g_bEnableOnIdleCalls )
		{
			for(	LONG nIdleCounter = 0L;
					::AfxGetThread()->OnIdle(nIdleCounter);
					nIdleCounter ++
					);
		}
	} // while( m_bRowResizing )
}

void CExtControlBar::_RowResizingStop( bool bCancel )
{
	m_bRowResizing = false;
	if( CExtMouseCaptureSink::GetCapture() == GetSafeHwnd() )
		CExtMouseCaptureSink::ReleaseCapture();
	ASSERT_VALID( m_pDockSite );
	ASSERT_VALID( m_pDockBar );
	ASSERT( !IsFloating() );

	if( !_IsShowContentWhenRowResizing() )
	{
		_DrawResizingTracker();

		if( !bCancel )
		{
			bool bHorz = IsDockedHorizontally();
			if(	m_nMetricOffset !=
					(bHorz ? m_sizeDockedH.cy : m_sizeDockedV.cx)
				)
			{
				ExtControlBarVector_t vBars;
				_GetRowExtBars( vBars );
				INT nCountOfBars = vBars.GetSize();
				ASSERT( nCountOfBars > 0 );
				LONG nDiff = 0;
				for( INT nBar = 0; nBar < nCountOfBars; nBar++ )
				{
					CExtControlBar * pBar = vBars[ nBar ];
					ASSERT_VALID( pBar );
//					if( !pBar->IsVisible() )
//						continue;
					if( pBar->IsFixedMode() )
						continue;
					if( bHorz )
					{
						if( nDiff == 0 )
							nDiff = pBar->m_sizeDockedH.cy - m_nMetricOffset;
						pBar->m_sizeDockedH.cy = m_nMetricOffset;
					}
					else
					{
						if( nDiff == 0 )
							nDiff = pBar->m_sizeDockedV.cx - m_nMetricOffset;
						pBar->m_sizeDockedV.cx = m_nMetricOffset;
					}
				} // for( INT nBar = 0; nBar < nCountOfBars; nBar++ )

				if( nDiff != 0 )
				{
					UINT nDockBarID = GetSafeDockBarDlgCtrlID();
					ASSERT_DOCKBAR_DLGCTRLID_DOCKED( nDockBarID );
					MfcControlBarVector_t vNextRow;
					if( nDockBarID == AFX_IDW_DOCKBAR_TOP
						|| nDockBarID == AFX_IDW_DOCKBAR_LEFT
						)
						_GetNextRowBars( true, vNextRow );
					else
						_GetNextRowBars( false, vNextRow );
					INT nCountOfBars = vNextRow.GetSize();
					for( INT nBar = 0; nBar < nCountOfBars; nBar++ )
					{
						CExtControlBar * pBar = (CExtControlBar *)vNextRow[ nBar ];
						ASSERT_VALID( pBar );
						if( !pBar->IsKindOf( RUNTIME_CLASS(CExtControlBar) ) )
							continue;
						if( pBar->IsFixedMode() )
							continue;
						if( bHorz )
							pBar->m_sizeDockedH.cy += nDiff;
						else
							pBar->m_sizeDockedV.cx += nDiff;
					} // for( INT nBar = 0; nBar < nCountOfBars; nBar++ )
				} // if( nDiff != 0 )
			}

//xx//
			//m_pDockSite->RecalcLayout();
			GetParentFrame()->RecalcLayout();
		} // if( !bCancel )

		ASSERT_VALID( m_pDockBar );
		m_pDockBar->RedrawWindow(
			NULL, NULL,
			RDW_ERASE|RDW_INVALIDATE|RDW_UPDATENOW|RDW_ERASENOW
				|RDW_ALLCHILDREN
				|RDW_NOFRAME
			);

	} // if( !_IsShowContentWhenRowResizing() )
}

void CExtControlBar::_RowResizingUpdateState()
{
	ASSERT( m_bRowResizing );
	ASSERT_VALID( m_pDockSite );

CRect rcDockSite;
	m_pDockSite->GetWindowRect( &rcDockSite );
CSize sizeDockMax =
		rcDockSite.Size()
		- CSize(
			_CalcDesiredMinHW(),
			_CalcDesiredMinVH()
			);
	if( sizeDockMax.cx <= 0 || sizeDockMax.cy <= 0 )
		return;

CPoint ptCursorScreen( 0, 0 );
	::GetCursorPos( &ptCursorScreen );
CPoint ptCursor( ptCursorScreen );

	//ScreenToClient( &ptCursor );
CRect rcBarWnd;
	GetWindowRect( &rcBarWnd );
CPoint ptDevOffset = -rcBarWnd.TopLeft();
	ptCursor += ptDevOffset;

bool bHorz = IsDockedHorizontally();
	if( bHorz )
	{
		bool bTop = IsDockedAtTop();
		m_nMetricOffset =
			max(
				_CalcDesiredMinVH()*2,
				bTop
					? (ptCursor.y + m_rcRowResize.Height()/2)
					: (m_sizeDockedH.cy - ptCursor.y + m_rcRowResize.Height()/2)
				);
		if( m_nMetricOffset > sizeDockMax.cy )
			m_nMetricOffset = sizeDockMax.cy;
		if( m_nMetricOffset == m_sizeDockedH.cy )
			return;
	} // if( bHorz )
	else
	{
		bool bLeft = IsDockedAtLeft();
		m_nMetricOffset =
			max(
				_CalcDesiredMinHW()*2,
				bLeft
					? (ptCursor.x + m_rcRowResize.Width()/2)
					: (m_sizeDockedV.cx - ptCursor.x + m_rcRowResize.Width()/2 )
				);
		if( m_nMetricOffset > sizeDockMax.cx )
			m_nMetricOffset = sizeDockMax.cx;
		if( m_nMetricOffset == m_sizeDockedV.cx )
			return;
	} // else from if( bHorz )

bool bShowContent = _IsShowContentWhenRowResizing();
	if( bShowContent )
	{

/*
		ExtControlBarVector_t vBars;
		_GetRowExtBars( vBars );
		INT nCountOfBars = vBars.GetSize();
		ASSERT( nCountOfBars > 0 );
		for( INT nBar = 0; nBar < nCountOfBars; nBar++ )
		{
			CExtControlBar * pBar = vBars[ nBar ];
			ASSERT_VALID( pBar );
			if( bHorz )
				pBar->m_sizeDockedH.cy = m_nMetricOffset;
			else
				pBar->m_sizeDockedV.cx = m_nMetricOffset;
		} // for( INT nBar = 0; nBar < nCountOfBars; nBar++ )
*/

		ExtControlBarVector_t vBars;
		_GetRowExtBars( vBars );
		INT nCountOfBars = vBars.GetSize();
		ASSERT( nCountOfBars > 0 );
		LONG nDiff = 0;
		for( INT nBar = 0; nBar < nCountOfBars; nBar++ )
		{
			CExtControlBar * pBar = vBars[ nBar ];
			ASSERT_VALID( pBar );
//					if( !pBar->IsVisible() )
//						continue;
			if( pBar->IsFixedMode() )
				continue;
			if( bHorz )
			{
				if( nDiff == 0 )
					nDiff = pBar->m_sizeDockedH.cy - m_nMetricOffset;
				pBar->m_sizeDockedH.cy = m_nMetricOffset;
			}
			else
			{
				if( nDiff == 0 )
					nDiff = pBar->m_sizeDockedV.cx - m_nMetricOffset;
				pBar->m_sizeDockedV.cx = m_nMetricOffset;
			}
		} // for( INT nBar = 0; nBar < nCountOfBars; nBar++ )

/*
		if( nDiff != 0 )
		{
			UINT nDockBarID = GetSafeDockBarDlgCtrlID();
			ASSERT_DOCKBAR_DLGCTRLID_DOCKED( nDockBarID );
			MfcControlBarVector_t vNextRow;
			if( nDockBarID == AFX_IDW_DOCKBAR_TOP
				|| nDockBarID == AFX_IDW_DOCKBAR_LEFT
				)
				_GetNextRowBars( true, vNextRow );
			else
				_GetNextRowBars( false, vNextRow );
			INT nCountOfBars = vNextRow.GetSize();
			for( INT nBar = 0; nBar < nCountOfBars; nBar++ )
			{
				CExtControlBar * pBar = (CExtControlBar *)vNextRow[ nBar ];
				ASSERT_VALID( pBar );
				if( !pBar->IsKindOf( RUNTIME_CLASS(CExtControlBar) ) )
					continue;
				if( pBar->IsFixedMode() )
					continue;
				if( bHorz )
					pBar->m_sizeDockedH.cy += nDiff;
				else
					pBar->m_sizeDockedV.cx += nDiff;
			} // for( INT nBar = 0; nBar < nCountOfBars; nBar++ )
		} // if( nDiff != 0 )
*/

		m_pDockSite->RecalcLayout();

		ASSERT_VALID( m_pDockBar );
		if( m_pDockBar->IsKindOf(RUNTIME_CLASS(CExtDockBar)) )
			((CExtDockBar *)m_pDockBar)->OnDynamicLayoutUpdate();

		return;
	} // if( bShowContent )

	_DrawResizingTracker();

	m_nTrackerOffset =
		bHorz ? ptCursorScreen.y : ptCursorScreen.x;
	_DrawResizingTracker();
}

void CExtControlBar::_RowRecalcingStart()
{
	ASSERT( !m_bRowRecalcing );
	ASSERT( !m_bRowResizing );
	CWnd::CancelToolTips();
	m_bRowRecalcing = true;
    CExtMouseCaptureSink::SetCapture( GetSafeHwnd() );
	ASSERT_VALID( m_pDockSite );
	if( !_IsShowContentWhenRowRecalcing() )
	{
		CPoint ptCursorScreen( 0, 0 );
		::GetCursorPos( &ptCursorScreen );
		m_nTrackerOffset =
			IsDockedHorizontally()
				? ptCursorScreen.x
				: ptCursorScreen.y;
		m_nMetricOffset = 0;
		_DrawRecalcingTracker();
	} // if( !_IsShowContentWhenRowRecalcing() )

	while( m_bRowRecalcing )
	{
		::WaitMessage();
		MSG msg;
		// Process all the messages in the message queue
		while( PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE) )
		{
			bool bStop = false;
			switch( msg.message )
			{
			case WM_ACTIVATEAPP:
			case WM_CANCELMODE:
//			case WM_LBUTTONUP:
			case WM_RBUTTONDOWN:
//			case WM_NCLBUTTONUP:
			case WM_NCLBUTTONDOWN:
			case WM_NCRBUTTONUP:
			case WM_NCRBUTTONDOWN:
			case WM_MBUTTONDOWN:
			case WM_MBUTTONUP:
			case WM_NCMBUTTONDOWN:
			case WM_NCMBUTTONUP:
			case WM_CONTEXTMENU:
				bStop = true;
			break;
			default:
				if(	WM_KEYFIRST <= msg.message
					&& msg.message <= WM_KEYLAST
					)
					bStop = true;
//				else
//				{
//					if( CExtMouseCaptureSink::GetCapture() != GetSafeHwnd() )
//						bStop = true;
//					else
//					{
//						if(	(!CExtPopupMenuWnd::
//								IsKeyPressed(VK_LBUTTON))
//							|| CExtPopupMenuWnd::
//								IsKeyPressed(VK_RBUTTON)
//							|| CExtPopupMenuWnd::
//								IsKeyPressed(VK_MBUTTON)
//							)
//							bStop = true;
//					}
//				}
			break;
			} // switch( msg.message )
			if( bStop )
			{
				_RowRecalcingStop( true );
				break;
			}
			if( !AfxGetThread()->PumpMessage() )
			{
				PostQuitMessage(0);
				break; // Signal WM_QUIT received
			} // if( !AfxGetThread()->PumpMessage() )
		} // while( PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE) )
		if( m_bRowRecalcing && CExtControlBar::g_bEnableOnIdleCalls )
		{
			for(	LONG nIdleCounter = 0L;
					::AfxGetThread()->OnIdle(nIdleCounter);
					nIdleCounter ++
					);
		}
	} // while( m_bRowRecalcing )

}

void CExtControlBar::_RowRecalcingStop( bool bCancel )
{
	m_bRowRecalcing = false;
	if( CExtMouseCaptureSink::GetCapture() == GetSafeHwnd() )
		CExtMouseCaptureSink::ReleaseCapture();
	ASSERT_VALID( m_pDockSite );
	ASSERT_VALID( m_pDockBar );
	ASSERT( !IsFloating() );

	if( !_IsShowContentWhenRowRecalcing() )
	{
		_DrawRecalcingTracker();

		if( !bCancel )
		{
			if( m_nMetricOffset != 0 )
			{
				bool bHorz = IsDockedHorizontally();
				ExtControlBarVector_t vBars;
				_GetRowExtBars( vBars );
				INT nCountOfBars = vBars.GetSize();
				ASSERT( nCountOfBars > 1 );
				bool bThisPassed = false;
				for( INT nBar = 0; nBar < nCountOfBars; nBar++ )
				{
					CExtControlBar * pBar =
						vBars[
							m_bTopRecalcing
								? (nCountOfBars - nBar - 1)
								: nBar
							];
					ASSERT_VALID( pBar );
					if( pBar == this )
					{
						bThisPassed = true;
						continue;
					}
					if( !bThisPassed )
						continue;
					if( bHorz )
					{
						pBar->m_sizeDockedH.cx += m_nMetricOffset;
						if( pBar->m_sizeDockedH.cx < pBar->_CalcDesiredMinHW() )
						{
							m_sizeDockedH.cx -=
								pBar->_CalcDesiredMinHW() - pBar->m_sizeDockedH.cx;
							pBar->m_sizeDockedH.cx = pBar->_CalcDesiredMinHW();
						}
					} // if( bHorz )
					else
					{
						pBar->m_sizeDockedV.cy += m_nMetricOffset;
						if( pBar->m_sizeDockedV.cy < pBar->_CalcDesiredMinVH() )
						{
							m_sizeDockedV.cy -=
								pBar->_CalcDesiredMinVH() - pBar->m_sizeDockedV.cy;
							pBar->m_sizeDockedV.cy = pBar->_CalcDesiredMinVH();
						}
					} // else from if( bHorz )
					break;
				} // for( INT nBar = 0; nBar < nCountOfBars; nBar++ )

				if( bHorz )
				{
					m_sizeDockedH.cx -= m_nMetricOffset;
					if( m_sizeDockedH.cx < _CalcDesiredMinHW() )
					{
						m_sizeDockedH.cx +=
							_CalcDesiredMinHW() - m_sizeDockedH.cx;
						m_sizeDockedH.cx = _CalcDesiredMinHW();
					}
				} // if( bHorz )
				else
				{
					m_sizeDockedV.cy -= m_nMetricOffset;
					if( m_sizeDockedV.cy < _CalcDesiredMinVH() )
					{
						m_sizeDockedV.cy +=
							_CalcDesiredMinVH() - m_sizeDockedV.cy;
						m_sizeDockedV.cy = _CalcDesiredMinVH();
					}
				} // else from if( bHorz )

//xx//
				//m_pDockSite->RecalcLayout();
				GetParentFrame()->RecalcLayout();
			} // if( m_nMetricOffset != 0 )
		} // if( !bCancel )

		ASSERT_VALID( m_pDockBar );
		m_pDockBar->RedrawWindow(
			NULL, NULL,
			RDW_ERASE|RDW_INVALIDATE|RDW_UPDATENOW|RDW_ERASENOW
				|RDW_ALLCHILDREN
				|RDW_NOFRAME
			);
	
	} // if( !_IsShowContentWhenRowRecalcing() )
}

void CExtControlBar::_RowRecalcingUpdateState()
{
	ASSERT( m_bRowRecalcing );
	ASSERT_VALID( m_pDockBar );
	ASSERT_VALID( m_pDockSite );

CPoint ptCursorScreen( 0, 0 );
	::GetCursorPos( &ptCursorScreen );
CPoint ptCursor( ptCursorScreen );

	//ScreenToClient( &ptCursor );
CRect rcBarWnd;
	GetWindowRect( &rcBarWnd );
CPoint ptDevOffset = -rcBarWnd.TopLeft();
	ptCursor += ptDevOffset;

bool bSysDragShowContent = _IsShowContentWhenRowRecalcing();
bool bHorz = IsDockedHorizontally();
	if( bHorz )
	{
		if( m_bTopRecalcing )
		{
			INT nMetric =
				max(
					_CalcDesiredMinHW(),
					(m_sizeDockedH.cx - ptCursor.x + m_rcRowRecalcUp.Width()/2)
					);
			m_nMetricOffset = m_sizeDockedH.cx - nMetric;
			if( m_nMetricOffset == 0 )
				return;
			if( bSysDragShowContent )
				m_sizeDockedH.cx = nMetric;
		} // if( m_bTopRecalcing )
		else
		{
			INT nMetric =
				max(
					_CalcDesiredMinHW(),
					(ptCursor.x + m_rcRowRecalc.Width()/2)
					);
			m_nMetricOffset = m_sizeDockedH.cx - nMetric;
			if( m_nMetricOffset == 0 )
				return;
			if( bSysDragShowContent )
				m_sizeDockedH.cx = nMetric;
		} // else from if( bTopRecalcing )
	} // if( bHorz )
	else
	{
		if( m_bTopRecalcing )
		{
			INT nMetric =
				max(
					_CalcDesiredMinVH(),
					(m_sizeDockedV.cy - ptCursor.y + m_rcRowRecalcUp.Height()/2)
					);
			m_nMetricOffset = m_sizeDockedV.cy - nMetric;
			if( m_nMetricOffset == 0 )
				return;
			if( bSysDragShowContent )
				m_sizeDockedV.cy = nMetric;
		} // if( m_bTopRecalcing )
		else
		{
			INT nMetric =
				max(
					_CalcDesiredMinVH(),
					(ptCursor.y + m_rcRowRecalc.Height()/2)
					);
			m_nMetricOffset = m_sizeDockedV.cy - nMetric;
			if( m_nMetricOffset == 0 )
				return;
			if( bSysDragShowContent )
				m_sizeDockedV.cy = nMetric;
		} // else from if( m_bTopRecalcing )
	} // else from if( bHorz )
	ASSERT( m_nMetricOffset != 0 );

	if( bSysDragShowContent )
	{
		ExtControlBarVector_t vBars;
		_GetRowExtBars( vBars );
		INT nCountOfBars = vBars.GetSize();
		ASSERT( nCountOfBars > 1 );
		bool bThisPassed = false;
		for( INT nBar = 0; nBar < nCountOfBars; nBar++ )
		{
			CExtControlBar * pBar =
				vBars[
					m_bTopRecalcing
						? (nCountOfBars - nBar - 1)
						: nBar
					];
			ASSERT_VALID( pBar );
			if( pBar == this )
			{
				bThisPassed = true;
				continue;
			}
			if( !bThisPassed )
				continue;
			if( bHorz )
			{
				pBar->m_sizeDockedH.cx += m_nMetricOffset;
				if( pBar->m_sizeDockedH.cx < pBar->_CalcDesiredMinHW() )
				{
					m_sizeDockedH.cx -=
						pBar->_CalcDesiredMinHW() - pBar->m_sizeDockedH.cx;
					pBar->m_sizeDockedH.cx = pBar->_CalcDesiredMinHW();
				}
			} // if( bHorz )
			else
			{
				pBar->m_sizeDockedV.cy += m_nMetricOffset;
				if( pBar->m_sizeDockedV.cy < pBar->_CalcDesiredMinVH() )
				{
					m_sizeDockedV.cy -=
						pBar->_CalcDesiredMinVH() - pBar->m_sizeDockedV.cy;
					pBar->m_sizeDockedV.cy = pBar->_CalcDesiredMinVH();
				}
			} // else from if( bHorz )
			break;
		} // for( INT nBar = 0; nBar < nCountOfBars; nBar++ )

		m_pDockSite->RecalcLayout();

		ASSERT_VALID( m_pDockBar );
		if( m_pDockBar->IsKindOf(RUNTIME_CLASS(CExtDockBar)) )
			((CExtDockBar *)m_pDockBar)->OnDynamicLayoutUpdate();
		
		return;
	} // if( bSysDragShowContent )

	ASSERT_VALID( m_pDockBar );
CRect rcDockBarWnd;
	m_pDockBar->GetWindowRect( &rcDockBarWnd );

INT nMinTrackerOffset = bHorz ?
		rcDockBarWnd.left : rcDockBarWnd.top;

	if( m_bTopRecalcing )
	{
		MfcControlBarVector_t vBars;
		_GetRowBars( vBars );
		INT nCountOfBars = vBars.GetSize();
		for( INT nBar = 0; nBar < nCountOfBars; nBar++ )
		{
			CControlBar * pBar = vBars[ nBar ];
			ASSERT_VALID( pBar );
			if( !pBar->IsVisible() )
				continue;
			CExtControlBar * pExtBar =
				DYNAMIC_DOWNCAST( CExtControlBar, pBar );
			if( pExtBar != NULL && pExtBar->IsFixedMode() )
				pExtBar = NULL;
			if( pExtBar == NULL )
			{
				CRect rcBarWnd;
				pBar->GetWindowRect( &rcBarWnd );
				nMinTrackerOffset += bHorz ?
					rcBarWnd.Width() : rcBarWnd.Height();
			} // if( pExtBar == NULL )
			else
			{
				nMinTrackerOffset += bHorz
					? pExtBar->_CalcDesiredMinHW()
					: pExtBar->_CalcDesiredMinVH();
			} // else from if( pExtBar == NULL )
			if( pBar == this )
				break;
		} // for( INT nBar = 0; nBar < nCountOfBars; nBar++ )
	} // if( m_bTopRecalcing )
	else
	{
		nMinTrackerOffset = bHorz
			? rcBarWnd.left + _CalcDesiredMinHW()
			: rcBarWnd.top  + _CalcDesiredMinVH()
			;
	} // else from if( m_bTopRecalcing )

INT nMaxTrackerOffset = 0;

	if( m_bTopRecalcing )
	{
		nMaxTrackerOffset = bHorz
			? rcBarWnd.right  - _CalcDesiredMinHW()
			: rcBarWnd.bottom - _CalcDesiredMinVH()
			;
	} // if( m_bTopRecalcing )
	else
	{
		nMaxTrackerOffset = bHorz ?
			rcDockBarWnd.right : rcDockBarWnd.bottom;
		MfcControlBarVector_t vBars;
			_GetRowBars( vBars );
		INT nCountOfBars = vBars.GetSize();
		for( INT nBar = 0; nBar < nCountOfBars; nBar++ )
		{
			CControlBar * pBar = vBars[ nCountOfBars - nBar - 1 ];
			ASSERT_VALID( pBar );
			if( !pBar->IsVisible() )
				continue;
			if( pBar == this )
				break;
			CExtControlBar * pExtBar =
				DYNAMIC_DOWNCAST( CExtControlBar, pBar );
			if( pExtBar != NULL && pExtBar->IsFixedMode() )
				pExtBar = NULL;
			if( pExtBar == NULL )
			{
				CRect rcBarWnd;
				pBar->GetWindowRect( &rcBarWnd );
				nMaxTrackerOffset -= bHorz ?
					rcBarWnd.Width() : rcBarWnd.Height();
			} // if( pExtBar == NULL )
			else
			{
				nMaxTrackerOffset -= bHorz
					? pExtBar->_CalcDesiredMinHW()
					: pExtBar->_CalcDesiredMinVH();
			} // else from if( pExtBar == NULL )
		} // for( INT nBar = 0; nBar < nCountOfBars; nBar++ )
	} // else from if( m_bTopRecalcing )

	_DrawRecalcingTracker();
	m_nTrackerOffset = bHorz
		? ptCursorScreen.x
		: ptCursorScreen.y;
	ASSERT( nMinTrackerOffset <= nMaxTrackerOffset );
	if( m_nTrackerOffset < nMinTrackerOffset )
		m_nTrackerOffset = nMinTrackerOffset;
	if( m_nTrackerOffset > nMaxTrackerOffset )
		m_nTrackerOffset = nMaxTrackerOffset;
	_DrawRecalcingTracker();
}

void CExtControlBar::_DrawResizingTracker()
{
	ASSERT( !IsFloating() );
	ASSERT_VALID( m_pDockSite );
	ASSERT_VALID( m_pDockBar );

CRect rcDockBar;
	m_pDockBar->GetWindowRect( &rcDockBar );
	if( rcDockBar.IsRectEmpty() )
		return;

CRect rcTracker( rcDockBar );
	if( IsDockedHorizontally() )
	{
		rcTracker.top =
			m_nTrackerOffset - m_rcRowResize.Height()/2;
		rcTracker.bottom =
			m_nTrackerOffset + m_rcRowResize.Height()/2;
	} // if( IsDockedHorizontally() )
	else
	{
		rcTracker.left =
			m_nTrackerOffset - m_rcRowResize.Width()/2;
		rcTracker.right =
			m_nTrackerOffset + m_rcRowResize.Width()/2;
	} // else from if( IsDockedHorizontally() )

CFrameWnd * pFrame = GetDockingFrame(); // m_pDockSite;
	ASSERT_VALID( pFrame );

CRect rcDockingFrame;
	pFrame->GetWindowRect( &rcDockingFrame );
	rcTracker.OffsetRect( -rcDockingFrame.TopLeft() );

CDC * pDC = pFrame->GetDCEx( NULL, __DOCKSITE_DCX_FLAGS );
CBrush * pBrushOld =
		pDC->SelectObject( CDC::GetHalftoneBrush() );
    pDC->PatBlt(
		rcTracker.left, rcTracker.top,
		rcTracker.Width(), rcTracker.Height(),
		PATINVERT
		);
    pDC->SelectObject(pBrushOld);
    pFrame->ReleaseDC(pDC);
}

void CExtControlBar::_DrawRecalcingTracker()
{
	ASSERT( !IsFloating() );
	ASSERT_VALID( m_pDockSite );
	ASSERT_VALID( m_pDockBar );

CRect rcTracker;
	GetWindowRect( &rcTracker );

	if( IsDockedHorizontally() )
	{
		INT nMetric =
			m_bTopRecalcing
				? m_rcRowRecalcUp.Width()/2
				: m_rcRowRecalc.Width()/2;
		rcTracker.left =
			m_nTrackerOffset - nMetric;
		rcTracker.right =
			m_nTrackerOffset + nMetric;
	} // if( IsDockedHorizontally() )
	else
	{
		INT nMetric =
			m_bTopRecalcing
				? m_rcRowRecalcUp.Height()/2
				: m_rcRowRecalc.Height()/2;
		rcTracker.top =
			m_nTrackerOffset - nMetric;
		rcTracker.bottom =
			m_nTrackerOffset + nMetric;
	} // else from if( IsDockedHorizontally() )

CFrameWnd * pFrame = GetDockingFrame(); // m_pDockSite;
	ASSERT_VALID( pFrame );

CRect rcDockingFrame;
	pFrame->GetWindowRect( &rcDockingFrame );
	rcTracker.OffsetRect( -rcDockingFrame.TopLeft() );

CDC * pDC = pFrame->GetDCEx( NULL, __DOCKSITE_DCX_FLAGS );
CBrush * pBrushOld =
		pDC->SelectObject( CDC::GetHalftoneBrush() );
    pDC->PatBlt(
		rcTracker.left, rcTracker.top,
		rcTracker.Width(), rcTracker.Height(),
		PATINVERT
		);
    pDC->SelectObject(pBrushOld);
    pFrame->ReleaseDC(pDC);
}

bool CExtControlBar::IsOleIpObjActive(
	CFrameWnd * pFrameSearch
	)
{
	if( FindPrintPreviewMode( pFrameSearch ) )
		return false;
	if( pFrameSearch == NULL )
	{
		pFrameSearch =
			DYNAMIC_DOWNCAST( CFrameWnd, AfxGetMainWnd() );
		if( pFrameSearch == NULL )
			return false;
	}
	ASSERT_VALID( pFrameSearch );
	if( pFrameSearch->IsKindOf(RUNTIME_CLASS(CMiniDockFrameWnd)) )
	{
		pFrameSearch = pFrameSearch->GetParentFrame();
		ASSERT_VALID( pFrameSearch );
		ASSERT( !pFrameSearch->IsKindOf(RUNTIME_CLASS(CMiniDockFrameWnd)) );
	}
	if( pFrameSearch->IsKindOf(RUNTIME_CLASS(CMDIFrameWnd)) )
	{
		pFrameSearch = ((CMDIFrameWnd*)pFrameSearch)->GetActiveFrame();
		if( pFrameSearch == NULL )
			return false;
	}
bool bOleInplaceItemActivated = false;
CView * pActiveView = pFrameSearch->GetActiveView();
	if(		pActiveView != NULL
		&&	(! pActiveView->IsKindOf(RUNTIME_CLASS(CPreviewView)) )
		)
	{
		ASSERT_VALID( pActiveView );
		CDocument * pActiveDoc = pActiveView->GetDocument();
		if( pActiveDoc != NULL )
		{
			ASSERT_VALID( pActiveDoc );
			COleDocument * pActiveOleDoc = 
				DYNAMIC_DOWNCAST(COleDocument,pActiveDoc);
			if( pActiveOleDoc != NULL )
			{
				ASSERT_VALID( pActiveOleDoc );
				COleClientItem * pItem =
					pActiveOleDoc->GetInPlaceActiveItem(pActiveView);
				if( pItem != NULL )
					bOleInplaceItemActivated = true;
			} // if( pActiveOleDoc != NULL )
		} // if( pActiveDoc != NULL )
	} // if( pActiveView != NULL ...
	return bOleInplaceItemActivated;
}

bool CExtControlBar::IsOleIpObjActive() const
{
	ASSERT_VALID( this );
	return IsOleIpObjActive( _GetDockingFrameImpl() );
}

bool CExtControlBar::SafeDisplayBar()
{
	if( m_bPresubclassDialogMode )
	{
		if( GetStyle() & WS_VISIBLE )
			return true;
		return false;
	}
	if( IsVisible() )
		return true;
	if( m_nStateFlags &
			//(CControlBar::delayHide | CControlBar::tempHide)
			CControlBar::tempHide
		)
		return false;
CFrameWnd * pFrame =
		_GetDockingFrameImpl();
	ASSERT_VALID( pFrame );
bool bOleInplaceItemActivated =
		//CExtControlBar::IsOleIpObjActive( pFrame );
		IsOleIpObjActive();
	if( bOleInplaceItemActivated &&
			(m_dwStyle & CBRS_HIDE_INPLACE)
		)
		return false;
	pFrame->ShowControlBar( this, TRUE, TRUE );
	pFrame = GetParentFrame();
	ASSERT_VALID( pFrame );
	pFrame->RecalcLayout();
HWND hWndThis = GetSafeHwnd();
	CExtPopupMenuWnd::PassMsgLoop(false);
	if( ! ::IsWindow(hWndThis) )
		return false;
	if( !IsVisible() )
	{
		ASSERT( FALSE );
		return false;
	}
	return true;
}

bool CExtControlBar::IsSingleOnRow(
	bool bOnlyFixed, // = false
	bool bOnlyNonFixed // = false
	) const
{
	ASSERT_VALID( this );
	ASSERT( !IsFloating() );
	ASSERT_VALID( m_pDockBar );
INT nTotalDockCount = m_pDockBar->m_arrBars.GetSize();
bool bThisFound = false;
INT nCountInRow = 0;
	for( INT nBar = 0; nBar < nTotalDockCount; nBar++ )
	{
		CControlBar * pBar = (CControlBar *)
			m_pDockBar->m_arrBars[ nBar ];
		if( pBar == NULL )
		{
			if( bThisFound )
				break;
			nCountInRow = 0;
			continue;
		}
		if( __PLACEHODLER_BAR_PTR( pBar ) )
			continue;
		ASSERT_KINDOF( CControlBar, pBar );

		if( pBar == (CControlBar *)this )
			bThisFound = true;

		if( !pBar->IsVisible() )
			continue;

		if( bOnlyFixed || bOnlyNonFixed )
		{
			bool bFixed = true;
			if( pBar->IsKindOf(RUNTIME_CLASS(CExtControlBar))
				&& !((CExtControlBar *)pBar)->IsFixedMode()
				)
				bFixed = false;
			if( bOnlyFixed && !bFixed )
				continue;
			if( !bOnlyFixed && bFixed )
				continue;
		} // if( bOnlyFixed || bOnlyNonFixed )

		nCountInRow++;

		if( bThisFound && nCountInRow > 1 )
			return false;
	} // for( INT nBar = 0; nBar < nTotalDockCount; nBar++ )

	ASSERT( nCountInRow >= 1 );
	return (nCountInRow == 1) ? true : false;
}

void CExtControlBar::MakeSingleOnRow()
{
CFrameWnd * pFrame = GetDockingFrame();
	ASSERT_VALID( pFrame );
	pFrame->RecalcLayout();
	ASSERT_VALID( m_pDockBar );
int nPos = m_pDockBar->FindBar( this );
	ASSERT( 1 <= nPos && nPos < m_pDockBar->m_arrBars.GetSize() );
	if( nPos < m_pDockBar->m_arrBars.GetSize()
		&&	m_pDockBar->m_arrBars[nPos+1] != NULL
		)
		m_pDockBar->m_arrBars.InsertAt(
			nPos+1, ((CControlBar*)NULL) );
	if( m_pDockBar->m_arrBars[nPos-1] != NULL )
		m_pDockBar->m_arrBars.InsertAt(
			nPos, ((CControlBar*)NULL) );
	if( IsDockedHorizontally() )
		m_sizeDockedH = CSize( MAXSHORT, m_sizeDockedH.cy );
	else
		m_sizeDockedV = CSize( m_sizeDockedV.cx, MAXSHORT );
	pFrame->RecalcLayout();
}

bool CExtControlBar::IsMinimizedOnRow() const
{
	if(	IsDockedVertically()
		&& m_sizeDockedV.cy == _CalcDesiredMinVH()
		)
		return true;
	if(	IsDockedHorizontally()
		&& m_sizeDockedH.cx == _CalcDesiredMinHW()
		)
		return true;
	return false;
}

bool CExtControlBar::IsMaximizedOnRow() const
{
	if( IsFloating() )
		return false;
	if(IsMinimizedOnRow())
		return false;
ExtControlBarVector_t vBars;
	(const_cast<CExtControlBar *>(this))->
		_GetRowExtBars(
			vBars
			);
INT nCountOfBars = vBars.GetSize();
	for( int nBar = 0; nBar < nCountOfBars; nBar++ )
	{
		CExtControlBar * pBar = vBars[ nBar ];
		ASSERT( pBar != NULL );
		if( pBar == this )
			continue;
		if( !(pBar->IsMinimizedOnRow()) )
			return false;
	}
	return true;
}

void CExtControlBar::MinimizeOnRow()
{
	ASSERT_VALID( this );
	ASSERT_VALID( m_pDockSite );
	ASSERT_VALID( m_pDockBar );
	ASSERT( GetSafeHwnd() != NULL );
	ASSERT( ::IsWindow( GetSafeHwnd() ) != NULL );

	if( IsFloating () || IsSingleOnRow() )
		return;

ExtControlBarVector_t vBars;
    _GetRowExtBars(vBars);
INT nCountOfBars = vBars.GetSize();
	if( nCountOfBars <= 1 )
		return;
CExtDockBar * pDockBar =
		(CExtDockBar*) m_pDockBar;
	ASSERT( pDockBar != NULL );
BOOL bHorz = IsDockedHorizontally();

INT nCalcExtentMax = 0;
	if( bHorz )
	{
		INT nMin = _CalcDesiredMinHW();
		nCalcExtentMax = m_sizeDockedH.cx - nMin;
		m_sizeDockedH.cx = nMin;
		ASSERT( nCalcExtentMax >= 0 );
	}
	else
	{
		INT nMin = _CalcDesiredMinVH();
		nCalcExtentMax = m_sizeDockedV.cy - nMin;
		m_sizeDockedV.cy = nMin;
		ASSERT( nCalcExtentMax >= 0 );
	}

	for( INT nBar = 0; nCalcExtentMax > 0; nBar++ )
	{
		if( nBar == nCountOfBars )
			nBar = 0;
		CExtControlBar * pBar = vBars[ nBar ];
		ASSERT_VALID( pBar );
		if( pBar != this )
		{
			if( bHorz )
				pBar->m_sizeDockedH.cx++;
			else
				pBar->m_sizeDockedV.cy++;
			nCalcExtentMax--;
		} // if( pBar != this )
	} // for( nBar = 0; nCalcExtentMax > 0; nBar++ )


//	m_pDockSite->RecalcLayout();
	GetParentFrame()->RecalcLayout();
	
	_GetDockingFrameImpl()->SetFocus();
}

void CExtControlBar::MaximizeOnRow()
{
	ASSERT_VALID( this );
	ASSERT_VALID( m_pDockSite );
	ASSERT_VALID( m_pDockBar );
	ASSERT( GetSafeHwnd() != NULL );
	ASSERT( ::IsWindow( GetSafeHwnd() ) != NULL );

	if( IsFloating () || IsSingleOnRow() )
		return;

ExtControlBarVector_t vBars;
    _GetRowExtBars(vBars);
INT nCountOfBars = vBars.GetSize();
	if( nCountOfBars <= 1 )
		return;
CExtDockBar * pDockBar =
		(CExtDockBar*) m_pDockBar;
	ASSERT( pDockBar != NULL );
BOOL bHorz = IsDockedHorizontally();
INT nMetric = 0;
	for( INT nBar = 0; nBar < nCountOfBars; nBar++ )
	{
		CExtControlBar * pBar = vBars[ nBar ];
		ASSERT_VALID( pBar );
		if( pBar == this )
			continue;
		if( bHorz )
		{
			INT nMin = pBar->_CalcDesiredMinHW();
			nMetric += pBar->m_sizeDockedH.cx - nMin;
			pBar->m_sizeDockedH.cx = nMin;
		}
		else
		{
			INT nMin = pBar->_CalcDesiredMinVH();
			nMetric += pBar->m_sizeDockedV.cy - nMin;
			pBar->m_sizeDockedV.cy = nMin;
		}
	} // for( INT nBar = 0; nBar < nCountOfBars; nBar++ )
	if( bHorz )
		m_sizeDockedH.cx += nMetric;
	else
		m_sizeDockedV.cy += nMetric;

//	m_pDockSite->RecalcLayout();
	GetParentFrame()->RecalcLayout();
}

void CExtControlBar::OnRepositionSingleChild(
	int cx, // = -1, // if negative - get from client area
	int cy, // = -1
	bool bRedraw // = TRUE
	)
{
	if( !m_bReposSingleChildMode )
		return;

    // automatic child resizing - only one child is allowed
CWnd * pWnd = GetWindow( GW_CHILD );
    if( pWnd != NULL
		&& ::IsWindow( pWnd->GetSafeHwnd() )
		)
	{
		CRect rcClient;
		if( cx < 0 || cy < 0 )
			GetClientRect( &rcClient );
		else
			rcClient.SetRect( 0, 0, cx, cy );
		if( IsFloating() )
		{
			CSize sizeFrame(
				::GetSystemMetrics(SM_CXSIZEFRAME), // SM_CXFIXEDFRAME
				::GetSystemMetrics(SM_CYSIZEFRAME)  // SM_CYFIXEDFRAME
				);
			rcClient.DeflateRect( sizeFrame );
		} // if( IsFloating() )
		pWnd->MoveWindow( &rcClient, FALSE);
		ASSERT( pWnd->GetWindow(GW_HWNDNEXT) == NULL );
		//pWnd->ShowWindow( IsMinimizedOnRow() ? SW_HIDE : SW_SHOW );
	}

	if( !bRedraw )
		return;

	//pWnd->
	RedrawWindow(
		NULL,
		NULL,
		RDW_INVALIDATE // |RDW_UPDATENOW
			|RDW_ERASE // |RDW_ERASENOW
			//|RDW_INTERNALPAINT
			|RDW_ALLCHILDREN
			|RDW_NOFRAME
		);
}

void CExtControlBar::OnSize(UINT nType, int cx, int cy) 
{
	//CControlBar::OnSize(nType, cx, cy);
	nType;
	if( m_bUpdatingChain )
		return;
    
	OnRepositionSingleChild( cx, cy, true );

CFrameWnd * pFrame = GetParentFrame();
	if( pFrame != NULL
		&& pFrame->IsKindOf(RUNTIME_CLASS(CMiniFrameWnd))
		)
	{
		OnNcAreaButtonsReposition();
		pFrame->SendMessage( WM_NCPAINT );
	}
}

void CExtControlBar::_Dragging_OnStart()
{
	CWnd::CancelToolTips();
	CExtPopupMenuWnd::CancelMenuTracking();

	ASSERT_VALID( m_pDockBar );
#if (!defined __EXT_MFC_NO_TAB_CONTROLBARS)
CExtDockDynTabBar * pTabbedDockBar =
		DYNAMIC_DOWNCAST(
			CExtDockDynTabBar,
			m_pDockBar
			);
	if( pTabbedDockBar != NULL )
	{
		CExtDynTabControlBar * pTabbedBar =
			STATIC_DOWNCAST(
				CExtDynTabControlBar,
				pTabbedDockBar->GetParent()
				);
		ASSERT_VALID( pTabbedBar );
		pTabbedBar->SaveIndex( this );
	}
#endif // (!defined __EXT_MFC_NO_TAB_CONTROLBARS)

	GetOwner()->
		SendMessage(
			WM_SETMESSAGESTRING,
			IDS_EXTSTATUS_PERVENT_DOCKING
			);
}

void CExtControlBar::_Dragging_OnStop(
	InternalDraggingState_t & _dsOld,
	InternalDraggingState_t & _dsNew,
	bool bCancel
	)
{
	_dsOld, _dsNew, bCancel;

	GetOwner()->
		SendMessage(
			WM_SETMESSAGESTRING,
			AFX_IDS_IDLEMESSAGE
			);

	ASSERT_VALID( this );
	if( IsFixedMode() )
		return;

	ASSERT_VALID( (&_dsOld) );
	ASSERT_VALID( (&_dsNew) );
	ASSERT( _dsNew.ExtBarSrcGet() == this );

	ASSERT_VALID( m_pDockBar );

#if (!defined __EXT_MFC_NO_TAB_CONTROLBARS)

CExtDockDynTabBar * pTabbedDockBar =
		DYNAMIC_DOWNCAST(
			CExtDockDynTabBar,
			m_pDockBar
			);
	if( pTabbedDockBar != NULL )
	{
		CExtDynTabControlBar * pTabbedBar =
			STATIC_DOWNCAST(
				CExtDynTabControlBar,
				pTabbedDockBar->GetParent()
				);
		ASSERT_VALID( pTabbedBar );
		pTabbedBar->RemoveTemporaryItems();
		if( bCancel )
		{
			pTabbedBar->RestoreIndex( this );
			pTabbedBar->SelectControlBar( this );
		} // if( bCancel )
	} // if( pTabbedDockBar != NULL )

	if( bCancel && _dsNew.ExtBarDstGet() != NULL )
	{
		CExtDynTabControlBar * pTabbedBar =
			DYNAMIC_DOWNCAST(
				CExtDynTabControlBar,
				_dsNew.ExtBarDstGet()
				);
		if( pTabbedBar != NULL )
		{
			pTabbedBar->RemoveTemporaryItems( true );
		}
	} // if( bCancel && _dsNew.ExtBarDstGet() != NULL )

#endif // (!defined __EXT_MFC_NO_TAB_CONTROLBARS)

}

void CExtControlBar::_SetCursor(
	const CPoint & point
	)
{
bool bCustomizeMode = false;
#if (!defined __EXT_MFC_NO_CUSTOMIZE)
CExtCustomizeSite * pSite =
		CExtCustomizeSite::GetCustomizeSite( m_hWnd );
	if( pSite != NULL )
	{
		if( pSite->DraggedNodeGet() != NULL )
			return;
		bCustomizeMode = pSite->IsCustomizeMode();
	} // if( pSite != NULL )
#endif // (!defined __EXT_MFC_NO_CUSTOMIZE)

	if( !bCustomizeMode )
	{
		if( CExtControlBar::FindHelpMode(this) )
			return;
	} // if( !bCustomizeMode )
#if (!defined __EXT_MFC_NO_CUSTOMIZE)
	else
	{
		ASSERT( !CExtControlBar::FindHelpMode(this) );
	} // else from if( !bCustomizeMode )
#endif // (!defined __EXT_MFC_NO_CUSTOMIZE)

HCURSOR hCursor = NULL;
	if( !m_bPresubclassDialogMode )
	{
		if( m_bDragging || m_bRowResizing || m_bRowRecalcing )
		{ // if can analyze resize cursors
			if( m_bDragging )
			{
				ASSERT( !(m_bRowResizing || m_bRowRecalcing) );
				if( IsFixedMode() )
				{
					e_calc_fixed_resizing_t eCFR =
						g_DragStateOld.GetCFR();
					if( eCFR == __ECFR_HORZ )
						hCursor = g_hCursorResizeH;
					else if( eCFR == __ECFR_VERT )
						hCursor = g_hCursorResizeV;
					else
						hCursor = g_hCursorDrag;
					ASSERT( hCursor != NULL );
				}
			} // if( m_bDragging )
			else
			{
				ASSERT( !m_bDragging );
				ASSERT( !IsFloating() );
				if( IsDockedVertically() )
				{
					if( m_bRowRecalcing )
					{
						ASSERT( !m_bRowResizing );
						hCursor = g_hCursorResizeV;
						ASSERT( hCursor != NULL );
					} // if( m_bRowRecalcing )
					else
					{
						ASSERT( !m_bRowRecalcing );
						hCursor = g_hCursorResizeH;
						ASSERT( hCursor != NULL );
					} // else from if( m_bRowRecalcing )
				} // if( IsDockedVertically() )
				else
				{
					if( m_bRowRecalcing )
					{
						ASSERT( !m_bRowResizing );
						hCursor = g_hCursorResizeH;
						ASSERT( hCursor != NULL );
					} // if( m_bRowRecalcing )
					else
					{
						ASSERT( !m_bRowRecalcing );
						hCursor = g_hCursorResizeV;
						ASSERT( hCursor != NULL );
					} // else if( m_bRowRecalcing )
				} // else from if( IsDockedVertically() )
			} // else from if( m_bDragging )
		} // if can analyze resize cursors
		else
		{ // if can not analyze resize cursors

			if( !IsFloating() )
			{
				CRect rcBarWnd;
				GetWindowRect( &rcBarWnd );
				CPoint ptDevOffset = -rcBarWnd.TopLeft();
				CPoint ptWnd( point );
				ClientToScreen( &ptWnd );
				ptWnd += ptDevOffset;
				if( m_rcGrip.PtInRect(ptWnd) )
				{
					INT nCountOfNcButtons = NcButtons_GetCount();
					for( INT nBtn = 0; nBtn < nCountOfNcButtons; nBtn++ )
					{
						CExtBarNcAreaButton * pBtn =
							NcButtons_GetAt( nBtn );
						hCursor =
							pBtn->OnNcAreaQueryCursor( ptWnd );
						if( hCursor != NULL )
							break;
					} // for( INT nBtn = 0; nBtn < nCountOfNcButtons; nBtn++ )
					if( hCursor == NULL )
					{
						hCursor = g_hCursorDrag;
						ASSERT( hCursor != NULL );
					} // if( hCursor == NULL )
				} // if( m_rcGrip.PtInRect(ptWnd) )
			} // if( !IsFloating() )
		
		} // if can not analyze resize cursors
	} // if( !m_bPresubclassDialogMode )

	if( hCursor == NULL )
	{
		hCursor = (HCURSOR)
			::GetClassLong( m_hWnd, GCL_HCURSOR );
		ASSERT( hCursor != NULL );
	} // if( hCursor == NULL )
	
	if( GetCursor() != hCursor )
		::SetCursor( hCursor );
}

CExtControlBar * CExtControlBar::_DraggingGetBar() // return currently dagging controlbar
{
	if( g_DragStateOld.IsEmpty() )
		return NULL;
	return g_DragStateOld.ExtBarSrcGet();
}

bool CExtControlBar::_DraggingCancel() // returns true if dragging was really canceled
{
CExtControlBar * pBar = _DraggingGetBar();
	if( pBar == NULL )
		return false;
	pBar->_DraggingStop( true );
	return true;
}

void CExtControlBar::_DraggingStart(
	const CPoint & point,
	const CPoint & pointOffset, // = CPoint( 0, 0 );
	CSize sizeWaitMouseMove // = CSize( 1, 1 )
	)
{
#ifdef _USRDLL
	// If this is a DLL, need to set up MFC state
	AFX_MANAGE_STATE(AfxGetStaticModuleState());
#endif

	ASSERT( !m_bRowRecalcing );
	ASSERT( !m_bRowResizing );
	ASSERT( !m_bDragging );

#if (!defined __EXT_MFC_NO_CUSTOMIZE)
CExtCustomizeSite * pSite =
		CExtCustomizeSite::GetCustomizeSite( m_hWnd );
	if(		pSite != NULL
		&&	pSite->IsCustomizeMode()
		)
		pSite->DropTargetPopupCancelEx( -2 );
#endif // (!defined __EXT_MFC_NO_CUSTOMIZE)

	// (+ v.2.23)
	// detect valid dragging start event
HWND hWndOwn = GetSafeHwnd();
	ASSERT( hWndOwn != NULL && ::IsWindow(hWndOwn) );
CExtMouseCaptureSink::SetCapture( hWndOwn );
//sizeWaitMouseMove.cx = sizeWaitMouseMove.cy = 5; // debug
	if( sizeWaitMouseMove.cx > 0 && sizeWaitMouseMove.cy > 0 )
	{
		::WaitMessage();
		CPoint ptMouseStart( 0, 0 ), ptMouseCurrent( 0, 0 );
		::GetCursorPos( &ptMouseStart );
		bool bEnableStartDragging = true, bMouseShiftDetected = false;
		for( ; bEnableStartDragging && (!bMouseShiftDetected); )
		{
			for( 	MSG msg;
					::IsWindow(hWndOwn)
					&&	PeekMessage( &msg, NULL, 0, 0, PM_NOREMOVE );
					)
			{ // wait any mouse movement look
				if( ::IsWindow(hWndOwn) )
				{
					if( msg.hwnd == hWndOwn )
					{
						if( msg.message == WM_MOUSEMOVE )
						{
							::GetCursorPos( &ptMouseCurrent );
							CSize sizeMouseShift(
								abs( (ptMouseCurrent.x - ptMouseStart.x) ),
								abs( (ptMouseCurrent.y - ptMouseStart.y) )
								);
							if(		sizeMouseShift.cx >= sizeWaitMouseMove.cx
								||	sizeMouseShift.cy >= sizeWaitMouseMove.cy
								)
							{
								bMouseShiftDetected = true;
								break; // start dragging
							}
							PeekMessage( &msg, hWndOwn, WM_MOUSEMOVE, WM_MOUSEMOVE, PM_REMOVE );
							continue;
						} // if( msg.message == WM_MOUSEMOVE )
						switch( msg.message )
						{
						case WM_CAPTURECHANGED:
							if( ((HWND)msg.lParam) != hWndOwn )
							{
								bEnableStartDragging = false;
								break;
							} // if( ((HWND)msg.lParam) != hWndOwn )
							continue;
						case WM_CANCELMODE:
						case WM_ACTIVATEAPP:
						case WM_CONTEXTMENU:
							bEnableStartDragging = false;
							break;
						default:
							if(		(	WM_KEYFIRST <= msg.message
									&&	msg.message <= WM_KEYLAST
									)
								||	(	WM_MOUSEFIRST <= msg.message
									&&	msg.message <= WM_MOUSELAST
									)
								)
								bEnableStartDragging = false;
							break;
						} // switch( msg.message )
					} // if( msg.hwnd == hWndOwn )
					else
					{
						switch( msg.message )
						{
						case WM_CANCELMODE:
						case WM_ACTIVATEAPP:
						case WM_CONTEXTMENU:
							bEnableStartDragging = false;
							break;
						default:
							if(		(	WM_KEYFIRST <= msg.message
									&&	msg.message <= WM_KEYLAST
									)
								||	(	WM_MOUSEFIRST <= msg.message
									&&	msg.message <= WM_MOUSELAST
									)
								)
								bEnableStartDragging = false;
							break;
						} // switch( msg.message )
					} // else from if( msg.hwnd == hWndOwn )
				} // if( ::IsWindow(hWndOwn) )
				else
					bEnableStartDragging = false;
				if( ! bEnableStartDragging )
					break;
				if( !AfxGetThread()->PumpMessage() )
				{
					PostQuitMessage(0);
					break; // Signal WM_QUIT received
				} // if( !AfxGetThread()->PumpMessage() )
				if( ! ( ::IsWindow(hWndOwn) ) )
				{
					bEnableStartDragging = false;
					break;
				}
				if( CExtControlBar::g_bEnableOnIdleCalls )
				{
					for(	LONG nIdleCounter = 0L;
							::AfxGetThread()->OnIdle(nIdleCounter);
							nIdleCounter ++
							);
				} // if( CExtControlBar::g_bEnableOnIdleCalls )
				if( ! ( ::IsWindow(hWndOwn) ) )
				{
					bEnableStartDragging = false;
					break;
				}
				::WaitMessage();
			} // wait any mouse movement look
		} // for( ; bEnableStartDragging && (!bMouseShiftDetected); )
		if( ! bMouseShiftDetected )
			bEnableStartDragging = false;
		if( ! bEnableStartDragging )
		{
			if(		::IsWindow(hWndOwn)
				&&	CExtMouseCaptureSink::GetCapture() == hWndOwn
				)
				CExtMouseCaptureSink::ReleaseCapture();
			return;
		} // if( ! bEnableStartDragging )
	} // if( sizeWaitMouseMove.cx > 0 && sizeWaitMouseMove.cy > 0 )
	ASSERT( CExtMouseCaptureSink::GetCapture() == hWndOwn );

	ASSERT( g_DragStateOld.IsEmpty() );
	ASSERT( g_DragStateNew.IsEmpty() );
	g_DragStateOld.ExtBarSrcSet( this );
	g_DragStateNew.ExtBarSrcSet( this );
	g_DragStateNew.SetEmpty( false );

    ASSERT( m_pDockBar != NULL );
    ASSERT( m_pDockContext != NULL );

	_Dragging_OnStart();
///	CExtMouseCaptureSink::SetCapture( GetSafeHwnd() ); // (- v.2.23)
	m_bDragging = TRUE;

INT nCyGripper = min( m_rcGrip.Width(), m_rcGrip.Height() );
CPoint ptHelperDragOffsetDefault(
		( nCyGripper > 2 )
			? nCyGripper
			: ( ::GetSystemMetrics(SM_CYSMCAPTION) / 2 )
			,
		( nCyGripper > 2 )
			? ( nCyGripper / 2 )
			: ( ::GetSystemMetrics(SM_CYSMCAPTION) / 2 )
		);
	m_ptHelperDragOffsetFloated = ptHelperDragOffsetDefault;
	m_ptHelperDragOffsetDockedH = ptHelperDragOffsetDefault;
	m_ptHelperDragOffsetDockedV = ptHelperDragOffsetDefault;
	if( pointOffset.x != 0 || pointOffset.y != 0 )
	{
		if( IsFloating() )
			m_ptHelperDragOffsetFloated = pointOffset;
		else if( IsDockedHorizontally() )
			m_ptHelperDragOffsetDockedH = pointOffset;
		else
			m_ptHelperDragOffsetDockedV = pointOffset;
	} // if( pointOffset.x != 0 || pointOffset.y != 0 )

	_DraggingUpdateState(
		point,
		CExtPopupMenuWnd::IsKeyPressed(VK_CONTROL) ? true : false
		);
	ASSERT( hWndOwn != NULL && ::IsWindow(hWndOwn) );
	while( m_bDragging && ::IsWindow(hWndOwn) )
	{
		::WaitMessage();
		MSG msg;
		// Process all the messages in the message queue
		while( ::IsWindow(hWndOwn) && PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE) )
		{
			bool bStop = false;
			switch( msg.message )
			{
			case WM_ACTIVATEAPP:
			case WM_CANCELMODE:
//			case WM_LBUTTONUP:
			case WM_RBUTTONDOWN:
			case WM_NCLBUTTONUP:
//			case WM_NCLBUTTONDOWN:
			case WM_NCRBUTTONUP:
			case WM_NCRBUTTONDOWN:
			case WM_MBUTTONDOWN:
			case WM_MBUTTONUP:
			case WM_NCMBUTTONDOWN:
			case WM_NCMBUTTONUP:
			case WM_CONTEXTMENU:
				bStop = true;
			break;
			case WM_MOUSEMOVE:
				{
					CPoint pt( (DWORD)msg.lParam );
					if( msg.hwnd != m_hWnd )
					{
						::ClientToScreen( msg.hwnd, &pt );
						::ScreenToClient( m_hWnd, &pt );
					}
					if( _OnMouseMoveMsg((UINT)msg.wParam,pt) )
					{
						PeekMessage(&msg,NULL,msg.message,msg.message,PM_REMOVE);
						continue;
					} // if( pTestBar->_OnMouseMoveMsg((UINT)msg.wParam,pt) )
				}
			default:
				if(	WM_KEYFIRST <= msg.message
					&& msg.message <= WM_KEYLAST
					)
				{
					if( g_bUpdatingDragState )
						break;
					if(		(	msg.message == WM_KEYDOWN
							||	msg.message == WM_KEYUP )
						&&	msg.wParam == VK_CONTROL
						)
					{
						CPoint ptCursor( 0, 0 );
						::GetCursorPos( &ptCursor );
						if( m_ptDraggingLast == ptCursor )
							m_ptDraggingLast.x --;
//						_DraggingUpdateState(
//							ptCursor,
//							(msg.message == WM_KEYDOWN) ? true : false
//							);
						ScreenToClient( &ptCursor );
						PostMessage(
							WM_MOUSEMOVE,
							(msg.message == WM_KEYDOWN) ? (VK_CONTROL) : 0L,
							MAKELPARAM( ptCursor.x, ptCursor.y )
							);
						break;
					}
					bStop = true;
				}
				else
				{
					if( CExtMouseCaptureSink::GetCapture() != GetSafeHwnd() )
						bStop = true;
					else
					{
						if(	(!CExtPopupMenuWnd::
								IsKeyPressed(VK_LBUTTON))
							|| CExtPopupMenuWnd::
								IsKeyPressed(VK_RBUTTON)
							|| CExtPopupMenuWnd::
								IsKeyPressed(VK_MBUTTON)
							)
							bStop = true;
					}
				}
			break;
			} // switch( msg.message )
			if( ! ( ::IsWindow(hWndOwn) ) )
				break;
			if( bStop )
			{
				_DraggingStop( true );
				break;
			}
			if( !AfxGetThread()->PumpMessage() )
			{
				PostQuitMessage(0);
				break; // Signal WM_QUIT received
			} // if( !AfxGetThread()->PumpMessage() )
		} // while( ::IsWindow(hWndOwn) && PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE) )
		if( ! ( ::IsWindow(hWndOwn) ) )
			break;
		if( m_bDragging && CExtControlBar::g_bEnableOnIdleCalls )
		{
			for(	LONG nIdleCounter = 0L;
					::AfxGetThread()->OnIdle(nIdleCounter);
					nIdleCounter ++
					);
		}
	} // while( m_bDragging && ::IsWindow(hWndOwn) )
}

void CExtControlBar::_DraggingStop( bool bCancel )
{
	ASSERT( !m_bRowRecalcing );
	ASSERT( !m_bRowResizing );
	//ASSERT( m_bDragging );
	if( !m_bDragging )
		return;

HWND hWndOwn = GetSafeHwnd();
	ASSERT( hWndOwn != NULL );
	ASSERT( ::IsWindow(hWndOwn) );

	m_bDragging = false;
	m_ptDraggingLast.x = m_ptDraggingLast.y = -1;

bool bEmptyOld = g_DragStateOld.IsEmpty();
bool bOldEqualNew =
		(g_DragStateOld == g_DragStateNew)
			? true : false;
	
//	g_DragStateOld.ExtBarDstSet( NULL );
//HWND hWndDstBar = g_DragStateNew.ExtBarDstGet()->GetSafeHwnd();

	if( !g_DragStateNew.IsEmpty() )
	{
		g_DragStateNew.DrawState();

		_Dragging_OnStop(
			g_DragStateOld,
			g_DragStateNew,
			bCancel
			);
		
		if( !bCancel )
		{
			if( _IsShowContentWhenDragging() )
			{
				if( (!bEmptyOld) && (!bOldEqualNew) )
					_DraggingApplyState( g_DragStateNew );
			} // if( _IsShowContentWhenDragging() )
			else
			{
///					g_DragStateOld.SetEmpty();
					_DraggingApplyState( g_DragStateNew );
			} // else from if( _IsShowContentWhenDragging() )
		} // if( !bCancel )
	}

//	g_DragStateNew.ExtBarDstSet(
//		NULL,
//		( ::IsWindow(hWndDstBar) ) ? false : true
//		);

	g_DragStateOld.ExtBarDstSet( NULL, true );
	g_DragStateNew.ExtBarDstSet( NULL, true );

	g_DragStateOld.SetEmpty();
	g_DragStateNew.SetEmpty();

	if( ::IsWindow(hWndOwn) )
	{
		ASSERT_VALID( this );

		if( CExtMouseCaptureSink::GetCapture() == GetSafeHwnd() )
			CExtMouseCaptureSink::ReleaseCapture();

		if(		IsFloating()
			&&	( ! _IsShowContentWhenDragging() )
			)
			RedrawWindow(
				NULL, NULL,
				RDW_INVALIDATE //|RDW_UPDATENOW
					|RDW_ERASE //|RDW_ERASENOW
					|RDW_ALLCHILDREN
				);

		if( bCancel )
			m_pDockSite->DelayRecalcLayout();
	} // if( ::IsWindow(hWndOwn) )

}

CExtControlBar::InternalDraggingState_t
	CExtControlBar::g_DragStateOld;
CExtControlBar::InternalDraggingState_t
	CExtControlBar::g_DragStateNew;

bool CExtControlBar::g_bUpdatingDragState = false;

void CExtControlBar::_DraggingUpdateState(
	const CPoint & point,
	bool bForceFloatMode
	)
{
	if( g_bUpdatingDragState || m_ptDraggingLast == point )
		return;
//	if( !IsFloating() )
//	{
//		bool bHorz = IsDockedHorizontally();
//		if( bHorz
//			&& abs(m_ptDraggingLast.y-point.y) < 3
//			&& m_ptDraggingLast.x == point.x
//			)
//			return;
//		if( abs(m_ptDraggingLast.x-point.x) < 3
//			&& m_ptDraggingLast.y == point.y
//			)
//			return;
//	}
	m_ptDraggingLast = point;
	g_bUpdatingDragState = true;

	ASSERT( !m_bRowRecalcing );
	ASSERT( !m_bRowResizing );
	ASSERT( m_bDragging );
	ASSERT( CExtMouseCaptureSink::GetCapture() == GetSafeHwnd() );

	g_DragStateNew.CalcStateDynamic( point, bForceFloatMode );
	if( g_DragStateNew != g_DragStateOld )
	{
		
		bool bShowContent = _IsShowContentWhenDragging();
		bool bEmptyOld = g_DragStateOld.IsEmpty();
		bool bEmptyNew = g_DragStateNew.IsEmpty();

		if( !bEmptyOld )
		{
#if (!defined __EXT_MFC_NO_TAB_CONTROLBARS)
			if( ! (!bEmptyNew
					&& g_DragStateOld.GetCDT() == __ECDT_TABBED_REINDEX
					&& g_DragStateOld.ExtBarDstGet() == g_DragStateNew.ExtBarDstGet()
					)
				)
#endif // (!defined __EXT_MFC_NO_TAB_CONTROLBARS)
				g_DragStateOld.DrawState();
//			else
//				bPassPaintMessages = false;
		}

#if (!defined __EXT_MFC_NO_TAB_CONTROLBARS)
		CFrameWnd * pFrame = g_DragStateOld.ExtBarSrcGet()->m_pDockSite;
		ASSERT_VALID( pFrame );
		POSITION pos = pFrame->m_listControlBars.GetHeadPosition();
		for( ; pos != NULL; )
		{
			CControlBar * pBar = (CControlBar *)
				pFrame->m_listControlBars.GetNext( pos );
			ASSERT_VALID( pBar );
			if( pBar->GetSafeHwnd() == NULL
				|| ( ! ::IsWindow( pBar->GetSafeHwnd() ) )
				|| ( ! pBar->IsVisible() )
				)
				continue;
			CExtDynTabControlBar * pTabbedBar =
				DYNAMIC_DOWNCAST(
					CExtDynTabControlBar,
					pBar
					);
			if( pTabbedBar == NULL )
				continue;
			pTabbedBar->InvalidateSwitcher();
		}

		if( (!bEmptyOld) && (!bEmptyNew) )
		{
			e_calc_dock_type_t eCDT = g_DragStateOld.GetCDT();
			if( (		eCDT == __ECDT_TABBED_UPDATE
					||	eCDT == __ECDT_TABBED_REINDEX
				)
				//&& g_DragStateOld.ExtBarDstGet() != g_DragStateNew.ExtBarDstGet()
				)
			{
				g_DragStateOld.ExtBarDstSet( NULL );
			}
		} // if( (!bEmptyOld) && (!bEmptyNew) )

#endif // (!defined __EXT_MFC_NO_TAB_CONTROLBARS)
		
		if( !bEmptyNew )
			g_DragStateNew.DrawState();

		if( bShowContent )
		{
			if( !g_DragStateOld.IsEmpty()
				&& g_DragStateOld != g_DragStateNew
				)
				_DraggingApplyState( g_DragStateNew );
		} // if( bShowContent )

		g_DragStateOld = g_DragStateNew;
	
	} // if( g_DragStateNew != g_DragStateOld )

	if( CExtMouseCaptureSink::GetCapture() != GetSafeHwnd() )
		CExtMouseCaptureSink::SetCapture( GetSafeHwnd() );
	g_bUpdatingDragState = false;
}

void CExtControlBar::OnNcAreaButtonsReinitialize()
{
INT nCountOfNcButtons = NcButtons_GetCount();
	if( nCountOfNcButtons > 0 )
		return;
	NcButtons_Add( new CExtBarNcAreaButtonClose(this) );
#if (!defined __EXT_MFC_NO_TAB_CONTROLBARS)
	NcButtons_Add( new CExtBarNcAreaButtonAutoHide(this) );
#endif // (!defined __EXT_MFC_NO_TAB_CONTROLBARS)
//	NcButtons_Add( new CExtBarNcAreaButtonExpand(this) );
	NcButtons_Add( new CExtBarNcAreaButtonMenu(this) );
}

void CExtControlBar::OnNcAreaButtonsReposition()
{

INT nCountOfNcButtons = NcButtons_GetCount();
CExtBarNcAreaButton * pPrevBtn = NULL;
	for( INT nBtn = 0; nBtn < nCountOfNcButtons; nBtn++ )
	{
		CExtBarNcAreaButton * pBtn =
			NcButtons_GetAt( nBtn );
		pBtn->OnNcAreaReposition( pPrevBtn );
		if( !pBtn->OnQueryVisibility() )
			continue;
		pPrevBtn = pBtn;
	} // for( INT nBtn = 0; nBtn < nCountOfNcButtons; nBtn++ )
}

/////////////////////////////////////////////////////////////////////////////
// CExtBarNcAreaButton

IMPLEMENT_DYNCREATE( CExtBarNcAreaButton, CObject )

CExtBarNcAreaButton::CExtBarNcAreaButton(
	CExtControlBar * pBar
	)
	: m_pBar( pBar )
	, m_rc( 0, 0, 0, 0 )
	, m_bHover( false )
	, m_bPushed( false )
	, m_bDisabled( false )
	, m_bPaintingCombinedArea( false )
{
	ASSERT_VALID( this );
}

CExtBarNcAreaButton::~CExtBarNcAreaButton()
{
	ASSERT_VALID( this );
}

void CExtBarNcAreaButton::OnNcDestroy()
{
	ASSERT_VALID( this );
	delete this;
}

bool CExtBarNcAreaButton::IsBarFixedMode() const
{
	ASSERT_VALID( this );
	return m_pBar->IsFixedMode();
}

bool CExtBarNcAreaButton::IsBarVisible() const
{
	ASSERT_VALID( this );
	return m_pBar->IsVisible() ? true : false;
}

#if (!defined __EXT_MFC_NO_TAB_CONTROLBARS)
bool CExtBarNcAreaButton::IsBarAutoHideMode(
	bool * p_bDisplayed, // = NULL
	bool * p_bActive // = NULL
	) const
{
	ASSERT_VALID( this );
	if( p_bDisplayed != NULL )
		*p_bDisplayed = false;
	if( p_bActive != NULL )
		*p_bActive = false;
bool bAutohide = m_pBar->AutoHideModeGet();
	if( !bAutohide )
		return false;
	if( p_bDisplayed != NULL || p_bActive != NULL )
	{
		ASSERT_VALID( m_pBar->m_pDockBar );
		ASSERT_KINDOF( CExtDockBar, m_pBar->m_pDockBar );
		CExtDynAutoHideArea * pWndAutoHideArea =
			((CExtDockBar*)m_pBar->m_pDockBar)->_GetAutoHideArea();
		ASSERT_VALID( pWndAutoHideArea );
		if( pWndAutoHideArea->m_pWndSlider != NULL )
		{
			ASSERT_VALID( pWndAutoHideArea->m_pWndSlider );
			if( pWndAutoHideArea->m_pWndSlider->m_pBar == m_pBar )
			{
				if( p_bDisplayed != NULL )
					*p_bDisplayed = true;
				if( p_bActive != NULL )
					*p_bActive = pWndAutoHideArea->m_pWndSlider->m_bWndActive;
			}
		}
	}
	return true;
}
#endif // (!defined __EXT_MFC_NO_TAB_CONTROLBARS)

bool CExtBarNcAreaButton::IsBarFloated() const
{
	ASSERT_VALID( this );
	return m_pBar->IsFloating();
}

bool CExtBarNcAreaButton::IsBarDocked() const
{
	ASSERT_VALID( this );
	return m_pBar->IsDocked();
}

bool CExtBarNcAreaButton::IsBarDockedHorizontally() const
{
	ASSERT_VALID( this );
	return m_pBar->IsDockedHorizontally();
}

bool CExtBarNcAreaButton::IsBarDockedVertically() const
{
	ASSERT_VALID( this );
	return m_pBar->IsDockedVertically();
}

bool CExtBarNcAreaButton::IsBarDockedAtLeft() const
{
	ASSERT_VALID( this );
	return m_pBar->IsDockedAtLeft();
}

bool CExtBarNcAreaButton::IsBarDockedAtRight() const
{
	ASSERT_VALID( this );
	return m_pBar->IsDockedAtRight();
}

bool CExtBarNcAreaButton::IsBarDockedAtTop() const
{
	ASSERT_VALID( this );
	return m_pBar->IsDockedAtTop();
}

bool CExtBarNcAreaButton::IsBarDockedAtBottom() const
{
	ASSERT_VALID( this );
	return m_pBar->IsDockedAtBottom();
}

bool CExtBarNcAreaButton::GetBarNcAreaInfo( // returns false if no nc area on bar
	LPRECT pRectGripper, //  = NULL // in window coords
	LPRECT pRectWnd, // = NULL // in screen coords
	bool * pbGripperAtTop, //  = NULL
	bool * pbTextOnGripper //  = NULL
	) const
{
	ASSERT_VALID( this );
	if( pRectGripper != NULL )
		::SetRectEmpty( pRectGripper );
	if( pRectWnd != NULL )
		::SetRectEmpty( pRectWnd );
	
	if( IsBarFloated() )
	{
		if( pbGripperAtTop != NULL )
			*pbGripperAtTop = false;
		if( pbTextOnGripper != NULL )
			*pbTextOnGripper = false;
		
		CFrameWnd * pMiniFrame =
			m_pBar->GetDockingFrame();
		if( pRectWnd != NULL )
			pMiniFrame->GetWindowRect( pRectWnd );
		CExtMiniDockFrameWnd * pExtMiniFrame =
			DYNAMIC_DOWNCAST( CExtMiniDockFrameWnd, pMiniFrame );
		if( pExtMiniFrame == NULL )
			return false;
		
		if( pRectGripper != NULL )
		{
			CRect rcGrip( pExtMiniFrame->m_rcFrameCaption );
			rcGrip.InflateRect( 2, 2, 1, 2 );
			*pRectGripper = rcGrip;
		}
		if( pbGripperAtTop != NULL )
			*pbGripperAtTop = true;
		if( pbTextOnGripper != NULL )
			*pbTextOnGripper = true;
		return true;
	} // if( IsBarFloated() )

	if( !m_pBar->IsFixedMode() )
	{
		CFrameWnd * pParentFrame = m_pBar->GetParentFrame();
		if(		pParentFrame != NULL
			&&	pParentFrame->IsKindOf(RUNTIME_CLASS(CExtMiniDockFrameWnd))
			)
		{
			if( m_pBar->_IsSingleVisibleInFloatingPalette() )
			{
				if( pbGripperAtTop != NULL )
					*pbGripperAtTop = false;
				if( pbTextOnGripper != NULL )
					*pbTextOnGripper = false;
				
				if( pRectWnd != NULL )
					pParentFrame->GetWindowRect( pRectWnd );
				CExtMiniDockFrameWnd * pExtMiniFrame =
					STATIC_DOWNCAST( CExtMiniDockFrameWnd, pParentFrame );
				
				if( pRectGripper != NULL )
				{
					CRect rcGrip( pExtMiniFrame->m_rcFrameCaption );
					rcGrip.InflateRect( 2, 2, 1, 2 );
					*pRectGripper = rcGrip;
				}
				if( pbGripperAtTop != NULL )
					*pbGripperAtTop = true;
				if( pbTextOnGripper != NULL )
					*pbTextOnGripper = true;
				return true;
			}
		}
	}


	if( pRectWnd != NULL )
		m_pBar->GetWindowRect( pRectWnd );
bool bGrip =
		m_pBar->IsBarWithGripper(
			pbGripperAtTop,
			pbTextOnGripper
			);
	if( !bGrip )
		return false;
	if( pRectGripper != NULL )
	{
#if (!defined __EXT_MFC_NO_TAB_CONTROLBARS)
		if( m_pBar->AutoHideModeGet() )
		{
			ASSERT_VALID( m_pBar->m_pDockBar );
			ASSERT_KINDOF( CExtDockBar, m_pBar->m_pDockBar );
			CExtDynAutoHideArea * pAutoHideArea =
				((CExtDockBar*)m_pBar->m_pDockBar)->_GetAutoHideArea();
			ASSERT_VALID( pAutoHideArea );
			ASSERT_VALID( pAutoHideArea->m_pWndSlider );
			pAutoHideArea->m_pWndSlider->
				CalcInnerNcRects(
					NULL,
					NULL,
					pRectGripper
					);
		}
		else
#endif // (!defined __EXT_MFC_NO_TAB_CONTROLBARS)
			*pRectGripper = m_pBar->m_rcGrip;
	}
	return true;
}

bool CExtBarNcAreaButton::IsBarWndActive() const
{
	ASSERT_VALID( this );
	
	if( IsBarFloated() )
	{
		CFrameWnd * pMiniFrame =
			m_pBar->GetDockingFrame();
		CExtMiniDockFrameWnd * pExtMiniFrame =
			DYNAMIC_DOWNCAST( CExtMiniDockFrameWnd, pMiniFrame );
		if( pExtMiniFrame == NULL )
			return false;

		HWND hTmpWndFocus = ::GetFocus();
		if( hTmpWndFocus != NULL
			&& (  pExtMiniFrame->GetSafeHwnd() == hTmpWndFocus
				  || ::IsChild( pExtMiniFrame->GetSafeHwnd(), hTmpWndFocus )
				)
			)
			return true;
		return  false;
	} // if( IsBarFloated() )

	return m_pBar->m_bWindowActive;
}

bool CExtBarNcAreaButton::IsBarSingleOnRow() const
{
	ASSERT_VALID( this );
	return m_pBar->IsSingleOnRow();
}

bool CExtBarNcAreaButton::IsBarMinimizedOnRow() const
{
	ASSERT_VALID( this );
	return m_pBar->IsMinimizedOnRow();
}

bool CExtBarNcAreaButton::IsBarMaximizedOnRow() const
{
	ASSERT_VALID( this );
	return m_pBar->IsMaximizedOnRow();
}

bool CExtBarNcAreaButton::IsBarFirstOnRow( bool bExtBar ) const
{
	ASSERT_VALID( this );
	return m_pBar->_IsFirstBarInRow( bExtBar );
}

bool CExtBarNcAreaButton::IsBarLastOnRow( bool bExtBar ) const
{
	ASSERT_VALID( this );
	return m_pBar->_IsLastBarInRow( bExtBar );
}

CFrameWnd * CExtBarNcAreaButton::GetDockingFrame()
{
	ASSERT_VALID( this );
	return m_pBar->_GetDockingFrameImpl();
}

void CExtBarNcAreaButton::OnNcAreaReposition(
	CExtBarNcAreaButton * pPrevBtn
	)
{
	ASSERT_VALID( this );

	//m_bHover = m_bPushed = false;

bool bGripperAtTop = false;
	if(	!GetBarNcAreaInfo( &m_rc, NULL, &bGripperAtTop ) )
		return;
const int _nGapToBordersH = 2;
const int _nGapToBordersV = 3;
const int _nGapBetweenButtons = 3;
	if( bGripperAtTop )
	{
		m_rc.DeflateRect(
			_nGapToBordersH,
			_nGapToBordersV
			);
		m_rc.left = m_rc.right - m_rc.Height();
		m_rc.OffsetRect( -1, 0 );
		if( pPrevBtn != NULL )
		{
			const CRect & rcPrev = *pPrevBtn;
			m_rc.OffsetRect(
				rcPrev.left - m_rc.right -
					_nGapBetweenButtons,
				0
				);
		} // if( pPrevBtn != NULL )
	} // if( bGripperAtTop )
	else
	{
		m_rc.DeflateRect(
			_nGapToBordersV,
			_nGapToBordersH
			);
		m_rc.bottom = m_rc.top + m_rc.Width();
		m_rc.OffsetRect( 0, 1 );
		if( pPrevBtn != NULL )
		{
			const CRect & rcPrev = *pPrevBtn;
			m_rc.OffsetRect(
				0,
				- rcPrev.top + m_rc.bottom +
					_nGapBetweenButtons
				);
		} // if( pPrevBtn != NULL )
	} // else from if( bGripperAtTop )
}

bool CExtBarNcAreaButton::OnQueryVisibility() const
{
	ASSERT_VALID( this );
	if( !IsBarVisible() )
	{
#if (!defined __EXT_MFC_NO_TAB_CONTROLBARS)
		bool bDisplayed = false;
		if( IsBarAutoHideMode( &bDisplayed ) )
		{
			if( bDisplayed )
				return true;
		}
#endif // (!defined __EXT_MFC_NO_TAB_CONTROLBARS)
		return false;
	}
CRect rcGrip;
	if(	!GetBarNcAreaInfo( &rcGrip ) )
		return false;
	if( rcGrip.IsRectEmpty() )
		return false;
	return true;
}

void CExtBarNcAreaButton::NcDrawDefault(
	CDC & dc,
	int nDockBtnGlyptT
	)
{
	ASSERT_VALID( this );
	ASSERT( dc.GetSafeHdc() != NULL );
	ASSERT( OnQueryVisibility() );
	if( m_rc.IsRectEmpty() )
		return;
bool bMenuTracking =
		CExtPopupMenuWnd::IsMenuTracking() ? true : false;

//bool bDrawActive = IsBarWndActive();
//	if( !bDrawActive )
//		IsBarAutoHideMode( NULL, &bDrawActive );
bool bDrawActive = false;
#if (!defined __EXT_MFC_NO_TAB_CONTROLBARS)
	if( !IsBarAutoHideMode( NULL, &bDrawActive ) )
#endif // (!defined __EXT_MFC_NO_TAB_CONTROLBARS)
		bDrawActive = IsBarWndActive();

CExtPaintManager::PAINTDOCKINGCAPTIONBUTTONDATA _pdcbd(
		this,
		m_rc,
		(CExtPaintManager::e_docking_caption_button_t)nDockBtnGlyptT,
		!m_bDisabled && m_bHover && !bMenuTracking && !m_bPaintingCombinedArea,
		!m_bDisabled && m_bPushed && !bMenuTracking && !m_bPaintingCombinedArea,
		!m_bDisabled,
		!IsBarFixedMode() || m_bPaintingCombinedArea,
		bDrawActive,
		IsBarFloated()
		);
	g_PaintManager->PaintDockingCaptionButton( dc, _pdcbd );
}

void CExtBarNcAreaButton::OnNcAreaDraw( CDC & dc )
{
	ASSERT_VALID( this );
	ASSERT( dc.GetSafeHdc() != NULL );
	ASSERT( OnQueryVisibility() );
	if( m_rc.IsRectEmpty() )
		return;

#if (defined __DEBUG_PAINTING_AREAS_EXTRESIZABLEBAR__)
	dc.FillSolidRect( &m_rc, RGB(255,128,128) );
#else // __DEBUG_PAINTING_AREAS_EXTRESIZABLEBAR__
	dc;
#endif // !__DEBUG_PAINTING_AREAS_EXTRESIZABLEBAR__
}

UINT CExtBarNcAreaButton::OnNcAreaHitTest( CPoint point )
{
	ASSERT_VALID( this );
	if( m_rc.PtInRect(point) )
	{
		m_bPushed =
			(
				CExtPopupMenuWnd::IsKeyPressed( VK_LBUTTON )
				&& !CExtPopupMenuWnd::IsKeyPressed( VK_MBUTTON )
				&& !CExtPopupMenuWnd::IsKeyPressed( VK_RBUTTON )
			)
			? true : false;
		m_bHover = true;
		return HTNOWHERE;
	}
	m_bHover = m_bPushed = false;
	return HTCLIENT; // not inside nc-button
}

HCURSOR CExtBarNcAreaButton::OnNcAreaQueryCursor( CPoint point )
{
	ASSERT_VALID( this );
	if( m_rc.PtInRect(point) )
		return g_hCursorArrow;
	return NULL; // not inside nc-button
}

bool CExtBarNcAreaButton::OnNcAreaClicked( CPoint point )
{
	ASSERT_VALID( this );
	if( m_rc.PtInRect(point) )
		return true;
	return false; // continue asking nc-buttons
}

int CExtBarNcAreaButton::OnToolHitTest(
	CPoint point,
	TOOLINFO * pTI
	)
{
	ASSERT_VALID( this );
	
	point; // shuld be in button area
	pTI;

	return -1;
}

int CExtBarNcAreaButton::DoDefaultReflectForToolHitTest(
	TOOLINFO * pTI,
	UINT nIdResourceTooltipText,
	__EXT_MFC_SAFE_LPCTSTR sTooltipTextDefault
	)
{
	ASSERT_VALID( this );
	ASSERT( sTooltipTextDefault != NULL );

#if (defined _AFXDLL && !defined __STATPROFUIS_WITH_DLLMFC__)
CExtLocalResourceHelper _LRH;
#endif // #if (defined _AFXDLL && !defined __STATPROFUIS_WITH_DLLMFC__)

CExtSafeString sTooltipText;
	if( !sTooltipText.LoadString(nIdResourceTooltipText) )
	{
#if (defined _AFXDLL && !defined __STATPROFUIS_WITH_DLLMFC__)
		ASSERT( FALSE );
#endif // #if (defined _AFXDLL && !defined __STATPROFUIS_WITH_DLLMFC__)
		sTooltipText = sTooltipTextDefault;
	}
	
	return
		DoDefaultReflectForToolHitTest(
			pTI,
			sTooltipText
			);
}

int CExtBarNcAreaButton::DoDefaultReflectForToolHitTest(
	TOOLINFO * pTI,
	__EXT_MFC_SAFE_LPCTSTR sTooltipText
	)
{
	ASSERT_VALID( this );
	ASSERT( sTooltipText != NULL );

#if (!defined __EXT_MFC_NO_TAB_CONTROLBARS)
	if( IsBarAutoHideMode() )
		return false;
#endif // (!defined __EXT_MFC_NO_TAB_CONTROLBARS)

	if( pTI != NULL )
	{
		CExtControlBar * pBar = GetBar();
		ASSERT_VALID( pBar );

		CPoint ptDevOffset( 0, 0 );
		if( pBar->IsFloating() )
		{
			CRect rcBarWnd, rcBarClient;
			CFrameWnd * pFrame = pBar->GetParentFrame();
			ASSERT_VALID( pFrame );
			pFrame->GetWindowRect( &rcBarWnd );
			pFrame->GetClientRect( &rcBarClient );
			pFrame->ClientToScreen( &rcBarClient );
			ptDevOffset =
				rcBarClient.TopLeft()
				- rcBarWnd.TopLeft();
/*
			//pTI->uFlags |= TTF_TRACK|TTF_ALWAYSTIP;
			//pFrame->m_nFlags |= WF_TRACKINGTOOLTIPS;
			//pTI->uFlags = TTF_ALWAYSTIP;
			//AfxGetApp()->m_pActiveWnd = pFrame;

			pTI->uFlags |= TTF_TRACK|TTF_ALWAYSTIP|TTF_NOTBUTTON;
			pFrame->m_nFlags |= WF_TRACKINGTOOLTIPS;

			// not implemented yet
			return -1;
*/
		} // if( pBar->IsFloating() )
		else
		{
			CRect rcBarWnd, rcBarClient;
			pBar->GetWindowRect( &rcBarWnd );
			pBar->GetClientRect( &rcBarClient );
			pBar->ClientToScreen( &rcBarClient );
			ptDevOffset =
				rcBarClient.TopLeft()
				- rcBarWnd.TopLeft();
		} // else from if( pBar->IsFloating() )

		CRect rcArea = *this;
		rcArea.OffsetRect( -ptDevOffset );
		
		::CopyRect(
			&(pTI->rect),
			&rcArea
			);

		int nCmdID = (int)pBar->GetDlgCtrlID();
		
		pTI->uId = (UINT)nCmdID;
		pTI->hwnd = pBar->GetSafeHwnd();

		pTI->lpszText = (LPTSTR)
			::calloc(
				(_tcslen(sTooltipText) + 1),
				sizeof(TCHAR)
				);
		if( pTI->lpszText != NULL )
			_tcscpy(
				pTI->lpszText,
				sTooltipText
				);
		else
			pTI->lpszText = LPSTR_TEXTCALLBACK;

		return nCmdID;
	} // if( pTI != NULL )
	
	return -1;
}

/////////////////////////////////////////////////////////////////////////////
// CExtBarNcAreaButtonExpand

IMPLEMENT_DYNCREATE( CExtBarNcAreaButtonExpand, CExtBarNcAreaButton )

CExtBarNcAreaButtonExpand::CExtBarNcAreaButtonExpand(
	CExtControlBar * pBar
	)
	: CExtBarNcAreaButton( pBar )
{
}

bool CExtBarNcAreaButtonExpand::OnQueryVisibility() const
{
	ASSERT_VALID( this );
	if( !CExtBarNcAreaButton::OnQueryVisibility() )
		return false;
#if (!defined __EXT_MFC_NO_TAB_CONTROLBARS)
	if( IsBarAutoHideMode() )
		return false;
#endif // (!defined __EXT_MFC_NO_TAB_CONTROLBARS)
	if( IsBarFixedMode() || IsBarFloated() )
		return false;
	return true;
}

void CExtBarNcAreaButtonExpand::OnNcAreaDraw( CDC & dc )
{
	ASSERT_VALID( this );
	ASSERT( dc.GetSafeHdc() != NULL );
	ASSERT( OnQueryVisibility() );
	if( m_rc.IsRectEmpty() )
		return;

#if (defined __DEBUG_PAINTING_AREAS_EXTRESIZABLEBAR__)

	dc.FillSolidRect( &m_rc, RGB(128,255,128) );

#else // __DEBUG_PAINTING_AREAS_EXTRESIZABLEBAR__

#if (!defined __EXT_MFC_NO_TAB_CONTROLBARS)
	m_bDisabled = IsBarAutoHideMode();
	if( !m_bDisabled )
#endif // (!defined __EXT_MFC_NO_TAB_CONTROLBARS)
		m_bDisabled =
			IsBarSingleOnRow()
			;
bool bMax = IsBarMaximizedOnRow();
bool bHorz = IsBarDockedHorizontally();
	NcDrawDefault(
		dc,
		bHorz
			? ( bMax
					? CExtPaintManager::__DCBT_ARROW_RIGHT
					: CExtPaintManager::__DCBT_ARROW_LEFT
				)
			: ( bMax
					? CExtPaintManager::__DCBT_ARROW_DOWN
					: CExtPaintManager::__DCBT_ARROW_UP
					)
		);

#endif // !__DEBUG_PAINTING_AREAS_EXTRESIZABLEBAR__
}

UINT CExtBarNcAreaButtonExpand::OnNcAreaHitTest( CPoint point )
{
	ASSERT_VALID( this );
UINT nHT = CExtBarNcAreaButton::OnNcAreaHitTest( point );
	if( nHT == HTCLIENT )
		return HTCLIENT; // not inside nc-button

#if (!defined __EXT_MFC_NO_TAB_CONTROLBARS)
	if( IsBarAutoHideMode() )
		return HTCLIENT;
#endif // (!defined __EXT_MFC_NO_TAB_CONTROLBARS)
	if( IsBarSingleOnRow() )
		return HTCLIENT;
//	if( IsBarMaximizedOnRow() )
		return HTMINBUTTON;
//	return HTMAXBUTTON;
}

bool CExtBarNcAreaButtonExpand::OnNcAreaClicked( CPoint point )
{
	ASSERT_VALID( this );
	if( !m_rc.PtInRect(point) )
		return false; // continue asking nc-buttons

#if (!defined __EXT_MFC_NO_TAB_CONTROLBARS)
	if( IsBarAutoHideMode() )
		return false;
#endif // (!defined __EXT_MFC_NO_TAB_CONTROLBARS)

	if( IsBarSingleOnRow() )
	{
		if( !IsBarWndActive() )
			m_pBar->SetFocus();
		return true;
	}

	if( IsBarMaximizedOnRow() )
		m_pBar->MinimizeOnRow();
	else
	{
		m_pBar->MaximizeOnRow();
		m_pBar->SetFocus();
	}
	
	return true;
}

int CExtBarNcAreaButtonExpand::OnToolHitTest(
	CPoint point,
	TOOLINFO * pTI
	)
{
	ASSERT_VALID( this );
	
	point; // shuld be in button area

bool bBarMaximizedOnRow = IsBarMaximizedOnRow();
	return
		DoDefaultReflectForToolHitTest(
			pTI,
			bBarMaximizedOnRow ? IDS_CBNCAREA_CONTRACT : IDS_CBNCAREA_EXPAND,
			bBarMaximizedOnRow ? _T("Contract") : _T("Expand")
			);
}

/////////////////////////////////////////////////////////////////////////////
// CExtBarNcAreaButtonClose

IMPLEMENT_DYNCREATE( CExtBarNcAreaButtonClose, CExtBarNcAreaButton )

CExtBarNcAreaButtonClose::CExtBarNcAreaButtonClose(
	CExtControlBar * pBar
	)
	: CExtBarNcAreaButton( pBar )
{
}

bool CExtBarNcAreaButtonClose::OnQueryVisibility() const
{
	ASSERT_VALID( this );
	if( !CExtBarNcAreaButton::OnQueryVisibility() )
		return false;
	if( !IsBarFixedMode()  )
		return true;
	return IsBarFloated();
}

void CExtBarNcAreaButtonClose::OnNcAreaDraw( CDC & dc )
{
	ASSERT_VALID( this );
	ASSERT( dc.GetSafeHdc() != NULL );
	ASSERT( OnQueryVisibility() );
	if( m_rc.IsRectEmpty() )
		return;

#if (defined __DEBUG_PAINTING_AREAS_EXTRESIZABLEBAR__)

	dc.FillSolidRect( &m_rc, RGB(128,128,255) );

#else // __DEBUG_PAINTING_AREAS_EXTRESIZABLEBAR__

	NcDrawDefault(
		dc,
		CExtPaintManager::__DCBT_CLOSE
		);

#endif // !__DEBUG_PAINTING_AREAS_EXTRESIZABLEBAR__
}

UINT CExtBarNcAreaButtonClose::OnNcAreaHitTest( CPoint point )
{
	ASSERT_VALID( this );
UINT nHT = CExtBarNcAreaButton::OnNcAreaHitTest( point );
	if( nHT == HTCLIENT )
		return HTCLIENT; // not inside nc-button
	//return HTCLOSE;
	return HTMINBUTTON;
}

bool CExtBarNcAreaButtonClose::OnNcAreaClicked( CPoint point )
{
	ASSERT_VALID( this );
	if( m_rc.PtInRect(point) )
	{

#if (!defined __EXT_MFC_NO_TAB_CONTROLBARS)
		if( !m_pBar->IsFixedMode()
			&& m_pBar->AutoHideModeGet()
			)
		{
			m_pBar->AutoHideModeSet( false, false, true, true );
// 2.21 fix
///			return true;
		}
#endif // (!defined __EXT_MFC_NO_TAB_CONTROLBARS)

		CFrameWnd * pFrame = GetDockingFrame();
// 2.21 fix
///		ASSERT( IsBarVisible() );

#if (!defined __EXT_MFC_NO_TAB_CONTROLBARS)

		if( m_pBar->IsFloating() )
		{
			pFrame->ShowControlBar( m_pBar, FALSE, FALSE );
			return true;
		}
		CExtDynTabControlBar * pTabbedBar =
			DYNAMIC_DOWNCAST(
				CExtDynTabControlBar,
				m_pBar
				);
		if( pTabbedBar != NULL )
		{
			ASSERT( pTabbedBar->GetSwitcherItemCount() > 0 );
			LONG nCurrent = pTabbedBar->GetSwitcherSelection();
			if( nCurrent >= 0 )
			{
				ASSERT( nCurrent < pTabbedBar->GetSwitcherItemCount() );
				CExtControlBar * pBar =
					pTabbedBar->GetBarAt( nCurrent, true );
				ASSERT_VALID( pBar );
				pFrame->ShowControlBar( pBar, FALSE, FALSE );
				return true;
			} // if( nCurrent >= 0 )
		} // if( pTabbedBar != NULL )
		pFrame->ShowControlBar( m_pBar, FALSE, FALSE );
		return true;

#else // (!defined __EXT_MFC_NO_TAB_CONTROLBARS)

		pFrame->ShowControlBar( m_pBar, FALSE, FALSE );
		return true;

#endif // else from (!defined __EXT_MFC_NO_TAB_CONTROLBARS)

	}
	return false; // continue asking nc-buttons
}

int CExtBarNcAreaButtonClose::OnToolHitTest(
	CPoint point,
	TOOLINFO * pTI
	)
{
	ASSERT_VALID( this );
	
	point; // shuld be in button area
	return
		DoDefaultReflectForToolHitTest(
			pTI,
			IDS_CBNCAREA_CLOSE,
			_T("Hide")
			);
}

#if (!defined __EXT_MFC_NO_TAB_CONTROLBARS)
/////////////////////////////////////////////////////////////////////////////
// CExtBarNcAreaButtonAutoHide

IMPLEMENT_DYNCREATE( CExtBarNcAreaButtonAutoHide, CExtBarNcAreaButton )

CExtBarNcAreaButtonAutoHide::CExtBarNcAreaButtonAutoHide(
	CExtControlBar * pBar
	)
	: CExtBarNcAreaButton( pBar )
{
}

bool CExtBarNcAreaButtonAutoHide::OnQueryVisibility() const
{
	ASSERT_VALID( this );
	if( !CExtBarNcAreaButton::OnQueryVisibility() )
		return false;
	if( IsBarFixedMode()  )
		return false;
	if( IsBarFloated() )
		return false;
const CExtControlBar * pExtBar = GetBar();
	ASSERT( pExtBar );
	if( pExtBar->m_pDockBar == NULL )
		return false;
CExtDockBar * pDockBar =
		DYNAMIC_DOWNCAST( CExtDockBar, pExtBar->m_pDockBar );
	if( pDockBar == NULL )
		return false;
	if( pDockBar->_GetAutoHideArea() == NULL )
		return false;
CFrameWnd * pFrame = pExtBar->GetParentFrame();
	ASSERT_VALID( pFrame );
	if( pFrame->IsKindOf(RUNTIME_CLASS(CMiniFrameWnd)) )
		return false;
	return true;
}

void CExtBarNcAreaButtonAutoHide::OnNcAreaDraw( CDC & dc )
{
	ASSERT_VALID( this );
	ASSERT( dc.GetSafeHdc() != NULL );
	ASSERT( OnQueryVisibility() );
	if( m_rc.IsRectEmpty() )
		return;

#if (defined __DEBUG_PAINTING_AREAS_EXTRESIZABLEBAR__)

	dc.FillSolidRect( &m_rc, RGB(255,128,255) );

#else // __DEBUG_PAINTING_AREAS_EXTRESIZABLEBAR__

	NcDrawDefault(
		dc,
		IsBarAutoHideMode()
			? CExtPaintManager::__DCBT_WND_UNKEEP
			: CExtPaintManager::__DCBT_WND_KEEP
		);

#endif // !__DEBUG_PAINTING_AREAS_EXTRESIZABLEBAR__
}

UINT CExtBarNcAreaButtonAutoHide::OnNcAreaHitTest( CPoint point )
{
	ASSERT_VALID( this );
UINT nHT = CExtBarNcAreaButton::OnNcAreaHitTest( point );
	if( nHT == HTCLIENT )
		return HTCLIENT; // not inside nc-button
	//return HTCLOSE;
	return HTMINBUTTON;
}

bool CExtBarNcAreaButtonAutoHide::OnNcAreaClicked( CPoint point )
{
	ASSERT_VALID( this );
	if( m_rc.PtInRect(point) )
	{
		m_bPushed = m_bHover = false;
		CExtControlBar * pExtBar = GetBar();
		ASSERT_VALID( pExtBar );
		bool bAutoHideMode = pExtBar->AutoHideModeGet();
		pExtBar->AutoHideModeSet( !bAutoHideMode, false, true, false );
		return true;
	}
	return false; // continue asking nc-buttons
}

void CExtBarNcAreaButtonAutoHide::OnNcAreaReposition(
	CExtBarNcAreaButton * pPrevBtn
	)
{
	ASSERT_VALID( this );
CExtControlBar * pExtBar = GetBar();
	ASSERT_VALID( pExtBar );
bool bAutoHideMode = pExtBar->AutoHideModeGet();
	if( !bAutoHideMode )
		m_bHover = m_bPushed = false;
	CExtBarNcAreaButton::OnNcAreaReposition( pPrevBtn );
}

int CExtBarNcAreaButtonAutoHide::OnToolHitTest(
	CPoint point,
	TOOLINFO * pTI
	)
{
	ASSERT_VALID( this );
	
	point; // shuld be in button area
	return
		DoDefaultReflectForToolHitTest(
			pTI,
			IDS_EXTTABWND_BTN_AUTOHIDE,
			_T("Auto Hide")
			);
}
#endif // (!defined __EXT_MFC_NO_TAB_CONTROLBARS)

/////////////////////////////////////////////////////////////////////////////
// CExtBarNcAreaButtonMenu

IMPLEMENT_DYNCREATE( CExtBarNcAreaButtonMenu, CExtBarNcAreaButton )

CExtBarNcAreaButtonMenu::CExtBarNcAreaButtonMenu(
	CExtControlBar * pBar
	)
	: CExtBarNcAreaButton( pBar )
{
}

bool CExtBarNcAreaButtonMenu::OnQueryVisibility() const
{
	ASSERT_VALID( this );
	if( !CExtBarNcAreaButton::OnQueryVisibility() )
		return false;
	if( !IsBarFixedMode() || !IsBarFloated() )
		return false;
	return true;
}

void CExtBarNcAreaButtonMenu::OnNcAreaDraw( CDC & dc )
{
	ASSERT_VALID( this );
	ASSERT( dc.GetSafeHdc() != NULL );
	ASSERT( OnQueryVisibility() );
	if( m_rc.IsRectEmpty() )
		return;

#if (!defined __EXT_MFC_NO_CUSTOMIZE)
CExtCustomizeSite * pSite =
		CExtCustomizeSite::GetCustomizeSite( GetBar()->GetSafeHwnd() );
	if(		pSite != NULL
		&&	pSite->IsCustomizeMode()
		)
		m_bHover = m_bPushed = false;
#endif // (!defined __EXT_MFC_NO_CUSTOMIZE)

#if (defined __DEBUG_PAINTING_AREAS_EXTRESIZABLEBAR__)

	dc.FillSolidRect( &m_rc, RGB(255,255,128) );

#else // __DEBUG_PAINTING_AREAS_EXTRESIZABLEBAR__

	NcDrawDefault(
		dc,
		CExtPaintManager::__DCBT_ARROW_DOWN
		);

#endif // !__DEBUG_PAINTING_AREAS_EXTRESIZABLEBAR__
}

UINT CExtBarNcAreaButtonMenu::OnNcAreaHitTest( CPoint point )
{
	ASSERT_VALID( this );

#if (!defined __EXT_MFC_NO_CUSTOMIZE)
CExtCustomizeSite * pSite =
		CExtCustomizeSite::GetCustomizeSite( GetBar()->GetSafeHwnd() );
	if(		pSite != NULL
		&&	pSite->IsCustomizeMode()
		)
		return HTCLIENT;
#endif // (!defined __EXT_MFC_NO_CUSTOMIZE)

UINT nHT = CExtBarNcAreaButton::OnNcAreaHitTest( point );
	if( nHT == HTCLIENT )
		return HTCLIENT; // not inside nc-button

	return HTMINBUTTON;
}

bool CExtBarNcAreaButtonMenu::OnNcAreaClicked( CPoint point )
{
	ASSERT_VALID( this );

#if (!defined __EXT_MFC_NO_CUSTOMIZE)
CExtCustomizeSite * pSite =
		CExtCustomizeSite::GetCustomizeSite( GetBar()->GetSafeHwnd() );
	if(		pSite != NULL
		&&	pSite->IsCustomizeMode()
		)
		return true;
#endif // (!defined __EXT_MFC_NO_CUSTOMIZE)

	if( CExtControlBar::FindHelpMode( GetBar() ) )
		return true;

	if( !m_rc.PtInRect(point) )
		return false; // continue asking nc-buttons

CFrameWnd * pFrame = GetDockingFrame();
	ASSERT_VALID( pFrame );

HWND hWndTrack = pFrame->GetSafeHwnd();
	ASSERT(
		hWndTrack != NULL
		&& ::IsWindow(hWndTrack)
		);

CExtPopupMenuWnd * pPopup = new CExtPopupMenuWnd;
	if( !pPopup->CreatePopupMenu(hWndTrack) )
	{
		ASSERT( FALSE );
		return false;
	}

CExtControlBar::POPUP_MENU_EVENT_DATA _pmed(
		CExtControlBar::POPUP_MENU_EVENT_DATA::__PMED_CONTROLBAR_NCBTNMENU_TOP,
		pPopup,
		m_pBar,
		CPoint( -1, -1 ),
		WM_NCLBUTTONDOWN,
		this
		);
	if( !_pmed.NotifyTarget( false ) )
	{
#if (defined _AFXDLL && !defined __STATPROFUIS_WITH_DLLMFC__)
		CExtLocalResourceHelper _LRH;
#endif // #if (defined _AFXDLL && !defined __STATPROFUIS_WITH_DLLMFC__)

		CExtSafeString sShowHidePanels;
		if( !sShowHidePanels.LoadString(IDS_SHOW_HIDE_PANELS) )
		{
#if (defined _AFXDLL && !defined __STATPROFUIS_WITH_DLLMFC__)
			ASSERT( FALSE );
#endif // #if (defined _AFXDLL && !defined __STATPROFUIS_WITH_DLLMFC__)
			sShowHidePanels = _T("&Show/hide panels");
		}
		VERIFY(
			pPopup->ItemInsert(
				(UINT)CExtPopupMenuWnd::TYPE_POPUP,
				-1,
				sShowHidePanels
				)
			);
		CExtPopupMenuWnd::MENUITEMDATA & mi = pPopup->ItemGetInfo( pPopup->ItemGetCount() - 1 );
		mi.SetChildCombine();
		mi.SetToolButton();
		CExtPopupMenuWnd * pPopupBars = mi.GetPopup();
		ASSERT( pPopupBars != NULL );

		if(	! CExtDockBar::_ConstructDockSiteControlBarPopupMenu(
				pFrame,
				pPopupBars,
				CExtControlBar::POPUP_MENU_EVENT_DATA::__PMED_CONTROLBAR_NCBTNMENU_BARS,
				m_pBar,
				WM_NCLBUTTONDOWN,
				this
				)
			)
		{
			VERIFY(
				pPopup->ItemRemove(
					pPopup->ItemGetCount() - 1
					)
				);
		}
#if (!defined __EXT_MFC_NO_CUSTOMIZE)
		if(		m_pBar->IsKindOf( RUNTIME_CLASS(CExtToolControlBar) )
			&&	((CExtToolControlBar*)m_pBar)->m_bCustomizationAllowed
			&&	((CExtToolControlBar*)m_pBar)->GetCustomizeSite() != NULL
			)
		{ // if customization allowed
			VERIFY(
				CExtDockBar::_AppendAddRemoveButtonsCustomizeMenu(
					pPopup,
					m_pBar
					)
				);
		} // if customization allowed
#endif // (!defined __EXT_MFC_NO_CUSTOMIZE)
	} // if( !_pmed.NotifyTarget( false ) )
	_pmed.NotifyTarget( true );

	if( pPopup->ItemGetCount() == 0 )
	{
		delete pPopup;
		return false;
	}

CRect rcBarWnd;
	VERIFY(
		GetBarNcAreaInfo( NULL, &rcBarWnd )
		);
CRect rcBtnScreen( m_rc );
	rcBtnScreen.OffsetRect( rcBarWnd.TopLeft() );
	rcBtnScreen.InflateRect( 1, 1 );

CPoint ptCursor = rcBtnScreen.CenterPoint();
	::SetFocus( hWndTrack );
	if(	! pPopup->TrackPopupMenu(
			TPMX_TOPALIGN|TPMX_COMBINE_DEFAULT|TPMX_OWNERDRAW_FIXED,
			ptCursor.x,  ptCursor.y,
			&rcBtnScreen,
			this,
			_CbPaintCombinedContent,
			NULL,
			true
			)
		)
	{
		delete pPopup;
		return false;
	}
	
	return true;
}

int CExtBarNcAreaButtonMenu::OnToolHitTest(
	CPoint point,
	TOOLINFO * pTI
	)
{
	ASSERT_VALID( this );
	
	point; // shuld be in button area
	return
		DoDefaultReflectForToolHitTest(
			pTI,
			IDS_CBNCAREA_MENU,
			_T("Options")
			);
}

void CExtBarNcAreaButtonMenu::_CbPaintCombinedContent(
	LPVOID pCookie,
	CDC & dc,
	const CWnd & refWndMenu,
	const CRect & rcExcludeArea, // in screen coords
	int eCombineAlign // CExtPopupMenuWnd::e_combine_align_t values
	)
{
	pCookie;
	dc;
	refWndMenu;
	rcExcludeArea;
	eCombineAlign;
	ASSERT( dc.GetSafeHdc() != NULL );
	ASSERT( refWndMenu.GetSafeHwnd() != NULL );

CExtBarNcAreaButtonMenu * pBtn = (CExtBarNcAreaButtonMenu *)pCookie;
	ASSERT( pBtn != NULL );
	ASSERT_VALID( pBtn );
	ASSERT( pBtn->IsKindOf(RUNTIME_CLASS(CExtBarNcAreaButtonMenu)) );

	ASSERT( eCombineAlign != CExtPopupMenuWnd::__CMBA_NONE );

	if( rcExcludeArea.IsRectEmpty() )
		return;

CRect rcBarWnd;
	VERIFY(
		pBtn->GetBarNcAreaInfo( NULL, &rcBarWnd )
		);
CRect rcExcludeAreaX;
	refWndMenu.GetClientRect( &rcExcludeAreaX );
	refWndMenu.ClientToScreen( &rcExcludeAreaX );
CPoint ptOffset =
		rcBarWnd.TopLeft()
		- rcExcludeAreaX.TopLeft()
		;
CPoint ptViewportOrg = dc.GetViewportOrg();
	dc.SetViewportOrg( ptOffset );
	pBtn->m_bPaintingCombinedArea = true;
	pBtn->OnNcAreaDraw( dc );
	pBtn->m_bPaintingCombinedArea = false;
	dc.SetViewportOrg( ptViewportOrg );
}

LRESULT CExtControlBar::OnSizeParent(WPARAM wParam, LPARAM lParam)
{
	if( !m_bReflectParentSizing )
		return (LRESULT)0;

//	if( CExtControlBar::g_bUpdatingDragState )
//		return 0;

LRESULT lResult =
		CControlBar::OnSizeParent(wParam,lParam);
	return lResult;
}

CExtControlBar * CExtControlBar::InternalDraggingState_t::ExtBarDstSet(
	CExtControlBar * pExtBarDst, // = NULL
	bool bNoCheckOnShutdown // = false
	)
{
	bNoCheckOnShutdown;
	ASSERT( this != NULL );
//	ASSERT_VALID( this );
CExtControlBar * pExtBarDstOld = m_pExtBarDst;
	m_pExtBarDst = pExtBarDst;
//	ASSERT_VALID( this );

#if (!defined __EXT_MFC_NO_TAB_CONTROLBARS)

	if(	(!bNoCheckOnShutdown)
		&& pExtBarDstOld != NULL
		&& pExtBarDstOld != m_pExtBarDst )
	{
		CExtDynTabControlBar * pTabbedBar =
			DYNAMIC_DOWNCAST(
				CExtDynTabControlBar,
				pExtBarDstOld
				);
		if( pTabbedBar != NULL )
			pTabbedBar->RemoveTemporaryItems( true );
	} // if( pExtBarDstOld != NULL && pExtBarDstOld != m_pExtBarDst )

	m_nTabReindex = 0;

#endif // (!defined __EXT_MFC_NO_TAB_CONTROLBARS)

	return pExtBarDstOld;
}

void CExtControlBar::InternalDraggingState_t::_AssignFromOther(
	const CExtControlBar::InternalDraggingState_t & other
	)
{
	ASSERT( this != NULL );
	ASSERT_VALID( (&other) );

	if( m_pExtBarDst != NULL
		&& m_pExtBarDst != other.m_pExtBarDst
		)
	{
		ExtBarDstSet( other.m_pExtBarDst );
	} // if( m_pExtBarDst ....

	m_bEmpty = other.m_bEmpty;
	m_bDeepHalfSplit = other.m_bDeepHalfSplit;
	m_eCDT = other.m_eCDT;
	m_eCFR = other.m_eCFR;
	m_nCircleNo = other.m_nCircleNo;
	m_rcTrack = other.m_rcTrack;
	m_pExtBarSrc = other.m_pExtBarSrc;
	m_pExtBarDst = other.m_pExtBarDst;
#if (!defined __EXT_MFC_NO_TAB_CONTROLBARS)
	m_nTabReindex = other.m_nTabReindex;
#endif // (!defined __EXT_MFC_NO_TAB_CONTROLBARS)
	ASSERT_VALID( this );
}

void CExtControlBar::InternalDraggingState_t::SetEmpty(
	bool bEmpty // = true
	)
{
//	ASSERT_VALID( this );
	ASSERT( this != NULL );

	m_eCFR = __ECFR_NO_RESIZING;
	if( bEmpty )
		ExtBarDstSet( NULL );
	
	m_bEmpty = bEmpty;
	if( m_bEmpty )
	{
		m_rcTrack.SetRectEmpty();
//		m_pExtBarDst = NULL;
	}

#if (!defined __EXT_MFC_NO_TAB_CONTROLBARS)
	m_nTabReindex = 0;
#endif // (!defined __EXT_MFC_NO_TAB_CONTROLBARS)
}

#if (!defined __EXT_MFC_NO_TAB_CONTROLBARS)
void CExtControlBar::InternalDraggingState_t::ReindexPosCalc( CPoint ptCursor )
{
	ASSERT_VALID( this );
	ASSERT( !IsEmpty() );
	ASSERT( m_eCDT == __ECDT_TABBED_REINDEX );
	ASSERT_VALID( m_pExtBarDst );
CExtDynTabControlBar * pTabbedBar =
		STATIC_DOWNCAST(
			CExtDynTabControlBar,
			m_pExtBarDst
			);
	m_nTabReindex = pTabbedBar-&g