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

📄 2dgraph.cpp

📁 Draw2DGraph.rar
💻 CPP
字号:
// 2DGraph.cpp : 实现文件
//

#include "stdafx.h"
#include "Draw2DGraph.h"
#include "2DGraph.h"


// C2DGraph

IMPLEMENT_DYNAMIC(C2DGraph, CWnd)

//构造函数
C2DGraph::C2DGraph()
{
	//初始化控件属性
	m_crBackColor = RGB(0,0,0);
	m_crGridColor = RGB(0,255,255);
	m_crLineColor = RGB(255,0,255);
	m_crTextColor = RGB(255,0,255);
	
	m_strXCaption = _T("X轴");
	m_strYCaption = _T("Y轴");
	m_dXMaxValue = 10;
	m_dXMinValue = 0;
	m_dYMaxValue = 10;
	m_dYMinValue = 0; 

	m_pOldBitmapGrid = NULL;
	m_pOldBitmapLine = NULL;

}

//析构函数
C2DGraph::~C2DGraph()
{	
	//还原GDI对象
	if (m_dcGrid.GetSafeHdc() != NULL)
	{
		m_dcGrid.SelectObject(m_pOldBitmapGrid);
	}

	if (m_dcLine.GetSafeHdc() != NULL)
	{
		m_dcLine.SelectObject(m_pOldBitmapLine);
	}
}


BEGIN_MESSAGE_MAP(C2DGraph, CWnd)
	ON_WM_PAINT()
END_MESSAGE_MAP()



// C2DGraph 消息处理程序

BOOL C2DGraph::Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, CCreateContext* pContext) 
{
	BOOL result ;
	//注册窗体类
	static CString className = AfxRegisterWndClass(CS_HREDRAW | CS_VREDRAW) ;
	//创建窗体类
	result = CWnd::CreateEx(WS_EX_CLIENTEDGE | WS_EX_STATICEDGE, 
		className, NULL, dwStyle, 
		rect.left, rect.top, rect.right-rect.left, rect.bottom-rect.top,
		pParentWnd->GetSafeHwnd(), (HMENU)nID) ;

	
	return TRUE;
}


//将用户添加的点值转换成屏幕坐标
CPoint C2DGraph::GpToSp(CPoint& point)
{
	CPoint rPoint;
   	CRect rectClient;
	CRect rectLine;
	
	GetClientRect(rectClient) ;
	rectLine.left = rectClient.left + 20;
	rectLine.right = rectClient.right - 10;
	rectLine.top = rectClient.top + 10;
	rectLine.bottom = rectClient.bottom - 20;
	rPoint.x = rectLine.left + (point.x / (m_dXMaxValue - m_dXMinValue))*rectLine.Width();
	rPoint.y = rectLine.top + (1 - point.y / (m_dYMaxValue - m_dYMinValue))*rectLine.Height(); 
	return rPoint;
}

//用于刷新控件显示
void C2DGraph::InvalidateCtrl()
{
    CPen *oldPen;
	CPen solidPen(PS_SOLID,0,m_crGridColor);
    CFont xFont,yFont,*oldFont;
	CBrush brushBack;
	brushBack.CreateSolidBrush(m_crBackColor) ;
	
	CRect rectClient;
	GetClientRect(rectClient);
	
	CClientDC dc(this);
	
	//创建表格设备环境以及创建相应缓冲区
	if (m_dcGrid.GetSafeHdc() == NULL)
	{
		m_dcGrid.CreateCompatibleDC(&dc);
		m_bitmapGrid.CreateCompatibleBitmap(&dc,rectClient.Width(),rectClient.Height());
		m_pOldBitmapGrid = m_dcGrid.SelectObject(&m_bitmapGrid);
	}
	
	//设置背景颜色
	m_dcGrid.SetBkColor(m_crBackColor);
	m_dcGrid.FillRect(rectClient,&brushBack);
	
	//画边框
	oldPen = m_dcGrid.SelectObject(&solidPen);
	m_dcGrid.MoveTo(rectClient.left + 20,rectClient.top + 10);
	m_dcGrid.LineTo(rectClient.right - 10,rectClient.top + 10);
	m_dcGrid.LineTo (rectClient.right - 10,rectClient.bottom - 20) ;
	m_dcGrid.LineTo (rectClient.left + 20 , rectClient.bottom - 20) ;
	m_dcGrid.LineTo (rectClient.left + 20 , rectClient.top  + 10) ;
	//还原GDI对象
	m_dcGrid.SelectObject(oldPen);
	
	//创建Y轴字体
	yFont.CreateFont (14, 0, 900, 0, 300,
		FALSE, FALSE, 0, ANSI_CHARSET,
		OUT_DEFAULT_PRECIS, 
		CLIP_DEFAULT_PRECIS,
		DEFAULT_QUALITY, 
		DEFAULT_PITCH|FF_SWISS, _T("宋体")) ;
	
	//创建X轴字体
	xFont.CreateFont (14, 0, 0, 0, 300,
		FALSE, FALSE, 0, ANSI_CHARSET,
		OUT_DEFAULT_PRECIS, 
		CLIP_DEFAULT_PRECIS,
		DEFAULT_QUALITY, 
		DEFAULT_PITCH|FF_SWISS, _T("宋体")) ;
	
	//画Y坐标标题
	m_dcGrid.SetTextColor(m_crTextColor);
	oldFont = m_dcGrid.SelectObject(&yFont);
	m_dcGrid.ExtTextOut (rectClient.left + 2, 
		(rectClient.top + rectClient.bottom ) / 2 + 5, ETO_CLIPPED,NULL,m_strYCaption,wcslen(m_strYCaption),NULL) ;
	
	//画Y坐标最大值
	CString strTmp;
	strTmp.Format(_T("%.2f"),m_dYMaxValue);
	m_dcGrid.ExtTextOut (rectClient.left+5  , 
		rectClient.top + 40 , ETO_CLIPPED,NULL
		,strTmp,strTmp.GetLength(),NULL) ;
	
	//画Y坐标最小值
	strTmp.Format(_T("%.2f"),m_dYMinValue);
	m_dcGrid.ExtTextOut (rectClient.left+5 , 
		rectClient.bottom - 18 , ETO_CLIPPED,NULL
		,strTmp,strTmp.GetLength(),NULL) ;
	
	//还原GDI对象
	m_dcGrid.SelectObject(oldPen);

	//画X坐标标题
	oldFont = m_dcGrid.SelectObject(&xFont);
	m_dcGrid.ExtTextOut ((rectClient.left+ rectClient.right)/2 - 5, 
		rectClient.bottom - 18 , ETO_CLIPPED,NULL,m_strXCaption,wcslen(m_strXCaption) ,NULL) ;
	
	//画X坐标最大值
	strTmp.Format(_T("%.2f"),m_dXMaxValue);
	m_dcGrid.ExtTextOut (rectClient.right - 40, 
		rectClient.bottom - 18 , ETO_CLIPPED,NULL
		,strTmp,strTmp.GetLength(),NULL) ;
	
	//画X坐标最小值
	strTmp.Format(_T("%.2f"),m_dXMinValue);
	m_dcGrid.ExtTextOut (rectClient.left + 20, 
		rectClient.bottom - 18 , ETO_CLIPPED,NULL
		,strTmp,strTmp.GetLength(),NULL) ;
	
	//还原GDI对象
	m_dcGrid.SelectObject(oldPen);
	
	//创建画线设备环境以及创建相应缓冲区
	if (m_dcLine.GetSafeHdc() == NULL)
	{
		m_dcLine.CreateCompatibleDC(&dc) ;
		m_bitmapLine.CreateCompatibleBitmap(&dc, rectClient.Width(), rectClient.Height()) ;
		m_pOldBitmapLine = m_dcLine.SelectObject(&m_bitmapLine) ;
	}
	
	m_dcLine.SetBkColor (m_crBackColor) ;
	m_dcLine.FillRect(rectClient, &brushBack) ;

	//删除创建的GDI对象
	solidPen.DeleteObject();
	xFont.DeleteObject();
	yFont.DeleteObject();
	brushBack.DeleteObject();
}

//绘制屏幕点
void C2DGraph::DrawPoints()
{
	CPen *oldPen;
	CRect rectCleanUp;
	CPoint points[2];
	CPoint point_old;
	CPen penLine;
	//创建画笔
	penLine.CreatePen(PS_SOLID, 0, m_crLineColor) ;

	//得到绘图区域
	CRect rectClient;
	GetClientRect(rectClient);

	m_dcLine.FillSolidRect(rectClient,m_crBackColor);

	int i = 0;
	oldPen = m_dcLine.SelectObject(&penLine) ;

	if (m_dcLine.GetSafeHdc() == NULL)
	{
		return;
	}

	
	//绘制曲线
	if (m_lstPointsY.GetCount() == 0 )
	{
		
	}
	//如果是第1个点
	else if (m_lstPointsY.GetCount() == 1) 
	{
		POSITION pos = m_lstPointsY.GetHeadPosition();
		points[0].y = m_lstPointsY.GetAt(pos);
		points[0].x = 0; //表示第1个点
        points[0] = GpToSp(points[0]); //转换成屏幕坐标
		m_dcLine.SetPixel(points[0],m_crLineColor);
	}
	//如果多于或等于2个点
	else
	{
		POSITION pos = m_lstPointsY.GetHeadPosition();
		
		points[0].y = m_lstPointsY.GetNext(pos);
		points[0].x = 0; //表示第1个点
		point_old = points[0];
		i = 0;
		while (TRUE)
		{
			if (pos == NULL)
			{
				break;
			}

			points[1] = point_old;
			points[0].y = m_lstPointsY.GetNext(pos);
			points[0].x = i+1;
			point_old = points[0];
			points[0] = GpToSp(points[0]);
			points[1] = GpToSp(points[1]);
			//绘制曲线
			m_dcLine.MoveTo (points[1].x, points[1].y) ;	
			m_dcLine.LineTo (points[0].x,points[0].y) ;
			i++;
		}
	}
	
	m_dcLine.SelectObject(oldPen) ;
	//删除画笔GDI对象
	penLine.DeleteObject();
}

//覆盖WM_PAINT消息方法
void C2DGraph::OnPaint()
{
	CPaintDC dc(this); // device context for painting
	
	CRect rectClient;
	GetClientRect(rectClient) ;
	
	CDC memDC ;
	CBitmap memBitmap ;
	CBitmap* oldBitmap ; 
	
	memDC.CreateCompatibleDC(&dc) ;
	memBitmap.CreateCompatibleBitmap(&dc, rectClient.Width(), rectClient.Height()) ;
	oldBitmap = (CBitmap *)memDC.SelectObject(&memBitmap) ;
	
	//更新背景显示
	InvalidateCtrl() ;
	//画点
	DrawPoints();
	//将m_dcGrid和m_dcLine绘制到控件上
	if (memDC.GetSafeHdc() != NULL)
	{

		memDC.BitBlt(0, 0, rectClient.Width(), rectClient.Height(), 
			         &m_dcGrid, 0, 0, SRCCOPY) ;
		memDC.BitBlt(0, 0, rectClient.Width(), rectClient.Height(), 
			         &m_dcLine, 0, 0, SRCPAINT) ;
		
		dc.BitBlt(0, 0, rectClient.Width(), rectClient.Height(), 
			&memDC, 0, 0, SRCCOPY) ;
	}
	
	memDC.SelectObject(oldBitmap) ;		
	
	//删除内存位图GDI对象
	memBitmap.DeleteObject();
	//删除内存绘图环境
	memDC.DeleteDC();

}

//在曲线末尾添加一个点
void C2DGraph::AppendPoint(DWORD dwPointY)
{
	//在队列中添加1个点
    m_lstPointsY.AddTail(dwPointY);	
	//更新显示
	Invalidate();
}

//删除曲线第一点
void C2DGraph::DeleteFirstPoint()
{
	//删除1个节点
	if (m_lstPointsY.GetCount() > 0)
	{
		m_lstPointsY.RemoveHead();
	}
	//更新显示
	Invalidate();		
}

⌨️ 快捷键说明

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