// 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()