VC++双缓冲绘图实战记录

名词解释:

当数据量很大时,绘图可能需要几秒钟甚至更长的时间,而且有时还会出现闪烁现象,为了解决这些问题,可采用双缓冲技术来绘图。 双缓冲即在内存中创建一个与屏幕绘图区域一致的对象,先将图形绘制到内存中的这个对象上,再一次性将这个对象上的图形拷贝到屏幕上,这样能大大加快绘图的速度。双缓冲实现过程如下:
  1. 在内存中创建与画布一致的缓冲区
  2. 在缓冲区画图
  3. 将缓冲区位图拷贝到当前画布上
  4. 释放内存缓冲区
上面是来自百度百科的名词解释,下面是我实践以后的总结:

土方法:

步骤一 屏蔽背景刷新

背景刷新其实是在响应WM_ERASEBKGND消息。我们在 视类中添加对这个消息的响应,缺省的代码如下:

BOOL CMYView::OnEraseBkgnd(CDC* pDC)
{
//return CView::OnEraseBkgnd(pDC);
return TRUE;
}

步骤二 缓冲绘图

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());

pPicture->Render(dcMem.m_hDC,0,0,rect.Width(),rect.Height(), 0,nHeight,nWidth,-nHeight,NULL);

pDC->BitBlt(0,0,rect.Width(),rect.Height(),

&dcMem,0,0,SRCCOPY);//将内存DC上的图象拷贝到前台

dcMem.DeleteDC(); //删除DC

新方法

在高版本的VS中已经自带了一个CMemDC类,利用这个类可以进行绘图,不必关注双缓冲的细节。PS:高版本=(VS2008SP1以及以后),老版本也有方法,耐心看下去。

步骤一 响应WM_ERASEBKGND消息

返回FALSE,这样就不擦除背景了。
BOOL CDemoView::OnEraseBkgnd(CDC* pDC) 
{ 
return FALSE; 
}

步骤二 在需要作图的地方使用CMemDC

void CDemoView::OnDraw(CDC* pDC)
{
CGestureDemoDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
CMemDC dcMem(*pDC, this);
CDC& dc = dcMem.GetDC();
//用dc来绘图就可以实现栓缓冲
……
}

关于低版本VS

在低版本中可以导入一个继承于CDC的类CMemDC,使用的时候需要使用
#include "MemDC.h"
使用方法与之前的类似,只需要用一个CDC的对象初始化就行。
CMemDC pMemDC(pDC);
点击这里下载MemDC.h

其他相关文章

如果对本文有其他疑问,可以在本文下方留言。 如果有其他GIS、3S相关疑问也可以到 麻辣GIS问答 版块发表提问。
本站QQ群:291616564; 微信公众号:malagis,扫描 二维码 直接关注。

打赏¥1

作者:,GIS爱好者。
分享本文,请您带上本文链接
分享到:

仅有一条评论

  1. fuzimango
    1#
    fuzimango  · 2014-04-18 16:07

    博主您好,可否请教个问题。请问我要在OnLButtonUp时实现绘图,是否在OnLButtonUp里调用OnDraw?可OnDraw里需要CDC* pDC变量,OnLButtonUp里用什么传过去?还有我画的图还是一直闪。。。最后要不要用MemDC.DeleteDC()清理?

发表评论