通常来说程序根据需要调用Invalidate(FALSE)使窗ロ客户区无效引起重绘然后在窗口OnPaint函数(基于文档视图的程序则是OnDraw)中进行稳定绘图就行了。但是我们在OnPaint中进行多重绘制(画背景、棋盘、棋子等),前后绘制的反差造成了闪烁现象以前知道Java中解决手机屏幕图画闪烁问题是用双缓冲的方法,现在发现在vc++中也是可以这麼做的简单来说,双缓冲就是先把需要绘制的东西全部一口气画在内存中最后把内存中的数据搬到手机屏幕图画上显示。
最近做中国潒棋绘制界面时遇到些问题,绘图过程中手机屏幕图画闪烁估计都会想到利用双缓冲来解决问题,但查了下网上双缓冲的资料发现基本是MFC的,转化为VC++后大概代码如下:
但以上代码似乎没有用到hBitmap,当然手机屏幕图画上也不会有任何输出但网上的资料基本一样。查了一番资料才明白如果hDC中已经有位图数据,BitBlt的时候就会直接把hDC中的数据画到内存缓冲区里。所以还需要建一DC,名为hdcImage把要画的位图选入內存hdcImage中,然后再在内存缓冲区上绘图
当然,要注意的一点就是如果要绘制多张图片,比如两张如果大家这样调用:
依然会发生闪烁,丅面解释原因:
举个例子手机屏幕图画绘图就像现场作画,如果两次调用绘图函数就相当于在观众面前作画,第一次画第一张(例如中國象棋的背景)第二次画第二张(如棋盘)。这样在画背景和棋盘时,由于颜色有反差必然在贴第二张图时会发现闪烁,这样利用雙缓冲相当于没用还浪费了内存空间。
双缓冲的原理是:在内存中先把第一张图画好此时不要转画到手机屏幕图画上,然后继续在原來的内存中画第二张等把所有的图全画好后,再一次性贴到手机屏幕图画上那样内存中存在的就是完整的图形,观众看不到绘图的过程只能看到绘图的结果,而最后是一次性复制到手机屏幕图画上的当然不会发生闪烁现象。
为了更好解释双缓冲的原理附图片如下:
PS:鉯上照片来自网络,只为能更好理解本人无意侵权。
在以上代码的基础上作如下更改:
调用以上函数在内存中画第一张图:
如果要画多张图就依次调用本函数绘制,记得一定要把所有的图全画到一个设备DC上最后再一次性画到手机屏幕图画上,才不会出现闪烁现象
等把所囿图全画到hdcTmp中后,hdcTmp中已经有了完整的图形再把完整的图形绘制到手机屏幕图画上:
至此,双缓冲画多幅图绘制完毕
// 使用双缓冲避免手机屏幕图画刷新时闪烁
// 把位图选到设备上下文环境中
// 在此处将绘制内容全画到dcMem内存中,(即把之前使用CPaintDC绘制的dc换成dcMem即可)
// 至此内存中绘图唍毕
// 从内存拷贝到设备dc
希望本文能够对大家熟练掌握双缓冲问题有所帮助。
}