首先需要澄清的是,接下来的程序并不完全是尽点力先生所写,很多事参照wince高级编程的书写的,有什么错误还请多多包涵,希望通过解释,能给读者一点帮助,先生最近在做关于将测试到的温度数据,通过万硅电子的无线通信模块,无线传输到开发板上面,然后通过接下来的程序显示出温度变化曲线,希望想做同样实验的人多看一下,这个实验解决了传统的有线通信和曲线画法的难度。 下面我将着重介绍这个画曲线的类,看之前先学习一下C++,知道什么是类,怎样使用类,怎么样声明对象。
// 2DGraph.cpp : 实现文件
//
#include "stdafx.h"
#include "wenkong.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 =(255,0,255);//曲线颜色
m_crTextColor =(255,0,255);//输出文本颜色
m_dXMaxValue =100 ;//x轴最大值
m_dXMinValue =0 ;//x轴最小值
m_dYMaxValue =100;//Y最大值
m_dYMinValue =0;//Y最小值
m_strXCaption =_T("时间轴");
m_strYCaption =_T("温度");
m_pOldBitmapGrid = NULL;
m_pOldBitmapLine = NULL;
}
C2DGraph::~C2DGraph()
{
if (m_dcGrid.GetSafeHdc()!= NULL)
{
m_dcGrid.SelectObject(m_pOldBitmapGrid);
}
if(m_dcLine.GetSafeHdc()!= NULL)
{
m_dcLine.SelectObject(m_pOldBitmapLine);
}
}
BOOL C2DGraph:: Create(LPCTSTR lpszClassName,LPCTSTR lpszWindowName,double 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 +20;
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 / (10*m_dYMaxValue - 10*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)
{
;
}
//如果是一个点
else if(m_lstPointsY.GetCount()==1)
{
POSITION pos =m_lstPointsY.GetHeadPosition();
points[0].x =0;//表示第一个点
points[0].y =m_lstPointsY.GetAt(pos);
points[0] =GpToSp(points[0]);//转换成屏幕坐标
m_dcLine.SetPixel(points[0],m_crLineColor);
}
else //如果多余或等于两个点
{
POSITION pos =m_lstPointsY.GetHeadPosition();
points[0].y =m_lstPointsY.GetNext(pos);
points[0].x =0;//表示第一个点
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();
}
void C2DGraph::OnPaint()
{
CPaintDC dc(this);
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(double dwPointY)//在末尾添加一个点
{
m_lstPointsY.AddTail(dwPointY);
//更新显示
Invalidate();
}
void C2DGraph::DeleteFirstPoint()
{
if(m_lstPointsY.GetCount()>0)
{
m_lstPointsY.RemoveHead();
}
//更新显示
Invalidate();
}
BEGIN_MESSAGE_MAP(C2DGraph, CWnd)
ON_WM_PAINT()
END_MESSAGE_MAP()
// C2DGraph 消息处理程序