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.
338 lines
8.9 KiB
C++
338 lines
8.9 KiB
C++
// XTPReportDragDrop.cpp : implementation of the CXTPReportHeaderDropWnd class.
|
|
//
|
|
// This file is a part of the XTREME REPORTCONTROL 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/XTPDrawHelpers.h"
|
|
#include "Common/XTPCustomHeap.h"
|
|
#include "Common/XTPSystemHelpers.h"
|
|
#include "Common/XTPSmartPtrInternalT.h"
|
|
#include "Common/XTPColorManager.h"
|
|
|
|
|
|
#include "XTPReportDefines.h"
|
|
#include "XTPReportHeader.h"
|
|
#include "XTPReportPaintManager.h"
|
|
#include "XTPReportDragDrop.h"
|
|
#include "XTPReportControl.h"
|
|
#include "XTPReportColumn.h"
|
|
#include "XTPReportColumns.h"
|
|
|
|
#ifdef _DEBUG
|
|
#define new DEBUG_NEW
|
|
#undef THIS_FILE
|
|
static char THIS_FILE[] = __FILE__;
|
|
#endif
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CXTPReportHeaderDragWnd
|
|
|
|
CXTPReportHeaderDragWnd::CXTPReportHeaderDragWnd()
|
|
{
|
|
m_pHeader = NULL;
|
|
m_pPaintManager = NULL;
|
|
m_pColumn = NULL;
|
|
}
|
|
|
|
CXTPReportHeaderDragWnd::~CXTPReportHeaderDragWnd()
|
|
{
|
|
}
|
|
|
|
|
|
BEGIN_MESSAGE_MAP(CXTPReportHeaderDragWnd, CWnd)
|
|
//{{AFX_MSG_MAP(CXTPReportHeaderDragWnd)
|
|
ON_WM_PAINT()
|
|
ON_WM_ERASEBKGND()
|
|
ON_WM_TIMER()
|
|
//}}AFX_MSG_MAP
|
|
END_MESSAGE_MAP()
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CXTPReportHeaderDragWnd message handlers
|
|
|
|
BOOL CXTPReportHeaderDragWnd::Create(CRect rect, CXTPReportHeader* pHeader, CXTPReportPaintManager* pPaintManager, CXTPReportColumn* pColumn)
|
|
{
|
|
m_pHeader = pHeader;
|
|
m_pPaintManager = pPaintManager;
|
|
m_pColumn = pColumn;
|
|
if (rect.Height() == 0)
|
|
rect.bottom = rect.top + pPaintManager->GetHeaderHeight();
|
|
|
|
DWORD dwStyle = WS_POPUP | WS_DISABLED;
|
|
DWORD dwExStyle = WS_EX_TOOLWINDOW | WS_EX_TOPMOST;
|
|
|
|
BOOL bCreated = CreateEx(dwExStyle, AfxRegisterWndClass(0, AfxGetApp()->LoadStandardCursor(IDC_ARROW)), NULL, dwStyle,
|
|
rect.left, rect.top, rect.Width(), rect.Height(),
|
|
NULL, NULL, NULL);
|
|
|
|
if (bCreated && m_pHeader && m_pHeader->GetControl() &&
|
|
m_pHeader->GetControl()->m_bHScrollBarVisible )
|
|
{
|
|
SetTimer(1, 100, NULL);
|
|
}
|
|
return bCreated;
|
|
}
|
|
|
|
|
|
void CXTPReportHeaderDragWnd::OnPaint()
|
|
{
|
|
CPaintDC dc(this);
|
|
CXTPClientRect rc(this);
|
|
CXTPBufferDC memDC(dc, rc);
|
|
OnDraw(&memDC, rc);
|
|
}
|
|
|
|
BOOL CXTPReportHeaderDragWnd::OnEraseBkgnd(CDC* /*pDC*/)
|
|
{
|
|
return TRUE;
|
|
}
|
|
|
|
void CXTPReportHeaderDragWnd::OnDraw(CDC* pDC, CRect rcClient)
|
|
{
|
|
if (!m_pPaintManager)
|
|
return;
|
|
|
|
// draw background
|
|
m_pPaintManager->FillHeaderControl(pDC, rcClient);
|
|
// draw column header
|
|
m_pPaintManager->DrawColumn(pDC, m_pColumn, m_pHeader, rcClient, TRUE);
|
|
}
|
|
|
|
void CXTPReportHeaderDragWnd::PostNcDestroy()
|
|
{
|
|
CWnd::PostNcDestroy();
|
|
delete this;
|
|
}
|
|
|
|
void CXTPReportHeaderDragWnd::OnTimer(UINT_PTR nIDEvent)
|
|
{
|
|
UNREFERENCED_PARAMETER(nIDEvent);
|
|
|
|
if (!m_pHeader || !m_pHeader->GetControl())
|
|
{
|
|
return;
|
|
}
|
|
CXTPReportControl* pControl = m_pHeader->GetControl();
|
|
|
|
ASSERT(pControl->m_bHScrollBarVisible);
|
|
|
|
CRect rcHeaderScreen = m_pHeader->m_rcHeader;
|
|
pControl->ClientToScreen(&rcHeaderScreen);
|
|
|
|
CRect rcControlScreen(0,0,0,0);
|
|
CRect rcDragScreen(0,0,0,0);
|
|
|
|
pControl->GetWindowRect(&rcControlScreen);
|
|
GetWindowRect(&rcDragScreen);
|
|
|
|
|
|
CPoint ptMouseScreen(0, 0);
|
|
if (!GetCursorPos(&ptMouseScreen) ||
|
|
ptMouseScreen.y < rcHeaderScreen.top || ptMouseScreen.y > rcHeaderScreen.bottom)
|
|
{
|
|
return;
|
|
}
|
|
|
|
BOOL bScrolled = FALSE;
|
|
BOOL bLayoutRTL = pControl->GetExStyle() & WS_EX_LAYOUTRTL;
|
|
|
|
int nDiffRight = bLayoutRTL ? rcControlScreen.left - rcDragScreen.left :
|
|
rcDragScreen.right - rcControlScreen.right;
|
|
|
|
//-----------------------------------------------------------------------
|
|
CXTPReportColumn *pPrev = NULL, *pCurr = NULL, *pNext = NULL;
|
|
int nScrollPos = 0, nScrollMax = 0;
|
|
int nFreezOffset = 0;
|
|
BOOL bFullColumnScrolling = pControl->IsFullColumnScrolling();
|
|
if (bFullColumnScrolling)
|
|
nFreezOffset = m_pHeader->GetFullColScrollInfo(pPrev, pCurr, pNext, nScrollPos, nScrollMax);
|
|
//-----------------------------------------------------------------------
|
|
|
|
if (nDiffRight > 0)
|
|
{
|
|
int nStep = max(min(7, nDiffRight/10), CXTPReportHeader::s_nMinAutoScrollStep);
|
|
UINT uTimer = bFullColumnScrolling ? max(30, 800 - nDiffRight * 10) : max(10, 100 - nDiffRight);
|
|
SCROLLINFO scrollInfo;
|
|
|
|
BOOL bRes = pControl->GetScrollInfo(SB_HORZ, &scrollInfo);
|
|
if (bRes)
|
|
{
|
|
if (!bFullColumnScrolling && scrollInfo.nPos < scrollInfo.nMax ||
|
|
bFullColumnScrolling && nScrollPos < nScrollMax)
|
|
{
|
|
if (bFullColumnScrolling)
|
|
pControl->SendMessage(WM_HSCROLL, SB_LINERIGHT);
|
|
else
|
|
pControl->SetScrollOffsetH(scrollInfo.nPos + nStep);
|
|
|
|
KillTimer(1);
|
|
SetTimer(1, uTimer, NULL);
|
|
bScrolled = TRUE;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
int nLeftBorderX = bLayoutRTL ? rcControlScreen.right : rcControlScreen.left;
|
|
|
|
int nFreezCols = pControl->GetFreezeColumnsCount();
|
|
if (nFreezCols && pControl->GetColumns())
|
|
{
|
|
CXTPReportColumn* pLastFCol = pControl->GetColumns()->GetVisibleAt(nFreezCols - 1);
|
|
if (pLastFCol)
|
|
{
|
|
CRect rcLastFCol = pLastFCol->GetRect();
|
|
pControl->ClientToScreen(&rcLastFCol);
|
|
|
|
int nLastFCol_middleX = rcLastFCol.left + rcLastFCol.Width() / 2;
|
|
if (rcDragScreen.left < rcLastFCol.right &&
|
|
ptMouseScreen.x > nLastFCol_middleX )
|
|
{
|
|
nLeftBorderX = rcLastFCol.right;
|
|
}
|
|
}
|
|
}
|
|
|
|
int nDiffLeft = bLayoutRTL ? rcDragScreen.right - nLeftBorderX : nLeftBorderX - rcDragScreen.left;
|
|
|
|
if (nDiffLeft > 0)
|
|
{
|
|
int nStep = max(min(7, nDiffLeft/10), CXTPReportHeader::s_nMinAutoScrollStep);
|
|
UINT uTimer = bFullColumnScrolling ? max(30, 800 - nDiffLeft * 10) : max(10, 100 - nDiffLeft);
|
|
SCROLLINFO scrollInfo;
|
|
|
|
BOOL bRes = pControl->GetScrollInfo(SB_HORZ, &scrollInfo);
|
|
if (bRes)
|
|
{
|
|
if (scrollInfo.nPos > scrollInfo.nMin)
|
|
{
|
|
if (bFullColumnScrolling)
|
|
pControl->SendMessage(WM_HSCROLL, SB_LINELEFT);
|
|
else
|
|
pControl->SetScrollOffsetH(scrollInfo.nPos - nStep);
|
|
|
|
SetTimer(1, uTimer, NULL);
|
|
bScrolled = TRUE;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//-------------------------------------------------------------------------
|
|
if (bScrolled)
|
|
{
|
|
CPoint ptMouse = ptMouseScreen;
|
|
pControl->ScreenToClient(&ptMouse);
|
|
|
|
pControl->RedrawControl();
|
|
pControl->UpdateWindow();
|
|
|
|
m_pHeader->OnMouseMove(0, ptMouse);
|
|
}
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CXTPReportHeaderDropWnd
|
|
|
|
CXTPReportHeaderDropWnd::CXTPReportHeaderDropWnd(COLORREF crColor)
|
|
: m_clr(crColor)
|
|
{
|
|
m_nHeight = 0;
|
|
}
|
|
|
|
CXTPReportHeaderDropWnd::~CXTPReportHeaderDropWnd()
|
|
{
|
|
}
|
|
|
|
|
|
BEGIN_MESSAGE_MAP(CXTPReportHeaderDropWnd, CWnd)
|
|
//{{AFX_MSG_MAP(CXTPReportHeaderDropWnd)
|
|
ON_WM_ERASEBKGND()
|
|
//}}AFX_MSG_MAP
|
|
END_MESSAGE_MAP()
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CXTPReportHeaderDropWnd message handlers
|
|
|
|
BOOL CXTPReportHeaderDropWnd::Create(CWnd* /*pParentWnd*/, int nHeight)
|
|
{
|
|
m_nHeight = nHeight + 20;
|
|
|
|
DWORD dwStyle = WS_POPUP | WS_DISABLED;
|
|
DWORD dwExStyle = WS_EX_TOOLWINDOW | WS_EX_TOPMOST ;
|
|
|
|
BOOL bResult = CreateEx(dwExStyle, AfxRegisterWndClass(0, AfxGetApp()->LoadStandardCursor(IDC_ARROW)), NULL, dwStyle,
|
|
0, 0, 12, m_nHeight,
|
|
NULL, NULL, NULL);
|
|
|
|
CRgn rgn1, rgn2;
|
|
POINT ptArrow[7];
|
|
|
|
ptArrow[0].x = 8; ptArrow[0].y = 0;
|
|
ptArrow[1].x = 8; ptArrow[1].y = 4;
|
|
ptArrow[2].x = 11; ptArrow[2].y = 4;
|
|
ptArrow[3].x = 6; ptArrow[3].y = 9;
|
|
ptArrow[4].x = 1; ptArrow[4].y = 4;
|
|
ptArrow[5].x = 4; ptArrow[5].y = 4;
|
|
ptArrow[6].x = 4; ptArrow[6].y = 0;
|
|
rgn1.CreatePolygonRgn(ptArrow, 7, ALTERNATE);
|
|
|
|
|
|
ptArrow[0].x = 4; ptArrow[0].y = m_nHeight;
|
|
ptArrow[1].x = 4; ptArrow[1].y = m_nHeight-4;
|
|
ptArrow[2].x = 0; ptArrow[2].y = m_nHeight-4;
|
|
ptArrow[3].x = 6; ptArrow[3].y = m_nHeight-10;
|
|
ptArrow[4].x = 12; ptArrow[4].y = m_nHeight-4;
|
|
ptArrow[5].x = 8; ptArrow[5].y = m_nHeight-4;
|
|
ptArrow[6].x = 8; ptArrow[6].y = m_nHeight;
|
|
rgn2.CreatePolygonRgn(ptArrow, 7, ALTERNATE);
|
|
|
|
m_rgn.CreateRectRgn(0, 0, 12, nHeight);
|
|
m_rgn.CombineRgn(&rgn1, &rgn2, RGN_OR);
|
|
SetWindowRgn(m_rgn, FALSE);
|
|
|
|
rgn1.DeleteObject();
|
|
rgn2.DeleteObject();
|
|
|
|
return bResult;
|
|
}
|
|
|
|
|
|
void CXTPReportHeaderDropWnd::PostNcDestroy()
|
|
{
|
|
m_rgn.DeleteObject();
|
|
|
|
CWnd::PostNcDestroy();
|
|
delete this;
|
|
}
|
|
|
|
BOOL CXTPReportHeaderDropWnd::OnEraseBkgnd(CDC* pDC)
|
|
{
|
|
pDC->FillSolidRect(0, 0, 12, m_nHeight, m_clr);
|
|
return TRUE;
|
|
}
|
|
|
|
void CXTPReportHeaderDropWnd::SetWindowPos(int x, int y)
|
|
{
|
|
CWnd::SetWindowPos(0, x - 6, y - (m_nHeight / 2), 0, 0, SWP_NOSIZE | SWP_SHOWWINDOW | SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOOWNERZORDER);
|
|
}
|