📄 stockgraph.cpp
字号:
int nNewLen = m_nIndexEnd - m_nIndexStart;
while( nOldLen * nOldThick > nNewLen * m_nThickness )
{
int nTemp = m_nThickness;
m_nThickness = GetNextThickness( m_nThickness, TRUE );
if( nTemp == m_nThickness )
break;
}
}
else if( nClickBegin > nClickEnd ) // 缩小
{
m_nThickness = GetNextThickness( m_nThickness, FALSE );
m_nThickness = GetNextThickness( m_nThickness, FALSE );
m_nThickness = GetNextThickness( m_nThickness, FALSE );
}
DrawStock( NULL );
}
}
}
void CStockGraph::OnMouseMove( UINT nFlags, CPoint point )
{
// Size Border
if( m_bCursorBorder && GetCapture() == m_pParent->GetSafeHwnd() )
{
DrawBorderMovingLine( NULL, m_ptLastMovingLine, TRUE );
DrawBorderMovingLine( NULL, point, TRUE );
m_ptLastMovingLine = point;
return;
}
int nPosSelectBorder = -1;
if( m_rectCenter.PtInRect(point) )
{
CRect rect = m_rectKLine;
for( int i=0; i<m_arcTech.GetSize(); i++ )
{
rect.top = rect.bottom-5;
rect.bottom = rect.bottom+5;
if( rect.PtInRect(point) )
nPosSelectBorder = i;
rect = m_arcTech[i];
}
}
if( -1 != nPosSelectBorder )
{
::SetCursor( AfxGetApp()->LoadCursor(AFX_IDC_VSPLITBAR) );
m_bCursorBorder = TRUE;
m_nPosSelectBorder = nPosSelectBorder;
}
if( -1 == nPosSelectBorder && m_bCursorBorder && GetCapture() != m_pParent->GetSafeHwnd() )
{
::SetCursor( AfxGetApp()->LoadCursor(IDC_ARROW) );
m_bCursorBorder = FALSE;
}
if( m_bCursorBorder )
return;
// Selection Rect
if( GetCapture() == m_pParent->GetSafeHwnd() )
{
DrawSelectionRect( NULL, m_ptSelectBegin, m_ptSelectEnd, FALSE );
m_ptSelectEnd = point;
if( m_ptSelectEnd.x <= m_rectKLineCenter.left )
m_ptSelectEnd.x = m_rectKLineCenter.left+1;
if( m_ptSelectEnd.x >= m_rectKLineCenter.right )
m_ptSelectEnd.x = m_rectKLineCenter.right-1;
if( m_ptSelectEnd.y <= m_rectKLineCenter.top )
m_ptSelectEnd.y = m_rectKLineCenter.top+1;
if( m_ptSelectEnd.y >= m_rectKLineCenter.bottom )
m_ptSelectEnd.y = m_rectKLineCenter.bottom-1;
DrawSelectionRect( NULL, m_ptSelectBegin, m_ptSelectEnd, TRUE );
}
}
void CStockGraph::OnRButtonDown( UINT nFlags, CPoint point, BOOL bShiftPressed, BOOL bCtrlPressed )
{
SelectTechID( point );
}
void CStockGraph::OnReturn( BOOL bShiftPressed, BOOL bCtrlPressed )
{
if( m_nIndexCurrent >= 0 )
{
CKData &kdata = m_CurStock.GetKData( m_nCurKType );
if( m_nIndexCurrent < kdata.GetSize() )
{
if( -1 != m_dwLatestDate && kdata.ElementAt(m_nIndexCurrent).m_date > m_dwLatestDate )
{
KDATA & kd = kdata.ElementAt(m_nIndexCurrent);
if( m_pParent && ::IsWindow( m_pParent->GetSafeHwnd() ) )
m_pParent->SetFocus( );
}
}
}
}
UINT CStockGraph::GetSelectedTech( )
{
return m_nSelectedTechID;
}
void CStockGraph::HideSelectedTech()
{
AfxGetProfile().ToggleGraphViewTech( m_nSelectedTechID );
if( m_pParent && ::IsWindow(m_pParent->GetSafeHwnd()) )
{
ResetClient( m_rectAll );
m_pParent->Invalidate();
}
}
void CStockGraph::MoveTo( int nIndex, BOOL bShiftPressed, BOOL bCtrlPressed )
{
DrawSelectionLine( NULL, FALSE );
// To Change m_anIndexCurrent
if( bShiftPressed && nIndex >= 0 )
{
if( m_nIndexCurrent < 0 )
{
AddIndexCurrent( nIndex );
}
else if( m_nIndexCurrent <= nIndex )
{
for( int nSel=m_nIndexCurrent; nSel<=nIndex; nSel++ )
{
AddIndexCurrent( nSel );
}
}
else
{
for( int nSel=nIndex; nSel<=m_nIndexCurrent; nSel++ )
{
AddIndexCurrent( nSel );
}
}
}
else if( bCtrlPressed && nIndex >= 0 )
{
AddIndexCurrent( nIndex );
}
else
{
m_anIndexCurrent.RemoveAll();
}
BOOL bNeedDrawAll = FALSE;
if( -1 != nIndex && nIndex < m_nIndexStart )
{
m_nIndexEnd -= (m_nIndexStart-nIndex);
m_nIndexStart = nIndex;
m_nIndexCurrent = nIndex;
bNeedDrawAll = TRUE;
}
if( -1 != nIndex && nIndex > m_nIndexEnd )
{
m_nIndexStart += (nIndex-m_nIndexEnd);
m_nIndexEnd = nIndex;
m_nIndexCurrent = nIndex;
bNeedDrawAll = TRUE;
}
if( m_nIndexCurrent != nIndex )
{
int nOld = m_nIndexCurrent;
m_nIndexCurrent = nIndex;
OnIndexCurrentChanged( );
}
if( bNeedDrawAll )
DrawStock( NULL );
else
DrawSelectionLine( NULL, TRUE );
}
void CStockGraph::OnIndexCurrentChanged( )
{
if( m_pParent && ::IsWindow(m_pParent->GetSafeHwnd()) )
{
CClientDC dc(m_pParent);
CRect rectKLineAttrib = m_rectKLineCenter;
rectKLineAttrib.top -= m_nHeightSubtitle;
CSPDWordArray & anTech = AfxGetProfile().GetGraphTechsKLine();
if( anTech.GetSize() > 0 )
DrawKLineAttribute( &dc, anTech[0], rectKLineAttrib, TRUE, 0, 0 );
CSPDWordArray & anShow = AfxGetProfile().GetGraphTechsShow( );
for( int k=0; k<m_arcTech.GetSize(); k++ )
{
CRect rect = m_arcTech.ElementAt(k);
if( k < anShow.GetSize() && anShow[k] == STT_MIKE )
{
DrawTechLine( &dc, anShow[k], rect, FALSE );
DrawTechLine( &dc, anShow[k], rect, TRUE );
}
else if( k < anShow.GetSize() )
{
DrawTechLine( &dc, anShow[k], rect, TRUE );
}
}
DrawReportRegion( &dc );
DrawKData( );
}
}
void CStockGraph::Move( int nMove, BOOL bShiftPressed, BOOL bCtrlPressed )
{
int nIndexCurrent = m_nIndexCurrent;
if( nIndexCurrent < 0 )
{
if( nMove < 0 )
nIndexCurrent = m_nIndexEnd;
else if( nMove > 0 )
nIndexCurrent = m_nIndexStart;
}
else
{
nIndexCurrent += nMove;
}
CKData &kdata = m_CurStock.GetKData( m_nCurKType );
if( nIndexCurrent < 0 )
nIndexCurrent = 0;
if( nIndexCurrent >= kdata.GetSize() )
nIndexCurrent = kdata.GetSize()-1;
MoveTo( nIndexCurrent, bShiftPressed, bCtrlPressed );
}
int CStockGraph::GetIndexClick( CPoint point )
{
int nIndexClick = -1;
if( m_rectCenter.PtInRect( point ) )
{
for( int nIndex=m_nIndexStart; nIndex<=m_nIndexEnd; nIndex ++ )
{
CRect rectK;
if( GetOneKLineRect( nIndex, &rectK, NULL, NULL, NULL ) && rectK.PtInRect(point) )
{
nIndexClick = nIndex;
break;
}
}
}
return nIndexClick;
}
void CStockGraph::SelectTechID( CPoint point )
{
m_nSelectedTechID = STT_INVALID;
int nTechClick = -1;
for( int k=0; k<m_arcTech.GetSize(); k++ )
{
if( m_arcTech.ElementAt(k).PtInRect( point ) )
{
nTechClick = k;
break;
}
}
CSPDWordArray & anTech = AfxGetProfile().GetGraphTechsShow();
if( nTechClick >= 0 && nTechClick < m_arcTech.GetSize() && nTechClick < anTech.GetSize() )
{
m_nSelectedTechID = anTech.ElementAt(nTechClick);
}
}
BOOL CStockGraph::AddIndexCurrent( int nIndex )
{
for( int k=0; k<m_anIndexCurrent.GetSize(); k++ )
{
if( (UINT)nIndex == m_anIndexCurrent[k] )
return FALSE;
}
m_anIndexCurrent.Add( nIndex );
return TRUE;
}
void CStockGraph::InvalidateCenter( )
{
if( !m_pParent || !::IsWindow(m_pParent->GetSafeHwnd()) )
return;
CClientDC dc(m_pParent);
DrawDateAxis( &dc );
DrawTechLine( &dc );
DrawKLine( &dc );
}
BOOL CStockGraph::GetOneKLineRect( int nIndex, LPRECT lpRect, long *pxEntityLeft, long *pxEntityRight, long *pxMedium )
{
if( nIndex == -1 || nIndex < m_nIndexStart || nIndex > m_nIndexEnd )
return FALSE;
CRect rectK = m_rectCenter;
rectK.left = m_rectKLineCenter.left + (nIndex-m_nIndexStart) * m_nThickness;
rectK.right = rectK.left + m_nThickness;
if( rectK.Width() <= 0 || rectK.Height() <= 0 )
return FALSE;
if( lpRect )
*lpRect = rectK;
int xStart = rectK.left;
CRect rcEntity;
switch( m_nThickness )
{
case 1:
case 2:
rcEntity.left = xStart;
rcEntity.right = xStart + 1;
break;
case 4:
case 5:
rcEntity.left = xStart;
rcEntity.right = xStart + 3;
break;
case 6:
case 7:
rcEntity.left = xStart;
rcEntity.right = xStart + 5;
break;
case 9:
case 10:
rcEntity.left = xStart;
rcEntity.right = xStart + 7;
break;
case 13:
case 15:
rcEntity.left = xStart;
rcEntity.right = xStart + 11;
break;
default:
ASSERT( FALSE );
rcEntity.left = xStart;
rcEntity.right = xStart + 3;
return FALSE;
}
if( pxEntityLeft )
*pxEntityLeft = rcEntity.left;
if( pxEntityRight )
*pxEntityRight = rcEntity.right;
if( pxMedium )
*pxMedium = rcEntity.left + rcEntity.Width() / 2;
return TRUE;
}
void CStockGraph::DrawStock( CDC * pDC )
{
ASSERT( m_pParent && ::IsWindow( m_pParent->GetSafeHwnd() ) );
if( !m_pParent || !::IsWindow(m_pParent->GetSafeHwnd()) )
return;
CClientDC dc(m_pParent);
if( NULL == pDC )
pDC = &dc;
if( !m_CurStock.GetStockInfo().IsValidStock() )
return;
CKData & kdata = m_CurStock.GetKData(m_nCurKType);
if( kdata.GetSize() == 0 )
{
DrawNoDataInfo( pDC );
}
else if( PrepareDrawKLine( ) ) // Reset m_nIndexStart, m_nIndexEnd, m_nIndexCurrent
{
DrawDateAxis( pDC );
DrawTechLine( pDC );
DrawKLine( pDC );
DrawKData( );
}
DrawReportRegion( pDC );
}
BOOL CStockGraph::PrepareDrawKLine( )
{
ASSERT( m_nThickness > 0 );
if( m_nThickness <= 0 || m_rectKLineCenter.Width() <= 0 )
return FALSE;
CKData & kdata = m_CurStock.GetKData(m_nCurKType);
int nWidth = m_rectKLineCenter.Width();
int nCount = nWidth / m_nThickness;
if( nCount <= 0 )
return FALSE;
if( kdata.GetSize() == 0 )
{
m_nIndexCurrent = m_nIndexStart = m_nIndexEnd = -1;
return FALSE;
}
// Check Old Values
ASSERT( m_nIndexStart <= m_nIndexEnd );
ASSERT( m_nIndexCurrent < 0 || (m_nIndexCurrent >= m_nIndexStart && m_nIndexCurrent <= m_nIndexEnd) );
if( m_nIndexCurrent >= 0 && (m_nIndexCurrent < m_nIndexStart || m_nIndexCurrent > m_nIndexEnd) )
m_nIndexCurrent = -1;
if( -1 == m_nIndexStart || -1 == m_nIndexEnd )
{
m_nIndexEnd = kdata.GetSize()-1;
}
else if( m_nIndexEnd - m_nIndexStart + 1 < nCount )
{
// Reset m_nIndexStart and m_nIndexEnd
int nExpand = nCount-(m_nIndexEnd-m_nIndexStart+1);
if( m_nIndexCurrent >= 0 && m_nIndexEnd-m_nIndexStart > 0 )
m_nIndexEnd += (m_nIndexEnd-m_nIndexCurrent)*nExpand / (m_nIndexEnd-m_nIndexStart);
}
else if( m_nIndexEnd - m_nIndexStart + 1 > nCount )
{
int nReduce = (m_nIndexEnd-m_nIndexStart+1)-nCount;
if( m_nIndexCurrent >= 0 && m_nIndexEnd-m_nIndexStart > 0 )
m_nIndexEnd -= (m_nIndexEnd-m_nIndexCurrent)*nReduce / (m_nIndexEnd-m_nIndexStart);
}
if( m_nIndexEnd >= kdata.GetSize() )
m_nIndexEnd = kdata.GetSize()-1;
m_nIndexStart = m_nIndexEnd - nCount + 1;
if( m_nIndexStart < 0 )
{
m_nIndexEnd += (-m_nIndexStart);
m_nIndexStart = 0;
}
if( m_nIndexEnd >= kdata.GetSize() )
m_nIndexEnd = kdata.GetSize()-1;
ASSERT( m_nIndexStart <= m_nIndexEnd );
ASSERT( m_nIndexCurrent < 0 || (m_nIndexCurrent >= m_nIndexStart && m_nIndexCurrent <= m_nIndexEnd) );
if( m_nIndexStart > m_nIndexEnd )
return FALSE;
if( m_nIndexCurrent >= 0 && (m_nIndexCurrent < m_nIndexStart || m_nIndexCurrent > m_nIndexEnd) )
m_nIndexCurrent = -1;
return TRUE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -