在圖形圖象處理程式設計過程中,雙緩衝是一種基本的技術。我們知道,如果窗體在響應wm_paint訊息的時候要進行複雜的圖形處理,那麼窗體在重繪時由於過頻的重新整理而引起閃爍現象。解決這一問題的有效方法就是雙緩衝技術。
因為窗體在重新整理時,總要有乙個擦除原來圖象的過程onerasebkgnd,它利用背景色填充窗體繪圖區,然
後在呼叫新的繪圖**進行重繪,這樣一擦一寫造成了圖象顏色的反差。當wm_paint的響應很頻繁的時候
,這種反差也就越發明顯。於是我們就看到了閃爍現象。
我們會很自然的想到,避免背景色的填充是最直接的辦法。但是那樣的話,窗體上會變的一團糟。因為每次繪
製圖象的時候都沒有將原來的圖象清除,造成了圖象的殘留,於是窗體重繪時,畫面往往會變的亂七八糟。所
以單純的禁止背景重繪是不夠的。我們還要進行重新繪圖,但要求速度很快,於是我們想到了使用bitblt函式。
它可以支援圖形塊的複製,速度很快。我們可以先在記憶體中作圖,然後用此函式將做好的圖複製到前台,同時
禁止背景重新整理,這樣就消除了閃爍。以上也就是雙緩衝繪圖的基本的思路。
一、普通方法:
先按普通做圖的方法進行程式設計。即在視類的ondraw函式中新增繪圖**。在此我們繪製若干同心圓,代
碼如下:
cbcdoc* pdoc = getdocument();
assert_valid(pdoc);
cpoint ptcenter;
crect rect,ellipserect;
getclientrect(&rect);
ptcenter = rect.centerpoint();
for(int i=20;i>0;i--)
編譯執行程式,嘗試改變視窗大小,可以發現閃爍現象。
二、雙緩衝方法:
在雙緩衝方法中,首先要做的是遮蔽背景重新整理。背景重新整理其實是在響應wm_erasebkgnd訊息。我們在
視類中新增對這個訊息的響應,可以看到預設的**如下:
bool cmyview::onerasebkgnd(cdc* pdc)
是呼叫父類的onerasebkgnd函式,我們遮蔽此呼叫,只須直接return true;即可。
下面是記憶體緩衝作圖的步驟。
cpoint ptcenter;
crect rect,ellipserect;
getclientrect(&rect);
ptcenter = rect.centerpoint();
cdc dcmem; //
用於緩衝作圖的記憶體dc
cbitmap bmp; //記憶體中承載臨時圖象的點陣圖
dcmem.createcompatibledc(pdc); //依附視窗dc建立相容記憶體dc
bmp.createcompatiblebitmap(pdc,rect.width(),rect.height());//建立相容位圖
dcmem.selectobject(&bmp); //將位圖選擇進記憶體dc
//按原來背景填充客戶區,不然會是黑色
dcmem.fillsolidrect(rect,pdc->getbkcolor());
for(int i=20;i>0;i--) //在記憶體dc上做同樣的同心圓圖象
pdc->bitblt(0,0,rect.width(),rect.height(),
&dcmem,0,0,srccopy);//將記憶體dc上的圖象拷貝到前台
dcmem.deletedc(); //刪除dc
bm.deleteobject(); //
刪除位圖
由於複雜的畫圖操作轉入後台,我們看到的是速度很快的複製操作,自然也就消除了閃爍現象。
如何實現雙緩衝 vc雙緩衝
cdc memdc 首先定義乙個顯示裝置物件 cbitmap membitmap 定義乙個位圖物件 隨後建立與螢幕顯示相容的記憶體顯示裝置 memdc.createcompatibledc null 這時還不能繪圖,因為沒有地方畫 下面建立乙個與螢幕顯示相容的點陣圖,至於點陣圖的大小嘛,可以用視窗的...
VC顯示雙緩衝
當應用程式中使用多次gdi呼叫繪製到視窗中時,在視窗清除並被重新繪製時,會出現明顯的閃爍。使用雙緩衝技術可輕鬆消除閃爍。步驟如下 1 假設當前顯示裝置上下文為cdc pdc 2 使用cdc物件建立可相容裝置上下文,cdc memdc memdc.createcompatibledc pdc 3 使用...
GDI 雙緩衝實現
gdi 使用雙緩衝繪圖 我再來詳細解釋一下剛才實現雙緩衝的具體步驟 1 在記憶體中建立一塊 虛擬畫布 bitmap bmp new bitmap 600,600 2 獲取這塊記憶體畫布的graphics引用 graphics g graphics.fromimage bmp 3 在這塊記憶體畫布上繪...