// XTPDockingPane.cpp : implementation of the CXTPDockingPaneclass. // // 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/XTPSystemHelpers.h" #include "TabManager/XTPTabManager.h" #include "TabManager/XTPTabPaintManager.h" #include "XTPDockingPaneDefines.h" #include "XTPDockingPaneBase.h" #include "XTPDockingPaneBaseContainer.h" #include "XTPDockingPane.h" #include "XTPDockingPaneManager.h" #include "XTPDockingPaneTabbedContainer.h" #include "XTPDockingPaneMiniWnd.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif CXTPDockingPane::CXTPDockingPane(CXTPDockingPaneLayout* pLayout) : CXTPDockingPaneBase(xtpPaneTypeDockingPane, pLayout) { m_dwOptions = 0; m_hwndChild = 0; m_nID = 0; m_nIconID = -1; m_dwData = 0; m_clrItemTab = COLORREF_NULL; m_nIDHelp = 0; m_bEnabled = xtpPaneEnabledAuto; m_ptMinTrackSize = CPoint(0, 0); m_ptMaxTrackSize = CPoint(32000, 32000); EnableAutomation(); } CXTPDockingPane::~CXTPDockingPane() { } void CXTPDockingPane::SetID(int nID) { ASSERT(nID != 0); m_nID = nID; CString strTitle; if (strTitle.LoadString(nID)) { SetTitle(strTitle); } } void CXTPDockingPane::SetWindowRect(CRect rc) { m_rcWindow = rc; m_szDocking = m_rcWindow.Size(); } XTPDockingPaneEnableOptions CXTPDockingPane::GetEnabled() const { if (m_bEnabled == xtpPaneEnabledAuto) { return xtpPaneEnabled; } return m_bEnabled; } void CXTPDockingPane::SetEnabled(XTPDockingPaneEnableOptions bEnabled) { if (m_bEnabled != bEnabled) { m_bEnabled = bEnabled; InvalidatePane(TRUE); } } void CXTPDockingPane::OnSizeParent(CWnd* pParent, CRect rect, LPVOID lParam) { AFX_SIZEPARENTPARAMS* lpLayout = (AFX_SIZEPARENTPARAMS*)lParam; SetDockingSite(pParent); if (lpLayout == 0 || lpLayout->hDWP != NULL) { m_rcWindow = rect; BOOL bVisible = !rect.IsRectEmpty(); ShowWindow(bVisible); if (m_hwndChild && pParent && m_pParentContainer && bVisible) { MapWindowPoints(pParent->GetSafeHwnd(), m_pParentContainer->GetPaneHwnd(), (LPPOINT)&rect, 2); ::MoveWindow(m_hwndChild, rect.left, rect.top, rect.Width(), rect.Height(), TRUE); if (m_bEnabled != xtpPaneEnabledAuto) { ::EnableWindow(m_hwndChild, m_bEnabled & xtpPaneEnableClient ? TRUE : FALSE); } } } } void CXTPDockingPane::SetFocus() { if (m_hwndChild) { if (!IsChild(m_hwndChild, ::GetFocus())) ::SetFocus(m_hwndChild); } } BOOL CXTPDockingPane::IsFocus() const { HWND hwndFocus = ::GetFocus(); return (m_hwndChild != 0) && (hwndFocus == m_hwndChild || IsChild(m_hwndChild, hwndFocus)); } void CXTPDockingPane::SetParentContainer(CXTPDockingPaneBase* pContainer) { m_pParentContainer = pContainer; if (m_hwndChild == 0) return; if (pContainer) { ASSERT(pContainer->GetType() == xtpPaneTypeTabbedContainer); ::SetParent(m_hwndChild, pContainer->GetPaneHwnd()); } else { ::ShowWindow(m_hwndChild, SW_HIDE); ::SetParent(m_hwndChild, GetDockingPaneManager()->GetSafeHwnd()); m_pDockingSite = NULL; } } void CXTPDockingPane::ShowWindow(BOOL bShow) { if (bShow) { GetDockingPaneManager()->NotifyOwner(XTP_DPN_SHOWWINDOW, (LPARAM)this); } if (m_hwndChild) { ::ShowWindow(m_hwndChild, bShow ? SW_SHOW : SW_HIDE); } } void CXTPDockingPane::Close() { GetDockingPaneManager()->ClosePane(this); } void CXTPDockingPane::Hide() { GetDockingPaneManager()->HidePane(this); } void CXTPDockingPane::Select() { GetDockingPaneManager()->ShowPane(this); } CWnd* CXTPDockingPane::GetDockingSite() const { return m_pParentContainer ? m_pParentContainer->m_pDockingSite : 0; } CFrameWnd* CXTPDockingPane::GetParentFrame() const { CWnd* pSite = GetDockingSite(); return pSite && pSite->IsFrameWnd() ? (CFrameWnd*)pSite : NULL; } void CXTPDockingPane::Copy(CXTPDockingPaneBase* pCloneBase, CXTPPaneToPaneMap* /*pMap*/, DWORD /*dwIgnoredOptions*/) { Copy((CXTPDockingPane*)pCloneBase); } void CXTPDockingPane::Copy(CXTPDockingPane* pClone) { m_szDocking = pClone->m_szDocking; m_strTitle = pClone->m_strTitle; m_strTabCaption = pClone->m_strTabCaption; m_strTitleToolTip = pClone->m_strTitleToolTip; m_nIconID = pClone->m_nIconID; m_dwOptions = pClone->m_dwOptions; m_dwData = pClone->m_dwData; m_nID = pClone->m_nID; m_bEnabled = pClone->m_bEnabled; m_ptMinTrackSize = pClone->m_ptMinTrackSize; m_ptMaxTrackSize = pClone->m_ptMaxTrackSize; m_hwndChild = 0; } BOOL CXTPDockingPane::IsValid() const { return m_hwndChild != NULL; } void CXTPDockingPane::Attach(CWnd* pWnd) { if (pWnd) { CXTPDockingPaneManager* pManager = GetDockingPaneManager(); m_hwndChild = pWnd->GetSafeHwnd(); pManager->_Redraw(); if (m_pParentContainer) { ::SetParent(m_hwndChild, m_pParentContainer->GetPaneHwnd()); } if (pManager->m_bInitialUpdateCalled && pManager->m_bAutoInitialUpdate) { pWnd->SendMessage(WM_INITIALUPDATE, 0, 0); pWnd->SendMessageToDescendants(WM_INITIALUPDATE, 0, 0, TRUE, TRUE); } } } CWnd* CXTPDockingPane::AttachView(CWnd* pParentWnd, CRuntimeClass* pViewClass, CDocument* pDocument/*= NULL*/, CCreateContext* pContext/*= NULL*/) { if (!pContext && !pViewClass) return NULL; #ifdef _DEBUG ASSERT(pContext != NULL || pViewClass != NULL); ASSERT(pContext != NULL || pViewClass->IsDerivedFrom(RUNTIME_CLASS(CWnd))); ASSERT(pContext != NULL || AfxIsValidAddress(pViewClass, sizeof(CRuntimeClass), FALSE)); #endif CCreateContext contextT; if (pContext == NULL) { // if no context specified, generate one from the // currently selected client if possible. contextT.m_pLastView = NULL; contextT.m_pCurrentFrame = NULL; contextT.m_pNewDocTemplate = NULL; contextT.m_pCurrentDoc = pDocument; contextT.m_pNewViewClass = pViewClass; if (pDocument != NULL) contextT.m_pNewDocTemplate = pDocument->GetDocTemplate(); pContext = &contextT; } CFrameWnd* pFrame = new CFrameWnd; if (!pFrame->Create(NULL, NULL, WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, CRect(0, 0, 0, 0), pParentWnd, NULL, 0, pContext)) { delete pFrame; return NULL; } pFrame->ModifyStyleEx(WS_EX_CLIENTEDGE, 0); Attach(pFrame); CWnd* pView = pFrame->GetDescendantWindow(AFX_IDW_PANE_FIRST, TRUE); if (DYNAMIC_DOWNCAST(CView, pView)) { pFrame->SetActiveView((CView*)pView); } return pView; } void CXTPDockingPane::Detach() { if (m_hwndChild) { ::ShowWindow(m_hwndChild, SW_HIDE); ::SetParent(m_hwndChild, GetDockingPaneManager()->GetSite()->GetSafeHwnd()); m_hwndChild = 0; } GetDockingPaneManager()->_Redraw(); } CString CXTPDockingPane::GetTitle() const { return m_strTitle; } void CXTPDockingPane::SetTitleToolTip(LPCTSTR lpszTitleToolTip) { m_strTitleToolTip = lpszTitleToolTip; } CString CXTPDockingPane::GetTitleToolTip() const { return m_strTitleToolTip; } void CXTPDockingPane::SetTabCaption(LPCTSTR lpszTabCaption) { CString strTabCaption(lpszTabCaption); if (m_strTabCaption != strTabCaption) { m_strTabCaption = strTabCaption; InvalidatePane(FALSE); } } CString CXTPDockingPane::GetTabCaption() const { if (m_strTabCaption.IsEmpty()) return m_strTitle; return m_strTabCaption; } void CXTPDockingPane::SetTitle(LPCTSTR lpszTitle) { CString strTitle = lpszTitle; if (m_strTitle != strTitle) { int nIndex = strTitle.Find('\n'); if (nIndex != -1) { AfxExtractSubString(m_strTitle, strTitle, 0, '\n'); AfxExtractSubString(m_strTabCaption, strTitle, 1, '\n'); } else { m_strTitle = strTitle; } InvalidatePane(FALSE); } } BOOL CXTPDockingPane::IsClosed() const { return m_pParentContainer == NULL; } BOOL CXTPDockingPane::IsHidden() const { if (m_pParentContainer == NULL) return FALSE; return m_pParentContainer->IsHidden(); } BOOL CXTPDockingPane::IsSelected() const { if (m_pParentContainer == NULL) return FALSE; ASSERT(m_pParentContainer->GetType() == xtpPaneTypeTabbedContainer); return ((CXTPDockingPaneTabbedContainer*)m_pParentContainer)->GetSelected() == this; } BOOL CXTPDockingPane::IsFloating() const { if (m_pParentContainer == NULL) return FALSE; if (IsHidden()) return FALSE; ASSERT(m_pParentContainer->GetType() == xtpPaneTypeTabbedContainer); if (m_pParentContainer->GetPaneHwnd() == 0) return FALSE; CWnd* pFrame = m_pParentContainer->GetDockingSite(); return pFrame && pFrame->IsKindOf(RUNTIME_CLASS(CXTPDockingPaneMiniWnd)); } CXTPImageManagerIcon* CXTPDockingPane::GetIcon(int nWidth) const { return GetDockingPaneManager()->GetIcon(GetIconID(), nWidth); } void CXTPDockingPane::SetItemColor(COLORREF clr) { m_clrItemTab = clr; InvalidatePane(FALSE); } COLORREF CXTPDockingPane::GetItemColor() const { if (m_clrItemTab != COLORREF_NULL) return m_clrItemTab; if (m_hwndChild) { COLORREF clr = (COLORREF)::SendMessage(m_hwndChild, WM_XTP_GETTABCOLOR, 0, 0); if (clr != 0) return clr; } return xtpTabColorBlue + GetID() % 8; } void CXTPDockingPane::GetMinMaxInfo(LPMINMAXINFO pMinMaxInfo) const { ZeroMemory(pMinMaxInfo, sizeof(MINMAXINFO)); pMinMaxInfo->ptMinTrackSize = m_ptMinTrackSize; pMinMaxInfo->ptMaxTrackSize = m_ptMaxTrackSize; } DWORD CXTPDockingPane::GetOptions() const { return GetDockingPaneManager()->m_dwDefaultPaneOptions | m_dwOptions; } void CXTPDockingPane::DeletePane() { InternalRelease(); } ////////////////////////////////////////////////////////////////////////// // Accessible CCmdTarget* CXTPDockingPane::GetAccessible() { return this; } HRESULT CXTPDockingPane::GetAccessibleParent(IDispatch* FAR* ppdispParent) { SAFE_MANAGE_STATE(m_pModuleState); *ppdispParent = NULL; if (m_pParentContainer) { *ppdispParent = ((CXTPDockingPaneTabbedContainer*)m_pParentContainer)->GetIDispatch(TRUE); return S_OK; } return E_FAIL; } HRESULT CXTPDockingPane::GetAccessibleChildCount(long FAR* pChildCount) { if (pChildCount == 0) return E_INVALIDARG; *pChildCount = m_hwndChild ? 1 : 0; return S_OK; } HRESULT CXTPDockingPane::GetAccessibleChild(VARIANT varChild, IDispatch* FAR* ppdispChild) { SAFE_MANAGE_STATE(m_pModuleState); *ppdispChild = NULL; if (GetChildIndex(&varChild) == 1) { return AccessibleObjectFromWindow(m_hwndChild, OBJID_WINDOW, IID_IDispatch, (void**)ppdispChild); } return S_OK; } HRESULT CXTPDockingPane::GetAccessibleName(VARIANT varChild, BSTR* pszName) { if (GetChildIndex(&varChild) != CHILDID_SELF) return E_INVALIDARG; *pszName = GetTabCaption().AllocSysString(); return S_OK; } HRESULT CXTPDockingPane::GetAccessibleDescription(VARIANT varChild, BSTR* pszDescription) { if (GetChildIndex(&varChild) != CHILDID_SELF) return E_INVALIDARG; *pszDescription = GetTitle().AllocSysString(); return S_OK; } HRESULT CXTPDockingPane::GetAccessibleRole(VARIANT varChild, VARIANT* pvarRole) { pvarRole->vt = VT_EMPTY; if (GetChildIndex(&varChild) == CHILDID_SELF) { pvarRole->vt = VT_I4; pvarRole->lVal = ROLE_SYSTEM_PAGETAB; return S_OK; } return E_INVALIDARG; } HRESULT CXTPDockingPane::AccessibleSelect(long /*flagsSelect*/, VARIANT varChild) { SAFE_MANAGE_STATE(m_pModuleState); if (GetChildIndex(&varChild) != CHILDID_SELF) return E_INVALIDARG; Select(); return S_OK; } HRESULT CXTPDockingPane::GetAccessibleState(VARIANT varChild, VARIANT* pvarState) { if (GetChildIndex(&varChild) != CHILDID_SELF) return E_INVALIDARG; pvarState->vt = VT_I4; pvarState->lVal = STATE_SYSTEM_SELECTABLE; if (!m_pParentContainer) pvarState->lVal |= STATE_SYSTEM_INVISIBLE; if (m_pParentContainer && ((CXTPDockingPaneTabbedContainer*)m_pParentContainer)->GetSelected() == this) pvarState->lVal |= STATE_SYSTEM_SELECTED; return S_OK; } HRESULT CXTPDockingPane::GetAccessibleDefaultAction(VARIANT varChild, BSTR* pszDefaultAction) { if (GetChildIndex(&varChild) != CHILDID_SELF) return E_INVALIDARG; *pszDefaultAction = SysAllocString(L"Switch"); return S_OK; } HRESULT CXTPDockingPane::AccessibleDoDefaultAction(VARIANT varChild) { SAFE_MANAGE_STATE(m_pModuleState); if (GetChildIndex(&varChild) != CHILDID_SELF) return E_INVALIDARG; Select(); return S_OK; } HRESULT CXTPDockingPane::AccessibleLocation(long* pxLeft, long* pyTop, long* pcxWidth, long* pcyHeight, VARIANT varChild) { CRect rc; if (GetChildIndex(&varChild) == 1) { GetWindowRect(m_hwndChild, &rc); } else if (GetChildIndex(&varChild) != CHILDID_SELF) { return E_INVALIDARG; } else { CXTPDockingPaneTabbedContainer* pContainer = (CXTPDockingPaneTabbedContainer*)m_pParentContainer; if (!pContainer) return S_FALSE; pContainer->GetWindowRect(&rc); if (pContainer->GetItemCount() > 1) { for (int i = 0; i < pContainer->GetItemCount(); i++) { CXTPTabManagerItem* pItem = pContainer->GetItem(i); if (pItem->GetData() == (DWORD_PTR)this) { CRect rcItem = pItem->GetRect(); rc = CRect(CPoint(rc.left + rcItem.left, rc.top + rcItem.top), rcItem.Size()); break; } } } } *pxLeft = rc.left; *pyTop = rc.top; *pcxWidth = rc.Width(); *pcyHeight = rc.Height(); return S_OK; } HRESULT CXTPDockingPane::AccessibleHitTest(long /*xLeft*/, long /*yTop*/, VARIANT* pvarID) { pvarID->vt = VT_I4; pvarID->lVal = 0; return S_OK; } BEGIN_INTERFACE_MAP(CXTPDockingPane, CCmdTarget) INTERFACE_PART(CXTPDockingPane, IID_IAccessible, ExternalAccessible) END_INTERFACE_MAP()