前幾課已經介紹了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;
這一步的作用是避免圖像閃爍。
第十五步,編譯並運行程序。
啥也沒有哇!
嗯,別著急,慢慢來。
第十六步,點擊菜單實時數據顯示——開始,曲線開始顯示。下圖是某個時刻的圖像。
耶,效果還不錯喲。
小結:本節課綜合利用前面學習的知識,模擬實現了一個實時數據顯示的功能,希望對同學們有所幫助。