#include "stdafx.h"
#include "KLine.h"
// m
IMPLEMENT_DYNCREATE(KLine, Coordinate)
KLine::KLine()
{
detailWindow = new DetailWindow();
volume = new Volume();
keyboardElves = new KeyboardElves();
}
KLine::~KLine()
{
}
BEGIN_MESSAGE_MAP(KLine, Coordinate)
ON_WM_CTLCOLOR()
ON_WM_MOUSEMOVE()
ON_WM_KEYDOWN()
END_MESSAGE_MAP()
// m 绘图
void KLine::OnDraw(CDC* pDC)
{
CDocument* pDoc = GetDocument();
// TODO: 在此添加绘制代码
Coordinate::OnDraw(pDC);
// TRACE("theApp.g_carr.GetSize在Kline:%d\n", theApp.g_carr.GetSize());
/*CDC MemDC; //首先定义一个显示设备对象
CBitmap MemBitmap;//定义一个位图对象
//随后建立与屏幕显示兼容的内存显示设备
MemDC.CreateCompatibleDC(pDC);
//这时还不能绘图,因为没有地方画 ^_^
//下面建立一个与屏幕显示兼容的位图,至于位图的大小嘛,可以用窗口的大小
MemBitmap.CreateCompatibleBitmap(pDC, 240, 320);
//将位图选入到内存显示设备中
//只有选入了位图的内存显示设备才有地方绘图,画到指定的位图上
CBitmap *pOldBit = MemDC.SelectObject(&MemBitmap);
//先用背景色将位图清除干净,这里我用的是白色作为背景
//你也可以用自己应该用的颜色
MemDC.FillSolidRect(0, 0, 240, 320, RGB(255, 0, 0));
//绘图
MemDC.MoveTo(20,40);
MemDC.LineTo(500,200);
//将内存中的图拷贝到屏幕上进行显示
pDC->BitBlt(0, 0, 240, 300, &MemDC, 0, 0, SRCCOPY);
//绘图完成后的清理
MemBitmap.DeleteObject();
MemDC.DeleteDC();*/
if (!theApp.g_carr.IsEmpty())
{
initial();
getIndicator();
drawYtick(pDC);
drawKline(pDC);
drawAverageLine(pDC, 5);
drawAverageLine(pDC, 10);
drawAverageLine(pDC, 30);
drawAverageLine(pDC, 60);
drawAverageLine(pDC, 120);
drawMouseMoveCrossVerLine(pDC);
drawMouseMoveCrossHorLine(pDC);
drawRectOnRight(pDC);
drawAverageLineDataOnTop(pDC);
}
}
void KLine::OnMouseMove(UINT nFlags, CPoint point)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
Coordinate::OnMouseMove(nFlags, point);
mousePoint = point;
if (mousePoint.x > getMarginLeft() && mousePoint.x < getWidgetWidth() - getMarginRight() && mousePoint.y > getMarginTop() && mousePoint.y < getWidgetHeight() - getMarginBottom())
{
int currentDay = (mousePoint.x - getMarginLeft()) * totalDay / getGridWidth() + beginDay;
if (currentDay < theApp.g_carr.GetSize())
{
detailWindow->receiveData(theApp.g_carr[currentDay].g_stockDay.m_lDate, theApp.g_carr[currentDay].g_stockDay.m_lOpenPrice / 1000.0,
theApp.g_carr[currentDay].g_stockDay.m_lMaxPrice / 1000.0, theApp.g_carr[currentDay].g_stockDay.m_lMinPrice / 1000.0,
theApp.g_carr[currentDay].g_stockDay.m_lClosePrice / 1000.0, theApp.g_carr[currentDay].g_stockDay.m_lTotal / 1000.0,
theApp.g_carr[currentDay].g_stockDay.m_lMoney / 1000.0);
}
volume->receiveMousePointFromOther(mousePoint);
}
// CClientDC p(this);
// OnDraw(&p);
Invalidate();
}
// m 诊断
#ifdef _DEBUG
void KLine::AssertValid() const
{
CView::AssertValid();
}
#ifndef _WIN32_WCE
void KLine::Dump(CDumpContext& dc) const
{
CView::Dump(dc);
}
#endif
#endif //_DEBUG
// m 消息处理程序
BOOL KLine::PreCreateWindow(CREATESTRUCT& cs)
{
// TODO: 在此添加专用代码和/或调用基类
cs.lpszClass = AfxRegisterWndClass(CS_HREDRAW | CS_VREDRAW, 0, (HBRUSH)::GetStockObject(BLACK_BRUSH), 0);
return CView::PreCreateWindow(cs);
}
//获取Y轴指标
void KLine::getIndicator()
{
highestBid = 0;
lowestBid = 1000000;
for (int i = beginDay; i < endDay; i++)
{
if (theApp.g_carr[i].g_stockDay.m_lMaxPrice / 1000 > highestBid)
{
highestBid = theApp.g_carr[i].g_stockDay.m_lMaxPrice / 1000;
}
if (theApp.g_carr[i].g_lineStockDay.avgLine5 / 1000 > highestBid)
{
highestBid = theApp.g_carr[i].g_lineStockDay.avgLine5 / 1000;
}
if (theApp.g_carr[i].g_lineStockDay.avgLine10 / 1000 > highestBid)
{
highestBid = theApp.g_carr[i].g_lineStockDay.avgLine10 / 1000;
}
if (theApp.g_carr[i].g_lineStockDay.avgLine30 / 1000 > highestBid)
{
highestBid = theApp.g_carr[i].g_lineStockDay.avgLine30 / 1000;
}
if (theApp.g_carr[i].g_lineStockDay.avgLine60 / 1000 > highestBid)
{
highestBid = theApp.g_carr[i].g_lineStockDay.avgLine60 / 1000;
}
if (theApp.g_carr[i].g_lineStockDay.avgLine120 / 1000 > highestBid)
{
highestBid = theApp.g_carr[i].g_lineStockDay.avgLine120 / 1000;
}
if (theApp.g_carr[i].g_stockDay.m_lMinPrice / 1000 < lowestBid)
{
lowestBid = theApp.g_carr[i].g_stockDay.m_lMinPrice / 1000;
}
if (theApp.g_carr[i].g_lineStockDay.avgLine5 / 1000 < lowestBid && theApp.g_carr[i].g_lineStockDay.avgLine5 != 0)
{
lowestBid = theApp.g_carr[i].g_lineStockDay.avgLine5 / 1000;
}
if (theApp.g_carr[i].g_lineStockDay.avgLine10 / 1000 < lowestBid && theApp.g_carr[i].g_lineStockDay.avgLine10 != 0)
{
lowestBid = theApp.g_carr[i].g_lineStockDay.avgLine10 / 1000;
}
if (theApp.g_carr[i].g_lineStockDay.avgLine30 / 1000 < lowestBid && theApp.g_carr[i].g_lineStockDay.avgLine30 != 0)
{
lowestBid = theApp.g_carr[i].g_lineStockDay.avgLine30 / 1000;
}
if (theApp.g_carr[i].g_lineStockDay.avgLine60 / 1000 < lowestBid && theApp.g_carr[i].g_lineStockDay.avgLine60 != 0)
{
lowestBid = theApp.g_carr[i].g_lineStockDay.avgLine60 / 1000;
}
if (theApp.g_carr[i].g_lineStockDay.avgLine120 / 1000 < lowestBid && theApp.g_carr[i].g_lineStockDay.avgLine120 != 0)
{
lowestBid = theApp.g_carr[i].g_lineStockDay.avgLine120 / 1000;
}
}
}
void KLine::initial()
{
//初始化一些成员变量
// TRACE(_T("theApp.g_carr.GetSize在Kline:%d\n", theApp.g_carr.GetSize()));
// TRACE(_T("i在Kline:%d\n", i));
endDay = theApp.g_carr.GetSize();
// TRACE(_T("endDay在Kline:%d\n", endDay));
totalDay = 200;
if (endDay > totalDay)
{
beginDay = endDay - totalDay;
}
else
{
beginDay = 0;
totalDay = theApp.g_carr.GetSize();
}
if (beginDay < 0)
{
beginDay = 0;
totalDay = theApp.g_carr.GetSize();
}
maxVolume = 0;
currentDay = 0;
mouseX = 0;
}
//画Y轴
void KLine::drawYtick(CDC * pDC)
{
CPen pen;
pen.CreatePen(PS_SOLID, 1, RGB(255, 0, 0));
double ystep = (highestBid - lowestBid) / getHGridNum();
CString str;
if (0 == getHGridNum())
{
str.Format("%.2f", lowestBid);
pDC->SetBkColor(RGB(0, 0, 0));
pDC->SetTextColor(RGB(255, 0, 0));
pDC->TextOut(getWidgetWidth() - getGridWidth() - getMarginLeft(), getWidgetHeight() - getMarginBottom(), _T(str));
str.Format("%.2f", highestBid);
pDC->SetBkColor(RGB(0, 0, 0));
pDC->SetTextColor(RGB(255, 0, 0));
pDC->TextOut(getWidgetWidth() - getGridWidth() - getMarginLeft(),
getMarginTop(),str);
return;
}
for (int i = 0; i <= getHGridNum(); i++)
{
str.Format("%.2f", (lowestBid + i * ystep));
pDC->SetBkColor(RGB(0, 0, 0));
pDC->SetTextColor(RGB(255, 0, 0));
pDC->TextOut(getWidgetWidth() - getGridWidth() - getMarginLeft() - 57,
getWidgetHeight() - getMarginBottom() - i * getAtomGridHeight(), str);
}
}
void KLine::drawKline(CDC * pDC)
{
CPen pen;
pen.CreatePen(PS_SOLID, 1, RGB(255, 0, 0));
pDC->SelectObject(&pen);
if (beginDay < 0)
return;
//y轴缩放
yscale = getGridHeight() / (highestBid - lowestBid);
xstep = getGridWidth() / totalDay;
for (int i = beginDay; i < endDay; i++)
{
if (theApp.g_carr[i].g_stockDay.m_lOpenPrice > theApp.g_carr[i].g_stockDay.m_lClosePrice && theApp.g_carr[i].g_stockDay.m_lOpenPrice != NULL)
{
pen.DeleteObject();
pen.CreatePen(PS_SOLID, 1, RGB(0, 255, 0));
pDC->SelectObject(&pen);
}
else
{
pen.DeleteObject();
pen.CreatePen(PS_SOLID, 1, RGB(255, 0, 0));
pDC->SelectObject(&pen);
}
lineWidth = getGridWidth() / totalDay;
//为了各个k线之间不贴在一起,设置一个间隔
lineWidth = lineWidth - 0.2*lineWidth;
//最小线宽为3
if (lineWidth < 3)
lineWidth = 3;
//阴线
if (theApp.g_carr[i].g_stockDay.m_lOpenPrice < theApp.g_carr[i].g_stockDay.m_lClosePrice && theApp.g_carr