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.

816 lines
19 KiB
C++

2 years ago
// XTPReportRecordTrack.cpp : implementation of the CXTPTrackControlItem 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/XTPPropExchange.h"
#include "Common/XTPToolTipContext.h"
#include "Common/XTPCustomHeap.h"
#include "Common/XTPSystemHelpers.h"
#include "Common/XTPSmartPtrInternalT.h"
#include "Common/XTPColorManager.h"
#include "../XTPReportDefines.h"
#include "../XTPReportRecordItem.h"
#include "../XTPReportControl.h"
#include "../XTPReportRow.h"
#include "../XTPReportColumn.h"
#include "../XTPReportPaintManager.h"
#include "XTPTrackBlock.h"
#include "XTPTrackControlItem.h"
#include "XTPTrackControl.h"
#include "XTPTrackPaintManager.h"
#include "XTPTrackUndoManager.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
//////////////////////////////////////////////////////////////////////////
// CXTPTrackControlItem
IMPLEMENT_SERIAL(CXTPTrackControlItem, CXTPReportRecordItem, VERSIONABLE_SCHEMA | _XTP_SCHEMA_CURRENT)
CXTPTrackControlItem::CXTPTrackControlItem()
: CXTPReportRecordItem()
{
m_bLocked = FALSE;
#ifdef _XTP_ACTIVEX
EnableAutomation();
#endif
}
CXTPTrackControlItem::~CXTPTrackControlItem()
{
for (int n = 0; n < m_arrBlocks.GetSize(); n++)
{
CXTPTrackBlock* pBlock = m_arrBlocks[n];
if (pBlock)
{
pBlock->InternalRelease();
}
}
m_arrBlocks.RemoveAll();
}
CString CXTPTrackControlItem::GetCaption(CXTPReportColumn* /*pColumn*/)
{
if (!m_strCaption.IsEmpty())
return m_strCaption;
return _T("");
}
void CXTPTrackControlItem::DoPropExchange(CXTPPropExchange* pPX)
{
CXTPReportRecordItem::DoPropExchange(pPX);
CXTPPropExchangeEnumeratorPtr pEnumRecords(pPX->GetEnumerator(_T("Block")));
if (pPX->IsStoring())
{
int nCount = (int)GetBlockCount();
POSITION pos = pEnumRecords->GetPosition((DWORD)nCount);
for (int i = 0; i < nCount; i++)
{
CXTPTrackBlock* pBlock = GetBlock(i);
ASSERT(pBlock);
CXTPPropExchangeSection sec(pEnumRecords->GetNext(pos));
PX_Object(&sec, pBlock, RUNTIME_CLASS(CXTPTrackBlock));
}
}
else
{
RemoveAll();
POSITION pos = pEnumRecords->GetPosition();
while (pos)
{
CXTPTrackBlock* pBlock = NULL;
CXTPPropExchangeSection sec(pEnumRecords->GetNext(pos));
PX_Object(&sec, pBlock, RUNTIME_CLASS(CXTPTrackBlock));
if (!pBlock)
AfxThrowArchiveException(CArchiveException::badClass);
Add(pBlock);
}
RecalcLayout();
}
}
CXTPTrackControl* CXTPTrackControlItem::GetTrackControl() const
{
return (CXTPTrackControl*)m_pControl;
}
void CXTPTrackControlItem::HighlightWorkArea(CDC* pDC, CRect rcItem)
{
CXTPTrackControl* pControl = ((CXTPTrackControl*)m_pControl);
if (pControl->m_bShowWorkArea)
{
int nWorkAreaMin = pControl->PositionToTrack(pControl->GetWorkAreaMin());
int nWorkAreaMax = pControl->PositionToTrack(pControl->GetWorkAreaMax());
CRect rcWorkArea(nWorkAreaMin, rcItem.top, nWorkAreaMax, rcItem.bottom);
pDC->FillSolidRect(rcWorkArea, pControl->GetTrackPaintManager()->m_clrWorkArea);
}
for (int i = 0; i < pControl->GetMarkers()->GetCount(); i++)
{
CXTPTrackMarker* pMarker = pControl->GetMarkers()->GetAt(i);
int nPos = pControl->PositionToTrack(pMarker->GetPosition());
pDC->FillSolidRect(CRect(nPos, rcItem.top, nPos + 1, rcItem.bottom + 10), pControl->GetTrackPaintManager()->GetGridColor());
}
}
int CXTPTrackControlItem::Draw(XTP_REPORTRECORDITEM_DRAWARGS* pDrawArgs)
{
ASSERT(pDrawArgs->pControl);
if (!pDrawArgs->pControl)
return 0;
else
m_pControl = pDrawArgs->pControl;
CDC* pDC = pDrawArgs->pDC;
CRect& rcItem = pDrawArgs->rcItem;
CXTPTrackControl* pControl = ((CXTPTrackControl*)m_pControl);
CRgn rgn;
rgn.CreateRectRgn(rcItem.left, rcItem.top - 1, rcItem.right, rcItem.bottom);
if (!pDC->IsPrinting())
pDC->SelectClipRgn(&rgn);
XTP_REPORTRECORDITEM_METRICS* pMetrics = new XTP_REPORTRECORDITEM_METRICS();
pDrawArgs->pRow->GetItemMetrics(pDrawArgs, pMetrics);
CFont* pOldFont = (CFont*)pDC->SelectObject(pMetrics->pFont);
HighlightWorkArea(pDC, rcItem);
CRect rect = rcItem;
rect.top ++;
rect.bottom --;
int j;
for (j = 0; j < (int) m_arrBlocks.GetSize(); j++)
{
CXTPTrackBlock* pBlock = m_arrBlocks.GetAt(j);
if (pBlock && !pBlock->IsKey())
{
BOOL bSelected(FALSE);
for (int iG = 0; iG < (int ) pControl->GetSelectedBlocks()->GetCount(); iG++)
{
CXTPTrackBlock* pSelBlock = (CXTPTrackBlock* ) pControl->GetSelectedBlocks()->GetAt(iG);
if (pSelBlock == pBlock)
{
bSelected = TRUE;
break;
}
}
pBlock->Draw(pDC, rect, bSelected);
}
}
for (j = 0; j < (int) m_arrBlocks.GetSize(); j++)
{
CXTPTrackBlock* pBlock = m_arrBlocks.GetAt(j);
if (pBlock && pBlock->IsKey())
{
BOOL bSelected(FALSE);
for (int iG = 0; iG < (int ) pControl->GetSelectedBlocks()->GetCount(); iG++)
{
CXTPTrackBlock* pSelBlock = (CXTPTrackBlock* ) pControl->GetSelectedBlocks()->GetAt(iG);
if (pSelBlock == pBlock)
{
bSelected = TRUE;
break;
}
}
pBlock->Draw(pDC, rect, bSelected);
}
}
pDC->SelectObject(pOldFont);
pMetrics->InternalRelease();
if (!pDC->IsPrinting())
pDC->SelectClipRgn(NULL);
return 1;
}
struct CXTPTrackControlItem::DOCK_INFO
{
DOCK_INFO(CXTPTrackBlock* p = 0, CRect rc = 0, int n = 0, int nPriority = 0)
{
pBar = p;
rcMRUPos = rcBar = rc;
nIndex = n;
nMinWidth = 0;
nTotlaMinWidth = 0;
this->nPriority = nPriority;
}
CXTPTrackBlock* pBar;
CRect rcBar;
CRect rcMRUPos;
int nIndex;
int nMinWidth;
int nTotlaMinWidth;
int nPriority;
};
class CXTPTrackControlItem::CDockInfoArray : public CArray<DOCK_INFO, DOCK_INFO&>
{
public:
void Sort()
{
qsort(GetData(), GetSize(), sizeof(DOCK_INFO), CompareFunc);
}
static int _cdecl CompareFunc(const void* elem1, const void* elem2)
{
return ((DOCK_INFO*)elem1)->rcBar.left < ((DOCK_INFO*)elem2)->rcBar.left ? -1 : 1;
}
void _swap(LONG& A, LONG& B)
{
int C = B;
B = A;
A = C;
}
void InvertRects()
{
for (int nPos = 0; nPos < GetSize(); nPos++)
{
CRect& rect = ElementAt(nPos).rcBar;
_swap(rect.left, rect.top);
_swap(rect.right, rect.bottom);
}
}
};
void CXTPTrackControlItem::RecalcLayout()
{
CDockInfoArray arrInfo;
int nPos;
// Step 1. Getting maximum available size;
for (nPos = 0; nPos < m_arrBlocks.GetSize(); nPos++)
{
CXTPTrackBlock* pBlock = m_arrBlocks[nPos];
pBlock->m_nPosition = pBlock->m_nMRUPosition;
if (pBlock->IsKey())
continue;
CSize sizeBar(pBlock->m_nLength, 0);
CPoint p(pBlock->m_nMRUPosition, 0);
DOCK_INFO dockInfo(pBlock, CRect(p, sizeBar), nPos, pBlock->m_nLastDragTime ? pBlock->m_nLastDragTime : nPos);
arrInfo.Add(dockInfo);
}
arrInfo.Sort();
// Step 2. if Total length is more than available, fill empty area.
int nPriority = -1;
int nLen = 0;
BOOL bMove = TRUE;
for (nPos = 0; nPos < arrInfo.GetSize(); nPos++)
{
CRect& rect = arrInfo[nPos].rcBar;
bMove = (rect.left < nLen && (nPriority > arrInfo[nPos].nPriority)) && !arrInfo[nPos].pBar->IsLocked();
if (bMove) rect.OffsetRect(nLen - rect.left, 0);
nLen = rect.right;
nPriority = bMove ? max(nPriority, arrInfo[nPos].nPriority) : arrInfo[nPos].nPriority;
}
nLen = GetTrackControl() ? GetTrackControl()->GetTimeLineMax() : 320000;
nPriority = -1;
bMove = TRUE;
for (nPos = (int)arrInfo.GetSize() - 1; nPos >= 0; nPos--)
{
CRect& rect = arrInfo[nPos].rcBar;
bMove = (rect.right - nLen >= 0 && (nPriority > arrInfo[nPos].nPriority || bMove)) && !arrInfo[nPos].pBar->IsLocked();
if (bMove) rect.OffsetRect(nLen - rect.right, 0);
nLen = rect.left;
if (arrInfo[nPos].pBar->IsLocked())
nPriority = INT_MAX;
else
nPriority = bMove ? max(nPriority, arrInfo[nPos].nPriority) : arrInfo[nPos].nPriority;
}
nLen = 0;
for (nPos = 0; nPos < arrInfo.GetSize(); nPos++)
{
CRect& rect = arrInfo[nPos].rcBar;
if (rect.left < nLen)
rect.OffsetRect(nLen - rect.left, 0);
nLen = rect.left + rect.Width();
}
// Step 4. Move it.
for (nPos = 0; nPos < arrInfo.GetSize(); nPos++)
{
CXTPTrackBlock* pBar = arrInfo[nPos].pBar;
CRect& rect = arrInfo[nPos].rcBar;
pBar->m_nPosition = rect.left;
}
}
void CXTPTrackControlItem::AdjustBlockPosition(CXTPTrackBlock* pNewBlock, BOOL bResize)
{
CXTPTrackControlItem* pItem = this;
ASSERT(pNewBlock->GetItem() == this);
int nPos;
if (pNewBlock->IsKey())
return;
if (bResize)
{
int nLeft = pNewBlock->m_nMRUPosition;
int nRight = nLeft + pNewBlock->GetLength();
for (nPos = 0; nPos < pItem->GetBlockCount(); nPos++)
{
CXTPTrackBlock* pBlock = pItem->GetBlock(nPos);
//pBlock->m_nPosition = pBlock->m_nMRUPosition;
if (pBlock->IsKey() || pBlock == pNewBlock)
continue;
if (pBlock->m_nMRUPosition + pBlock->m_nLength <= nLeft)
continue;
if (pBlock->m_nMRUPosition >= nRight)
continue;
if (bResize == 2 && pNewBlock->m_nMRUPosition < pBlock->m_nMRUPosition) nRight = pBlock->m_nMRUPosition;
if (bResize == 1 && pNewBlock->m_nMRUPosition + pNewBlock->m_nLength > pBlock->m_nMRUPosition + pBlock->m_nLength) nLeft = pBlock->m_nMRUPosition + pBlock->m_nLength;
}
pNewBlock->SetLength(nRight - nLeft);
pNewBlock->SetPosition(nLeft);
}
else
{
int nPosition = pNewBlock->m_nMRUPosition;
int nLength = pNewBlock->GetLength();
CDockInfoArray arrInfo;
for (nPos = 0; nPos < pItem->GetBlockCount(); nPos++)
{
CXTPTrackBlock* pBlock = pItem->GetBlock(nPos);
pBlock->m_nPosition = pBlock->m_nMRUPosition;
if (pBlock->IsKey() || pBlock == pNewBlock)
continue;
CSize sizeBar(pBlock->m_nLength, 0);
CPoint p(pBlock->m_nPosition, 0);
DOCK_INFO dockInfo(pBlock, CRect(p, sizeBar), nPos, pBlock->m_nLastDragTime ? pBlock->m_nLastDragTime : nPos);
arrInfo.Add(dockInfo);
}
arrInfo.Sort();
int nRightPosition = nPosition;
for (nPos = 0; nPos < arrInfo.GetSize(); nPos++)
{
CRect rc = arrInfo[nPos].rcBar;
if (rc.right <= nRightPosition)
continue;
if (rc.left >= nRightPosition + nLength)
break;
nRightPosition = rc.right;
}
int nLeftPosition = nPosition;
for (nPos = (int)arrInfo.GetSize() - 1; nPos >= 0; nPos--)
{
CRect rc = arrInfo[nPos].rcBar;
if (rc.left >= nLeftPosition + nLength)
continue;
if (rc.right <= nLeftPosition)
break;
nLeftPosition = rc.left - nLength;
}
if (nLeftPosition < 0)
nLeftPosition = nRightPosition;
if (abs(nRightPosition - nPosition) < abs(nLeftPosition - nPosition))
pNewBlock->SetPosition(nRightPosition);
else
pNewBlock->SetPosition(nLeftPosition);
}
}
BOOL CXTPTrackControlItem::OnLButtonDown(XTP_REPORTRECORDITEM_CLICKARGS* pClickArgs)
{
CXTPTrackControl* pControl = (CXTPTrackControl*)pClickArgs->pControl;
CPoint point = pClickArgs->ptClient;
CPoint ptFrom(point);
pControl->ClientToScreen(&point);
CRect rc = pClickArgs->rcItem;
pControl->ClientToScreen(&rc);
//pControl->SetFocusedRow(pClickArgs->pRow, FALSE, FALSE);
CRect rcControl = pControl->GetReportRectangle();
m_pControl->ClientToScreen(&rcControl);
CXTPTrackBlock* pBlock = HitTest(ptFrom);
if (pBlock && !pBlock->IsLocked())
{
BOOL bShiftKey = (GetKeyState(VK_SHIFT) < 0);
BOOL bControlKey = (GetKeyState(VK_CONTROL) < 0);
BOOL bChanged = FALSE;
BOOL bSelected(FALSE);
for (int iG = 0; iG < (int ) pControl->GetSelectedBlocks()->GetCount(); iG++)
{
CXTPTrackBlock* pSelBlock = (CXTPTrackBlock* ) pControl->GetSelectedBlocks()->GetAt(iG);
if (pSelBlock == pBlock)
{
if (bControlKey)
{
pControl->GetSelectedBlocks()->RemoveAt(iG);
bChanged = TRUE;
}
bSelected = TRUE;
break;
}
}
if (!bSelected)
{
if (!bShiftKey && !bControlKey)
{
pControl->GetSelectedBlocks()->RemoveAll();
}
pControl->GetSelectedBlocks()->Add(pBlock);
bChanged = TRUE;
}
if (bChanged)
{
pControl->SendMessageToParent(XTP_NM_TRACK_SELECTEDBLOCKSCHANGED);
}
pControl->RedrawControl();
if (pControl->m_bAllowBlockScale && pBlock->IsResizable() && pBlock->GetRect().left >= ptFrom.x - 4)
{
pControl->StartDragBlocks(1);
}
else if (pControl->m_bAllowBlockScale && pBlock->IsResizable() && pBlock->GetRect().right <= ptFrom.x + 4)
{
pControl->StartDragBlocks(2);
}
else if (pControl->m_bAllowBlockMove)
{
pControl->StartDragBlocks(0);
}
}
else
{
pControl->GetSelectedBlocks()->RemoveAll();
pControl->RedrawControl();
pControl->StartDragSelection();
}
return TRUE;
}
BOOL CXTPTrackControlItem::OnLButtonUp(XTP_REPORTRECORDITEM_CLICKARGS* pClickArgs)
{
UNREFERENCED_PARAMETER(pClickArgs);
return TRUE;
}
void CXTPTrackControlItem::OnClick(XTP_REPORTRECORDITEM_CLICKARGS* pClickArgs)
{
if (!pClickArgs || !pClickArgs->pControl)
return;
if (OnLButtonUp(pClickArgs))
return;
InternalAddRef();
CMDTARGET_ADDREF(pClickArgs->pColumn);
CMDTARGET_ADDREF(pClickArgs->pControl);
CXTPReportRow* pRow = pClickArgs->pRow;
CMDTARGET_ADDREF(pRow);
pClickArgs->pControl->SendMessageToParent(pClickArgs->pRow, this, pClickArgs->pColumn,
NM_CLICK, &pClickArgs->ptClient);
CMDTARGET_RELEASE(pRow);
CMDTARGET_RELEASE(pClickArgs->pColumn);
CMDTARGET_RELEASE(pClickArgs->pControl);
InternalRelease();
}
void CXTPTrackControlItem::OnDblClick(XTP_REPORTRECORDITEM_CLICKARGS* pClickArgs)
{
if (!pClickArgs || !pClickArgs->pControl)
return;
if (OnLButtonDown(pClickArgs))
return;
CXTPReportControl* pControl = pClickArgs->pControl;
pControl->SendMessageToParent(pClickArgs->pRow, this, pClickArgs->pColumn, NM_DBLCLK, &pClickArgs->ptClient, -1);
}
CXTPTrackBlock* CXTPTrackControlItem::HitTest(CPoint ptPoint)
{
CXTPTrackBlock* pClip = NULL;
for (int j = 0; j < (int) m_arrBlocks.GetSize(); j++)
{
CXTPTrackBlock* pBlock = m_arrBlocks.GetAt(j);
if (pBlock->GetRect().PtInRect(ptPoint))
{
if (pBlock->IsKey())
return pBlock;
pClip = pBlock;
}
}
return pClip;
}
void CXTPTrackControlItem::OnMouseMove(UINT nFlags, CPoint point, CXTPReportControl* pControl)
{
UNREFERENCED_PARAMETER(nFlags);
CXTPReportRow* pRow = pControl->HitTest(point);
if (pRow)
{
CXTPTrackBlock* pBlock = HitTest(point);
if (pBlock && !pBlock->IsLocked())
{
if (((CXTPTrackControl*)pControl)->m_bAllowBlockScale && pBlock->IsResizable()
&& (pBlock->GetRect().left >= point.x - 4 || pBlock->GetRect().right <= point.x + 4))
{
::SetCursor(((CXTPTrackControl*)pControl)->m_hResizeCursor);
}
else if (((CXTPTrackControl*)pControl)->m_bAllowBlockMove)
{
::SetCursor(((CXTPTrackControl*)pControl)->m_hMoveCursor);
}
}
}
}
void CXTPTrackControlItem::RemoveAll()
{
CXTPTrackUndoManager* pUndoManager = m_pControl ? GetTrackControl()->GetUndoManager() : NULL;
if (pUndoManager) pUndoManager->StartGroup();
int N = (int) m_arrBlocks.GetSize();
for (int j = 0; j < N; j++)
{
CXTPTrackBlock* pBlock = m_arrBlocks.GetAt(j);
if (pUndoManager) pUndoManager->AddUndoCommand(new CXTPTrackUndoDeleteBlockCommand(pBlock));
pBlock->InternalRelease();
}
if (pUndoManager) pUndoManager->EndGroup();
m_arrBlocks.RemoveAll();
RedrawControl();
}
BOOL CXTPTrackControlItem::Remove(CXTPTrackBlock* pPassedBlock)
{
ASSERT(pPassedBlock->m_pItem == this);
int j, N = (int) m_arrBlocks.GetSize();
for (j = 0; j < N; j++)
{
CXTPTrackBlock* pBlock = m_arrBlocks.GetAt(j);
if (pBlock == pPassedBlock)
{
return RemoveAt(j);
}
}
return FALSE;
}
BOOL CXTPTrackControlItem::RemoveAt(int nIndex)
{
if (nIndex < 0 || nIndex >= m_arrBlocks.GetSize())
return FALSE;
CXTPTrackBlock* pBlock = m_arrBlocks[nIndex];
if (m_pControl)
{
GetTrackControl()->GetUndoManager()->AddUndoCommand(new CXTPTrackUndoDeleteBlockCommand(pBlock));
}
m_arrBlocks.RemoveAt(nIndex);
pBlock->InternalRelease();
for (int j = nIndex; j < m_arrBlocks.GetSize(); j++)
{
m_arrBlocks[j]->m_nIndex = j;
}
RecalcLayout();
RedrawControl();
return TRUE;
}
CXTPTrackBlock* CXTPTrackControlItem::Add(CXTPTrackBlock* pBlock)
{
pBlock->m_nIndex = (int)m_arrBlocks.Add(pBlock);
pBlock->m_pItem = this;
if (m_pControl)
{
GetTrackControl()->GetUndoManager()->AddUndoCommand(new CXTPTrackUndoAddBlockCommand(pBlock));
}
RecalcLayout();
RedrawControl();
return pBlock;
}
INT_PTR CXTPTrackControlItem::OnToolHitTest(CPoint point, TOOLINFO* pTI)
{
CXTPTrackBlock* pBlock = HitTest(point);
if (pBlock != NULL)
{
CString strTip = pBlock->GetTooltip();
CXTPToolTipContext::FillInToolInfo(pTI, m_pControl->m_hWnd, pBlock->GetRect(), (INT_PTR)pBlock, strTip);
return (INT_PTR)pBlock;
}
return (INT_PTR)this;
}
void CXTPTrackControlItem::RedrawControl()
{
if (m_pControl) m_pControl->RedrawControl();
}
#ifdef _XTP_ACTIVEX
BEGIN_DISPATCH_MAP(CXTPTrackControlItem, CXTPReportRecordItem)
DISP_PROPERTY_EX_ID(CXTPTrackControlItem, "Block", 1000, OleGetBlock, SetNotSupported, VT_DISPATCH)
DISP_PROPERTY_EX_ID(CXTPTrackControlItem, "BlockCount", 1001, OleGetBlockCount, SetNotSupported, VT_I4)
DISP_FUNCTION_ID(CXTPTrackControlItem, "AddBlock", 1002, OleAddBlock, VT_DISPATCH, VTS_BOOL VTS_I4 VTS_I4)
DISP_PROPERTY_EX_ID(CXTPTrackControlItem, "Locked", 1003, OleGetLocked, OleSetLocked, VT_BOOL)
DISP_FUNCTION_ID(CXTPTrackControlItem, "RemoveBlock", 1004, OleRemoveBlock, VT_EMPTY, VTS_I4)
DISP_FUNCTION_ID(CXTPTrackControlItem, "RemoveAllBlocks", 1005, RemoveAll, VT_EMPTY, VTS_NONE)
END_DISPATCH_MAP()
// {ABC89CE5-E015-4f87-885D-DE3326A63BEA}
static const GUID IID_ITrackControlItem =
{ 0xabc89ce5, 0xe015, 0x4f87, { 0x88, 0x5d, 0xde, 0x33, 0x26, 0xa6, 0x3b, 0xea } };
BEGIN_INTERFACE_MAP(CXTPTrackControlItem, CXTPReportRecordItem)
INTERFACE_PART(CXTPTrackControlItem, IID_ITrackControlItem, Dispatch)
END_INTERFACE_MAP()
IMPLEMENT_OLETYPELIB_EX(CXTPTrackControlItem, IID_ITrackControlItem)
LPDISPATCH CXTPTrackControlItem::OleGetBlock(int nIndex)
{
return XTPGetDispatch(GetBlock(nIndex));
}
int CXTPTrackControlItem::OleGetBlockCount()
{
return GetBlockCount();
}
LPDISPATCH CXTPTrackControlItem::OleAddBlock(BOOL bKey, int nPosition, int nLength)
{
CXTPTrackBlock* pBlock = bKey ? new CXTPTrackKey() : new CXTPTrackBlock();
pBlock->SetPosition(nPosition);
pBlock->SetLength(nLength);
Add(pBlock);
return XTPGetDispatch(pBlock);
}
BOOL CXTPTrackControlItem::OleGetLocked()
{
return m_bLocked;
}
void CXTPTrackControlItem::OleSetLocked(BOOL bLocked)
{
if (bLocked != m_bLocked)
{
m_bLocked = bLocked;
if (m_pControl) m_pControl->RedrawControl();
}
}
void CXTPTrackControlItem::OleRemoveBlock(int nIndex)
{
RemoveAt(nIndex);
}
#endif