双缓冲的原理可以这样形象的理解:把电脑屏幕看作一块黑板。首先我们在内存环境中建立一个“虚拟“的黑板,然后在这块黑板上绘制复杂的图形,等图形全部绘制完毕的时候,再一次性的把内存中绘制好的图形“拷贝”到另一块黑板(屏幕)上。采取这种方法可以提高绘图速度,极大的改善绘图效果。

例如在OnDraw()函数中可以如下所述实现双缓冲,其主要步骤分为四步:

 CPen Pen;
Pen.CreatePen(PS_INSIDEFRAME,1,RGB(225,225,0));
CBrush Brush;
Brush.CreateSolidBrush(RGB(225,225,0));
CDC dcMem;
CBitmap bm;
CRect rc;
GetClientRect(&rc);
// Step 1:为屏幕DC创建兼容的内存DC :CreateCompatibleDC()
dcMem.CreateCompatibleDC(pDC);
// Step 2:创建位图:CreateCompatibleBitmap()
bm.CreateCompatibleBitmap(pDC,rc.Width(),rc.Height());
// Step 3:把位图选入设备环境:SelectObject(),可以理解为选择画布
dcMem.SelectObject(&bm);
dcMem.SelectObject(Pen);
dcMem.SelectObject(Brush);
dcMem.Ellipse(0,0,50,50);//画椭圆
// Step 4:把绘制好的图形“拷贝“到屏幕上:BitBlt()
pDC->BitBlt(0,0,rc.Width(),rc.Height(),&dcMem,0,0,SRCCOPY);
dcMem.DeleteDC();
bm.DeleteObject();

这样便实现了双缓冲,通过这个方法可以防止在VC中画图时出现屏幕闪烁的情况。

在自己画的窗口中,有时候会有闪烁现象。为什么会有闪烁现象呢?其实是因为程序在画窗口时需要用背景色清空显示区域,然后再画。由于这两者的反差比较大,就会被人眼睛捕捉到,感觉闪烁。

双缓冲就是先在内存中把图画好,然后直接复制到屏幕上去,这样的反差就比较小,也就不觉得闪烁了。

WTL中的CDoubleBufferImpl

WTL中有现成的双缓冲类实现,可以很方便的使用就达到效果。

CDoubleBufferImpl 在AtlFrame.h中。

1.首先继承自CDoubleBufferImpl

class TCtrl:
public CWindowImpl< TCtrl>,
public WTL::CDoubleBufferImpl<TCtrl> // 继承双缓冲类

2.由于双缓冲类中已经处理了WM_ERASEBKGND 和WM_PAINT消息,所以需要从你的代码中删除对这些消息的处理。然后加上双缓冲的消息处理即可。

    BEGIN_MSG_MAP(TCtrl)
// MESSAGE_HANDLER(WM_PAINT, OnPaint)
CHAIN_MSG_MAP( WTL::CDoubleBufferImpl<TCtrl>)
END_MSG_MAP()

3.增加一个DoPaint函数,函数声明如下:

void DoPaint(CDCHandle dc);

4.将原来OnPaint函数中的代码移到DoPaint中,注意原来的CPaintDC需要改用参数中的CDCHandler

void TCtrl::DoPaint( CDCHandle dc )
{
//CPaintDC dc(m_hWnd);

dc.MoveTo( xx… )
}

OK,编译吧。

参考资料

VC画图不闪烁的方法(双缓冲技术)

http://hi.baidu.com/lovefqing/blog/item/3f86cdb6cc5c75f830add174.html

走近WTL--GDI篇

http://blog.iceyer.net/walk_up_to_wtl_gdi_part

Visual C++中实现双缓冲的基本原理

http://www.builder.com.cn/2007/1016/558583.shtml

C++零食:WTL中使用双缓冲避免闪烁的更多相关文章

  1. Qt组件中的双缓冲无闪烁绘图

      双缓冲绘图在Qt4中,所有的窗口部件默认都使用双缓冲进行绘图.使用双缓冲,可以减轻绘制的闪烁感.在有些情况下,用户要关闭双缓冲,自己管理绘图.下面的语句设置了窗口部件的Qt::WA_PaintOn ...

  2. OpenGL中实现双缓冲技术

    在OpenGL中实现双缓冲技术的一种简单方法: 1.在调用glutInitDisplayMode函数时, 开启GLUT_DOUBLE,即glutInitDisplayMode(GLUT_RGB | G ...

  3. C#中利用双缓冲技术解决绘图闪屏问题。

    这段时间在做一个小型游戏,在界面显示的时候用到了一些图形.一开始涉及到的图形全都用控件的背景图片代替了.这样游戏运行的时候存在的一个很大的问题是游戏运行很慢.小组成员费尽周折,即将放弃,每一个成员都愁 ...

  4. C#中使用双缓冲来避免绘制图像过程中闪烁

    自己所做项目中,在显示医学图像的界面中,当鼠标拖动图像时,不断刷新从后台获取新的图像,而整个过程就很诡异,一直闪个不停. 找到的一个可行方法是:在用户控件的构造函数中加入以下代码: SetStyle( ...

  5. MFC中的双缓冲技术(解决绘图闪烁问题)

    转自 MFC绘图不闪烁——双缓冲技术[转] 在VC/MFC用CDC绘图时,频繁的刷新,屏幕会出现闪烁的现象,CPU时间占用率相当高,绘图效率极低,很容易出现程序崩溃. 所谓双缓冲技术,下面是百度百科的 ...

  6. [Qt2D绘图]-06QPainter的复合模式&&双缓冲绘图&&绘图中的其他问题

    本篇读书笔记主要记录QPainter的复合模式&&双缓冲绘图&&绘图中的其他问题   大纲:     复合模式     双缓冲绘图     绘图中的其他问题       ...

  7. C++实现双缓冲

    首先声明下,这篇资料也是整理别人的资料的基础上,总结来的. 在图形图像处理过程中,双缓冲技术是一种比较常见的技术.窗体在响应WM_PAINT消息时,需要对图像进行绘制处理.如果图像绘制次数过多,重绘过 ...

  8. MFC双缓冲绘图实例

    本人之前一直了解双缓冲绘图的基本原理,但是在研究很久之后才大概知道具体的使用过程,本文将详细介绍本人在实际项目中使用双缓冲绘图的案例. 实现功能:主界面显示某张包含人脸的图片,通过dlib detec ...

  9. C#绘图双缓冲

    C#绘图双缓冲 C#双缓冲解释: 简单说就是当我们在进行画图操作时,系统并不是直接把内容呈现到屏幕上,而是先在内存中保存,然后一次性把结果输出来,如果没用双缓冲的话,你会发现在画图过程中屏幕会闪的很厉 ...

随机推荐

  1. 「洛谷P1343」地震逃生 解题报告

    P1343 地震逃生 题目描述 汶川地震发生时,四川XX中学正在上课,一看地震发生,老师们立刻带领x名学生逃跑,整个学校可以抽象地看成一个有向图,图中有n个点,m条边.1号点为教室,n号点为安全地带, ...

  2. 基于Antd框架的通信与交互

    基于Antd框架的通信与交互 1.与用户交互 对于input输入框,在于用户交互的过程中,用户在输入任何东西时,都会引起该组件的onChange事件(如果写有这个方法的话). <FormItem ...

  3. 如何在oracle中缩小临时表空间?ORA-01652无法在表空间中扩展temp

    查询临时表空间有多大: SQL> SELECT tablespace_name, file_name, bytes FROM dba_temp_files WHERE tablespace_na ...

  4. caffe实战笔记

    Caffe简要介绍: Caffe还没有windows版本,所以我需要远程登录linux服务器 Caffe主要处理图片/图片序列 Caffe读取的数据格式 从专用的数据库中读取(lmdb.leveldb ...

  5. Web及网络基础学习(一)

    ---恢复内容开始--- 2019.10.16 1.TCP.IP分层  应用层.网络层.传输层.数据链路层 2.各层讲解 应用层 决定了向用户提供应用服务时通信的活动.例如FTP(File Trans ...

  6. 【Java基础总结】总结

    总想着把学习的过程全都记录下来 以便某一时刻回头的时候,还能看见走过的路 对于基础来说,即使不回头看,也知道这条路是什么样子的 记录不记录,都无所谓 况且我不是专业的记录者,不记录比记录好 实在想不起 ...

  7. Java项目之家庭收支记账软件

    模拟实现基于文本界面的家庭记账软件,该软件能够记录家庭的收入支出,并能够打印收支明细表. 项目采用分级菜单方式.主菜单如下: 假设家庭起始的生活基本金为10000元. 每次登记收入(菜单2)后,收入的 ...

  8. python线性数据结构

    1.栈(Stack)(后进先出) 栈的实现: class Stack: def __init__(self): self.items = [] def isEmpty(self): return se ...

  9. bzoj_1036 树链剖分套线段树

    bzoj_1036 ★★★★   输入文件:bzoj_1036.in   输出文件:bzoj_1036.out   简单对比时间限制:1 s   内存限制:162 MB [题目描述] 一棵树上有n个节 ...

  10. cf 697C Lorenzo Von Matterhorn 思维

    题目链接:https://codeforces.com/problemset/problem/697/C 两种操作: 1是对树上u,v之间的所有边的权值加上w 2是查询树上u,v之间的边权和 树是满二 ...