C++实现双缓冲

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

在图形图像处理过程中,双缓冲技术是一种比较常见的技术。窗体在响应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;

原文地址:https://www.cnblogs.com/guolixiucai/p/4719490.html