前幾課已經介紹了CChart的不少功能,這節課我們稍微停留一下,做一個復習。復習的方法呢,就是一個綜合練習:用CChart實現實時數據顯示功能。
由於是練習,我們的問題背景可以任意設定。現在假設一台儀器每隔200ms傳出兩個溫度數據。一個溫度數據是儀器外的溫度,基本是一個恆定值;另一位溫度數據是儀器內部的溫度,這個溫度是隨時間變化的,先升溫,再降溫,不停地循環。
我們按照上一課的方法編程。簡單起見,本節課就不處理CChart的交互了。
仍然一步一步來。
第一步到第七步,按照上一課的方法,建立一個名為Lesson09的VC6工程。
第八步,給Lesson09的主窗口添加菜單資源。
圖中添加了兩個菜單項,其對應ID如下。
開始(S)——ID_REALTIME_START
停止(T)——ID_REALTIME_STOP
第九步,在Lesson09.cpp文件的頭部附近添加頭文件引用。
#include <time.h> #include <math.h>這兩個頭文件後面要用到。
第十步,在第七步中添加的一行代碼staticCChartchart;的下一行,添加以下代碼。
static unsigned int nCount; static bool bRun; static int nTimer;
由於我們是用代碼來模擬儀器輸入,這個nCount可以控制儀器的輸出值。
bRun表示定時器是否運行,nTimer是定時器的代號。
第十一步,建立WM_CREATE消息的響應例程。
case WM_CREATE:
chart.SetType(kTypeXY);
chart.SetUseLegend(true);
chart.SetAxisTitle(_T("時間(分)"), 1);
chart.SetAxisTitle(_T("溫度(度)"), 0);
chart.SetTitle(_T("烘箱溫度變化圖"));
nCount = 0;
bRun = false;
nTimer = 0;
srand( (unsigned)time( NULL ) );
break;
這裡設置圖像的一些參數,並初始化定時器的狀態和隨機數種子。
第十二步,建立WM_TIMER的響應例程。
case WM_TIMER:
if(bRun)
{
double Pi = 3.1415926536;
double x, y1, y2;
nCount++;
x = nCount/10.0;
y1 = 20.0 * sin(2.0*Pi/400.0*nCount) + 40.0 + (2.0*rand()/RAND_MAX-1.0);
y2 = 20.0 + (2.0*rand()/RAND_MAX-1.0)/2.0;
if(nCount == 1)
{
double pX[1], pY[1];
pX[0] = x;
pY[0] = y1;
chart.AddCurve(pX, pY, 1);
pY[0] = y2;
chart.AddCurve(pX, pY, 1);
chart.SetDataTitle(_T("加熱溫度"), 0);
chart.SetDataTitle(_T("環境溫度"), 1);
break;
}
chart.AddPoint2D(x, y1, 0);
chart.AddPoint2D(x, y2, 1);
RECT rt;
GetClientRect(hWnd, &rt);
InvalidateRect(hWnd, &rt, TRUE);
}
break;
這裡產生模擬的溫度數據並添加到圖像中。模擬數據中添加了一個隨機數,以便產生真實的感覺,呵呵。
第十三步,建立菜單響應函數。在switch(wmid)後面的花括號裡面,輸入如下代碼。
case ID_REALTIME_START:
nTimer = SetTimer(hWnd, 1, 200, 0);
bRun = true;
break;
case ID_REALTIME_STOP:
if(nTimer>0)
{
KillTimer(hWnd, nTimer);
nTimer = 0;
}
bRun = false;
break;
兩個菜單分別啟動定時器和停止定時器。
第十四步,響應WM_ERASEBKGND消息。
case WM_ERASEBKGND: return 0;
這一步的作用是避免圖像閃爍。
第十五步,編譯並運行程序。
啥也沒有哇!
嗯,別著急,慢慢來。
第十六步,點擊菜單實時數據顯示——開始,曲線開始顯示。下圖是某個時刻的圖像。
耶,效果還不錯喲。
小結:本節課綜合利用前面學習的知識,模擬實現了一個實時數據顯示的功能,希望對同學們有所幫助。