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.

644 lines
14 KiB
C++

2 years ago
// 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()