You cannot select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
	
	
		
			1649 lines
		
	
	
		
			41 KiB
		
	
	
	
		
			C++
		
	
		
		
			
		
	
	
			1649 lines
		
	
	
		
			41 KiB
		
	
	
	
		
			C++
		
	
| 
											2 years ago
										 | // XTPDockingPaneManager.cpp : implementation of the CXTPDockingPaneManager class.
 | ||
|  | //
 | ||
|  | // This file is a part of the XTREME DOCKINGPANE MFC class library.
 | ||
|  | // (c)1998-2012 Codejock Software, All Rights Reserved.
 | ||
|  | //
 | ||
|  | // THIS SOURCE FILE IS THE PROPERTY OF CODEJOCK SOFTWARE AND IS NOT TO BE
 | ||
|  | // RE-DISTRIBUTED BY ANY MEANS WHATSOEVER WITHOUT THE EXPRESSED WRITTEN
 | ||
|  | // CONSENT OF CODEJOCK SOFTWARE.
 | ||
|  | //
 | ||
|  | // THIS SOURCE CODE CAN ONLY BE USED UNDER THE TERMS AND CONDITIONS OUTLINED
 | ||
|  | // IN THE XTREME TOOLKIT PRO LICENSE AGREEMENT. CODEJOCK SOFTWARE GRANTS TO
 | ||
|  | // YOU (ONE SOFTWARE DEVELOPER) THE LIMITED RIGHT TO USE THIS SOFTWARE ON A
 | ||
|  | // SINGLE COMPUTER.
 | ||
|  | //
 | ||
|  | // CONTACT INFORMATION:
 | ||
|  | // support@codejock.com
 | ||
|  | // http://www.codejock.com
 | ||
|  | //
 | ||
|  | /////////////////////////////////////////////////////////////////////////////
 | ||
|  | 
 | ||
|  | #include "stdafx.h"
 | ||
|  | #include "Common/XTPColorManager.h"
 | ||
|  | #include "Common/XTPDrawHelpers.h"
 | ||
|  | #include "Common/XTPImageManager.h"
 | ||
|  | #include "Common/XTPToolTipContext.h"
 | ||
|  | #include "Common/XTPPropExchange.h"
 | ||
|  | #include "Common/XTPSystemHelpers.h"
 | ||
|  | 
 | ||
|  | #include "TabManager/XTPTabManager.h"
 | ||
|  | 
 | ||
|  | #include "XTPDockingPaneDefines.h"
 | ||
|  | #include "XTPDockingPaneManager.h"
 | ||
|  | #include "XTPDockingPaneBase.h"
 | ||
|  | #include "XTPDockingPaneBaseContainer.h"
 | ||
|  | #include "XTPDockingPane.h"
 | ||
|  | #include "XTPDockingPaneSplitterContainer.h"
 | ||
|  | #include "XTPDockingPaneTabbedContainer.h"
 | ||
|  | #include "XTPDockingPaneMiniWnd.h"
 | ||
|  | #include "XTPDockingPanePaintManager.h"
 | ||
|  | #include "XTPDockingPaneLayout.h"
 | ||
|  | #include "XTPDockingPaneAutoHidePanel.h"
 | ||
|  | #include "XTPDockingPaneSidePanel.h"
 | ||
|  | #include "XTPDockingPaneContext.h"
 | ||
|  | #include "XTPDockingPaneKeyboardHook.h"
 | ||
|  | 
 | ||
|  | #ifdef _DEBUG
 | ||
|  | #define new DEBUG_NEW
 | ||
|  | #undef THIS_FILE
 | ||
|  | static char THIS_FILE[] = __FILE__; | ||
|  | #endif
 | ||
|  | 
 | ||
|  | #define XTP_IDC_DOCKINGPANE 1300
 | ||
|  | 
 | ||
|  | 
 | ||
|  | CXTPDockingPaneManager::CXTPDockingPaneManager() | ||
|  | { | ||
|  | 	m_pSite = 0; | ||
|  | 	m_pLayout = 0; | ||
|  | 
 | ||
|  | 	m_nSplitterGap = 22; | ||
|  | 	m_nClientMargin = 0; | ||
|  | 
 | ||
|  | 	m_dwDefaultPaneOptions = 0; | ||
|  | 
 | ||
|  | 	m_bAttachingPane = FALSE; | ||
|  | 
 | ||
|  | 	m_bHideClient = FALSE; | ||
|  | 	m_bUseSplitterTracker = TRUE; | ||
|  | 
 | ||
|  | 	m_pPaintManager = NULL; | ||
|  | 	SetTheme(xtpPaneThemeDefault); | ||
|  | 
 | ||
|  | 	m_pImageManager = new CXTPImageManager(); | ||
|  | 
 | ||
|  | 	m_bLockSplitters = FALSE; | ||
|  | 
 | ||
|  | 	m_bThemedFloatingFrames = FALSE; | ||
|  | 
 | ||
|  | 	m_pDockingContext = new CXTPDockingPaneContext(); | ||
|  | 	m_pDockingContext->m_pManager = this; | ||
|  | 
 | ||
|  | 	m_bAlphaDockingContext = FALSE; | ||
|  | 	m_bShowDockingContextStickers = FALSE; | ||
|  | 	m_nDockingContextStickerStyle = xtpPaneStickerStyleVisualStudio2005; | ||
|  | 
 | ||
|  | 	m_bShowCloseTabButton = xtpTabNavigateButtonNone; | ||
|  | 
 | ||
|  | 	m_bCloseGroupOnButtonClick = FALSE; | ||
|  | 	m_bHideGroupOnButtonClick = TRUE; | ||
|  | 	m_pPreviewLayout = 0; | ||
|  | 	m_bSyncActiveFloatingFrames = TRUE; | ||
|  | 
 | ||
|  | 	m_captionDirection = xtpPaneCaptionHorizontal; | ||
|  | 
 | ||
|  | 	m_pToolTipContext = new CXTPToolTipContext(); | ||
|  | 
 | ||
|  | 	m_pActivePane = 0; | ||
|  | 	m_bShowMaximizeButton = FALSE; | ||
|  | 	m_bLayoutCreated = FALSE; | ||
|  | 
 | ||
|  | 	m_bShowContentsWhileDragging = FALSE; | ||
|  | 
 | ||
|  | 	m_bShowSizeCursorWhileDragging = FALSE; | ||
|  | 	m_bInitialUpdateCalled = FALSE; | ||
|  | 	m_bAutoInitialUpdate = TRUE; | ||
|  | 
 | ||
|  | 	m_ptMinClientSize = CPoint(60, 60); | ||
|  | 
 | ||
|  | 	m_hwndLastFocus = NULL; | ||
|  | 
 | ||
|  | 	m_bStickyFloatingFrames = FALSE; | ||
|  | 	m_nStickyGap = 15; | ||
|  | 	m_nFloatingFramesOpacity = 255; | ||
|  | 	m_rcSideDockingMargin.SetRect(0, 0, 0, 0); | ||
|  | 
 | ||
|  | 	m_bSideDocking = FALSE; | ||
|  | 
 | ||
|  | 	m_bShowPanelScrollButtons = FALSE; | ||
|  | 
 | ||
|  | 	m_bKeyboardEnabled = xtpPaneKeyboardUnused; | ||
|  | 
 | ||
|  | 	HMODULE hLib = GetModuleHandle(_T("USER32")); | ||
|  | 	if (hLib) | ||
|  | 	{ | ||
|  | 		m_pfnSetLayeredWindowAttributes = (PFNSETLAYEREDWINDOWATTRIBUTES)::GetProcAddress(hLib, "SetLayeredWindowAttributes"); | ||
|  | 	} | ||
|  | 
 | ||
|  | 	XTPDrawHelpers()->RegisterWndClass(0, _T("XTPDockingPaneSplitter"), 0); | ||
|  | 	XTPDrawHelpers()->RegisterWndClass(0, _T("XTPDockingPaneTabbedContainer"), CS_DBLCLKS); | ||
|  | 	XTPDrawHelpers()->RegisterWndClass(0, _T("XTPDockingPaneManager"), 0); | ||
|  | 	XTPDrawHelpers()->RegisterWndClass(0, _T("XTPDockingPaneAutoHidePanel"), 0); | ||
|  | 	XTPDrawHelpers()->RegisterWndClass(0, _T("XTPDockingPaneMiniWnd"), CS_DBLCLKS); | ||
|  | 	XTPDrawHelpers()->RegisterWndClass(0, _T("XTPDockingPaneSidePanel"), CS_DBLCLKS); | ||
|  | 
 | ||
|  | 	m_pWindowSelectClass = RUNTIME_CLASS(CXTPDockingPaneWindowSelect); | ||
|  | 
 | ||
|  | 	OleInitialize(NULL); | ||
|  | 
 | ||
|  | 	EnableAutomation(); | ||
|  | } | ||
|  | 
 | ||
|  | CXTPDockingPaneManager::~CXTPDockingPaneManager() | ||
|  | { | ||
|  | 	CMDTARGET_RELEASE(m_pLayout); | ||
|  | 
 | ||
|  | 	CMDTARGET_RELEASE(m_pActivePane); | ||
|  | 
 | ||
|  | 	CMDTARGET_RELEASE(m_pPaintManager); | ||
|  | 
 | ||
|  | 	CMDTARGET_RELEASE(m_pToolTipContext); | ||
|  | 
 | ||
|  | 	delete m_pDockingContext; | ||
|  | 
 | ||
|  | 	CMDTARGET_RELEASE(m_pImageManager); | ||
|  | 
 | ||
|  | 	OleUninitialize(); | ||
|  | } | ||
|  | 
 | ||
|  | void CXTPDockingPaneManager::HideClient(BOOL bHide) | ||
|  | { | ||
|  | 	RecalcFrameLayout(NULL); | ||
|  | 
 | ||
|  | 	m_bHideClient = bHide; | ||
|  | 	m_pLayout->m_pTopContainer->OnParentContainerChanged(m_pLayout->m_pTopContainer); | ||
|  | 
 | ||
|  | 	RedrawPanes(); | ||
|  | } | ||
|  | 
 | ||
|  | BEGIN_MESSAGE_MAP(CXTPDockingPaneManager, CWnd) | ||
|  | 	ON_MESSAGE(WM_SIZEPARENT, OnSizeParent) | ||
|  | 	ON_MESSAGE(WM_IDLEUPDATECMDUI, OnIdleUpdateCmdUI) | ||
|  | 	ON_WM_SYSCOLORCHANGE() | ||
|  | 	ON_WM_SETTINGCHANGE() | ||
|  | 	ON_MESSAGE_VOID(WM_INITIALUPDATE, OnInitialUpdate) | ||
|  | 	ON_MESSAGE(WM_GETOBJECT, OnGetObject) | ||
|  | END_MESSAGE_MAP() | ||
|  | 
 | ||
|  | void CXTPDockingPaneManager::OnSysColorChange() | ||
|  | { | ||
|  | 	RefreshXtremeColors(); | ||
|  | 
 | ||
|  | 	m_pPaintManager->RefreshMetrics(); | ||
|  | 
 | ||
|  | 
 | ||
|  | 	_Redraw(); | ||
|  | } | ||
|  | 
 | ||
|  | void CXTPDockingPaneManager::OnSettingChange(UINT /*uFlags*/, LPCTSTR /*lpszSection*/) | ||
|  | { | ||
|  | 	m_pPaintManager->RefreshMetrics(); | ||
|  | 
 | ||
|  | 	RecalcFramesLayout(); | ||
|  | } | ||
|  | 
 | ||
|  | void CXTPDockingPaneManager::SetFloatingFramesOpacity(int nOpacity) | ||
|  | { | ||
|  | 	m_nFloatingFramesOpacity = nOpacity; | ||
|  | 
 | ||
|  | 	POSITION pos = GetPaneStack().GetHeadPosition(); | ||
|  | 	while (pos) | ||
|  | 	{ | ||
|  | 		CXTPDockingPaneBase* pPane = GetPaneStack().GetNext(pos); | ||
|  | 
 | ||
|  | 		if (pPane->GetType() == xtpPaneTypeMiniWnd) | ||
|  | 		{ | ||
|  | 			((CXTPDockingPaneMiniWnd*)pPane)->UpdateWindowOpacity(); | ||
|  | 		} | ||
|  | 	} | ||
|  | } | ||
|  | 
 | ||
|  | void CXTPDockingPaneManager::UpdatePanes() | ||
|  | { | ||
|  | 	HWND hWndFocus = ::GetFocus(); | ||
|  | 
 | ||
|  | 	if (m_hwndLastFocus == hWndFocus) | ||
|  | 		return; | ||
|  | 
 | ||
|  | 	m_hwndLastFocus = hWndFocus; | ||
|  | 
 | ||
|  | 	POSITION pos = GetPaneStack().GetHeadPosition(); | ||
|  | 	while (pos) | ||
|  | 	{ | ||
|  | 		CXTPDockingPaneBase *pPane = GetPaneStack().GetNext(pos); | ||
|  | 
 | ||
|  | 		if (pPane->GetType() == xtpPaneTypeTabbedContainer || | ||
|  | 			 pPane->GetType() == xtpPaneTypeMiniWnd         || | ||
|  | 			 pPane->GetType() == xtpPaneTypeSidePanel) | ||
|  | 		{ | ||
|  | 			pPane->OnFocusChanged(); | ||
|  | 		} | ||
|  | 	} | ||
|  | } | ||
|  | 
 | ||
|  | void CXTPDockingPaneManager::OnInitialUpdate() | ||
|  | { | ||
|  | 	if (m_pSite && m_pSite->IsFrameWnd() && ((CFrameWnd*)m_pSite)->m_nIdleFlags & CFrameWnd::idleLayout) | ||
|  | 	{ | ||
|  | 		RecalcFrameLayout(NULL); | ||
|  | 	} | ||
|  | 
 | ||
|  | 	OnIdleUpdateCmdUI(TRUE, 0L); | ||
|  | 
 | ||
|  | 
 | ||
|  | 	if (m_pLayout && m_bAutoInitialUpdate) | ||
|  | 	{ | ||
|  | 		POSITION pos = m_pLayout->m_lstStack.GetHeadPosition(); | ||
|  | 		while (pos) | ||
|  | 		{ | ||
|  | 			CXTPDockingPaneBase* pPane = m_pLayout->m_lstStack.GetNext(pos); | ||
|  | 			if (pPane->GetType() == xtpPaneTypeMiniWnd) | ||
|  | 			{ | ||
|  | 				CXTPDockingPaneMiniWnd* pMiniFrame = (CXTPDockingPaneMiniWnd*)pPane; | ||
|  | 
 | ||
|  | 				if (pMiniFrame->GetSafeHwnd()) | ||
|  | 				{ | ||
|  | 					if (pMiniFrame->m_nIdleFlags & CFrameWnd::idleLayout) | ||
|  | 					{ | ||
|  | 						pMiniFrame->RecalcLayout(); | ||
|  | 					} | ||
|  | 
 | ||
|  | 					pMiniFrame->SendMessageToDescendants(WM_INITIALUPDATE, 0, 0, TRUE, TRUE); | ||
|  | 				} | ||
|  | 			} | ||
|  | 		} | ||
|  | 	} | ||
|  | 
 | ||
|  | 	m_bInitialUpdateCalled = TRUE; | ||
|  | } | ||
|  | 
 | ||
|  | 
 | ||
|  | LRESULT CXTPDockingPaneManager::OnIdleUpdateCmdUI(WPARAM /*wParam*/, LPARAM /*lParam*/) | ||
|  | { | ||
|  | 	UpdatePanes(); | ||
|  | 	return 0; | ||
|  | } | ||
|  | 
 | ||
|  | void CXTPDockingPaneManager::SyncPanesState() | ||
|  | { | ||
|  | 	POSITION pos = GetPaneList().GetHeadPosition(); | ||
|  | 	while (pos) | ||
|  | 	{ | ||
|  | 		XTP_DOCKINGPANE_INFO& info = GetPaneList().GetNext(pos); | ||
|  | 		CXTPDockingPaneBase* pContainer = info.pPane->m_pParentContainer; | ||
|  | 
 | ||
|  | 		if (info.pPane->GetDockingSite() && pContainer) | ||
|  | 		{ | ||
|  | 			if (pContainer->m_pParentContainer == 0 || pContainer->m_pParentContainer->GetType() != xtpPaneTypeAutoHidePanel) | ||
|  | 			{ | ||
|  | 
 | ||
|  | 				if (DYNAMIC_DOWNCAST(CXTPDockingPaneMiniWnd, info.pPane->GetDockingSite())) | ||
|  | 				{ | ||
|  | 					info.pLastHolder = info.pFloatingHolder = pContainer; | ||
|  | 				} | ||
|  | 				else | ||
|  | 				{ | ||
|  | 					info.pLastHolder = info.pDockingHolder = pContainer; | ||
|  | 				} | ||
|  | 			} | ||
|  | 		} | ||
|  | 	} | ||
|  | } | ||
|  | 
 | ||
|  | LRESULT CXTPDockingPaneManager::OnSizeParent(WPARAM, LPARAM lParam) | ||
|  | { | ||
|  | 	if (GetTopPane() != NULL) | ||
|  | 	{ | ||
|  | 		AFX_SIZEPARENTPARAMS* lpLayout = (AFX_SIZEPARENTPARAMS*)lParam; | ||
|  | 
 | ||
|  | 		m_pLayout->OnSizeParent(m_pSite, lpLayout->rect, lpLayout); | ||
|  | 
 | ||
|  | 		SyncPanesState(); | ||
|  | 
 | ||
|  | 		m_bLayoutCreated = TRUE; | ||
|  | 	} | ||
|  | 	return 0; | ||
|  | } | ||
|  | 
 | ||
|  | CXTPDockingPaneBase* CXTPDockingPaneManager::_Clone(CXTPDockingPaneBase* pPane) | ||
|  | { | ||
|  | 	return pPane->Clone(m_pLayout, 0); | ||
|  | } | ||
|  | 
 | ||
|  | BOOL CXTPDockingPaneManager::NotifyAction(XTPDockingPaneAction action, CXTPDockingPane* pPane, CXTPDockingPaneBase* pDockContainer /*= NULL*/, XTPDockingPaneDirection dockDirection /*= xtpPaneDockLeft*/) | ||
|  | { | ||
|  | 	if (!pPane) | ||
|  | 		return FALSE; | ||
|  | 
 | ||
|  | 	XTP_DOCKINGPANE_ACTION dpAction(action); | ||
|  | 	dpAction.pPane = pPane; | ||
|  | 	dpAction.pDockContainer = pDockContainer; | ||
|  | 	dpAction.dockDirection = dockDirection; | ||
|  | 
 | ||
|  | 	if ((pPane->GetEnabled() & xtpPaneEnableActions) == 0) | ||
|  | 		dpAction.bCancel = TRUE; | ||
|  | 
 | ||
|  | 	NotifyOwner(XTP_DPN_ACTION, (LPARAM)&dpAction); | ||
|  | 
 | ||
|  | 	return dpAction.bCancel; | ||
|  | } | ||
|  | 
 | ||
|  | void CXTPDockingPaneManager::LockSplitters(BOOL bLock /*= TRUE*/) | ||
|  | { | ||
|  | 	m_bLockSplitters = bLock; | ||
|  | 
 | ||
|  | 	POSITION pos = GetPaneList().GetHeadPosition(); | ||
|  | 	while (pos) | ||
|  | 	{ | ||
|  | 		CXTPDockingPane* pPane = GetPaneList().GetNext(pos); | ||
|  | 		if (pPane->GetContainer()) | ||
|  | 			SAFE_CALLPTR(pPane->GetContainer()->GetContainer(), OnChildContainerChanged(pPane)); | ||
|  | 	} | ||
|  | } | ||
|  | 
 | ||
|  | CXTPDockingPaneSidePanel* CXTPDockingPaneManager::DockSidePane(CXTPDockingPaneBase* pPane, XTPDockingPaneDirection direction, CRect rc) | ||
|  | { | ||
|  | 	CXTPDockingPaneSidePanel* pMiniFrame = (CXTPDockingPaneSidePanel*)OnCreatePane(xtpPaneTypeSidePanel, m_pLayout); | ||
|  | 	pMiniFrame->Init(pPane, direction, rc); | ||
|  | 
 | ||
|  | 	SyncPanesState(); | ||
|  | 	m_hwndLastFocus = 0; | ||
|  | 
 | ||
|  | 	RecalcFrameLayout(NULL, TRUE); | ||
|  | 
 | ||
|  | 	return pMiniFrame; | ||
|  | } | ||
|  | 
 | ||
|  | CXTPDockingPaneMiniWnd* CXTPDockingPaneManager::FloatPane(CXTPDockingPaneBase* pPane, CRect rc) | ||
|  | { | ||
|  | 	ASSERT(pPane->GetType() == xtpPaneTypeDockingPane || pPane->GetType() == xtpPaneTypeTabbedContainer); | ||
|  | 
 | ||
|  | 	if (pPane->GetType() == xtpPaneTypeDockingPane) | ||
|  | 	{ | ||
|  | 		_RemovePane(pPane); | ||
|  | 	} | ||
|  | 	else | ||
|  | 	{ | ||
|  | 		pPane = pPane->Clone(m_pLayout, 0); | ||
|  | 	} | ||
|  | 
 | ||
|  | 	CXTPDockingPaneMiniWnd* pMiniFrame = (CXTPDockingPaneMiniWnd*)OnCreatePane(xtpPaneTypeMiniWnd, m_pLayout); | ||
|  | 	pMiniFrame->Init(pPane, rc); | ||
|  | 
 | ||
|  | 	SyncPanesState(); | ||
|  | 	m_hwndLastFocus = 0; | ||
|  | 
 | ||
|  | 	return pMiniFrame; | ||
|  | } | ||
|  | 
 | ||
|  | CXTPDockingPane* CXTPDockingPaneManager::CreatePane(UINT nID, CRect rc, XTPDockingPaneDirection direction, CXTPDockingPaneBase* pNeighbour) | ||
|  | { | ||
|  | 	ASSERT(GetTopPane()); | ||
|  | 	CXTPDockingPane* pPane = (CXTPDockingPane*)OnCreatePane(xtpPaneTypeDockingPane, m_pLayout); | ||
|  | 	ASSERT(pPane); | ||
|  | 	if (!pPane) | ||
|  | 		return NULL; | ||
|  | 
 | ||
|  | 	pPane->SetID(nID); | ||
|  | 	pPane->SetWindowRect(rc); | ||
|  | 
 | ||
|  | 
 | ||
|  | 	XTP_DOCKINGPANE_INFO pane(pPane); | ||
|  | 	GetPaneList().AddTail(pane); | ||
|  | 
 | ||
|  | 	_InsertPane(pPane, direction, pNeighbour); | ||
|  | 
 | ||
|  | 	SyncPanesState(); | ||
|  | 
 | ||
|  | 	return pPane; | ||
|  | } | ||
|  | 
 | ||
|  | 
 | ||
|  | CXTPDockingPaneBase* CXTPDockingPaneManager::OnCreatePane(XTPDockingPaneType type, CXTPDockingPaneLayout* pLayout) | ||
|  | { | ||
|  | 	CXTPDockingPaneBase* pPane = NULL; | ||
|  | 	switch (type) | ||
|  | 	{ | ||
|  | 		case xtpPaneTypeDockingPane: | ||
|  | 			pPane = new CXTPDockingPane(pLayout); | ||
|  | 			break; | ||
|  | 
 | ||
|  | 		case xtpPaneTypeSplitterContainer: | ||
|  | 			pPane = new CXTPDockingPaneSplitterContainer(pLayout); | ||
|  | 			break; | ||
|  | 
 | ||
|  | 		case xtpPaneTypeTabbedContainer: | ||
|  | 			pPane = new CXTPDockingPaneTabbedContainer(pLayout); | ||
|  | 			break; | ||
|  | 
 | ||
|  | 		case xtpPaneTypeClient: | ||
|  | 			pPane = new CXTPDockingPaneClientContainer(pLayout); | ||
|  | 			break; | ||
|  | 
 | ||
|  | 		case xtpPaneTypeMiniWnd: | ||
|  | 			pPane = new CXTPDockingPaneMiniWnd(pLayout); | ||
|  | 			break; | ||
|  | 
 | ||
|  | 		case xtpPaneTypeAutoHidePanel: | ||
|  | 			pPane = new CXTPDockingPaneAutoHidePanel(pLayout); | ||
|  | 			break; | ||
|  | 
 | ||
|  | 		case xtpPaneTypeSidePanel: | ||
|  | 			pPane = new CXTPDockingPaneSidePanel(pLayout); | ||
|  | 			break; | ||
|  | 	} | ||
|  | 	ASSERT(pPane); | ||
|  | 	return pPane; | ||
|  | } | ||
|  | 
 | ||
|  | 
 | ||
|  | void CXTPDockingPaneManager::DockPane(CXTPDockingPaneBase* pPane, XTPDockingPaneDirection direction, CXTPDockingPaneBase* pNeighbour) | ||
|  | { | ||
|  | 	if (pPane->GetType() == xtpPaneTypeSplitterContainer) | ||
|  | 	{ | ||
|  | 		CXTPDockingPaneBaseList lst; | ||
|  | 		pPane->FindPane(xtpPaneTypeTabbedContainer, &lst); | ||
|  | 
 | ||
|  | 		if (lst.GetCount() == 1) | ||
|  | 		{ | ||
|  | 			pPane = lst.GetHead(); | ||
|  | 		} | ||
|  | 	} | ||
|  | 
 | ||
|  | 	if (pPane->GetType() == xtpPaneTypeDockingPane) | ||
|  | 	{ | ||
|  | 		_RemovePane(pPane); | ||
|  | 	} | ||
|  | 	else | ||
|  | 	{ | ||
|  | 		pPane = _Clone(pPane); | ||
|  | 	} | ||
|  | 	_InsertPane(pPane, direction, pNeighbour); | ||
|  | 
 | ||
|  | 	m_pLayout->_FreeEmptyPanes(); | ||
|  | 	m_hwndLastFocus = 0; | ||
|  | } | ||
|  | 
 | ||
|  | void CXTPDockingPaneManager::_RemovePane(CXTPDockingPaneBase* pPane) | ||
|  | { | ||
|  | 	if (!pPane) | ||
|  | 		return; | ||
|  | 
 | ||
|  | 	if (!pPane->m_pParentContainer) | ||
|  | 		return; | ||
|  | 
 | ||
|  | 	pPane->m_pParentContainer->RemovePane(pPane); | ||
|  | } | ||
|  | 
 | ||
|  | void CXTPDockingPaneManager::AttachPane(CXTPDockingPaneBase* pPane, CXTPDockingPaneBase* pNeighbour) | ||
|  | { | ||
|  | 	_AttachPane(pPane, pNeighbour); | ||
|  | 	SyncPanesState(); | ||
|  | } | ||
|  | 
 | ||
|  | void CXTPDockingPaneManager::_AttachPane(CXTPDockingPaneBase* pPane, CXTPDockingPaneBase* pNeighbour) | ||
|  | { | ||
|  | 	ASSERT(pNeighbour); | ||
|  | 	if (!pNeighbour) | ||
|  | 		return; | ||
|  | 
 | ||
|  | 	if (pNeighbour->GetType() == xtpPaneTypeDockingPane) | ||
|  | 	{ | ||
|  | 		pNeighbour = pNeighbour->m_pParentContainer; | ||
|  | 		ASSERT(pNeighbour); | ||
|  | 	} | ||
|  | 	if (!pNeighbour) | ||
|  | 		return; | ||
|  | 	ASSERT(pNeighbour->GetType() == xtpPaneTypeTabbedContainer); | ||
|  | 
 | ||
|  | 	if (pPane->GetType() == xtpPaneTypeDockingPane) | ||
|  | 	{ | ||
|  | 		_RemovePane(pPane); | ||
|  | 		((CXTPDockingPaneTabbedContainer*)pNeighbour)->_InsertPane((CXTPDockingPane*)pPane); | ||
|  | 	} | ||
|  | 	else | ||
|  | 	{ | ||
|  | 		ASSERT(pPane->GetType() == xtpPaneTypeSplitterContainer || pPane->GetType() == xtpPaneTypeTabbedContainer); | ||
|  | 
 | ||
|  | 		CXTPDockingPaneBaseList lst; | ||
|  | 		pPane->FindPane(xtpPaneTypeDockingPane, &lst); | ||
|  | 
 | ||
|  | 		ASSERT(lst.GetCount() > 0); | ||
|  | 		POSITION pos = lst.GetHeadPosition(); | ||
|  | 		while (pos) | ||
|  | 		{ | ||
|  | 			CXTPDockingPaneBase* pListPane = lst.GetNext(pos); | ||
|  | 			ASSERT(pListPane->GetType() == xtpPaneTypeDockingPane); | ||
|  | 
 | ||
|  | 			_RemovePane(pListPane); | ||
|  | 			((CXTPDockingPaneTabbedContainer*)pNeighbour)->_InsertPane((CXTPDockingPane*)pListPane); | ||
|  | 		} | ||
|  | 
 | ||
|  | 	} | ||
|  | 	m_hwndLastFocus = NULL; | ||
|  | } | ||
|  | 
 | ||
|  | CRect CXTPDockingPaneManager::_CalculateResultDockingRect(CXTPDockingPaneBase* pPane, XTPDockingPaneDirection direction, CXTPDockingPaneBase* pNeighbour) | ||
|  | { | ||
|  | 	if (pNeighbour == NULL) | ||
|  | 	{ | ||
|  | 		pNeighbour = GetTopPane(); | ||
|  | 	} | ||
|  | 
 | ||
|  | 	ASSERT(pNeighbour); | ||
|  | 	if (!pNeighbour) | ||
|  | 		return CRect(0, 0, 0, 0); | ||
|  | 
 | ||
|  | 	BOOL bHoriz = (direction == xtpPaneDockLeft || direction == xtpPaneDockRight); | ||
|  | 
 | ||
|  | 	if (pNeighbour == GetTopPane()) | ||
|  | 	{ | ||
|  | 		CXTPDockingPaneSplitterContainer* pSplitter = (CXTPDockingPaneSplitterContainer*)pNeighbour; | ||
|  | 
 | ||
|  | 		return CXTPDockingPaneSplitterContainer::_CalculateResultDockingRectChild(pSplitter, pPane, direction); | ||
|  | 	} | ||
|  | 	else | ||
|  | 	{ | ||
|  | 		ASSERT(pNeighbour->m_pParentContainer); | ||
|  | 		if (!pNeighbour->m_pParentContainer) | ||
|  | 			return CRect(0, 0, 0, 0); | ||
|  | 
 | ||
|  | 		if (pNeighbour->m_pParentContainer->GetType() == xtpPaneTypeTabbedContainer) | ||
|  | 		{ | ||
|  | 			pNeighbour = pNeighbour->m_pParentContainer; | ||
|  | 			ASSERT(pNeighbour->m_pParentContainer != NULL); | ||
|  | 			if (!pNeighbour->m_pParentContainer) | ||
|  | 				return CRect(0, 0, 0, 0); | ||
|  | 		} | ||
|  | 
 | ||
|  | 		ASSERT(pNeighbour->m_pParentContainer); | ||
|  | 		ASSERT(pNeighbour->m_pParentContainer->GetType() == xtpPaneTypeSplitterContainer); | ||
|  | 
 | ||
|  | 		CXTPDockingPaneSplitterContainer* pSplitter = (CXTPDockingPaneSplitterContainer*)pNeighbour->m_pParentContainer; | ||
|  | 
 | ||
|  | 		if (pSplitter->m_bHoriz == bHoriz) | ||
|  | 			return pSplitter->_CalculateResultDockingRectSelf(pPane, direction, pNeighbour); | ||
|  | 
 | ||
|  | 		return CXTPDockingPaneSplitterContainer::_CalculateResultDockingRectChild(pNeighbour, pPane, direction); | ||
|  | 	} | ||
|  | } | ||
|  | 
 | ||
|  | void CXTPDockingPaneManager::_InsertPane(CXTPDockingPaneBase* pPane, XTPDockingPaneDirection direction, CXTPDockingPaneBase* pNeighbour) | ||
|  | { | ||
|  | 	ASSERT(pPane->m_pParentContainer == NULL); | ||
|  | 
 | ||
|  | 	if (pNeighbour == NULL || (pNeighbour->GetType() == xtpPaneTypeDockingPane && | ||
|  | 		(IsPaneHidden((CXTPDockingPane*)pNeighbour) || IsPaneClosed((CXTPDockingPane*)pNeighbour)))) | ||
|  | 	{ | ||
|  | 		pNeighbour = GetTopPane(); | ||
|  | 	} | ||
|  | 
 | ||
|  | 	ASSERT(pNeighbour); | ||
|  | 	if (!pNeighbour) | ||
|  | 		return; | ||
|  | 
 | ||
|  | 	CWnd* pParentFrame = pNeighbour->GetDockingSite(); | ||
|  | 	ASSERT(pParentFrame != NULL); | ||
|  | 
 | ||
|  | 	BOOL bHoriz = (direction == xtpPaneDockLeft || direction == xtpPaneDockRight); | ||
|  | 	BOOL bAfter = (direction == xtpPaneDockRight || direction == xtpPaneDockBottom); | ||
|  | 
 | ||
|  | 	if (pPane->GetType() == xtpPaneTypeDockingPane) | ||
|  | 	{ | ||
|  | 		CXTPDockingPaneTabbedContainer* pContainer = (CXTPDockingPaneTabbedContainer*)OnCreatePane(xtpPaneTypeTabbedContainer, m_pLayout); | ||
|  | 		pContainer->Init((CXTPDockingPane*)pPane, pParentFrame); | ||
|  | 
 | ||
|  | 		pPane = pContainer; | ||
|  | 	} | ||
|  | 
 | ||
|  | 	if (pNeighbour == GetTopPane()) | ||
|  | 	{ | ||
|  | 		CXTPDockingPaneSplitterContainer* pSplitter = (CXTPDockingPaneSplitterContainer*)pNeighbour; | ||
|  | 
 | ||
|  | 		if (pSplitter->m_bHoriz == bHoriz) | ||
|  | 			pSplitter->_InsertPane(pPane, NULL, bAfter); | ||
|  | 		else | ||
|  | 		{ | ||
|  | 			CXTPDockingPaneSplitterContainer* pChildSplitter = (CXTPDockingPaneSplitterContainer*)OnCreatePane(xtpPaneTypeSplitterContainer, m_pLayout); | ||
|  | 			pChildSplitter->Init(pSplitter, bHoriz, pParentFrame); | ||
|  | 
 | ||
|  | 			pChildSplitter->_InsertPane(pPane, NULL, bAfter); | ||
|  | 			m_pLayout->m_pTopContainer = pChildSplitter; | ||
|  | 		} | ||
|  | 	} | ||
|  | 	else | ||
|  | 	{ | ||
|  | 		ASSERT(pNeighbour->m_pParentContainer); | ||
|  | 		if (!pNeighbour->m_pParentContainer) | ||
|  | 			return; | ||
|  | 
 | ||
|  | 		if (pNeighbour->m_pParentContainer->GetType() == xtpPaneTypeTabbedContainer) | ||
|  | 		{ | ||
|  | 			pNeighbour = pNeighbour->m_pParentContainer; | ||
|  | 			ASSERT(pNeighbour->m_pParentContainer != NULL); | ||
|  | 			if (!pNeighbour->m_pParentContainer) | ||
|  | 				return; | ||
|  | 		} | ||
|  | 
 | ||
|  | 		ASSERT(pNeighbour->m_pParentContainer); | ||
|  | 		ASSERT(pNeighbour->m_pParentContainer->GetType() == xtpPaneTypeSplitterContainer); | ||
|  | 
 | ||
|  | 		CXTPDockingPaneSplitterContainer* pSplitter = (CXTPDockingPaneSplitterContainer*)pNeighbour->m_pParentContainer; | ||
|  | 
 | ||
|  | 		if (pSplitter->m_bHoriz == bHoriz) | ||
|  | 		{ | ||
|  | 			pSplitter->_InsertPane(pPane, pNeighbour, bAfter); | ||
|  | 		} | ||
|  | 		else | ||
|  | 		{ | ||
|  | 			CXTPDockingPaneSplitterContainer* pChildSplitter = (CXTPDockingPaneSplitterContainer*)OnCreatePane(xtpPaneTypeSplitterContainer, m_pLayout); | ||
|  | 			pChildSplitter->Init(pNeighbour, bHoriz, pParentFrame); | ||
|  | 
 | ||
|  | 			pChildSplitter->_InsertPane(pPane, pNeighbour, bAfter); | ||
|  | 			pSplitter->_Replace(pNeighbour, pChildSplitter); | ||
|  | 		} | ||
|  | 
 | ||
|  | 
 | ||
|  | 	} | ||
|  | 	RecalcFrameLayout(pNeighbour, TRUE); | ||
|  | } | ||
|  | 
 | ||
|  | CXTPDockingPaneBase* CXTPDockingPaneManager::_GetHolder(CXTPDockingPaneBase* pPane, BOOL bFloating) | ||
|  | { | ||
|  | 	POSITION pos = GetPaneList().GetHeadPosition(); | ||
|  | 	while (pos) | ||
|  | 	{ | ||
|  | 		XTP_DOCKINGPANE_INFO& info = GetPaneList().GetNext(pos); | ||
|  | 		if (info.pPane == pPane) | ||
|  | 			return bFloating ? info.pFloatingHolder : info.pDockingHolder; | ||
|  | 	} | ||
|  | 	return NULL; | ||
|  | } | ||
|  | 
 | ||
|  | void CXTPDockingPaneManager::ToggleAutoHide(CXTPDockingPaneBase* pPane) | ||
|  | { | ||
|  | 	if (pPane == NULL) | ||
|  | 		return; | ||
|  | 
 | ||
|  | 	if (pPane->IsHidden()) | ||
|  | 	{ | ||
|  | 		if (pPane->GetType() == xtpPaneTypeDockingPane && m_bHideGroupOnButtonClick) | ||
|  | 		{ | ||
|  | 			pPane = pPane->m_pParentContainer; | ||
|  | 		} | ||
|  | 
 | ||
|  | 		ToggleDocking(pPane); | ||
|  | 	} | ||
|  | 	else | ||
|  | 	{ | ||
|  | 		HidePane(pPane); | ||
|  | 	} | ||
|  | } | ||
|  | 
 | ||
|  | void CXTPDockingPaneManager::ToggleDocking(CXTPDockingPaneBase* pPane) | ||
|  | { | ||
|  | 	ASSERT(pPane); | ||
|  | 	if (!pPane) | ||
|  | 		return; | ||
|  | 	BOOL bFloating = DYNAMIC_DOWNCAST(CXTPDockingPaneMiniWnd, pPane->GetDockingSite()) != NULL; | ||
|  | 	BOOL bHidden = pPane->IsHidden(); | ||
|  | 	BOOL bDocking = !bFloating && !bHidden; | ||
|  | 
 | ||
|  | 	if (pPane->GetType() == xtpPaneTypeSplitterContainer || pPane->GetType() == xtpPaneTypeTabbedContainer) | ||
|  | 	{ | ||
|  | 
 | ||
|  | 		CXTPDockingPaneBaseList lst; | ||
|  | 		pPane->FindPane(xtpPaneTypeDockingPane, &lst); | ||
|  | 
 | ||
|  | 		int nIDSelected = 0, nIDFocused = 0; | ||
|  | 
 | ||
|  | 		POSITION pos = lst.GetHeadPosition(); | ||
|  | 		while (pos) | ||
|  | 		{ | ||
|  | 			CXTPDockingPane* pListPane = (CXTPDockingPane*)lst.GetNext(pos); | ||
|  | 			if (pListPane->IsSelected()) nIDSelected = pListPane->GetID(); | ||
|  | 			if (pListPane->IsFocus()) nIDFocused = pListPane->GetID(); | ||
|  | 		} | ||
|  | 
 | ||
|  | 		pos = lst.GetHeadPosition(); | ||
|  | 		CXTPDockingPaneBase* pLastHolder = NULL; | ||
|  | 		while (pos) | ||
|  | 		{ | ||
|  | 			CXTPDockingPane* pListPane = (CXTPDockingPane*)lst.GetNext(pos); | ||
|  | 
 | ||
|  | 			CXTPDockingPaneTabbedContainer* pHolder = (CXTPDockingPaneTabbedContainer*)_GetHolder(pListPane, bDocking); | ||
|  | 			if (!_ToggleDocking(pListPane, pHolder ? pHolder : pLastHolder)) | ||
|  | 			{ | ||
|  | 				if (pListPane->GetID() == nIDSelected) nIDSelected = 0; | ||
|  | 				if (pListPane->GetID() == nIDFocused) nIDFocused = 0; | ||
|  | 			} | ||
|  | 
 | ||
|  | 			pLastHolder = pHolder ? pHolder : pListPane->GetContainer(); | ||
|  | 		} | ||
|  | 
 | ||
|  | 		if (nIDFocused > 0) | ||
|  | 			ShowPane(nIDFocused); | ||
|  | 		else if (nIDSelected > 0) | ||
|  | 			ShowPane(nIDSelected); | ||
|  | 	} | ||
|  | 	else if (pPane->GetType() == xtpPaneTypeDockingPane) | ||
|  | 	{ | ||
|  | 		CXTPDockingPaneTabbedContainer* pHolder = (CXTPDockingPaneTabbedContainer*)_GetHolder(pPane, bDocking); | ||
|  | 		_ToggleDocking((CXTPDockingPane*)pPane, pHolder); | ||
|  | 	} | ||
|  | 	else | ||
|  | 	{ | ||
|  | 		ASSERT(FALSE); | ||
|  | 	} | ||
|  | 
 | ||
|  | 
 | ||
|  | 	m_pLayout->_FreeEmptyPanes(); | ||
|  | 	m_hwndLastFocus = 0; | ||
|  | } | ||
|  | 
 | ||
|  | 
 | ||
|  | 
 | ||
|  | BOOL CXTPDockingPaneManager::_ToggleDocking(CXTPDockingPane* pPane, CXTPDockingPaneBase* pHolder) | ||
|  | { | ||
|  | 	BOOL bFloating = DYNAMIC_DOWNCAST(CXTPDockingPaneMiniWnd, pPane->GetDockingSite()) != NULL; | ||
|  | 	BOOL bHidden = pPane->IsHidden(); | ||
|  | 	BOOL bDocking = !bFloating && !bHidden; | ||
|  | 
 | ||
|  | 
 | ||
|  | 	if (bFloating && (pPane->GetOptions() & xtpPaneNoDockable)) | ||
|  | 		return FALSE; | ||
|  | 
 | ||
|  | 	if (bDocking && (pPane->GetOptions() & xtpPaneNoFloatable)) | ||
|  | 		return FALSE; | ||
|  | 
 | ||
|  | 	if (NotifyAction(bHidden ? xtpPaneActionPinning : !bDocking ? xtpPaneActionDocking : xtpPaneActionFloating, pPane, pHolder)) | ||
|  | 		return FALSE; | ||
|  | 
 | ||
|  | 	if (pHolder) | ||
|  | 	{ | ||
|  | 		m_bAttachingPane = TRUE; | ||
|  | 		AttachPane(pPane, pHolder); | ||
|  | 		m_bAttachingPane = FALSE; | ||
|  | 	} | ||
|  | 	else | ||
|  | 	{ | ||
|  | 		FloatPane(pPane, pPane->GetContainer()->GetPaneWindowRect()); | ||
|  | 	} | ||
|  | 
 | ||
|  | 	NotifyAction(bHidden ? xtpPaneActionPinned : !bDocking ? xtpPaneActionDocked : xtpPaneActionFloated, pPane); | ||
|  | 
 | ||
|  | 	return TRUE; | ||
|  | } | ||
|  | 
 | ||
|  | void CXTPDockingPaneManager::EnableKeyboardNavigate(DWORD options) | ||
|  | { | ||
|  | 	CXTPDockingPaneKeyboardHook::GetThreadState()->SetupKeyboardHook(this, options != xtpPaneKeyboardUnused); | ||
|  | 	m_bKeyboardEnabled = options; | ||
|  | } | ||
|  | 
 | ||
|  | bool CXTPDockingPaneManager::InstallDockingPanes(CWnd* pSite, bool bClipChildren/*=true*/) | ||
|  | { | ||
|  | #ifdef _DEBUG
 | ||
|  | 	// must be a valid frame window.
 | ||
|  | 	ASSERT(::IsWindow(pSite->GetSafeHwnd())); | ||
|  | 
 | ||
|  | 	// should not be initialized yet.
 | ||
|  | 	ASSERT(m_pLayout == 0); | ||
|  | 	ASSERT(m_pSite == 0); | ||
|  | #endif
 | ||
|  | 
 | ||
|  | 	if (!::IsWindow(pSite->GetSafeHwnd()) || m_pSite != 0) | ||
|  | 	{ | ||
|  | 		// if the docking site is not a valid frame window handle,
 | ||
|  | 		// or the docking site is already initialized, return false.
 | ||
|  | 		return false; | ||
|  | 	} | ||
|  | 
 | ||
|  | 	// Frame windows must have the WS_CLIPCHILDREN and WS_CLIPSIBLINGS
 | ||
|  | 	// styles for panes to be drawn correctly when they are displayed
 | ||
|  | 	// from a hidden state. WS_CLIPSIBLINGS should already be set by
 | ||
|  | 	// default for most frames, however we will include it here just
 | ||
|  | 	// in case.
 | ||
|  | 
 | ||
|  | 	if (bClipChildren /*&& DYNAMIC_DOWNCAST(CMDIFrameWnd, pSite) == 0*/) | ||
|  | 	{ | ||
|  | 		long lStyle = ::GetWindowLong(pSite->GetSafeHwnd(), GWL_STYLE); | ||
|  | 		if ((lStyle & WS_CLIPSIBLINGS) == 0 || (lStyle & WS_CLIPCHILDREN) == 0) | ||
|  | 		{ | ||
|  | 			::SetWindowLong(pSite->GetSafeHwnd(), GWL_STYLE, | ||
|  | 				lStyle | WS_CLIPCHILDREN | WS_CLIPSIBLINGS); | ||
|  | 		} | ||
|  | 	} | ||
|  | 
 | ||
|  | 	if (!Create(_T("XTPDockingPaneManager"), _T(""), WS_CHILD, CRect(0, 0, 0, 0), pSite, XTP_IDC_DOCKINGPANE)) | ||
|  | 		return false; | ||
|  | 
 | ||
|  | 	m_pSite = pSite; | ||
|  | 	m_pLayout = CreateLayout(); | ||
|  | 	m_pLayout->m_bUserLayout = FALSE; | ||
|  | 
 | ||
|  | 
 | ||
|  | 	CMenu* pMenu = m_pSite->GetSystemMenu(FALSE); | ||
|  | 	if (pMenu) | ||
|  | 	{ | ||
|  | 		pMenu->GetMenuString(SC_MOVE, m_strMove, MF_BYCOMMAND); | ||
|  | 		if (m_strMove.IsEmpty()) m_strMove = _T("&Move"); | ||
|  | 	} | ||
|  | 
 | ||
|  | 	return true; | ||
|  | } | ||
|  | void CXTPDockingPaneManager::HidePane(int nID) | ||
|  | { | ||
|  | 	HidePane(FindPane(nID)); | ||
|  | } | ||
|  | 
 | ||
|  | CXTPDockingPane* CXTPDockingPaneManager::FindPane(int nID) const | ||
|  | { | ||
|  | 	if (!m_pLayout) | ||
|  | 		return NULL; | ||
|  | 
 | ||
|  | 	return m_pLayout->FindPane(nID); | ||
|  | } | ||
|  | 
 | ||
|  | BOOL CXTPDockingPaneManager::SetIcons(UINT nIDResource, const int* nIDs, int nCount, COLORREF clrMask) | ||
|  | { | ||
|  | 	CImageList il; | ||
|  | 	il.Create(16, 16, ILC_COLOR24 | ILC_MASK, nCount, 1); | ||
|  | 
 | ||
|  | 	CBitmap bmp; | ||
|  | 	bmp.LoadBitmap(nIDResource); | ||
|  | 	il.Add(&bmp, clrMask); | ||
|  | 
 | ||
|  | 	ASSERT(il.GetImageCount() == nCount); // Icons must be 16x16.
 | ||
|  | 	if (il.GetImageCount() != nCount) | ||
|  | 		return FALSE; | ||
|  | 
 | ||
|  | 	for (int i = 0; i < nCount; i++) | ||
|  | 	{ | ||
|  | 		HICON hIcon = il.ExtractIcon(i); | ||
|  | 		if (nIDs[i] > 0) | ||
|  | 		{ | ||
|  | 			SetIcon(nIDs[i], hIcon); | ||
|  | 		} | ||
|  | 		DestroyIcon(hIcon); | ||
|  | 	} | ||
|  | 
 | ||
|  | 	return TRUE; | ||
|  | } | ||
|  | 
 | ||
|  | void CXTPDockingPaneManager::SetImageManager(CXTPImageManager* pImageManager) | ||
|  | { | ||
|  | 	if (pImageManager) | ||
|  | 	{ | ||
|  | 		m_pImageManager->InternalRelease(); | ||
|  | 
 | ||
|  | 		m_pImageManager = pImageManager; | ||
|  | 	} | ||
|  | } | ||
|  | 
 | ||
|  | void CXTPDockingPaneManager::ShowPane(CXTPDockingPane* pPane, BOOL bSetFocus /*= TRUE*/) | ||
|  | { | ||
|  | 	if (pPane == NULL || m_pLayout == NULL) return; | ||
|  | 
 | ||
|  | 	if (pPane->m_pParentContainer == NULL) | ||
|  | 	{ | ||
|  | 		POSITION pos = GetPaneList().GetHeadPosition(); | ||
|  | 		while (pos) | ||
|  | 		{ | ||
|  | 			XTP_DOCKINGPANE_INFO& info = GetPaneList().GetNext(pos); | ||
|  | 			if (info.pPane == pPane && info.pLastHolder != NULL) | ||
|  | 			{ | ||
|  | 				((CXTPDockingPaneTabbedContainer*)info.pLastHolder)->_InsertPane(pPane, bSetFocus); | ||
|  | 			} | ||
|  | 		} | ||
|  | 	} | ||
|  | 	else | ||
|  | 	{ | ||
|  | 		((CXTPDockingPaneTabbedContainer*)pPane->m_pParentContainer)->ShowPane(pPane, bSetFocus); | ||
|  | 	} | ||
|  | 
 | ||
|  | 	if (bSetFocus && m_bLayoutCreated) | ||
|  | 	{ | ||
|  | 		pPane->ShowWindow(TRUE); | ||
|  | 	} | ||
|  | 
 | ||
|  | 	if (bSetFocus) | ||
|  | 	{ | ||
|  | 		pPane->SetFocus(); | ||
|  | 	} | ||
|  | } | ||
|  | 
 | ||
|  | LRESULT CXTPDockingPaneManager::NotifyOwner(UINT nCode, LPARAM lParam) | ||
|  | { | ||
|  | 	CWnd* pOwner = m_hWndOwner != NULL ? GetOwner() : m_pSite; | ||
|  | 	ASSERT_VALID(pOwner); | ||
|  | 
 | ||
|  | 	return pOwner->SendMessage(XTPWM_DOCKINGPANE_NOTIFY, | ||
|  | 		(WPARAM)nCode, lParam); | ||
|  | } | ||
|  | 
 | ||
|  | void CXTPDockingPaneManager::ClosePane(CXTPDockingPane* pPane) | ||
|  | { | ||
|  | 	if (pPane == NULL) | ||
|  | 		return; | ||
|  | 
 | ||
|  | 	pPane->InternalAddRef(); | ||
|  | 
 | ||
|  | 	if (NotifyOwner(XTP_DPN_CLOSEPANE, (LPARAM)pPane) != XTP_ACTION_NOCLOSE) | ||
|  | 	{ | ||
|  | 		SAFE_CALLPTR(pPane->m_pParentContainer, RemovePane(pPane)); | ||
|  | 	} | ||
|  | 
 | ||
|  | 	pPane->InternalRelease(); | ||
|  | } | ||
|  | 
 | ||
|  | 
 | ||
|  | void CXTPDockingPaneManager::HidePane(CXTPDockingPaneBase* pPane) | ||
|  | { | ||
|  | 	if (pPane == NULL) return; | ||
|  | 
 | ||
|  | 	if (pPane->GetType() == xtpPaneTypeDockingPane && m_bHideGroupOnButtonClick) | ||
|  | 	{ | ||
|  | 		pPane = pPane->m_pParentContainer; | ||
|  | 	} | ||
|  | 
 | ||
|  | 	if (pPane == NULL || pPane->GetContainer() == NULL) | ||
|  | 		return; | ||
|  | 
 | ||
|  | 	if (pPane->GetContainer()->GetType() == xtpPaneTypeAutoHidePanel) | ||
|  | 	{ | ||
|  | 		((CXTPDockingPaneAutoHidePanel*)pPane->GetContainer())->CloseActiveWindow(); | ||
|  | 		return; | ||
|  | 	} | ||
|  | 
 | ||
|  | 	m_pLayout->HidePane(pPane); | ||
|  | 
 | ||
|  | 	RecalcFrameLayout(NULL, TRUE); | ||
|  | } | ||
|  | 
 | ||
|  | void CXTPDockingPaneManager::DestroyPane(CXTPDockingPane* pPane) | ||
|  | { | ||
|  | 	if (m_pLayout && pPane) | ||
|  | 	{ | ||
|  | 		m_pLayout->DestroyPane(pPane); | ||
|  | 		RecalcFrameLayout(NULL); | ||
|  | 	} | ||
|  | } | ||
|  | 
 | ||
|  | BOOL CXTPDockingPaneManager::IsPaneClosed(CXTPDockingPane* pPane) const | ||
|  | { | ||
|  | 	return pPane == NULL || pPane->IsClosed(); | ||
|  | } | ||
|  | 
 | ||
|  | BOOL CXTPDockingPaneManager::IsPaneHidden(CXTPDockingPane* pPane) const | ||
|  | { | ||
|  | 	return pPane != NULL && pPane->IsHidden(); | ||
|  | } | ||
|  | 
 | ||
|  | BOOL CXTPDockingPaneManager::IsPaneSelected(CXTPDockingPane* pPane) const | ||
|  | { | ||
|  | 	return pPane != NULL && pPane->IsSelected(); | ||
|  | } | ||
|  | 
 | ||
|  | void CXTPDockingPaneManager::_Redraw() | ||
|  | { | ||
|  | 	if (!m_hWnd) | ||
|  | 		return; | ||
|  | 
 | ||
|  | 	POSITION pos = GetPaneList().GetHeadPosition(); | ||
|  | 	while (pos) | ||
|  | 	{ | ||
|  | 		CXTPDockingPane* pPane = GetPaneList().GetNext(pos); | ||
|  | 		RecalcFrameLayout(pPane, TRUE); | ||
|  | 
 | ||
|  | 		CWnd* pFrame = pPane->GetDockingSite(); | ||
|  | 
 | ||
|  | 		if (DYNAMIC_DOWNCAST(CXTPDockingPaneMiniWnd, pFrame)) | ||
|  | 		{ | ||
|  | 			((CXTPDockingPaneMiniWnd*)pFrame)->OnThemedChanged(); | ||
|  | 		} | ||
|  | 
 | ||
|  | 		if (pPane->GetContainer()) | ||
|  | 		{ | ||
|  | 			pPane->GetContainer()->InvalidatePane(FALSE); | ||
|  | 		} | ||
|  | 	} | ||
|  | } | ||
|  | 
 | ||
|  | void CXTPDockingPaneManager::SyncActiveFloatingFrames(BOOL bSyncActiveFloatingFrames) | ||
|  | { | ||
|  | 	if (m_bSyncActiveFloatingFrames == bSyncActiveFloatingFrames) | ||
|  | 		return; | ||
|  | 
 | ||
|  | 	m_bSyncActiveFloatingFrames = bSyncActiveFloatingFrames; | ||
|  | 
 | ||
|  | 	POSITION pos = GetPaneStack().GetHeadPosition(); | ||
|  | 	while (pos) | ||
|  | 	{ | ||
|  | 		CXTPDockingPaneBase* pPane = GetPaneStack().GetNext(pos); | ||
|  | 		if (pPane->GetType() == xtpPaneTypeMiniWnd) | ||
|  | 		{ | ||
|  | 			CXTPDockingPaneMiniWnd* pFrame = (CXTPDockingPaneMiniWnd*)pPane; | ||
|  | 			if (pFrame->m_hWnd) | ||
|  | 			{ | ||
|  | 				pFrame->ModifyStyle(bSyncActiveFloatingFrames ? 0: MFS_SYNCACTIVE, bSyncActiveFloatingFrames ? MFS_SYNCACTIVE : SWP_FRAMECHANGED); | ||
|  | 			} | ||
|  | 		} | ||
|  | 	} | ||
|  | } | ||
|  | 
 | ||
|  | 
 | ||
|  | void CXTPDockingPaneManager::SetTheme(XTPDockingPanePaintTheme paintTheme) | ||
|  | { | ||
|  | 	if (m_pPaintManager != NULL) | ||
|  | 		m_pPaintManager->InternalRelease(); | ||
|  | 
 | ||
|  | 	switch (paintTheme) | ||
|  | 	{ | ||
|  | 	case xtpPaneThemeGrippered: m_pPaintManager = new CXTPDockingPaneGripperedTheme(); break; | ||
|  | 	case xtpPaneThemeWinNative: m_pPaintManager = new CXTPDockingPaneWinNativeTheme(); break; | ||
|  | 	case xtpPaneThemeWinExplorer: m_pPaintManager = new CXTPDockingPaneWinExplorerTheme(); break; | ||
|  | 	case xtpPaneThemeVisualStudio6: m_pPaintManager = new CXTPDockingPaneVisualStudio6Theme(); break; | ||
|  | 	case xtpPaneThemeVisualStudio2003: m_pPaintManager = new CXTPDockingPaneVisualStudio2003Theme(); break; | ||
|  | 	case xtpPaneThemeVisualStudio2005Beta1: m_pPaintManager = new CXTPDockingPaneVisualStudio2005Beta1Theme(); break; | ||
|  | 	case xtpPaneThemeVisualStudio2005Beta2: m_pPaintManager = new CXTPDockingPaneVisualStudio2005Beta2Theme(); break; | ||
|  | 	case xtpPaneThemeVisualStudio2005: m_pPaintManager = new CXTPDockingPaneVisualStudio2005Theme(); break; | ||
|  | 	case xtpPaneThemeVisualStudio2008: m_pPaintManager = new CXTPDockingPaneVisualStudio2008Theme(); break; | ||
|  | 	case xtpPaneThemeVisualStudio2010: m_pPaintManager = new CXTPDockingPaneVisualStudio2010Theme(); break; | ||
|  | 	case xtpPaneThemeOffice2002Visio: m_pPaintManager = new CXTPDockingPaneOffice2002VisioTheme(); break; | ||
|  | 	case xtpPaneThemeOffice2003: m_pPaintManager = new CXTPDockingPaneOffice2003Theme(); break; | ||
|  | 	case xtpPaneThemeOffice2003Visio: m_pPaintManager = new CXTPDockingPaneOffice2003VisioTheme(); break; | ||
|  | 	case xtpPaneThemeOffice2003Outlook: m_pPaintManager = new CXTPDockingPaneOffice2003OutlookTheme(); break; | ||
|  | 	case xtpPaneThemeResource: m_pPaintManager = new CXTPDockingPaneOffice2007Theme(); break; | ||
|  | 	case xtpPaneThemeOffice2007Visio: m_pPaintManager = new CXTPDockingPaneOffice2007VisioTheme(); break; | ||
|  | 	case xtpPaneThemeOffice2007Outlook: m_pPaintManager = new CXTPDockingPaneOffice2007OutlookTheme(); break; | ||
|  | 	case xtpPaneThemeOffice2007Word: m_pPaintManager = new CXTPDockingPaneOffice2007WordTheme(); break; | ||
|  | 	default: m_pPaintManager = new CXTPDockingPaneDefaultTheme(); break; | ||
|  | 	} | ||
|  | 
 | ||
|  | 	m_pPaintManager->m_themeCurrent = paintTheme; | ||
|  | 
 | ||
|  | 	if (paintTheme == xtpPaneThemeVisualStudio2010) | ||
|  | 		m_nDockingContextStickerStyle = xtpPaneStickerStyleVisualStudio2010; | ||
|  | 	else if (paintTheme == xtpPaneThemeVisualStudio2008) | ||
|  | 		m_nDockingContextStickerStyle = xtpPaneStickerStyleVisualStudio2008; | ||
|  | 	else | ||
|  | 		m_nDockingContextStickerStyle = xtpPaneStickerStyleVisualStudio2005; | ||
|  | 
 | ||
|  | 	m_pPaintManager->RefreshMetrics(); | ||
|  | 
 | ||
|  | 	_Redraw(); | ||
|  | } | ||
|  | 
 | ||
|  | void CXTPDockingPaneManager::SetCustomTheme(CXTPDockingPanePaintManager* pTheme) | ||
|  | { | ||
|  | 	ASSERT(pTheme); | ||
|  | 	if (!pTheme) | ||
|  | 		return; | ||
|  | 
 | ||
|  | 	if (m_pPaintManager != NULL) | ||
|  | 		m_pPaintManager->InternalRelease(); | ||
|  | 
 | ||
|  | 	m_pPaintManager = pTheme; | ||
|  | 	m_pPaintManager->m_themeCurrent = xtpPaneThemeCustom; | ||
|  | 	m_pPaintManager->RefreshMetrics(); | ||
|  | 
 | ||
|  | 	_Redraw(); | ||
|  | } | ||
|  | 
 | ||
|  | 
 | ||
|  | XTPDockingPanePaintTheme CXTPDockingPaneManager::GetCurrentTheme() const | ||
|  | { | ||
|  | 	return m_pPaintManager->m_themeCurrent; | ||
|  | } | ||
|  | 
 | ||
|  | CXTPDockingPaneLayout* CXTPDockingPaneManager::CreateLayout() | ||
|  | { | ||
|  | 	return new CXTPDockingPaneLayout(this); | ||
|  | } | ||
|  | 
 | ||
|  | 
 | ||
|  | void CXTPDockingPaneManager::GetLayout(CXTPDockingPaneLayout* pLayout) const | ||
|  | { | ||
|  | 	ASSERT(pLayout); | ||
|  | 	if (!pLayout) | ||
|  | 		return; | ||
|  | 
 | ||
|  | 	pLayout->Copy(m_pLayout); | ||
|  | } | ||
|  | 
 | ||
|  | void CXTPDockingPaneManager::_DetachAll() | ||
|  | { | ||
|  | 	POSITION pos = GetPaneList().GetHeadPosition(); | ||
|  | 	while (pos) | ||
|  | 	{ | ||
|  | 		CXTPDockingPane* pPane = GetPaneList().GetNext(pos); | ||
|  | 		pPane->Detach(); | ||
|  | 	} | ||
|  | } | ||
|  | 
 | ||
|  | void CXTPDockingPaneManager::SetLayout(const CXTPDockingPaneLayout* pLayout) | ||
|  | { | ||
|  | 	ASSERT(pLayout); | ||
|  | 
 | ||
|  | 	if (!pLayout || !pLayout->IsValid()) | ||
|  | 		return; | ||
|  | 
 | ||
|  | 	_DetachAll(); | ||
|  | 
 | ||
|  | 	m_pLayout->Copy(pLayout); | ||
|  | 	_Redraw(); | ||
|  | } | ||
|  | 
 | ||
|  | void CXTPDockingPaneManager::DestroyAll() | ||
|  | { | ||
|  | 	if (m_pLayout) | ||
|  | 	{ | ||
|  | 		m_pLayout->InternalRelease(); | ||
|  | 		m_pLayout = CreateLayout(); | ||
|  | 		m_pLayout->m_bUserLayout = FALSE; | ||
|  | 	} | ||
|  | } | ||
|  | void CXTPDockingPaneManager::CloseAll() | ||
|  | { | ||
|  | 	CXTPDockingPaneInfoList& paneList = GetPaneList(); | ||
|  | 	POSITION pos = paneList.GetHeadPosition(); | ||
|  | 	while (pos) | ||
|  | 	{ | ||
|  | 		CXTPDockingPane* pPane = paneList.GetNext(pos); | ||
|  | 		pPane->Close(); | ||
|  | 	} | ||
|  | } | ||
|  | 
 | ||
|  | 
 | ||
|  | CXTPDockingPaneBaseList& CXTPDockingPaneManager::GetPaneStack() const | ||
|  | { | ||
|  | 	return m_pLayout->m_lstStack; | ||
|  | } | ||
|  | 
 | ||
|  | CXTPDockingPaneInfoList& CXTPDockingPaneManager::GetPaneList() const | ||
|  | { | ||
|  | 	return m_pLayout->m_lstPanes; | ||
|  | } | ||
|  | 
 | ||
|  | CXTPDockingPaneBase* CXTPDockingPaneManager::GetClientPane() const | ||
|  | { | ||
|  | 	return m_pLayout ? m_pLayout->m_pClient : NULL; | ||
|  | } | ||
|  | 
 | ||
|  | CXTPDockingPaneBase* CXTPDockingPaneManager::GetTopPane() const | ||
|  | { | ||
|  | 	return m_pLayout ? m_pLayout->m_pTopContainer : NULL; | ||
|  | } | ||
|  | 
 | ||
|  | void CXTPDockingPaneManager::SetIcon(UINT nID, const CXTPImageManagerIconHandle& hIcon) | ||
|  | { | ||
|  | 	m_pImageManager->SetIcon(hIcon, nID, 0, xtpImageNormal); | ||
|  | } | ||
|  | 
 | ||
|  | CXTPImageManagerIcon* CXTPDockingPaneManager::GetIcon(UINT nID, int nWidth) const | ||
|  | { | ||
|  | 	return m_pImageManager->GetImage(nID, nWidth); | ||
|  | } | ||
|  | 
 | ||
|  | void CXTPDockingPaneManager::ClearIconMap() | ||
|  | { | ||
|  | 	m_pImageManager->RemoveAll(); | ||
|  | } | ||
|  | 
 | ||
|  | void CXTPDockingPaneManager::SetThemedFloatingFrames(BOOL bThemedFloatingFrames) | ||
|  | { | ||
|  | 	m_bThemedFloatingFrames = bThemedFloatingFrames; | ||
|  | 
 | ||
|  | 	if (!m_pLayout) | ||
|  | 		return; | ||
|  | 
 | ||
|  | 	POSITION pos = GetPaneList().GetHeadPosition(); | ||
|  | 	while (pos) | ||
|  | 	{ | ||
|  | 		CXTPDockingPane* pPane = GetPaneList().GetNext(pos); | ||
|  | 		CWnd* pFrame = pPane->GetDockingSite(); | ||
|  | 
 | ||
|  | 		if (DYNAMIC_DOWNCAST(CXTPDockingPaneMiniWnd, pFrame)) | ||
|  | 		{ | ||
|  | 			((CXTPDockingPaneMiniWnd*)pFrame)->OnThemedChanged(); | ||
|  | 		} | ||
|  | 	} | ||
|  | 
 | ||
|  | } | ||
|  | 
 | ||
|  | 
 | ||
|  | 
 | ||
|  | void CXTPDockingPaneManager::SetAnimationDelay(double dAnimationDelay /*= -1*/, int nAnimationDuration /*= 128*/, int nAnimationInterval /*= 16*/) | ||
|  | { | ||
|  | 	CXTPDockingPaneAutoHideWnd::m_dAnimationDelay = dAnimationDelay; | ||
|  | 	CXTPDockingPaneAutoHideWnd::m_nAnimationDuration = nAnimationDuration; | ||
|  | 	CXTPDockingPaneAutoHideWnd::m_nAnimationInterval = nAnimationInterval; | ||
|  | } | ||
|  | double CXTPDockingPaneManager::GetAnimationDelay(int* pAnimationDuration /*= NULL*/, int* pAnimationInterval /*= NULL*/) const | ||
|  | { | ||
|  | 	if (pAnimationDuration) *pAnimationDuration = CXTPDockingPaneAutoHideWnd::m_nAnimationDuration; | ||
|  | 	if (pAnimationInterval) *pAnimationInterval = CXTPDockingPaneAutoHideWnd::m_nAnimationInterval; | ||
|  | 
 | ||
|  | 	return CXTPDockingPaneAutoHideWnd::m_dAnimationDelay; | ||
|  | } | ||
|  | 
 | ||
|  | BOOL CXTPDockingPaneManager::IsLayoutRTL() const | ||
|  | { | ||
|  | 	return (GetSite()->GetExStyle() & WS_EX_LAYOUTRTL) != 0; | ||
|  | } | ||
|  | 
 | ||
|  | XTPDockingPaneDirection CXTPDockingPaneManager::GetRTLDirection(XTPDockingPaneDirection direction) const | ||
|  | { | ||
|  | 	if (IsLayoutRTL()) | ||
|  | 	{ | ||
|  | 		if (direction == xtpPaneDockLeft) direction = xtpPaneDockRight; | ||
|  | 		else if (direction == xtpPaneDockRight) direction = xtpPaneDockLeft; | ||
|  | 	} | ||
|  | 	return direction; | ||
|  | } | ||
|  | 
 | ||
|  | XTPDockingPaneDirection CXTPDockingPaneManager::GetPaneDirection(const CXTPDockingPaneBase* pPane) const | ||
|  | { | ||
|  | 	ASSERT(m_pLayout); | ||
|  | 	if (!m_pLayout) | ||
|  | 		return xtpPaneDockTop; | ||
|  | 
 | ||
|  | 	return m_pLayout->_GetPaneDirection(pPane); | ||
|  | } | ||
|  | 
 | ||
|  | void CXTPDockingPaneManager::SetDockingContext(CXTPDockingPaneContext* pDockingContext) | ||
|  | { | ||
|  | 	delete m_pDockingContext; | ||
|  | 	m_pDockingContext = pDockingContext; | ||
|  | 	m_pDockingContext->m_pManager = this; | ||
|  | } | ||
|  | 
 | ||
|  | 
 | ||
|  | 
 | ||
|  | void CXTPDockingPaneManager::NormalizeSplitters() | ||
|  | { | ||
|  | 	CXTPDockingPaneBaseList& lst = GetPaneStack(); | ||
|  | 	POSITION pos = lst.GetHeadPosition(); | ||
|  | 
 | ||
|  | 	while (pos) | ||
|  | 	{ | ||
|  | 		CXTPDockingPaneBase* pPane = lst.GetNext(pos); | ||
|  | 
 | ||
|  | 		if (pPane->GetType() == xtpPaneTypeSplitterContainer) | ||
|  | 		{ | ||
|  | 			((CXTPDockingPaneSplitterContainer*)pPane)->NormalizeDockingSize(); | ||
|  | 		} | ||
|  | 	} | ||
|  | } | ||
|  | 
 | ||
|  | void CXTPDockingPaneManager::RecalcFramesLayout() | ||
|  | { | ||
|  | 	CXTPDockingPaneBaseList& lst = GetPaneStack(); | ||
|  | 	POSITION pos = lst.GetHeadPosition(); | ||
|  | 
 | ||
|  | 	while (pos) | ||
|  | 	{ | ||
|  | 		CXTPDockingPaneBase* pPane = lst.GetNext(pos); | ||
|  | 
 | ||
|  | 		if (pPane->GetType() == xtpPaneTypeMiniWnd) | ||
|  | 		{ | ||
|  | 			CXTPDockingPaneMiniWnd* pMiniWnd = (CXTPDockingPaneMiniWnd*)pPane; | ||
|  | 
 | ||
|  | 			if (pMiniWnd->m_hWnd && pMiniWnd->GetStyle() & WS_VISIBLE) | ||
|  | 			{ | ||
|  | 				pMiniWnd->RecalcLayout(TRUE); | ||
|  | 				pMiniWnd->MoveWindow(CXTPWindowRect(pMiniWnd)); | ||
|  | 			} | ||
|  | 		} | ||
|  | 	} | ||
|  | 	RecalcFrameLayout(NULL); | ||
|  | } | ||
|  | 
 | ||
|  | void CXTPDockingPaneManager::EnsureVisible(CXTPDockingPaneBase* pPane) | ||
|  | { | ||
|  | 	if (!pPane) | ||
|  | 		return; | ||
|  | 
 | ||
|  | 	if (pPane->GetType() == xtpPaneTypeDockingPane) | ||
|  | 	{ | ||
|  | 		ShowPane((CXTPDockingPane*)pPane, FALSE); | ||
|  | 		pPane = pPane->GetContainer(); | ||
|  | 	} | ||
|  | 
 | ||
|  | 	if (pPane->GetType() == xtpPaneTypeTabbedContainer) | ||
|  | 	{ | ||
|  | 		((CXTPDockingPaneTabbedContainer*)pPane)->Show(FALSE); | ||
|  | 	} | ||
|  | 
 | ||
|  | 	CWnd* pSite = pPane->GetDockingSite(); | ||
|  | 	if (DYNAMIC_DOWNCAST(CXTPDockingPaneMiniWnd, pSite)) | ||
|  | 	{ | ||
|  | 		pSite->BringWindowToTop(); | ||
|  | 	} | ||
|  | } | ||
|  | 
 | ||
|  | void CXTPDockingPaneManager::OnSetPreviewMode(BOOL bPreview) | ||
|  | { | ||
|  | 
 | ||
|  | // Toggle Docking Panes.
 | ||
|  | 	if (bPreview) | ||
|  | 	{ | ||
|  | 		ASSERT(m_pPreviewLayout == NULL); | ||
|  | 		m_pPreviewLayout = CreateLayout(); | ||
|  | 		GetLayout(m_pPreviewLayout); | ||
|  | 		CloseAll(); | ||
|  | 	} | ||
|  | 	else | ||
|  | 	{ | ||
|  | 		ASSERT(m_pPreviewLayout != NULL); | ||
|  | 		SetLayout(m_pPreviewLayout); | ||
|  | 
 | ||
|  | 		CMDTARGET_RELEASE(m_pPreviewLayout); | ||
|  | 	} | ||
|  | } | ||
|  | 
 | ||
|  | void CXTPDockingPaneManager::OnActivatePane(BOOL bActive, CXTPDockingPane* pPane) | ||
|  | { | ||
|  | 	if (bActive && m_pActivePane != pPane) | ||
|  | 	{ | ||
|  | 		if (m_pActivePane) | ||
|  | 		{ | ||
|  | 			NotifyAction(xtpPaneActionDeactivated, m_pActivePane); | ||
|  | 			m_pActivePane->InternalRelease(); | ||
|  | 		} | ||
|  | 
 | ||
|  | 		m_pActivePane = pPane; | ||
|  | 
 | ||
|  | 		if (m_pActivePane) | ||
|  | 		{ | ||
|  | 			m_pActivePane->InternalAddRef(); | ||
|  | 			NotifyAction(xtpPaneActionActivated, m_pActivePane); | ||
|  | 		} | ||
|  | 	} | ||
|  | 	else if (!bActive && pPane && m_pActivePane == pPane) | ||
|  | 	{ | ||
|  | 		m_pActivePane = 0; | ||
|  | 		NotifyAction(xtpPaneActionDeactivated, pPane); | ||
|  | 
 | ||
|  | 		pPane->InternalRelease(); | ||
|  | 	} | ||
|  | } | ||
|  | 
 | ||
|  | BOOL CXTPDockingPaneManager::DoPropExchange(CXTPPropExchange* pPX) | ||
|  | { | ||
|  | 	if (pPX->IsStoring()) | ||
|  | 	{ | ||
|  | 		CXTPDockingPaneLayout layoutNormal(this); | ||
|  | 		GetLayout(&layoutNormal); | ||
|  | 		layoutNormal.DoPropExchange(pPX); | ||
|  | 	} | ||
|  | 	else | ||
|  | 	{ | ||
|  | 		CXTPDockingPaneLayout layoutNormal(this); | ||
|  | 		if (!layoutNormal.DoPropExchange(pPX)) | ||
|  | 			return FALSE; | ||
|  | 		SetLayout(&layoutNormal); | ||
|  | 	} | ||
|  | 	return TRUE; | ||
|  | } | ||
|  | 
 | ||
|  | void CXTPDockingPaneManager::RecalcFrameLayout(CXTPDockingPaneBase* pPane, BOOL bDelay) | ||
|  | { | ||
|  | 	CWnd* pSite = pPane ? pPane->GetDockingSite() : GetSite(); | ||
|  | 	if (!pSite || !IsWindow(pSite->GetSafeHwnd())) | ||
|  | 		return; | ||
|  | 
 | ||
|  | 	CFrameWnd* pFrame = pSite->IsFrameWnd() ? (CFrameWnd*)pSite : NULL; | ||
|  | 
 | ||
|  | 	if (pFrame) | ||
|  | 	{ | ||
|  | 		if (bDelay) | ||
|  | 		{ | ||
|  | 			pFrame->DelayRecalcLayout(FALSE); | ||
|  | 			pFrame->PostMessage(WM_IDLEUPDATECMDUI); | ||
|  | 		} | ||
|  | 		else | ||
|  | 			pFrame->RecalcLayout(FALSE); | ||
|  | 	} | ||
|  | 	else | ||
|  | 	{ | ||
|  | 		CXTPClientRect rc(pSite); | ||
|  | 		if (bDelay) | ||
|  | 		{ | ||
|  | 			MSG msg; | ||
|  | 			if (PeekMessage(&msg, pSite->GetSafeHwnd(), WM_SIZE, WM_SIZE, PM_NOREMOVE)) | ||
|  | 				return; | ||
|  | 
 | ||
|  | 			pSite->PostMessage(WM_SIZE, 0, MAKELPARAM(rc.Width(), rc.Height())); | ||
|  | 		} | ||
|  | 		else | ||
|  | 			pSite->SendMessage(WM_SIZE, 0, MAKELPARAM(rc.Width(), rc.Height())); | ||
|  | 	} | ||
|  | } | ||
|  | 
 | ||
|  | void CXTPDockingPaneManager::_TrackPopupContextMenu(CXTPDockingPane* pPane) | ||
|  | { | ||
|  | 	CPoint pt(0, 0); | ||
|  | 	CXTPDockingPaneBase* pContainer = pPane->GetContainer(); | ||
|  | 
 | ||
|  | 	if (pPane->IsFloating()) | ||
|  | 	{ | ||
|  | 		pPane->GetDockingSite()->ClientToScreen(&pt); | ||
|  | 		pContainer = ((CXTPDockingPaneMiniWnd*)pPane->GetDockingSite())->GetTopPane(); | ||
|  | 	} | ||
|  | 	else | ||
|  | 	{ | ||
|  | 		CRect rc = pContainer->GetPaneWindowRect(); | ||
|  | 		GetPaintManager()->AdjustCaptionRect((CXTPDockingPaneTabbedContainer*)pContainer, rc); | ||
|  | 		pt = rc.TopLeft(); | ||
|  | 	} | ||
|  | 
 | ||
|  | 	CMenu menu; | ||
|  | 	menu.CreatePopupMenu(); | ||
|  | 	menu.InsertMenu(0, MF_BYPOSITION | MF_STRING, SC_MOVE, m_strMove); | ||
|  | 
 | ||
|  | 	BOOL nCommand = TrackPopupMenu(menu, TPM_RETURNCMD, pt.x, pt.y, 0, GetSite()->GetSafeHwnd(), NULL); | ||
|  | 
 | ||
|  | 	if (nCommand == SC_MOVE) | ||
|  | 	{ | ||
|  | 		CXTPDockingPaneContext* pContext = GetDockingContext(); | ||
|  | 		pContext->Drag(pContainer, CPoint(-1, -1)); | ||
|  | 	} | ||
|  | } | ||
|  | 
 | ||
|  | BOOL CXTPDockingPaneManager::ActivateNextPane(CXTPDockingPane* pPaneActive, BOOL bForward) | ||
|  | { | ||
|  | 	if (!m_pLayout) | ||
|  | 		return FALSE; | ||
|  | 
 | ||
|  | 	CXTPDockingPaneInfoList& paneList = m_pLayout->GetPaneList(); | ||
|  | 	if (paneList.IsEmpty()) | ||
|  | 		return FALSE; | ||
|  | 
 | ||
|  | 	BOOL bActive = (pPaneActive != NULL); | ||
|  | 
 | ||
|  | 	POSITION posFirst = bForward ? paneList.GetHeadPosition() : paneList.GetTailPosition(); | ||
|  | 	POSITION pos = posFirst; | ||
|  | 
 | ||
|  | 	while (pos) | ||
|  | 	{ | ||
|  | 		CXTPDockingPane* pPane = bForward ? paneList.GetNext(pos) : paneList.GetPrev(pos); | ||
|  | 
 | ||
|  | 		if (pos == NULL && bActive) | ||
|  | 		{ | ||
|  | 			pos = posFirst; | ||
|  | 			bActive = FALSE; | ||
|  | 		} | ||
|  | 
 | ||
|  | 		if (!pPaneActive) | ||
|  | 		{ | ||
|  | 			if ((pPane->GetEnabled() & xtpPaneEnableClient) == 0) | ||
|  | 				continue; | ||
|  | 
 | ||
|  | 			ShowPane(pPane); | ||
|  | 			return TRUE; | ||
|  | 		} | ||
|  | 		else if (pPane == pPaneActive) | ||
|  | 		{ | ||
|  | 			pPaneActive = NULL; | ||
|  | 		} | ||
|  | 	} | ||
|  | 	return FALSE; | ||
|  | } | ||
|  | 
 | ||
|  | BOOL CXTPDockingPaneManager::OnWndMsg(UINT message, WPARAM wParam, LPARAM lParam, LRESULT* pResult) | ||
|  | { | ||
|  | 	if (message == WM_DESTROY && m_bKeyboardEnabled) | ||
|  | 	{ | ||
|  | 		m_bKeyboardEnabled = FALSE; | ||
|  | 		CXTPDockingPaneKeyboardHook::GetThreadState()->SetupKeyboardHook(this, FALSE); | ||
|  | 	} | ||
|  | 
 | ||
|  | 	if (message == WM_SYSCOMMAND && wParam == SC_KEYMENU && LOWORD(lParam) == TEXT('-')) | ||
|  | 	{ | ||
|  | 		CXTPDockingPane* pPane = GetActivePane(); | ||
|  | 		if (pPane && !pPane->IsClosed() && !pPane->IsHidden()) | ||
|  | 		{ | ||
|  | 			_TrackPopupContextMenu(pPane); | ||
|  | 			return TRUE; | ||
|  | 		} | ||
|  | 	} | ||
|  | 
 | ||
|  | 	if (message == WM_SYSCOMMAND && (wParam == SC_NEXTWINDOW || wParam == SC_PREVWINDOW)) | ||
|  | 	{ | ||
|  | 		return ActivateNextPane(GetActivePane(), wParam == SC_NEXTWINDOW); | ||
|  | 	} | ||
|  | 
 | ||
|  | 	return CWnd::OnWndMsg(message, wParam, lParam, pResult); | ||
|  | } | ||
|  | 
 | ||
|  | 
 | ||
|  | //////////////////////////////////////////////////////////////////////////
 | ||
|  | // Accessible
 | ||
|  | 
 | ||
|  | CCmdTarget* CXTPDockingPaneManager::GetAccessible() | ||
|  | { | ||
|  | 	return this; | ||
|  | } | ||
|  | 
 | ||
|  | HRESULT CXTPDockingPaneManager::GetAccessibleParent(IDispatch* FAR* ppdispParent) | ||
|  | { | ||
|  | 	if (GetSafeHwnd()) | ||
|  | 	{ | ||
|  | 		return AccessibleObjectFromWindow(GetSafeHwnd(), OBJID_WINDOW, IID_IDispatch, (void**)ppdispParent); | ||
|  | 	} | ||
|  | 	return E_FAIL; | ||
|  | } | ||
|  | 
 | ||
|  | HRESULT CXTPDockingPaneManager::GetAccessibleChildCount(long FAR* pChildCount) | ||
|  | { | ||
|  | 	if (pChildCount == 0) | ||
|  | 		return E_INVALIDARG; | ||
|  | 
 | ||
|  | 	*pChildCount = (long)m_pLayout->GetPaneList().GetCount(); | ||
|  | 
 | ||
|  | 	return S_OK; | ||
|  | } | ||
|  | 
 | ||
|  | HRESULT CXTPDockingPaneManager::GetAccessibleChild(VARIANT varChild, IDispatch* FAR* ppdispChild) | ||
|  | { | ||
|  | 	*ppdispChild = NULL; | ||
|  | 	int nChild = GetChildIndex(&varChild); | ||
|  | 
 | ||
|  | 	if (nChild > 0 && nChild <= m_pLayout->GetPaneList().GetCount()) | ||
|  | 	{ | ||
|  | 		CXTPDockingPane* pPane = m_pLayout->GetPaneList().GetAt(m_pLayout->GetPaneList().FindIndex(nChild - 1)); | ||
|  | 		if (pPane) | ||
|  | 		{ | ||
|  | 			*ppdispChild = pPane->GetIDispatch(TRUE); | ||
|  | 		} | ||
|  | 	} | ||
|  | 
 | ||
|  | 	return S_OK; | ||
|  | } | ||
|  | 
 | ||
|  | HRESULT CXTPDockingPaneManager::GetAccessibleName(VARIANT varChild, BSTR* pszName) | ||
|  | { | ||
|  | 	int nChild = GetChildIndex(&varChild); | ||
|  | 
 | ||
|  | 	if (nChild == CHILDID_SELF || nChild == -1) | ||
|  | 	{ | ||
|  | 		*pszName = SysAllocString(L"XTPDockingPaneManager"); | ||
|  | 		return S_OK; | ||
|  | 	} | ||
|  | 
 | ||
|  | 	return E_INVALIDARG; | ||
|  | } | ||
|  | 
 | ||
|  | HRESULT CXTPDockingPaneManager::GetAccessibleRole(VARIANT varChild, VARIANT* pvarRole) | ||
|  | { | ||
|  | 	pvarRole->vt = VT_EMPTY; | ||
|  | 	int nChild = GetChildIndex(&varChild); | ||
|  | 
 | ||
|  | 	if (nChild == CHILDID_SELF) | ||
|  | 	{ | ||
|  | 		pvarRole->vt = VT_I4; | ||
|  | 		pvarRole->lVal = ROLE_SYSTEM_PROPERTYPAGE; | ||
|  | 		return S_OK; | ||
|  | 	} | ||
|  | 
 | ||
|  | 	return E_INVALIDARG; | ||
|  | } | ||
|  | 
 | ||
|  | HRESULT CXTPDockingPaneManager::GetAccessibleState(VARIANT varChild, VARIANT* pvarState) | ||
|  | { | ||
|  | 	int nChild = GetChildIndex(&varChild); | ||
|  | 
 | ||
|  | 	if (nChild == CHILDID_SELF || nChild == -1) | ||
|  | 	{ | ||
|  | 		pvarState->vt = VT_I4; | ||
|  | 		pvarState->lVal = 0; | ||
|  | 		return S_OK; | ||
|  | 	} | ||
|  | 
 | ||
|  | 	return E_INVALIDARG; | ||
|  | 
 | ||
|  | } | ||
|  | 
 | ||
|  | 
 | ||
|  | HRESULT CXTPDockingPaneManager::AccessibleLocation(long* pxLeft, long* pyTop, long* pcxWidth, long* pcyHeight, VARIANT /*varChild*/) | ||
|  | { | ||
|  | 	*pxLeft = *pyTop = 0; | ||
|  | 	*pcxWidth = *pcyHeight = 10; | ||
|  | 
 | ||
|  | 	return S_OK; | ||
|  | } | ||
|  | 
 | ||
|  | HRESULT CXTPDockingPaneManager::AccessibleHitTest(long /*xLeft*/, long /*yTop*/, VARIANT* /*pvarID*/) | ||
|  | { | ||
|  | 	return S_FALSE; | ||
|  | } | ||
|  | 
 | ||
|  | 
 | ||
|  | LRESULT CXTPDockingPaneManager::OnGetObject(WPARAM wParam, LPARAM lParam) | ||
|  | { | ||
|  | 	if (((LONG)lParam) != OBJID_CLIENT) | ||
|  | 		return (LRESULT)Default(); | ||
|  | 
 | ||
|  | 	LPUNKNOWN lpUnknown = GetInterface(&IID_IAccessible); | ||
|  | 	if (!lpUnknown) | ||
|  | 		return E_FAIL; | ||
|  | 
 | ||
|  | 	return LresultFromObject(IID_IAccessible, wParam, lpUnknown); | ||
|  | } | ||
|  | 
 | ||
|  | BEGIN_INTERFACE_MAP(CXTPDockingPaneManager, CCmdTarget) | ||
|  | 	INTERFACE_PART(CXTPDockingPaneManager, IID_IAccessible, ExternalAccessible) | ||
|  | END_INTERFACE_MAP() |