⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 stockgraph.cpp

📁 股软 通达信行情接收接口, 包括美元汇率
💻 CPP
📖 第 1 页 / 共 5 页
字号:
// StockGraph.cpp : implementation of the CStockGraph class
//

#include "stdafx.h"

#include "StockGraph.h"
#include <math.h>

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// Some Useful static function

void DrawLine( CDC * pDC, int nWidth, COLORREF clr, int xStart, int yStart, int xEnd, int yEnd )
{
	CPen	pen( PS_SOLID, nWidth, clr );
	CPen *pOldPen = pDC->SelectObject( &pen );
	pDC->MoveTo( xStart, yStart );
	pDC->LineTo( xEnd, yEnd );
	pDC->SelectObject( pOldPen );
}

void DrawDashLine( CDC * pDC, int nWidth, COLORREF clr, int xStart, int yStart, int xEnd, int yEnd )
{
	CPen	pen( PS_SOLID, nWidth, clr );
	CPen *pOldPen = pDC->SelectObject( &pen );
	int	x = xStart, y = yStart;
	while( x < xEnd || y < yEnd )
	{
		if( x > xEnd )	x	=	xEnd;
		if( y > yEnd )	y	=	yEnd;
		pDC->MoveTo( x, y );
		int	xNew = x+3;
		int	yNew = y+3;
		if( xNew > xEnd )	xNew	=	xEnd;
		if( yNew > yEnd )	yNew	=	yEnd;
		pDC->LineTo( xNew, yNew );
		x	=	xNew+3;
		y	=	yNew+3;
	}
	pDC->SelectObject( pOldPen );
}

void DrawDashAxis( CDC * pDC, int nWidth, COLORREF clr, int nCount, int xStart, int yStart, int xEnd, int yEnd )
{
	int	nHeight	=	yEnd - yStart;
	if( nHeight <= 0 )
		return;
	if( nCount <= 0 )
		return;
	for( int k=0; k<nCount; k++ )
		DrawDashLine( pDC, nWidth, clr, xStart, yStart+k*nHeight/nCount, xEnd, yStart+k*nHeight/nCount );
}

void DrawAxisNumber(CDC * pDC, COLORREF clr, int nCount,
					int xStart, int yStart, int xEnd, int yEnd,
					double fMin, double fMax, BOOL bDrawMin, BOOL bDrawMax, int nDotCount )
{
	int	nHeight	=	yEnd - yStart;
	if( nHeight <= 0 )
		return;
	if( nCount <= 0 )
		return;
	ASSERT( nDotCount >= 0 );

	CString	strFmt;
	strFmt.Format( "%%.%df", nDotCount );

	pDC->SetTextColor( clr );
	CString	strText;
	CSize	sizeText;
	
	for( int k=0; k<=nCount; k++ )
	{
		if( !bDrawMin && 0 == k )
			continue;
		if( !bDrawMax && nCount == k )
			continue;
		double	dTemp	=	fMin+k*(fMax-fMin)/nCount;
		if( dTemp < 0 && dTemp > (0-0.6*pow((double)10,0-nDotCount)) )
			dTemp	=	0;
		strText.Format( strFmt, dTemp );
		sizeText	=	pDC->GetTextExtent( strText );
		pDC->TextOut( xStart-sizeText.cx-1, yStart+(nCount-k)*nHeight/nCount-7, strText );
	}
}

BOOL DrawAxis(CDC * pDC, CRect rect, int nMarginTop, int nAxisLines, double dMin, double dMax, BOOL bDrawMin, BOOL bDrawMax, int nDotCount )
{
	DECLARE_COLOR_DEFINATION

	if( rect.Height() <= nMarginTop )
		return FALSE;

	// Draw Axis
	pDC->Draw3dRect( &rect, clrBorder, clrBorder );
	DrawDashAxis(	pDC, 1, clrBorder, nAxisLines,
					rect.left, rect.top+nMarginTop, rect.right, rect.bottom );

	// Draw Axis Number, Will Extent the rect
	pDC->SetBkColor( clrBK );
	DrawAxisNumber( pDC, clrText, nAxisLines,
					rect.left, rect.top+nMarginTop, rect.right, rect.bottom,
					dMin, dMax, bDrawMin, bDrawMax, nDotCount );
	return TRUE;
}

BOOL DrawTechTitle(CDC * pDC, int x, int y, LPCTSTR lpszText,
				   UINT nTextAlign, int nFontSize, COLORREF clrBK, COLORREF clrText )
{
	pDC->SetBkColor( clrBK );
	pDC->SetTextColor( clrText );
	UINT nOldAlign = pDC->SetTextAlign( nTextAlign );
	pDC->TextOut( x, y, lpszText );
	pDC->SetTextAlign( nOldAlign );
	return TRUE;
}

BOOL FixRect( CRect & rect, LPRECT lpRectMax )
{
	if( lpRectMax )
	{
		if( rect.left < lpRectMax->left )
			rect.left	=	lpRectMax->left;
		if( rect.top < lpRectMax->top )
			rect.top	=	lpRectMax->top;
		if( rect.right > lpRectMax->right )
			rect.right	=	lpRectMax->right;
		if( rect.bottom > lpRectMax->bottom )
			rect.bottom	=	lpRectMax->bottom;
		return TRUE;
	}
	return FALSE;
}

BOOL DrawTextWithRect(CDC *pDC, int left, int top, int right, int bottom, LPCTSTR lpszText,
					  COLORREF clrRect, COLORREF clrText, COLORREF clrBK, LPRECT lpRectMax )
{
	CRect	rectDraw	=	CRect( left, top, right, bottom );
	if( lpRectMax )
		FixRect( rectDraw, lpRectMax );
	pDC->Draw3dRect( &rectDraw, clrRect, clrRect );
	pDC->SetTextColor( clrText );
	pDC->SetBkColor( clrBK );
	pDC->DrawText( lpszText, rectDraw, DT_CENTER | DT_VCENTER | DT_SINGLELINE );
	return TRUE;
}

BOOL DrawTextWithRect(CDC *pDC, int left, int top, int right, int bottom, UINT nIDString,
					  COLORREF clrRect, COLORREF clrText, COLORREF clrBK, LPRECT lpRectMax )
{
	CString	string;
	string.LoadString( nIDString );
	return DrawTextWithRect( pDC, left, top, right, bottom, string, clrRect, clrText, clrBK, lpRectMax );
}

/////////////////////////////////////////////////////////////////////////////
// CStockGraph

CStockGraph::CStockGraph( )
{
	ResetMargins( );

	m_pParent		=	NULL;
	m_nThickness	=	m_nDefaultThickness;
	m_dwLatestDate		=	-1;

	m_ptSelectBegin	=	CPoint(0,0);
	m_ptSelectEnd	=	CPoint(0,0);

	m_nReportWhat	=	CStockGraph::reportParam;

	SetKType( );
	SetKFormat( AfxGetProfile().GetGraphKFormat() );
	SetMaindataType( AfxGetProfile().GetGraphMaindataType() );
#ifdef	CLKLAN_ENGLISH_US
	SetKLineMode( CStockGraph::klineAmerica );
#else
	SetKLineMode( CStockGraph::klineCandle );
#endif
	ResetIndex( );

	m_rectAll.SetRectEmpty();

	m_dMaxPrice			=	0;
	m_dMinPrice			=	0;

	m_bCursorBorder		=	FALSE;

	m_nSelectedTechID	=	STT_INVALID;
}

CStockGraph::~CStockGraph( )
{
	ClearCurStock( );
}

void CStockGraph::SetParent( CWnd * pParent )
{
	m_pParent	=	pParent;
}

void CStockGraph::ResetMargins(	int nMarginTop, int nMarginBottom,
								int nHeightSubtitle, int nWidthSubtitle,
								int nWidthParameter, int nDefaultThickness )
{
	ASSERT( nMarginTop >= 0 && nMarginBottom >= 0 );
	ASSERT( nHeightSubtitle >= 0 && nWidthSubtitle >= 0 );
	ASSERT( nWidthParameter >= 0 );
	ASSERT( nDefaultThickness > 0 );

	m_nMarginTop		=	nMarginTop;
	m_nMarginBottom		=	nMarginBottom;
	m_nHeightSubtitle	=	nHeightSubtitle + 2;
	m_nWidthSubtitle	=	nWidthSubtitle;
	m_nWidthParameter	=	nWidthParameter;
	m_nDefaultThickness	=	nDefaultThickness;
}

LRESULT CStockGraph::OnStkReceiverData( WPARAM wParam, LPARAM lParam )
{
	PCOMMPACKET	pCommPacket	=	(PCOMMPACKET)lParam;

	switch( wParam )
	{
	case CStock::dataReport:
		if( pCommPacket && CStock::dataReport == pCommPacket->m_dwDataType )
		{
			DWORD i;
			for( i=0; i<pCommPacket->m_dwCount; i++ )
			{
				if( m_CurStock.GetStockInfo().IsEqualTo( pCommPacket->m_pReport[i].m_dwMarket, pCommPacket->m_pReport[i].m_szCode ) )
					break;
			}
			if( i != pCommPacket->m_dwCount )
			{
				// 加入最新一天的K线数据
				PrepareStockData( TRUE );
				if( m_pParent && ::IsWindow(m_pParent->GetSafeHwnd()) )
					m_pParent->Invalidate();
			}
		}
		break;
	case CStock::dataK:
		if( pCommPacket && CStock::dataK == pCommPacket->m_dwDataType )
		{
			DWORD i;
			for( i=0; i<pCommPacket->m_dwCount; i++ )
			{
				if( m_CurStock.GetStockInfo().IsEqualTo( pCommPacket->m_pKdata[i].m_dwMarket, pCommPacket->m_pKdata[i].m_szCode ) )
					break;
			}
			if( i != pCommPacket->m_dwCount )
			{
				// 加入最新一天的K线数据
				PrepareStockData( TRUE );
				if( m_pParent && ::IsWindow(m_pParent->GetSafeHwnd()) )
					m_pParent->Invalidate();
			}
		}
		break;
	case CStock::dataMinute:
		// WILLCHECK
		if( !CKData::IsDayOrMin(m_nCurKType) && pCommPacket && CStock::dataMinute == pCommPacket->m_dwDataType )
		{
			int	nOldSize	=	m_CurStock.GetMinute().GetSize();
			DWORD i;
			for(i=0; i<pCommPacket->m_dwCount; i++)
			{
				if( m_CurStock.GetStockInfo().IsEqualTo( pCommPacket->m_pMinute[i].m_dwMarket, pCommPacket->m_pMinute[i].m_szCode ) )
					break;
			}
			if( i != pCommPacket->m_dwCount )
			{
				// 加入最新的分钟K线数据
				PrepareStockData( TRUE );
				if( m_pParent && ::IsWindow(m_pParent->GetSafeHwnd()) )
					m_pParent->Invalidate();
			}
		}
		break;
	}

	return 0L;
}

int CStockGraph::GetKType( )
{
	return m_nCurKType;
}

void CStockGraph::SetKType( int ktype )
{
	m_nCurKType	=	ktype;
	PrepareStockData( );
}

int CStockGraph::GetKFormat( )
{
	return m_nCurKFormat;
}

void CStockGraph::SetKFormat( int kformat )
{
	m_nCurKFormat	=	kformat;
	AfxGetProfile().SetGraphKFormat( kformat );
	PrepareStockData( );
}

int CStockGraph::GetMaindataType( )
{
	return m_nCurMaindataType;
}

void CStockGraph::SetMaindataType( int maindatatype )
{
	m_nCurMaindataType	=	maindatatype;
	AfxGetProfile().SetGraphMaindataType( maindatatype );
	PrepareStockData( );
}

int CStockGraph::GetKLineMode( )
{
	return m_nCurKLineMode;
}

void CStockGraph::SetKLineMode( int klineMode )
{
	m_nCurKLineMode	=	klineMode;
}

CRect & CStockGraph::GetKDataRect( )
{
	return m_rectKData;
}

void CStockGraph::ResetIndexCurrent( int nIndexCurrent )
{
	m_nIndexCurrent	=	nIndexCurrent;
	m_anIndexCurrent.RemoveAll();
}

void CStockGraph::ResetIndex( int nIndexStart, int nIndexEnd, int nIndexCurrent )
{
	m_nIndexStart	=	nIndexStart;
	m_nIndexEnd		=	nIndexEnd;
	m_nIndexCurrent	=	nIndexCurrent;
	m_anIndexCurrent.RemoveAll();
}

void CStockGraph::ResetClient( CRect rectAll )
{
	if( rectAll.IsRectEmpty() )
		return;

	m_rectAll	=	rectAll;
	if( m_rectAll.IsRectEmpty() )
		return;

	//	The Left Side m_rectKData
	m_rectKData.top		=	m_rectAll.top + m_nMarginTop+m_nMarginTop;
	m_rectKData.left	=	m_rectAll.left+1;
	m_rectKData.bottom	=	m_rectKData.top + 313;
	m_rectKData.right	=	m_rectKData.left + 82;

	// The Right Side m_rectReport
	m_rectReport.top	=	m_rectAll.top + m_nMarginTop+7;
	m_rectReport.left	=	m_rectAll.right - 174;
	m_rectReport.bottom	=	m_rectAll.bottom - m_nMarginBottom;
	m_rectReport.right	=	m_rectAll.right;

	// The Center m_rectKLine
	CSPDWordArray	& anTech	=	AfxGetProfile().GetGraphTechsShow();
	int	nTechCount	=	anTech.GetSize();
	int	nUnit		=	(int)( (m_rectAll.Height()-m_nMarginTop-m_nMarginBottom) / (nTechCount+1.8) );
	m_rectKLine.top		=	m_rectAll.top + m_nMarginTop;
	m_rectKLine.left	=	m_rectKData.right+1;
	m_rectKLine.bottom	=	m_rectKLine.top + m_rectAll.Height() - m_nMarginTop - m_nMarginBottom - nUnit*nTechCount;
	m_rectKLine.right	=	m_rectAll.right-m_rectReport.Width()-1;

	// The m_rectKLineCenter
	m_rectKLineCenter	=	m_rectKLine;
	m_rectKLineCenter.InflateRect( -2, -m_nHeightSubtitle, -2, -2 );

	// The m_arcTech
	m_arcTech.RemoveAll();
	int	nLastBottom = m_rectKLine.bottom;
	for( int k=0; k<anTech.GetSize(); k++ )
	{
		CRect	rectTech;
		rectTech.top		=	nLastBottom;
		rectTech.left		=	m_rectKLine.left;
		rectTech.bottom		=	rectTech.top + nUnit;
		rectTech.right		=	m_rectKLine.right;
		nLastBottom			=	rectTech.bottom;
		m_arcTech.Add( rectTech );
	}

	// The m_rectCenter
	m_rectCenter	=	m_rectKLine;
	m_rectCenter.bottom	=	m_rectAll.bottom;
}

void CStockGraph::ClearTechniqueCache( )
{
	m_techparam.Clear();
	for( int i=0; i<m_aptrTechUser.GetSize(); i++ )
	{
		CTechUser * pTechUser = (CTechUser *)m_aptrTechUser.GetAt(i);
		if( pTechUser )
			delete	pTechUser;
	}
	m_aptrTechUser.RemoveAll();
}

void CStockGraph::ClearCurStock( )
{
	ClearTechniqueCache( );
	m_CurStock.Clear();
	m_CurStockDown.Clear();
}

BOOL CStockGraph::SetCurStock( const char * szCode )
{
	if( NULL == szCode || strlen(szCode) <= 0 )
	{
		ASSERT( FALSE );
		return FALSE;
	}

	CStockInfo	info;
	if( !AfxGetStockContainer().GetStockInfo( szCode, &info ) )
	{
		ASSERT( FALSE );
		return FALSE;
	}

	return SetCurStock( info );
}

BOOL CStockGraph::SetCurStock( CStockInfo & info )
{
	if( m_CurStock.GetStockInfo().IsEqualTo( info.GetMarket(), info.GetStockCode() ) )
	{
		return TRUE;
	}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -