-- 作者:卷积内核
-- 发布时间:9/2/2006 3:51:00 PM
-- 實時曲線顯示方法及主要代碼,
實進曲張顯示時,圖形閃爍的主要原因是: 窗口重繪時,總先用背景色將顯示區清除,然後才調用OnPaint,而背景色往往與繪圖內容反差很大,短時間內背景色與顯示圖形的交替出現,使得顯示窗口看起來在閃,可采用雙緩沖機制來消除閃屏. 實現繪圖雙緩沖的方法 (顯示窗口的 CDC *pDC=GetDC( ) ): 1.定義一個CDC MemDC 及一個位圖對象 CBitmap bm 2.創建與原DC兼容的內存顯示設備 MemDC.CreateCompatibleDC(pDC); 3.創建一個原DC相兼容的位圖 bm.CreateCompatibleBitmap(pDC,寬,高); 4.將位圖選入內存設備中,才能在MemDC中繪圖 CBitmap *pOldbm=MemDC.SelectObject(&bm); 5.在MemDC中繪圖 MemDC...... 6.繪完圖後,將MemDC拷貝至原pDC中 pDC->BitBlt(0,0,寬,高,&MemDC,0,0,SRCCOPY); 7.清理 bm.DeleteObject( ); MemDC.DeleteDC( ); 主要代碼:(VC6.0+Win9x測試通過) 代碼說明: 在CRect(25,25,425,425)的400*400區域內畫一個20行20列的表格,然後畫曲線(用隨機數取值).每秒左移一次.采用雙緩沖機制消除閃屏. 1.在WM_CREATE 消息中創建定時器: SetTimer (1, 1000, NULL); 2.在WM_DESTROY消息中刪除定時器: KillTimer (1); 3.響應WM_TIMER消息: Invalidate ( ); 4.響應WM_ERASEBKGND消息: return TRUE; 5.在WM_PAINT消息中加入: static int iCol=4; //當前豎線顏色標記 static int arrayHeight[21]; //存儲21條線上的每個點的高度 CPaintDC dc(this); CRect rc; dc.GetClipBox (&rc); //取得當前客戶區大小 CDC MemDC; MemDC.CreateCompatibleDC (&dc); CBitmap bm; bm.CreateCompatibleBitmap (&dc, rc.Width( ), rc.Height( )); CBitmap *pOldbmp=MemDC.SelectObject (&bm); CBrush brWhite(RGB(255,255,255)); CBrush *oldbr=MemDC.SelectObject (&brWhite); MemDC.FillRect (&rc, &brWhite); //將MemDC背景刷成白色 CPen penR(PS_SOLID,1,RGB(255,0,0)); //創建畫筆 CPen penG(PS_SOLID,1,RGB(0,255,0)); CPen penB(PS_SOLID,1,RGB(0,0,255)); CPen *oldPen=MemDC.SelectObject (&penG); //畫橫線 int i; for (i=0; i<21; i++) { if(i%5==0) MemDC.SelectObject (&penB); else MemDC.SelectObject (&penG); MemDC.MoveTo(25,25+20*i); MemDC.LineTo(425,25+20*i); } //畫豎線 if(iCol==-1) iCol=4; for(i=20;i>=0;i--){ if(i%5==iCol) MemDC.SelectObject (&penB); else MemDC.SelectObject (&penG); MemDC.MoveTo(25+i*20,25); MemDC.LineTo (25+i*20,425); } iCol--; for(i=0;i<20;i++) arrayHeight[i]=arrayHeight[i+1]; //將數組左移一位 arrayHeight[20]=rand() % 400 +1; //取新值(采用隨機數) MemDC.MoveTo(425,426-arrayHeight[20]); MemDC.SelectObject (&penR); for (i=19;i>=0;i--){ //開始畫曲線(從右到左) if (arrayHeight[i]<1) break; MemDC.LineTo (25+i*20,426-arrayHeight[i]); } dc.BitBlt(0, 0, rc.Width ( ), rc.Height ( ), &MemDC, 0, 0, SRCCOPY); MemDC.SelectObject (oldPen); //以下是清除工作 MemDC.SelectObject (oldbr); bm.DeleteObject ( ); MemDC.DeleteDC ( );
|