博客园  :: 首页  :: 新随笔  :: 订阅 订阅  :: 管理

MFC绘图时窗口闪烁问题的办法

Posted on 2010-08-29 20:47  扬名  阅读(3425)  评论(0编辑  收藏  举报

  在网上看了不少解决办法,主要都是关于运用双缓冲的,就自己稍微总结了下双缓冲。

  1、显示的图形为什么会闪烁? 
      我们的绘图过程大多放在OnDraw或者OnPaint函数中,OnDraw在进行屏幕显示时是由OnPaint进行调用的。当窗口由于任何原因需要重绘时,总是先用背景色将显示区清除,然后才调用OnPaint,而背景色往往与绘图内容反差很大,这样在短时间内背景色与显示图形的交替出现,使得显示窗口看起来在闪。如果将背景刷设置成NULL,这样无论怎样重绘图形都不会闪了。当然,这样做会使得窗口的显示乱成一团,因为重绘时没有背景色对原来绘制的图形进行清除,而又叠加上了新的图形。

  2、如何避免闪烁 

  双缓冲就是除了在屏幕上有图形进行显示以外,在内存中也有图形在绘制。我们可以把要显示的图形先在内存中绘制好,然后再一次性的将内存中的图形按照一个点一个点地覆盖到屏幕上去(这个过程非常快,因为是非常规整的内存拷贝)。这样在内存中绘图时,随便用什么反差大的背景色进行清除都不会闪,因为看不见。当贴到屏幕上时,因为内存中最终的图形与屏幕显示图形差别很小(如果没有运动,当然就没有差别),这样看起来就不会闪。 

  3、如何实现双缓冲 
      首先给出实现的程序,然后再解释,同样是在OnDraw(CDC   *pDC)中: 

  

CDC   MemDC;   //首先定义一个显示设备对象 
CBitmap   MemBitmap;//定义一个位图对象 

//随后建立与屏幕显示兼容的内存显示设备 
MemDC.CreateCompatibleDC(NULL); 
//这时还不能绘图,因为没有地方画   ^_^ 
//下面建立一个与屏幕显示兼容的位图,至于位图的大小嘛,可以用窗口的大小 
MemBitmap.CreateCompatibleBitmap(pDC,nWidth,nHeight); 
  
//将位图选入到内存显示设备中 
//只有选入了位图的内存显示设备才有地方绘图,画到指定的位图上 
CBitmap  *pOldBit=MemDC.SelectObject(&MemBitmap); 

//先用背景色将位图清除干净,这里我用的是白色作为背景 
//你也可以用自己应该用的颜色 
MemDC.FillSolidRect(0,0,nWidth,nHeight,RGB(255,255,255)); 

//绘图 
MemDC.MoveTo(……); 
MemDC.LineTo(……); 

//将内存中的图拷贝到屏幕上进行显示 
pDC->BitBlt(0,0,nWidth,nHeight,&MemDC,0,0,SRCCOPY); 

//绘图完成后的清理 
MemBitmap.DeleteObject(); 
MemDC.DeleteDC();