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.
527 lines
11 KiB
C++
527 lines
11 KiB
C++
// XTPTabControl.cpp : implementation file
|
|
//
|
|
// This file is a part of the XTREME TOOLKIT PRO 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/XTPToolTipContext.h"
|
|
#include "Common/XTPDrawHelpers.h"
|
|
#include "Common/XTPImageManager.h"
|
|
#include "Common/XTPColorManager.h"
|
|
|
|
#include "XTPTabManager.h"
|
|
#include "XTPTabControl.h"
|
|
#include "XTPTabPaintManager.h"
|
|
|
|
#ifdef _DEBUG
|
|
#define new DEBUG_NEW
|
|
#undef THIS_FILE
|
|
static char THIS_FILE[] = __FILE__;
|
|
#endif
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// CTabManagerDropTarget
|
|
|
|
class CXTPTabControl::CTabControlDropTarget : public COleDropTarget
|
|
{
|
|
public:
|
|
CTabControlDropTarget()
|
|
{
|
|
m_ptDragLastPoint = CPoint(-1, -1);
|
|
m_dwDragLastTick = 0;
|
|
}
|
|
|
|
void OnDragLeave(CWnd* /*pWnd*/)
|
|
{
|
|
m_dwDragLastTick = 0;
|
|
m_ptDragLastPoint = CPoint(-1, -1);
|
|
}
|
|
|
|
virtual DROPEFFECT OnDragOver(CWnd* pWnd, COleDataObject* /*pDataObject*/, DWORD /*dwKeyState*/, CPoint point)
|
|
{
|
|
CXTPTabControl* pControl = (CXTPTabControl*)pWnd;
|
|
ASSERT_VALID(pControl);
|
|
|
|
if (!pControl->GetPaintManager()->m_bSelectOnDragOver)
|
|
return DROPEFFECT_NONE;
|
|
|
|
if (m_dwDragLastTick != (DWORD)-1 && pControl->GetPaintManager()->m_bSelectOnDragOver == 2)
|
|
{
|
|
DWORD dwTick = GetTickCount();
|
|
|
|
if (point != m_ptDragLastPoint)
|
|
{
|
|
m_dwDragLastTick = dwTick;
|
|
m_ptDragLastPoint = point;
|
|
}
|
|
|
|
if (dwTick - m_dwDragLastTick > CXTPTabPaintManager::m_nSelectOnDragOverDelay)
|
|
{
|
|
m_dwDragLastTick = (DWORD)-1;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
CXTPTabManagerItem* pItem = pControl->HitTest(point);
|
|
|
|
if (pItem)
|
|
{
|
|
pControl->SetSelectedItem(pItem);
|
|
}
|
|
else
|
|
{
|
|
m_dwDragLastTick = 0;
|
|
}
|
|
}
|
|
|
|
return DROPEFFECT_NONE;
|
|
}
|
|
|
|
protected:
|
|
DWORD m_dwDragHoverMode;
|
|
DWORD m_dwDragLastTick;
|
|
CPoint m_ptDragLastPoint;
|
|
};
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CXTPTabControl
|
|
|
|
CXTPTabControl::CXTPTabControl()
|
|
{
|
|
m_pPaintManager = new CXTPTabPaintManager();
|
|
m_pPaintManager->DisableLunaColors(TRUE);
|
|
m_pPaintManager->m_bDrawTextNoPrefix = FALSE;
|
|
|
|
m_hwndClient = 0;
|
|
m_bAllowReorder = FALSE;
|
|
m_nLockRedraw = 0;
|
|
|
|
m_pDropTarget = new CTabControlDropTarget();
|
|
m_pImageManager = new CXTPImageManager();
|
|
m_pToolTipContext = new CXTPToolTipContext;
|
|
|
|
CXTPDrawHelpers::RegisterWndClass(0, _T("XTPTabControl"), CS_DBLCLKS);
|
|
}
|
|
|
|
CXTPTabControl::~CXTPTabControl()
|
|
{
|
|
CMDTARGET_RELEASE(m_pPaintManager);
|
|
CMDTARGET_RELEASE(m_pImageManager);
|
|
CMDTARGET_RELEASE(m_pToolTipContext);
|
|
|
|
delete m_pDropTarget;
|
|
}
|
|
|
|
BOOL CXTPTabControl::Create(DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID)
|
|
{
|
|
if (!CWnd::Create(AfxRegisterWndClass(CS_DBLCLKS, AfxGetApp()->LoadStandardCursor(IDC_ARROW)), NULL, dwStyle, rect, pParentWnd, nID))
|
|
return FALSE;
|
|
|
|
m_pDropTarget->Register(this);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
CXTPTabManagerItem* CXTPTabControl::InsertItem(int nItem, LPCTSTR lpszItem, HWND hwndChild /*= NULL*/, int nImage /*= -1*/, CXTPTabManagerItem* pAddItem /* = NULL */)
|
|
{
|
|
CXTPTabManagerItem* pItem = AddItem(nItem, pAddItem);
|
|
pItem->SetCaption(lpszItem);
|
|
pItem->SetHandle(hwndChild);
|
|
pItem->SetImageIndex(nImage);
|
|
|
|
if (hwndChild)
|
|
::ShowWindow(hwndChild, SW_HIDE);
|
|
|
|
if (nItem == 0 && m_pSelected == NULL)
|
|
{
|
|
SetCurSel(0);
|
|
}
|
|
|
|
return pItem;
|
|
}
|
|
|
|
void CXTPTabControl::RedrawControl(LPCRECT lpRect, BOOL /*bAnimate*/)
|
|
{
|
|
if (!GetSafeHwnd())
|
|
return;
|
|
|
|
if (m_nLockRedraw > 0)
|
|
return;
|
|
|
|
InvalidateRect(lpRect, FALSE);
|
|
}
|
|
|
|
void CXTPTabControl::SetLockRedraw(BOOL bLockRedraw)
|
|
{
|
|
m_nLockRedraw += bLockRedraw ? +1 : -1;
|
|
ASSERT(m_nLockRedraw >= 0);
|
|
|
|
if (m_nLockRedraw == 0)
|
|
Reposition();
|
|
}
|
|
|
|
void CXTPTabControl::Reposition()
|
|
{
|
|
if (!GetSafeHwnd())
|
|
return;
|
|
|
|
if (m_nLockRedraw > 0)
|
|
return;
|
|
|
|
CXTPClientRect rc(this);
|
|
CClientDC dc(this);
|
|
|
|
GetPaintManager()->RepositionTabControl(this, &dc, rc);
|
|
|
|
if (m_hwndClient && ::IsWindow(m_hwndClient))
|
|
{
|
|
GetPaintManager()->AdjustClientRect(this, rc);
|
|
::MoveWindow(m_hwndClient, rc.left, rc.top, rc.Width(), rc.Height(), TRUE);
|
|
}
|
|
|
|
Invalidate(FALSE);
|
|
}
|
|
|
|
void CXTPTabControl::OnItemClick(CXTPTabManagerItem* pItem)
|
|
{
|
|
CXTPTabManager::OnItemClick(pItem);
|
|
|
|
if (m_hwndClient)
|
|
{
|
|
if (::GetFocus() != m_hWnd && !::IsChild(m_hwndClient, ::GetFocus()))
|
|
{
|
|
HWND hWnd = ::GetNextDlgTabItem(m_hwndClient, NULL, FALSE);
|
|
::SetFocus(hWnd ? hWnd : m_hwndClient);
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
void CXTPTabControl::SetSelectedItem(CXTPTabManagerItem* pItem)
|
|
{
|
|
if (m_pSelected == pItem)
|
|
return;
|
|
|
|
NMHDR nmhdr;
|
|
nmhdr.hwndFrom = GetSafeHwnd();
|
|
nmhdr.idFrom = GetDlgCtrlID();
|
|
nmhdr.code = TCN_SELCHANGING;
|
|
|
|
CWnd* pOwner = GetOwner();
|
|
if (pOwner && IsWindow(pOwner->m_hWnd))
|
|
{
|
|
if (pOwner->SendMessage(WM_NOTIFY, nmhdr.idFrom, (LPARAM)&nmhdr) == TRUE)
|
|
return;
|
|
}
|
|
|
|
if (m_hwndClient)
|
|
::ShowWindow(m_hwndClient, SW_HIDE);
|
|
|
|
if (pItem)
|
|
{
|
|
m_hwndClient = pItem->GetHandle();
|
|
}
|
|
else
|
|
{
|
|
m_hwndClient = 0;
|
|
}
|
|
|
|
if (m_hwndClient)
|
|
{
|
|
::ShowWindow(m_hwndClient, SW_SHOW);
|
|
}
|
|
|
|
CXTPTabManager::SetSelectedItem(pItem);
|
|
|
|
|
|
nmhdr.code = TCN_SELCHANGE;
|
|
|
|
if (pOwner && IsWindow(pOwner->m_hWnd))
|
|
{
|
|
pOwner->SendMessage(WM_NOTIFY, nmhdr.idFrom, (LPARAM)&nmhdr);
|
|
}
|
|
}
|
|
|
|
void CXTPTabControl::PreSubclassWindow()
|
|
{
|
|
CWnd::PreSubclassWindow();
|
|
|
|
Reposition();
|
|
}
|
|
|
|
void CXTPTabControl::SetImageList(CImageList* pImageList)
|
|
{
|
|
if (pImageList)
|
|
{
|
|
m_pImageManager->SetIcons(*pImageList, 0, 0, 0, xtpImageNormal);
|
|
}
|
|
Reposition();
|
|
}
|
|
|
|
void CXTPTabControl::SetImageManager(CXTPImageManager* pImageManager)
|
|
{
|
|
if (pImageManager)
|
|
{
|
|
m_pImageManager->InternalRelease();
|
|
|
|
m_pImageManager = pImageManager;
|
|
}
|
|
Reposition();
|
|
}
|
|
|
|
|
|
BEGIN_MESSAGE_MAP(CXTPTabControl, CWnd)
|
|
//{{AFX_MSG_MAP(CXTPTabControl)
|
|
ON_WM_ERASEBKGND()
|
|
ON_WM_PAINT()
|
|
ON_WM_SIZE()
|
|
ON_WM_LBUTTONDOWN()
|
|
ON_WM_SYSCOLORCHANGE()
|
|
ON_WM_MOUSEMOVE()
|
|
ON_MESSAGE_VOID(WM_MOUSELEAVE, OnMouseLeave)
|
|
ON_MESSAGE(WM_PRINTCLIENT, OnPrintClient)
|
|
ON_WM_KEYDOWN()
|
|
ON_WM_GETDLGCODE()
|
|
ON_WM_SETFOCUS()
|
|
ON_WM_KILLFOCUS()
|
|
//}}AFX_MSG_MAP
|
|
END_MESSAGE_MAP()
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CXTPTabControl message handlers
|
|
|
|
BOOL CXTPTabControl::OnEraseBkgnd(CDC* /*pDC*/)
|
|
{
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL CXTPTabControl::DrawParentBackground(CDC* pDC, CRect rc)
|
|
{
|
|
HBRUSH hBrush = (HBRUSH)GetParent()->SendMessage(WM_CTLCOLORSTATIC,
|
|
(WPARAM)pDC->GetSafeHdc(), (LPARAM)m_hWnd);
|
|
if (hBrush)
|
|
{
|
|
::FillRect(pDC->GetSafeHdc(), rc, hBrush);
|
|
return TRUE;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
void CXTPTabControl::OnPaint()
|
|
{
|
|
CPaintDC dcPaint(this);
|
|
CXTPBufferDC dc(dcPaint);
|
|
|
|
GetPaintManager()->DrawTabControl(this, &dc, m_rcControl);
|
|
}
|
|
|
|
LRESULT CXTPTabControl::OnPrintClient(WPARAM wParam, LPARAM /*lParam*/)
|
|
{
|
|
CXTPClientRect rc(this);
|
|
|
|
CDC* pDC = CDC::FromHandle((HDC)wParam);
|
|
if (pDC) GetPaintManager()->DrawTabControl(this, pDC, rc);
|
|
|
|
return 1;
|
|
}
|
|
|
|
void CXTPTabControl::OnSize(UINT nType, int cx, int cy)
|
|
{
|
|
CWnd::OnSize(nType, cx, cy);
|
|
|
|
Reposition();
|
|
}
|
|
|
|
|
|
void CXTPTabControl::OnLButtonDown(UINT /*nFlags*/, CPoint point)
|
|
{
|
|
if ((GetStyle() & WS_TABSTOP) && m_pSelected && (m_pSelected == HitTest(point)))
|
|
{
|
|
SetFocus();
|
|
}
|
|
|
|
PerformClick(m_hWnd, point);
|
|
}
|
|
|
|
void CXTPTabControl::OnNavigateButtonClick(CXTPTabManagerNavigateButton* pButton)
|
|
{
|
|
CXTPTabManager::OnNavigateButtonClick(pButton->GetID());
|
|
|
|
CXTPTabManagerItem* pItem = pButton->GetItem() ? pButton->GetItem() : m_pSelected;
|
|
|
|
if (pItem && (pButton->GetID() == xtpTabNavigateButtonClose) && pItem->IsClosable())
|
|
{
|
|
DeleteItem(pItem->GetIndex());
|
|
}
|
|
}
|
|
|
|
|
|
void CXTPTabControl::OnSysColorChange()
|
|
{
|
|
CWnd::OnSysColorChange();
|
|
|
|
RefreshXtremeColors();
|
|
GetPaintManager()->RefreshMetrics();
|
|
|
|
Reposition();
|
|
|
|
}
|
|
|
|
INT_PTR CXTPTabControl::OnToolHitTest(CPoint point, TOOLINFO* pTI) const
|
|
{
|
|
return PerformToolHitTest(m_hWnd, point, pTI);
|
|
}
|
|
|
|
void CXTPTabControl::OnMouseMove(UINT nFlags, CPoint point)
|
|
{
|
|
PerformMouseMove(m_hWnd, point);
|
|
|
|
CWnd::OnMouseMove(nFlags, point);
|
|
}
|
|
|
|
void CXTPTabControl::OnMouseLeave()
|
|
{
|
|
PerformMouseMove(m_hWnd, CPoint(-1, -1));
|
|
}
|
|
|
|
BOOL CXTPTabControl::DrawIcon(CDC* pDC, CPoint pt, CXTPTabManagerItem* pItem, BOOL bDraw, CSize& szIcon) const
|
|
{
|
|
if (!pItem)
|
|
return GetPaintManager()->m_bShowIcons;
|
|
|
|
if (pItem->GetImageIndex() == -1 || GetPaintManager()->m_bShowIcons == FALSE)
|
|
return FALSE;
|
|
|
|
CXTPImageManagerIcon* pImage = m_pImageManager->GetImage(pItem->GetImageIndex(), szIcon.cx);
|
|
|
|
if (!pImage)
|
|
return FALSE;
|
|
|
|
if (!bDraw)
|
|
{
|
|
return TRUE;
|
|
}
|
|
|
|
pItem->DrawImage(pDC, CRect(pt, szIcon), pImage);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
void CXTPTabControl::SetPaintManager(CXTPTabPaintManager* pPaintManager)
|
|
{
|
|
delete m_pPaintManager;
|
|
m_pPaintManager = pPaintManager;
|
|
m_pPaintManager->RefreshMetrics();
|
|
Reposition();
|
|
}
|
|
|
|
BOOL CXTPTabControl::OnWndMsg(UINT message, WPARAM wParam, LPARAM lParam, LRESULT* pResult)
|
|
{
|
|
m_pToolTipContext->FilterToolTipMessage(this, message, wParam, lParam);
|
|
|
|
return CWnd::OnWndMsg(message, wParam, lParam, pResult);
|
|
}
|
|
|
|
void CXTPTabControl::EnableToolTips(XTPTabToolTipBehaviour behaviour /*= xtpTabToolTipAlways*/)
|
|
{
|
|
m_pPaintManager->EnableToolTips(behaviour);
|
|
}
|
|
|
|
|
|
void CXTPTabControl::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
|
|
{
|
|
PerformKeyDown(m_hWnd, nChar);
|
|
|
|
CWnd::OnKeyDown(nChar, nRepCnt, nFlags);
|
|
}
|
|
|
|
UINT CXTPTabControl::OnGetDlgCode()
|
|
{
|
|
return ::GetFocus() == m_hWnd ? DLGC_WANTARROWS : CWnd::OnGetDlgCode();
|
|
}
|
|
|
|
void CXTPTabControl::OnSetFocus(CWnd* pOldWnd)
|
|
{
|
|
CWnd::OnSetFocus(pOldWnd);
|
|
InvalidateRect(m_rcHeaderRect, FALSE);
|
|
}
|
|
|
|
void CXTPTabControl::OnKillFocus(CWnd* pNewWnd)
|
|
{
|
|
CWnd::OnKillFocus(pNewWnd);
|
|
InvalidateRect(m_rcHeaderRect, FALSE);
|
|
}
|
|
|
|
#ifndef WM_QUERYUISTATE
|
|
#define WM_QUERYUISTATE 0x0129
|
|
#endif
|
|
|
|
#ifndef WM_CHANGEUISTATE
|
|
#define WM_CHANGEUISTATE 0x0127
|
|
#endif
|
|
|
|
#ifndef UISF_HIDEFOCUS
|
|
#define UISF_HIDEFOCUS 0x1
|
|
#endif
|
|
|
|
#ifndef UIS_CLEAR
|
|
#define UIS_CLEAR 2
|
|
#endif
|
|
|
|
void CXTPTabControl::SetFocusedItem(CXTPTabManagerItem* pItem)
|
|
{
|
|
CXTPTabManager::SetFocusedItem(pItem);
|
|
|
|
if ((::SendMessage(::GetParent(m_hWnd), WM_QUERYUISTATE, 0, 0) & UISF_HIDEFOCUS) != 0)
|
|
{
|
|
::SendMessage(::GetParent(m_hWnd), WM_CHANGEUISTATE, MAKEWPARAM(UIS_CLEAR, UISF_HIDEFOCUS), 0);
|
|
|
|
}
|
|
}
|
|
|
|
BOOL CXTPTabControl::HeaderHasFocus() const
|
|
{
|
|
return (GetStyle() & WS_TABSTOP) && (::GetFocus() == m_hWnd)
|
|
&& ((::SendMessage(::GetParent(m_hWnd), WM_QUERYUISTATE, 0, 0) & UISF_HIDEFOCUS) == 0);
|
|
}
|
|
|
|
void CXTPTabControl::AdjustRect(BOOL bLarger, LPRECT lpRect) const
|
|
{
|
|
if (!lpRect)
|
|
return;
|
|
|
|
CRect rc(lpRect);
|
|
GetPaintManager()->AdjustClientRect((CXTPTabControl*)this, rc);
|
|
|
|
if (bLarger)
|
|
{
|
|
lpRect->top -= rc.top - lpRect->top;
|
|
lpRect->left -= rc.left - lpRect->left;
|
|
lpRect->bottom -= rc.bottom - lpRect->bottom;
|
|
lpRect->right -= rc.right - lpRect->right;
|
|
}
|
|
else
|
|
{
|
|
*lpRect = rc;
|
|
}
|
|
}
|