📄 curvedevice.cpp
字号:
/////////////////////////////////////////////////////////
// 曲线显示设备CurveDevice封装类
// 版本:1.04
// 最后修改日期:2002.1.25
/////////////////////////////////////////////////////////
// CurveDevice.cpp : implementation file
//
#include "stdafx.h"
#include "CurveDevice.h"
#include "math.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CurveDevice
/////////////////////////////////////////////////////////////////////////////////////////
//函数名:CurveDevice(CWnd *parent)
//输入参数:父窗口的指针
//返回值:无
//作用:构造函数,初始化变量的值,创建并显示对象
CurveDevice::CurveDevice(CWnd * parent)
{
CD_Width = 260; //默认的仪表尺寸
CD_Height = 55;
CD_XGridNum = 80; //X轴正方向上的格子数目
CD_YGridNum = 6; //Y轴正方向上的格子数目
CD_XGridLength = 5; //X方向格子的宽度
CD_YGridLength = 5; //Y方向格子的宽度
CD_BorderWidth = 3; //默认的边界宽度
CD_AxleLength = 25; //默认仪表函数值对应的轴的最大长度
CD_StepLength = 1; //默认的X轴步长
CD_Origin.x = CD_Width - CD_BorderWidth - 1; //默认的原点位置
CD_Origin.y = 28;
CD_BorderTop = 1; //默认情况下,四个边界都要显示
CD_BorderBottom = 1;
CD_BorderLeft = 1;
CD_BorderRight = 1;
CD_BkColor = RGB(0, 0, 0); //默认的背景颜色
CD_BdDarkColor = RGB(100, 100, 100); //默认的暗边界颜色
CD_BdLightColor = RGB(255, 255, 255); //默认的量边界颜色
CD_AxleColor = RGB(55, 155, 255); //默认的坐标轴颜色
CD_GridColor = RGB(0, 80, 0); //默认的网格颜色
CD_CurveColor = RGB(255, 255, 255); //默认的曲线颜色
CD_CurrentNumber = 0; //默认的当前值
CD_MaxNumber = 10; //默认的正半轴量程(负半轴与它对称)
CD_Status = CD_WORK; //默认的仪表状态
CD_WorkMode = CD_REALTIME; //默认的仪表工作方式
CD_PlaceMode = CD_HORIZONTAL; //仪表的默认放置方式
CD_TestAngle = 0; //起始的测试角度
CD_Timer = 500; //默认的定时器触发间隔时间
CD_RecordLength = CD_Width - CD_BorderWidth;//记录长度
CD_RecordStartPos = 0; //默认记录从0索引开始
CD_Record = new int[CD_RecordLength]; //分配记录数组的内存
memset(CD_Record, 0, CD_RecordLength * sizeof(CD_Record[0])); //记录清零
//创建相应的静态控件并且显示
CRect rect;
rect.left = rect.top = 0;
rect.bottom = CD_Height - 1;
rect.right = CD_Width - 1;
Create(NULL, WS_CHILD | WS_VISIBLE | SS_NOTIFY, rect, parent);
SetTimer(1, CD_Timer, NULL); //设置自检时使用的计时器
}
CurveDevice::~CurveDevice()
{
KillTimer(1);
delete [] CD_Record;
}
BEGIN_MESSAGE_MAP(CurveDevice, CStatic)
//{{AFX_MSG_MAP(CurveDevice)
ON_WM_TIMER()
ON_WM_PAINT()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CurveDevice message handlers
/////////////////////////////////////////////////////////////////////////////////////////
//函数名:OnTimer(UINT nIDEvent)
//输入参数:定时器触发事件的ID
//返回值:无
//作用:重载函数,负责自检状态下和工作状态下仪表显示的更新
void CurveDevice::OnTimer(UINT nIDEvent)
{
// TODO: Add your message handler code here and/or call default
switch(CD_Status)
{
case CD_TEST: //自检状态,输出cos函数曲线
CD_TestAngle += 5; //角速度是5度/单位抽样时间
CD_CurrentNumber = CD_AxleLength * cos(ANG * CD_TestAngle);
CD_Record[CD_RecordStartPos] = (int)CD_CurrentNumber;
CD_RecordStartPos ++; //记录起始指针移动
if(CD_RecordStartPos == CD_RecordLength) //如果记录满了,从记录首部开始记录
CD_RecordStartPos = 0;
DrawFace(); //更新显示
break;
case CD_WORK: //工作状态,每过单位抽样时间就检测一次CD_CurrentNumber的值
if(CD_WorkMode == CD_REALTIME) //只有实时曲线方式需要响应定时器消息
{
CD_Record[CD_RecordStartPos] = (int)(CD_AxleLength * CD_CurrentNumber / CD_MaxNumber);
CD_RecordStartPos ++;//记录起始指针移动
if(CD_RecordStartPos == CD_RecordLength) //如果记录满了,从记录首部开始记录
CD_RecordStartPos = 0;
DrawFace();//更新显示
}
break;
default:
break;
}
CStatic::OnTimer(nIDEvent);
}
/////////////////////////////////////////////////////////////////////////////////////////
//函数名:OnPaint()
//输入参数:无
//返回值:无
//作用:重载函数,绘制仪表界面
void CurveDevice::OnPaint()
{
CPaintDC dc(this); // device context for painting
// TODO: Add your message handler code here
DrawFace();
// Do not call CStatic::OnPaint() for painting messages
}
/////////////////////////////////////////////////////////////////////////////////////////
//函数名:DrawFace()
//输入参数:无
//返回值:无
//作用:绘制仪表界面
void CurveDevice::DrawFace()
{
int i;
CClientDC dc(this);
CBitmap bmpc;
bmpc.CreateCompatibleBitmap(&dc, CD_Width, CD_Height); //创建与系统兼容的位图
BITMAP bmp;
bmpc.GetBitmap(&bmp);
//绘制仪表的背景色
CDC dcmem;
CBrush brush, *pbrushold;
CPen pen, *ppenold;
dcmem.CreateCompatibleDC(&dc);
CBitmap * pbitmapold = (CBitmap *)dcmem.SelectObject(&bmpc);
brush.CreateSolidBrush(CD_BkColor);
pbrushold= (CBrush *)dcmem.SelectObject(&brush);
dcmem.SelectStockObject(NULL_PEN);
dcmem.Rectangle(0, 0, bmp.bmWidth + 1, bmp.bmHeight + 1);
dcmem.SelectObject(pbrushold);
brush.DeleteObject();
//绘制坐标网格
pen.CreatePen(PS_SOLID, 1, CD_GridColor);
ppenold = (CPen *)dcmem.SelectObject(&pen);
for(i = 0; i < (int)CD_XGridNum; i ++) //垂直于X轴的网格线
{
dcmem.MoveTo(CD_Origin.x - i * CD_XGridLength, CD_Origin.y - CD_Height);
dcmem.LineTo(CD_Origin.x - i * CD_XGridLength, CD_Origin.y + CD_Height);
dcmem.MoveTo(CD_Origin.x + i * CD_XGridLength, CD_Origin.y - CD_Height);
dcmem.LineTo(CD_Origin.x + i * CD_XGridLength, CD_Origin.y + CD_Height);
}
for(i = 0; i < (int)CD_YGridNum; i ++) //垂直于Y轴的网格线
{
dcmem.MoveTo(CD_Origin.x - CD_Width, CD_Origin.y - i * CD_YGridLength);
dcmem.LineTo(CD_Origin.x + CD_Width, CD_Origin.y - i * CD_YGridLength);
dcmem.MoveTo(CD_Origin.x - CD_Width, CD_Origin.y + i * CD_YGridLength);
dcmem.LineTo(CD_Origin.x + CD_Width, CD_Origin.y + i * CD_YGridLength);
}
dcmem.SelectObject(ppenold);
pen.DeleteObject();
//绘制坐标轴线
pen.CreatePen(PS_SOLID, 1, CD_AxleColor);
ppenold = (CPen *)dcmem.SelectObject(&pen);
dcmem.MoveTo(CD_Origin.x - CD_Width, CD_Origin.y);
dcmem.LineTo(CD_Origin.x + CD_Width, CD_Origin.y);
dcmem.MoveTo(CD_Origin.x, CD_Origin.y - CD_Height);
dcmem.LineTo(CD_Origin.x, CD_Origin.y + CD_Height);
dcmem.SelectObject(ppenold);
pen.DeleteObject();
//绘制实时曲线
int j = 0;
pen.CreatePen(PS_SOLID, 1, CD_CurveColor);
ppenold = (CPen *)dcmem.SelectObject(&pen);
if(CD_PlaceMode == CD_HORIZONTAL) //如果是水平放置
{
for(i = CD_RecordStartPos - 1; i >= 0; i --)
{
if(j == 0)
dcmem.MoveTo(CD_Origin.x - 1, CD_Origin.y - CD_Record[(i > 0) ? (i - 1) : 0]);
else
dcmem.LineTo(CD_Origin.x - 1 - j * CD_StepLength, CD_Origin.y - CD_Record[i]);
j ++;
}
for(i = CD_RecordLength - 1; i >= (int)CD_RecordStartPos; i --)
{
if(j == 0)
dcmem.MoveTo(CD_Origin.x - 1, CD_Origin.y - CD_Record[(i > 0) ? (i - 1) : 0]);
else
dcmem.LineTo(CD_Origin.x - 1 - j * CD_StepLength, CD_Origin.y - CD_Record[i]);
j ++;
}
}
else //如果是垂直放置
{
for(i = CD_RecordStartPos - 1; i >= 0; i --)
{
if(j == 0)
dcmem.MoveTo(CD_Origin.x - CD_Record[(i > 0) ? (i - 1) : 0], CD_Origin.y - 1);
else
dcmem.LineTo(CD_Origin.x - CD_Record[i], CD_Origin.y - 1 - j * CD_StepLength);
j ++;
}
for(i = CD_RecordLength - 1; i >= (int)CD_RecordStartPos; i --)
{
if(j == 0)
dcmem.MoveTo(CD_Origin.x - CD_Record[(i > 0) ? (i - 1) : 0], CD_Origin.y - 1);
else
dcmem.LineTo(CD_Origin.x - CD_Record[i], CD_Origin.y - 1 - j * CD_StepLength);
j ++;
}
}
dcmem.SelectObject(ppenold);
pen.DeleteObject();
//绘制仪表的边框
brush.CreateSolidBrush(CD_BdDarkColor);
pbrushold = (CBrush *)dcmem.SelectObject(&brush);
if(CD_BorderTop)
dcmem.Rectangle(0, 0, CD_Width + 1, CD_BorderWidth);
if(CD_BorderLeft)
dcmem.Rectangle(0, 0, CD_BorderWidth, CD_Height + 1);
dcmem.SelectObject(pbrushold);
brush.DeleteObject();
brush.CreateSolidBrush(CD_BdLightColor);
pbrushold = (CBrush *)dcmem.SelectObject(&brush);
if(CD_BorderBottom)
dcmem.Rectangle(0, CD_Height - CD_BorderWidth + 1, CD_Width + 1, CD_Height + 1);
if(CD_BorderRight)
dcmem.Rectangle(CD_Width - CD_BorderWidth + 1, 0, CD_Width + 1, CD_Height + 1);
dcmem.SelectObject(pbrushold);
brush.DeleteObject();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -