MFC_9.26_坐标十字线、滚轮放缩上下留白、取屏幕中心为放缩焦点
#include "StdAfx.h"
#include "Client.h"
#include "MainFrm.h"
#include <math.h>
#include "KlineMiddleView.h"
IMPLEMENT_DYNCREATE(CKlineMiddleView , CView)
const int maxNum = 300;
int m_Wheel=100;
int px,py,pxf,pxy = 0;
int ScreenHeight,ScreenWidth;
int maxh = 0;
int minh = 100000;
int newh = 0;
int WNumber = 100;
int WNS = 200;
int WNF = maxNum;
int flag=1;
int LDx=0,LDy=0;
bool LBDW=false;
CString XlineR;
CString XlineB;
CKlineMiddleView::CKlineMiddleView(void){}
CKlineMiddleView::~CKlineMiddleView(void){}
void CKlineMiddleView::OnDraw(CDC*)
{
this->KlineDraw();
SetFocus();
}
BEGIN_MESSAGE_MAP(CKlineMiddleView, CView)
ON_WM_MOUSEWHEEL()
ON_WM_LBUTTONDOWN()
ON_WM_CREATE()
ON_WM_MOUSEMOVE()
ON_WM_LBUTTONUP()
END_MESSAGE_MAP()
int CKlineMiddleView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CView::OnCreate(lpCreateStruct) == -1)
return -1;
CClientDoc* pDoc = (CClientDoc*)GetDocument();
pDoc->m_DataKLine=new KLINEDATA[maxNum];
for(int i=0;i<maxNum;i++)
{
pDoc->m_DataKLine[i].KOpenPrice = (sin((double)i*0.05)+2)*1500 + rand()%3000 - 1000;
pDoc->m_DataKLine[i].KClosePrice = (sin((double)i*0.05)+2)*1500 + rand()%3000 - 1000;
pDoc->m_DataKLine[i].KHighestPrice = max(pDoc->m_DataKLine[i].KOpenPrice,pDoc->m_DataKLine[i].KClosePrice)*(1+(double)(rand()%20)/100);
pDoc->m_DataKLine[i].KLowestPrice = min(pDoc->m_DataKLine[i].KOpenPrice,pDoc->m_DataKLine[i].KClosePrice)*(1-(double)(rand()%20)/100);
}
for(int i=0;i<50;i++)
{
int xWhite = rand()%maxNum;
pDoc->m_DataKLine[xWhite].KClosePrice = pDoc->m_DataKLine[xWhite].KOpenPrice;
pDoc->m_DataKLine[xWhite].KHighestPrice = max(pDoc->m_DataKLine[xWhite].KOpenPrice,pDoc->m_DataKLine[xWhite].KClosePrice)*(1+(double)(rand()%20)/100);
pDoc->m_DataKLine[xWhite].KLowestPrice = min(pDoc->m_DataKLine[xWhite].KOpenPrice,pDoc->m_DataKLine[xWhite].KClosePrice)*(1-(double)(rand()%20)/100);
}
return 0;
}
BOOL CKlineMiddleView::OnMouseWheel(UINT nFlags, short zDelta, CPoint pt)
{
CRect rect;
GetClientRect(&rect);
m_Wheel -= zDelta* 0.1;
if(m_Wheel >= (maxNum+50)) m_Wheel= maxNum+50;
else if(m_Wheel <=65) m_Wheel=65;
else
{
CPoint p;
GetCursorPos(&p);
WNS += (float)WNumber/2 -(float)(m_Wheel-50)/2;
WNF = WNS + m_Wheel - 50;
if((WNS>=0)&&(WNF<=maxNum))
this -> KlineDraw ();
if(flag%2==0)
this->XlinePaint();
}
return CView::OnMouseWheel(nFlags, zDelta, pt);
}
void CKlineMiddleView::OnLButtonDown(UINT nFlags, CPoint point)
{
LBDW=true;
CPoint p;
GetCursorPos(&p);
LDx=p.x;
LDy=p.y;
CView::OnLButtonDown(nFlags, point);
}
void CKlineMiddleView::OnLButtonUp(UINT nFlags, CPoint point)
{
LBDW=false;
CPoint p;
GetCursorPos(&p);
if(LDx<(p.x+10)&&LDx>(p.x-10)&&LDy>(p.y-10)&&LDy<(p.y+10))
{
flag++;
if(flag%2==0)
this->XlinePaint();
else if(flag > 2)
this->XlineDel();
}
CView::OnLButtonUp(nFlags, point);
}
void CKlineMiddleView::OnMouseMove(UINT nFlags, CPoint point)
{
CRect rect;
GetClientRect(&rect);
CClientDoc* pDoc = (CClientDoc*)GetDocument();
if(flag%2==0)
this->XlineDel();
if(LBDW&&(flag%2))
{
if(px < point.x)
{
if( WNS > 0 )
{
WNS --;
WNF --;
this->KlineDraw();
}
}
if(px > point.x)
{
if( WNF < maxNum)
{
WNS ++;
WNF ++;
this->KlineDraw();
}
}
}
px = point.x ;
py = point.y ;
XlineR.Format("%d",(rect.bottom-py)*newh/rect.bottom + minh);
SYSTEMTIME st;
GetLocalTime(&st);
XlineB.Format("%4d/%2d/%2d %2d:%2d:%2d %2d",st.wYear,st.wMonth,st.wDay,st.wHour,st.wMinute,st.wSecond,st.wDayOfWeek);
if(flag%2==0)
this->XlinePaint();
CView::OnMouseMove(nFlags, point);
}
void CKlineMiddleView::KlineDraw()
{
CDC* pDC;
CRect rect;
CDC MemDC;
CBitmap MemBitmap;
BITMAP bm;
CPen PenBlue(PS_SOLID,1,RGB(39,176,216));
CPen PenRed(PS_SOLID,1,RGB(255,74,102));
CPen PenWhite(PS_SOLID,1,RGB(255,255,255));
pDC = GetWindowDC();
GetClientRect(&rect);
pDC->FillSolidRect(rect, RGB(0,0,0));
ScreenHeight = rect.Height();
ScreenWidth = rect.Width();
CClientDoc* pDoc = (CClientDoc*)GetDocument();
MemDC.CreateCompatibleDC(NULL);
MemBitmap.CreateCompatibleBitmap(pDC,ScreenWidth,ScreenHeight);
MemDC.SelectObject(&MemBitmap);
MemDC.FillSolidRect(0,0,ScreenWidth,ScreenHeight,RGB(0,0,0));
if( WNS < 0) WNS = 0 ;
if( WNF > maxNum ) WNF = maxNum ;
WNumber=WNF-WNS;
float KWidth = (float)(ScreenWidth - 60)/WNumber;
maxh = 0;
minh = 100000;
newh = 0;
for(int i = WNS ; i < WNF ; i++)
{
if( maxh < pDoc->m_DataKLine[i].KHighestPrice)
maxh = pDoc->m_DataKLine[i].KHighestPrice;
if( minh > pDoc->m_DataKLine[i].KLowestPrice)
minh = pDoc->m_DataKLine[i].KLowestPrice;
newh = maxh - minh;
}
for(int i = WNS ; i < WNF ; i++)
{
int khigh = pDoc->m_DataKLine[i].KHighestPrice;
int klow = pDoc->m_DataKLine[i].KLowestPrice;
int kopen = pDoc->m_DataKLine[i].KOpenPrice;
int kclose = pDoc->m_DataKLine[i].KClosePrice;
int maxOC = max(kopen,kclose);
int minOC = min(kopen,kclose);
int mainHigh = maxOC - minOC;
int rebot = ScreenHeight - 30;
float multiple = (float)(rebot-10)/newh;
int xleftTop = KWidth*(i-WNS);
float yleftTop = rebot- (maxOC-minh)*multiple;
int xWidth = KWidth*0.9;
double yHeight = (double)mainHigh*multiple;
if(pDoc->m_DataKLine[i].KOpenPrice > pDoc->m_DataKLine[i].KClosePrice)
{
MemDC.FillSolidRect(xleftTop,yleftTop,xWidth,yHeight,RGB(39,176,216));
MemDC.SelectObject(&PenBlue);
MemDC.MoveTo( xleftTop + xWidth/2 , rebot - (khigh-minh)*multiple);
MemDC.LineTo( xleftTop + xWidth/2 , rebot - (klow-minh)*multiple);
}
else if(pDoc->m_DataKLine[i].KOpenPrice < pDoc->m_DataKLine[i].KClosePrice)
{
MemDC.SelectObject(&PenRed);
MemDC.MoveTo(xleftTop,yleftTop);
MemDC.LineTo(xleftTop+xWidth, yleftTop);
MemDC.LineTo(xleftTop+xWidth, yleftTop+yHeight);
MemDC.LineTo(xleftTop, yleftTop+yHeight);
MemDC.LineTo(xleftTop, yleftTop);
MemDC.MoveTo( xleftTop + xWidth/2 , rebot - (khigh-minh)*multiple);
MemDC.LineTo( xleftTop + xWidth/2 , yleftTop);
MemDC.MoveTo( xleftTop + xWidth/2 , yleftTop+yHeight);
MemDC.LineTo( xleftTop + xWidth/2 , rebot- (klow-minh)*multiple);
}
else
{
int yleftTop = rebot - (maxOC-minh)*multiple;
int yHeight = 1;
MemDC.FillSolidRect(xleftTop,yleftTop,xWidth,yHeight,RGB(255,255,255));
MemDC.SelectObject(&PenWhite);
MemDC.MoveTo( xleftTop + xWidth/2 , rebot - (khigh-minh)*multiple);
MemDC.LineTo( xleftTop + xWidth/2 , rebot - (klow-minh)*multiple);
}
}
pDC->BitBlt(0,0,ScreenWidth,ScreenHeight,&MemDC,0,0,SRCCOPY);
pDC->BitBlt(0,0,ScreenWidth,ScreenHeight,&MemDC,0,0,SRCCOPY);
pDC->BitBlt(0,0,ScreenWidth,ScreenHeight,&MemDC,0,0,SRCCOPY);
pDC->BitBlt(0,0,ScreenWidth,ScreenHeight,&MemDC,0,0,SRCCOPY);
pDC->BitBlt(0,0,ScreenWidth,ScreenHeight,&MemDC,0,0,SRCCOPY);
MemBitmap.DeleteObject();
MemDC.DeleteDC();
}
void CKlineMiddleView::XlinePaint(void)
{
CDC* pDC;
CRect rect;
pDC = GetWindowDC();
GetClientRect(&rect);
pDC->FillSolidRect(rect.right-50,rect.top,50,rect.Height(), RGB(0,0,0));
pDC->FillSolidRect(0,rect.bottom-15,rect.right,15, RGB(0,0,0));
CPen PenWhite(PS_SOLID,1,RGB(255,255,255));
pDC->SelectObject(&PenWhite);
pDC->SetROP2(R2_NOT);
pDC->MoveTo(0,py);
pDC->LineTo(rect.right,py);
pDC->MoveTo(px,0);
pDC->LineTo(px,rect.bottom);
pDC->MoveTo(rect.right-50,py);
pDC->LineTo(rect.right-50,py-15);
pDC->LineTo(rect.right,py-15);
pDC->LineTo(rect.right,py);
pDC->MoveTo(px,rect.bottom-15);
pDC->LineTo(px+200,rect.bottom-15);
pDC->LineTo(px+200,rect.bottom);
SetTextColor(*pDC, RGB(255,255,255));
SetBkMode(*pDC, TRANSPARENT);
pDC->TextOut(rect.right-45,py-15,XlineR);
pDC->TextOut(px+10,rect.bottom-15,XlineB);
}
void CKlineMiddleView::XlineDel(void)
{
CDC* pDC;
CRect rect;
pDC = GetWindowDC();
GetClientRect(&rect);
CPen PenWhite(PS_SOLID,1,RGB(255,255,255));
pDC->SelectObject(&PenWhite);
pDC->SetROP2(R2_NOT);
pDC->MoveTo(0,py);
pDC->LineTo(rect.right,py);
pDC->MoveTo(px,0);
pDC->LineTo(px,rect.bottom);
pDC->FillSolidRect(rect.right-50,rect.top,50,rect.Height(), RGB(0,0,0));
pDC->FillSolidRect(0,rect.bottom-15,rect.right,15, RGB(0,0,0));
}