MFC_9.26_坐标十字线、滚轮放缩,取屏幕中心为放缩焦点

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*)
{
	// TODO: 在此添加专用代码和/或调用基类
	this->KlineDraw();
	SetFocus();
}

// KlineLeftView.cpp : 实现文件

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)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认
	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
	{
		//WNumber = m_Wheel - 50 ;
		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)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值
	LBDW=true;
	CPoint p;
    GetCursorPos(&p);
	LDx=p.x;
	LDy=p.y;

	CView::OnLButtonDown(nFlags, point);
}


void CKlineMiddleView::OnLButtonUp(UINT nFlags, CPoint point)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值
	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)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值
	CRect rect;
	GetClientRect(&rect);
	CClientDoc* pDoc = (CClientDoc*)GetDocument(); //载入数据的结构体

	if(flag%2==0)
		this->XlineDel();//删除作用.删除之前不能赋值

	//int plusx = WNumber/50;

	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();
			}
			/*
			if(((px-point.x)*WNumber/rect.right)>=1)
			{
				WNS += (px-point.x)*WNumber/rect.right;
				WNF += (px-point.x)*WNumber/rect.right;
				if( WNF > maxNum ) WNF = maxNum ;
				else 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); 
	//CBitmap *pOldBit=MemDC.SelectObject(&MemBitmap); 
	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);

		//缩减代码,提前计算FillSolidRect的前四个参数
		int mainHigh = maxOC - minOC;

		int rebot = ScreenHeight - 30;       //30是下方空出的高度
		float multiple = (float)(rebot-10)/newh;  //10是上方空出的高度

		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);
			
			//MemDC.FillSolidRect(xleftTop+1,yleftTop+1,xWidth-2,yHeight-2,RGB(0,0,0));
		}
		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);
		}
	}

	//MemBitmap.GetBitmap(&bm);
	
	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.Detach();
	//MemDC.Detach();

	MemBitmap.DeleteObject(); 
    MemDC.DeleteDC();         //清除上一次位图

	//ReleaseDC(&MemDC);
	//pDC->DeleteDC();
	//ReleaseDC(pDC);

}

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); 

	//pDC->DeleteDC();
	//ReleaseDC(pDC);


}


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));

	//pDC->DeleteDC();
	//ReleaseDC(pDC);

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值