这一课,我们将利用CChart,在SoUI中绘制动态的实时曲线。
第一步,我们完全按照上一课的全部步骤新建一个项目,只是项目名称改变为LessonA46。
我们新建的控件SChartWnd已经比较完善了,文件SChartWnd.h和SChartWnd.cpp可以直接拷贝过来使用。这一课只需要对这两个文件做一些修改即可。
第二步,把OnCreate函数修改如下。
int SChartWnd::OnCreate(LPVOID lpVoid)
{
SetFocus();
chart.SetType(kTypeXY);
chart.SetTitle(_T("实时曲线"));
chart.SetBkgndColor(RGB(228, 228, 228));
chart.AddCurve();
chart.SetDataTitle(_T("实验数据"), 0);
chart.SetXFloatTicks(true);
chart.SetDataMaxPoints(1080, 0);
return 0;
}
这里我们设置图像类型为kTypeXY,即折线图。通过AddCurve添加了一条空曲线,通过SetXFloatTicks(true)使得X坐标为浮动坐标(即坐标轴两端可以不是格点),通过SetDataMaxPoints使得第一条曲线上最多只能放置1080个数据点(添加多于的点后,最初的点自动移除,这样可以实现曲线的自动移动)。
第三步,在SChartWnd.h中加入定时器函数声明及映射。
声明的代码:
void OnTimer(UINT_PTR nIDEvent);
映射的代码:
MSG_WM_TIMER_EX(OnTimer)
第四步,在SChartWnd.cpp中实现定时器函数。
void SChartWnd::OnTimer(UINT_PTR nIDEvent)
{
if(1 != nIDEvent)return;
static int nCnt = 0;
static int nLen = 360;
static double pi = 4.0*atan(1.0);
double x, y;
x = nCnt/100.0;
y = 4.0*sin(2.0*pi*nCnt/nLen) + (2.0*rand()/RAND_MAX-1.0);
chart.AddPoint2D(x, y);
nCnt++;
Invalidate();
}
这里只对ID为1的定时器进行处理,所以我们需要建立一个ID为1的定时器。另外我们这里用到了随机数函数rand(),需要初始化随机数种子。
另外,这里用到了数学函数,需要包含系统头文件。
#include <math.h>
第五步,打开SChartWnd.cpp文件。
在OnCreate函数里面,加上:
SetTimer(1, 20);
srand( (unsigned)time( NULL ) );
这里建立了一个ID为1的定时器,为了快一点,定时器的时间跨度为20毫秒。另外,我们用当前时间来初始化随机数种子。
由于用到了时间函数,需要在头部包含头文件。
#include <time.h>
第六步,我们需要在系统退出时销毁定时器。
首先在SChartWnd.h中,声明和映射OnDestroy函数。
声明代码:
void OnDestroy();
映射代码:
MSG_WM_DESTROY(OnDestroy)
然后在SChartWnd.cpp中实现这个函数。
void SChartWnd::OnDestroy()
{
KillTimer(1);
}
现在所有的工作已经完成,编译并运行。
如图是数据点还没有填满1080个的时候,某一时刻的图像。
如图是数据填满1080个点后,某一时刻的图像。
效果还是不错的。