在工業(yè)控制系統(tǒng)中,經(jīng)常需要實時的顯示一些曲線,運用傳統(tǒng)的繪圖方法,會引起屏幕的強烈閃爍?,F(xiàn)在常用的解決方法是:利用內(nèi)存繪圖的技術(shù),將需顯示的圖形繪制在內(nèi)存位圖中,然后再拷貝到屏幕上,很好的解決了屏幕閃爍的問題。并且處理速度快。
其實VC的內(nèi)存繪圖的資料網(wǎng)上也很多,本人根據(jù)自己的實踐經(jīng)驗,并結(jié)合網(wǎng)友的文章,給出一個簡單的編程實例,僅供網(wǎng)友參考。
編程實現(xiàn):
第一步:用VC6.0生成一個基于對話框的工程,起名為:xv001。
在對話框上添加一個Picture控件,設(shè)置ID為IDC_COORD,調(diào)整控件的位置和大小,直至合適。
在xv001Dlg的類中添加以下變量:
CRect rect; // 存儲繪圖控件的繪圖區(qū)域
CDC *pDC; // 控件的屏幕繪圖設(shè)備指針
CDC memDC; // 內(nèi)存繪圖設(shè)備
CBitmap memBitmap; // 用于內(nèi)存繪圖的位圖
CBitmap* pOldBmp; // 備份舊的位圖指針
CWnd* pWnd; // 繪圖控件的指針
第二步:用ClassWizard在xv001Dlg類中添加OnInitDialog()消息響應(yīng)函數(shù)。實現(xiàn)繪圖需要變量的初始化工作,具體代碼如下:
pWnd = GetDlgItem(IDC_COORD); // 獲得對話框上的picture的窗口句柄
pWnd->GetClientRect(&rect); // 獲取繪制坐標的文本框
pDC = pWnd->GetDC(); // 獲得對話框上的picture的設(shè)備指針
pOldBmp = NULL; // 將舊的位圖指針置空
// 創(chuàng)建內(nèi)存繪圖設(shè)備,使內(nèi)存位圖的DC與控件的DC關(guān)聯(lián)
memDC.CreateCompatibleDC(pDC);
memBitmap.CreateCompatibleBitmap(pDC,rect.right,rect.bottom);
pOldBmp = memDC.SelectObject(&memBitmap);
第三步:在xv001Dlg類中添加繪圖函數(shù),此函數(shù)的功能是:隨機繪制一幅位圖。
void CXv001Dlg::DrawWave(CDC *pDC)
{
CPen pen,*oldpen;
memDC.Rectangle(rect.left,rect.top,rect.right,rect.bottom);
for(int i =0; i<1500; i++)
{
pen.CreatePen(PS_SOLID,1, RGB(rand()%255,rand()%255,rand()%255));
oldpen = memDC.SelectObject(&pen);
int x0,y0,x1,y1;
x0 = rand()%rect.Width();
x1 = rand()%rect.Width();
y0 = rand()%rect.Height();
y1 = rand()%rect.Height();
memDC.MoveTo(x0,y0);
memDC.LineTo(x1,y1);
memDC.SelectObject(oldpen);
pen.DeleteObject();
}
}
第四步:在xv001Dlg類中添加OnTimer()、OnPaint()和OnClose的消息響應(yīng)函數(shù)。
在OnInitDialog()函數(shù)總添加如下代碼
SetTimer(1,10,NULL); // 啟動定時器
在OnTimer()函數(shù)中添加
DrawWave(&memDC); // 在位圖中畫圖片
OnPaint(); // 使屏幕刷新
在OnPaint()函數(shù)中添加如下代碼,實現(xiàn)將生成的圖片拷貝到屏幕上,完成整個繪圖的工作。
pDC->BitBlt(rect.left,rect.top,rect.right,rect.bottom,&memDC,0,0,SRCCOPY);
最后:在OnClose()函數(shù)中,別忘了銷毀繪圖及位圖設(shè)備的指針。
memDC.SelectObject(pOldBmp);
memDC.DeleteDC();
memBitmap.DeleteObject();
程序執(zhí)行結(jié)果如下:
此程序在winxp系統(tǒng)下,用VC++6.0調(diào)試通過。