首先聲明下,這篇資料也是整理別人的資料的基礎上,總結來的。
在圖形圖像處理過程中,雙緩沖技術是一種比較常見的技術。窗體在響應WM_PAINT消息時,需要對圖像進行繪制處理。如果圖像繪制次數過多,重繪過於頻繁時,或者當要繪制的對象太復雜,尤其是含有位圖時,一般計算機便力不從心了。顯示器上就會因為刷新過頻或者過慢而閃爍。雙緩沖就是解決這種問題的技術。
窗體在刷新前,會首先擦除(OnEraseBkgnd)之前的內容,然后利用背景色填充,再調用繪制代碼進行繪制。一擦一填一寫,就會形成顏色的反差,當反差過於明顯且頻繁時,閃爍就來了。擦除繪制需要時間去處理。如果不在窗體上直接繪制,而是在“別的地方”繪制好,然后再直接搬過來,就不會有這種問題了。這就是雙緩沖的基本原理。
雙緩沖技術中,內存就充當了“別的地方”。雙緩沖技術分為五步:
1、在內存中申請緩沖區,創建兼容內存;
2、創建位圖,並將位圖與緩沖區內存相關聯起來;
3、在兼容內存里繪制;
4、將繪制好的位圖拷貝到當前設備;
5、釋放兼容內存。
具體代碼實現如下(這是一個繪制同心圓的例子):
CPoint ptCenter; CRect rect,ellipseRect; GetClientRect(&rect); ptCenter = rect.CenterPoint(); CDC dcMem; //用於緩沖作圖的內存DC CBitmap cbBmp; //內存中承載臨時圖象的位圖 dcMem.CreateCompatibleDC(pDC); //申請緩沖區,依附窗口DC創建兼容內存DC cbBmp.CreateCompatibleBitmap(pDC,rect.Width(),rect.Height());//創建兼容位圖 dcMem.SelectObject(&cbBmp); //將位圖選擇進內存DC //按原來背景填充客戶區,不然會是黑色 dcMem.FillSolidRect(rect,pDC->GetBkColor()); for(int i=20;i>0;i--) //在內存DC上做同樣的同心圓圖象 { ellipseRect.SetRect(ptCenter,ptCenter); ellipseRect.InflateRect(i*10,i*10); dcMem.Ellipse(ellipseRect); } /* //提供下繪制方框、畫線等方法 dcMem.FillSolidRect(0,0,nWidth,nHeight,RGB(255,255,255)); //繪圖 dcMem.MoveTo(……); dcMem.LineTo(……); */ pDC->BitBlt(0,0,rect.Width(),rect.Height(), &dcMem,0,0,SRCCOPY);//將內存DC上的圖象拷貝到前台 dcMem.DeleteDC(); //刪除DC
該段代碼中已經提供了填充客戶區的方法,為了提高繪制效率,可以繼承OnEraseBkgnd,然后直接返回true就行。
BOOL Test::OnEraseBkgnd(CDC* pDC)
{
//調用父類的OnEraseBkgnd函數,我們屏蔽此調用
//return CView::OnEraseBkgnd(pDC);
return TRUE;
}