首先声明下,这篇资料也是整理别人的资料的基础上,总结来的。

在图形图像处理过程中,双缓冲技术是一种比较常见的技术。窗体在响应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=;i>;i--) //在内存DC上做同样的同心圆图象 

{

ellipseRect.SetRect(ptCenter,ptCenter); 

ellipseRect.InflateRect(i*,i*); 

dcMem.Ellipse(ellipseRect); 

} 

/*  

//提供下绘制方框、画线等方法

dcMem.FillSolidRect(0,0,nWidth,nHeight,RGB(255,255,255));

//绘图

dcMem.MoveTo(……);

dcMem.LineTo(……);

*/

pDC->BitBlt(,,rect.Width(),rect.Height(),  &dcMem,,,SRCCOPY);//将内存DC上的图象拷贝到前台 

dcMem.DeleteDC(); //删除DC 

该段代码中已经提供了填充客户区的方法,为了提高绘制效率,可以继承OnEraseBkgnd,然后直接返回true就行。

BOOL Test::OnEraseBkgnd(CDC* pDC)

{

//调用父类的OnEraseBkgnd函数,我们屏蔽此调用

//return CView::OnEraseBkgnd(pDC);

return TRUE;

}

C++实现双缓冲的更多相关文章

  1. C++双缓冲多线程分析大文件词频

    实习生活告一段落,我正式从一名.NET程序员转入Java阵营,不得不说刚开始用Java的东西是多么的不习惯,但是经过三个月的使用与开发,我也发现了Java的优势:不在于语言,而在于开源.这意味着有更多 ...

  2. (转载)GDI+双缓冲

    双缓冲在GDI+里可以有效的提高描画效率.改善显示的质量. 下面的代码是一个最简单的双缓冲的模板.可以根据需要,做简单的修改即可. Bitmap CacheImage( [Width], [Heigh ...

  3. OpenGL中实现双缓冲技术

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

  4. MFC双缓冲绘图(2015.09.24)

    问题引入: 最近在尝试编写贪吃蛇游戏时遇到这么一个问题:当系统以较快频率向窗口发送WM_PAINT消息时,调用OnPaint()函数在窗口中绘制图形就会发生闪烁现象. 问题分析: 当我们把绘图过程放在 ...

  5. winform上控件太多,绘制时会逐个出现,通常说双缓冲能解决但实际不能解决的问题的解决方法。

    protected override CreateParams CreateParams { get { CreateParams cp = base.CreateParams; cp.ExStyle ...

  6. Winform打砖块游戏制作step by step第6节---双缓冲应用

    一 引子 为了让更多的编程初学者,轻松愉快地掌握面向对象的思考方法,对象继承和多态的妙用,故推出此系列随笔,还望大家多多支持. 二 本节内容---双缓冲应用 1.  主界面截图如下: 2.  什么是双 ...

  7. OpenGL的消隐与双缓冲

    首先是大家可能已经发现,在我们之前提到的所有例子中,在图形的旋转过程中整个图形都有一定程度的闪烁现象,显得图形的过渡极不平滑,这当然不是我们所要的效果,幸好opengl 支 持一个称为双缓存的技术,可 ...

  8. win32下的双缓冲绘图技术

    一:双缓冲原理 为了解决窗口刷新频率过快所带来的闪烁问题,利用双缓冲技术进行绘图.所谓双缓冲技术,就是将资源加载到内存,然后复制内存数据到设备DC(这个比较快),避免了直接在设备DC上绘图(这个比较慢 ...

  9. VC++绘图时,利用双缓冲解决屏幕闪烁 转载

    最近做中国象棋,绘制界面时遇到些问题,绘图过程中屏幕闪烁,估计都会想到利用双缓冲来解决问题,但查了下网上双缓冲的资料,发现基本是MFC的,转化为VC++后,大概代码如下: void DrawBmp(H ...

随机推荐

  1. 注册Com组件..

    开发一些第三方的接口或者功能时..有时会需要接入对方提供Com组件..是一个dll文件.. 这个文件会在你的程序中引用.. 比如一个CMBChina.dll文件..这是招商银行的支付开发时必备的.. ...

  2. Python开发【第十一篇】:JavaScript

    JavaScript是一门编程语言,浏览器内置了JavaScript语言的解释器,所以在浏览器上按照JavaScript语言的规则编写相应代码之,浏览器可以解释并做出相应的处理. 一.如何编写 1.J ...

  3. Devexpress-1 DataGrid控件

    参考资料: 使用XtraGrid自定义列计算 DEV GridControl小结 实现对两列求和后作为新的列

  4. IOS表情存入MYSQL数据库失败

    从 MySQL 5.5.3 开始,MySQL 支持一种 utf8mb4 的字符集,这个字符集能够支持 4 字节的 UTF8 编码的字符. utf8mb4 字符集能够完美地向下兼容 utf8 字符串.在 ...

  5. 移动端 css实现自适应正圆 ( 宽高随着手机屏幕宽度自适应 )

    序言:应朋友要求随手写了一下移动端 css实现自适应正圆 ( 宽高随着手机屏幕宽度自适应 ) ,以备后用 LESS代码: .adaptive-circle { margin: 50px auto 0; ...

  6. PHP CLI下接受参数的几种方法

    PHP CLI(命令行模式下)接受参数有多种方法: (1)使用$argv接受参数 <?php //变量仅在 register_argc_argv 打开时可用. print_r($argc); / ...

  7. 此请求的查询字符串的长度超过配置的 maxQueryStringLength 值 --不仅wen.fonfig一个地方需要设置

    提示已经很明确了... 搜出来的都是: <system.webServer> <security> <requestFiltering> <requestLi ...

  8. assign与weak区别(面试)

    weak 比 assign 多了一个功能就是当属性所指向的对象消失的时候(也就是内存引用计数为0)会自动赋值为 nil ,这样再向 weak 修饰的属性发送消息就不会导致野指针操作crash. 可能不 ...

  9. SQL Server数据库邮件配置

    一.数据库邮件介绍 数据库邮件是从SQL Server数据库引擎中发送电子邮件的企业解决方案,通过使用数据库邮件,数据库应用程序可以向用户发送电子邮件.邮件中可以包含查询结果,还可以包含来自网络中任何 ...

  10. 在PHP中$_SESSION的使用方法

    使用PHP应用session时,将session中的数据存储在服务器上,然后通过客户端传来的sessionID识别客户端的信息,并提取信息. php中的session的常用操作:session的写入. ...