1. 程式人生 > >VC使用雙緩衝避免繪圖閃爍的正確使用方法【轉】

VC使用雙緩衝避免繪圖閃爍的正確使用方法【轉】

使用記憶體DC繪圖,然後實現雙緩衝,避免繪圖閃爍,這個小技術簡單但很有效。但是仍然有很多人說使用了雙緩衝,圖片卻仍然有閃爍,分析了幾個這樣的例子,發現

其實不是雙緩衝的技術問題,而是使用者沒有正確理解和使用雙緩衝的方法。使用雙緩衝要點如下:

1. 保證繪圖過程中的所有CDC及其繼承類指向記憶體DC。

在視窗或者檢視中繪圖,一般都是在OnDraw或者OnPaint事件中,但是有時根據需要繪圖是通過呼叫其他類及函式完成比較複雜的繪製,在這些函式中,有時編寫者會獲取諸如CClientDC,然後繪圖,此時的任何動作都會繞過緩衝區直接繪製到螢幕,從而造成閃爍。正確的做法是檢查並修改所有繪圖過程函式,避免直接獲取CClientDC、CWindowDC、CPaintDC之類。而是採用傳遞CDC指標的方式寫繪圖類或者函式。

2. 修改OnEraseBkgnd(CDC* /*pDC*/)  事件 

將程式碼遮蔽,改為一句    return TRUE;   這樣做是避免使用原來父類程式碼中的擦除螢幕語句。

3. 另一個容易忽略的關鍵點-〉擦除背景。

第2條是必要的,避免了擦除背景的工作,但是這不代表背景不需要擦除了,只不過這個擦除過程要放到記憶體緩衝區中去做。

例如下面程式碼:

void CGraphView::EraseBkgnd(CDC* pDC) { // TODO: Add your message handler code here and/or call default
CRect rect; GetClientRect( &rect ); CBrush brush; brush.CreateSolidBrush(GetColor(CColorClass::clrGraphBK) ); pDC->FillRect( &rect, &brush ); } void CGraphView::OnDraw(CDC* pDC) { CRect rectClient; GetClientRect( &rectClient ); CMemDC memDC(pDC, rectClient);
EraseBkgnd(&memDC);            // OnEraseBkgnd 失效了,但是仍然需要在記憶體緩衝區中擦除背景 m_graph.Redraw( &memDC, rectClient ); }

如果要求更高的繪圖效率,重畫時可以採用區域性擦除的辦法,即擦除一定區域內的程式碼。

使用雙緩衝的整個步驟如下:

定義記憶體裝置CMemDC,將所有繪圖DC指向該裝置  ---〉去掉擦除背景語句 ---〉在記憶體DC中擦除背景

-〉在記憶體DC中繪圖 -〉結果切換到顯示DC。

實際應用於複雜圖形繪製,沒有任何閃爍變化。

*文中提到的雙緩衝程式碼CMemDC是個開源類,其內容如下:

#ifndef _MEMDC_H_ #define _MEMDC_H_ ////////////////////////////////////////////////// // CMemDC - memory DC // // Author: Keith Rule // Email:  [email protected] // Copyright 1996-1999, Keith Rule // // You may freely use or modify this code provided this // Copyright is included in all derived versions. // // History - 10/3/97 Fixed scrolling bug. //                   Added print support. - KR // //           11/3/99 Fixed most common complaint. Added //                   background color fill. - KR // //           11/3/99 Added support for mapping modes other than //                   MM_TEXT as suggested by Lee Sang Hun. - KR // // This class implements a memory Device Context which allows // flicker free drawing. class CMemDC : public CDC { protected: CBitmap  m_bitmap;       // Offscreen bitmap CBitmap* m_oldBitmap;    // bitmap originally found in CMemDC CDC*     m_pDC;          // Saves CDC passed in constructor CRect    m_rect;         // Rectangle of drawing area.

相關推薦

VC使用緩衝避免繪圖閃爍正確使用方法

使用記憶體DC繪圖,然後實現雙緩衝,避免繪圖閃爍,這個小技術簡單但很有效。但是仍然有很多人說使用了雙緩衝,圖片卻仍然有閃爍,分析了幾個這樣的例子,發現 其實不是雙緩衝的技術問題,而是使用者沒有正確理解和使用雙緩衝的方法。使用雙緩衝要點如下: 1. 保證繪圖過程中的所有CDC及其繼承類指向記

C# 通過GDI+緩衝解決繪圖閃爍的問題

總體思路:        把圖先畫在bitmap上,每次都通過drawimage將bitmap傳到顯示裝置,雙快取的graphics不用每次都create一個,這樣會閃爍,解決方法是定義一個全域性的BufferedGraphics graphBuffer,然後在每次畫的時候取

Delphi 導出數據至Excel的7種方法

dbase cas excel classes date pbo item 方式 down 轉自:http://blog.csdn.net/zang141588761/article/details/52275948 一; delphi 快速導出excel u

dpkg: error processing package bluez (--configure) 解決方法

operation proc addition too opera report add message ace 轉自:http://blog.csdn.net/heray1990/article/details/47803541 在 Ubuntu 執行 sudo apt

C++中三種創建對象的方法

內存 stream self 一般來說 ron ref 支持 內存碎片 搜索 我們都知道C++中有三種創建對象的方法,如下: #include <iostream> using namespace std; class A { private: in

軟件項目中的成本構成及估算方法

一個 發生 折舊費 art 載體 計算機 需求 復雜度 content 隨著知識經濟、信息時代的來臨,計算機軟件業迅猛發展。商品化、資本化、資產化的計算機軟件的價值 評估的社會需求也日益增多,而且有越來越多的趨勢。由於系統軟件通常是一些規模大、復雜程度高的人一 機系統,因此

軟件開發成本估算方法

ec2 結果 div 列表 持續時間 整理 str 似的 cti 轉自:http://hi.baidu.com/wangziming/blog/item/d8ee34010b18cf0e7bec2c4b.html 我的學習感悟:對於這個並不懂,尤其是什麽靜態單變

各瀏覽器禁用某網站JS腳本的方法

per gin width aaa all firefox nal opera 腳本 某些網站,經常會加載一些非常討厭的JS腳本,如果我們想禁止這個網站的JS腳本,可以使用下面的方法: 一、IE瀏覽器 1、在Internet選項中,選擇安全選項卡,然後點擊受限制的站點,

分區工具parted的詳解及常用分區使用方法

ima nbsp 磁盤 很好 main adding ext3 當前 padding 來源:http://blog.51cto.com/zhangmingqian/1068779 分區工具parted的詳解及常用分區使用方法 一、 parted的用途

學習的方法

時間 中大 思想 高級 一個 平時 能夠 data body 我主張,在具備基礎之後,學習任何新東西,都要抓住主線,突出重點。對於關鍵理論的學習,要集中精力,速戰速決。而旁枝末節和非本質性的知識內容,完全可以留給實踐去零敲碎打。原因是這樣的,任何一個高級的知識內容,其中都只

Mysql處理海量數據時的一些優化查詢速度方法

有意義 最好 普通 drop git .com war 解決方案 臨時 最近一段時間由於工作需要,開始關註針對Mysql數據庫的select查詢語句的相關優化方法。由於在參與的實際項目中發現當mysql表的數據量達到百萬級時,普通SQL查詢效率呈直線下降,而且如果where

vscode中檢測代碼中的空白行並去除的方法

圖片 nts ctrl+h 空白行 正則匹配 term .net 替換 fcm 按下ctrl+h鍵進行正則匹配:^\s*(?=\r?$)\n 然後直接替換,再看代碼發現空行已經不見了。vscode中檢測代碼中的空白行並去除的方法【轉】

python的pymysql使用方法

提交 gda bubuko pymysql swd 數據庫 delet 參數 for 前言 pymsql是Python中操作MySQL的模塊,其使用方法和MySQLdb幾乎相同。但目前pymysql支持python3.x而後者不支持3.x版本。 本文測試python版本

多執行緒記憶體問題分析之mprotect方法

轉自:https://blog.csdn.net/agwtpcbox/article/details/53230664 http://www.yebangyu.org/blog/2016/02/01/detectmemoryghostinmultithread/ 多執行緒中的記憶體問題,一直被認為是噩夢般

hive中文字符亂碼 解決方法

為我 如果 mysql blog res mys shake 如何 color 一.個人初始開發環境的基本情況以及Hive元數據庫說明 ①hive的元數據庫改成了mysql(安裝完mysql之後也沒有進行其它別的設置) ②hive-site.xml中設置元數據庫對應的配

pt-table-checksum 使用方法

27. pt-table-checksum27.1 pt-table-checksum 作用  主要用來檢查主從資料是否一致,原理即在主庫執行把表每行的列通過concat函式進行拼接,然後對拼接的值進行hash,並把該動作通過binlog傳遞到從庫,從而在從庫上也執行相關操作(pt-table-ch

WinCE程式除錯方法

剛剛接觸WinCE程式設計,感覺大部分跟WinForm一樣。剛開始的時候,不知道怎麼進行斷點除錯,後來同事告訴我,可以直接連線進行斷點除錯,一試之下,果然好用,所以拿出來分享一下。必備工具:Microsoft ActiveSync,該工具主要用於WinCE裝置和Windows Mobile系統的手機跟PC進行

Git衝突與解決方法 Git衝突與解決方法

本文轉載自:https://www.cnblogs.com/gavincoder/p/9071959.html Git衝突與解決方法 1、git衝突的場景 情景一:多個分支程式碼合併到一個分支時; 情景二:多個分支向同一個遠端分支推送程式碼時; 實際上,push操作即是將

VC6下CHtmlView中最簡單最全面的程式與網頁互動方法

寫的太實用了,未經允許就轉了,不行的話,我可以刪除。 VC6下CHtmlView中最簡單最全面的程式與網頁互動方法 簡單來說,終極目標------VC6和網頁相互呼叫對方的資料和方法;而呼叫方法時重點要捕獲返回值。 VC6下遠沒有VC7及其之後提供的操作豐富方便。