MFC双缓冲和裁剪问题导致闪烁
2013-11-12 10:26
246 查看
问题描述:
应用场景:在对话框中,自定义一个MFC图形控件(为了描述方便,暂定为HSPaintControl),控件覆盖整个对话框的客户区,属于最底层的控件,在这之上放置了很多其他的小图形控件。
问题:更具业务需要,HSPaintControl需要高频率(大概是60FPS)的刷新,为了解决闪烁问题,使用了双缓冲技术。运行时,HSPaintControl不断刷新,其上层的其他小控件也在刷新,HSPaintControl控件不会闪烁,但上层小控件界面一直在闪。
问题的原因:
HSPaintControl使用双缓冲刷新时,覆盖了整个背景,上层小控件界面显示,也会执行一次刷新,从而导致一个地方界面刷新了两次,就导致闪烁问题。
界面不闪烁的绘制原则:
确保界面每个像素只刷新一次。
解决办法:
1. 能解决该问题最笨的方式是完全自己控制,在HSPaintControl刷新时,不刷新上层控件所在区域。HSPaintControl刷新时,获取上层的所有子控件,计算区域,然后一个一个排除。这个方法有两个比较麻烦的问题:第一是如何获取在上层存在遮盖的控件;第二是要计算排除所有这些控件和HSPaintControl控件的叠加区域。最开始的时候,上层只有一个控件,而且是完全放在上上面的,可以硬编码的方式解决上面两个问题(可以自己计算排除区域,再使用BitBlt函数一块一块的拷贝,也可以借助于函数ExcludeClipRect,直接排除掉,当然使用已经有的函数,是比较方便的)。但是后来小控件越来越多,就很麻烦了。
2. 上层小控件很多的情况下,第一个方法就搞不定了,考虑到MFC自己的控件叠加刷新时,都不存在闪烁的问题,那么肯定在内部实现了裁剪,经寻找果然存在该机制,通过设置自定义控件的样式即可搞定,增加样式WS_CLIPSIBLINGS(不明白的请google一下)。自定义控件是基于CStatic做的,在实现时,重载函数PreSubclassWindow,添加上对应的样式设置语句:
用系统自带的机制,确实就方便多了。如果自己要实现图形系统,那么相应的裁剪就还得自己来做了。
值得注意的是ExcludeClipRect函数和样式WS_CLIPSIBLINGS对BitBlt函数都会造成影响。
应用场景:在对话框中,自定义一个MFC图形控件(为了描述方便,暂定为HSPaintControl),控件覆盖整个对话框的客户区,属于最底层的控件,在这之上放置了很多其他的小图形控件。
问题:更具业务需要,HSPaintControl需要高频率(大概是60FPS)的刷新,为了解决闪烁问题,使用了双缓冲技术。运行时,HSPaintControl不断刷新,其上层的其他小控件也在刷新,HSPaintControl控件不会闪烁,但上层小控件界面一直在闪。
问题的原因:
HSPaintControl使用双缓冲刷新时,覆盖了整个背景,上层小控件界面显示,也会执行一次刷新,从而导致一个地方界面刷新了两次,就导致闪烁问题。
界面不闪烁的绘制原则:
确保界面每个像素只刷新一次。
解决办法:
1. 能解决该问题最笨的方式是完全自己控制,在HSPaintControl刷新时,不刷新上层控件所在区域。HSPaintControl刷新时,获取上层的所有子控件,计算区域,然后一个一个排除。这个方法有两个比较麻烦的问题:第一是如何获取在上层存在遮盖的控件;第二是要计算排除所有这些控件和HSPaintControl控件的叠加区域。最开始的时候,上层只有一个控件,而且是完全放在上上面的,可以硬编码的方式解决上面两个问题(可以自己计算排除区域,再使用BitBlt函数一块一块的拷贝,也可以借助于函数ExcludeClipRect,直接排除掉,当然使用已经有的函数,是比较方便的)。但是后来小控件越来越多,就很麻烦了。
2. 上层小控件很多的情况下,第一个方法就搞不定了,考虑到MFC自己的控件叠加刷新时,都不存在闪烁的问题,那么肯定在内部实现了裁剪,经寻找果然存在该机制,通过设置自定义控件的样式即可搞定,增加样式WS_CLIPSIBLINGS(不明白的请google一下)。自定义控件是基于CStatic做的,在实现时,重载函数PreSubclassWindow,添加上对应的样式设置语句:
// TODO: 在此添加专用代码和/或调用基类 DWORD dwStyle = GetStyle(); SetWindowLong(GetSafeHwnd(),GWL_STYLE,dwStyle | WS_CHILD | WS_CLIPSIBLINGS | SS_OWNERDRAW ); CStatic::PreSubclassWindow();
用系统自带的机制,确实就方便多了。如果自己要实现图形系统,那么相应的裁剪就还得自己来做了。
值得注意的是ExcludeClipRect函数和样式WS_CLIPSIBLINGS对BitBlt函数都会造成影响。
相关文章推荐
- MFC双缓冲解决闪烁问题
- MFC下双缓冲解决高速绘制刷新闪烁问题+多媒体定时器
- MFC中的双缓冲技术(解决绘图闪烁问题)
- VC++ MFC+GDIPlus 双缓冲解决闪烁问题
- OpenGL+MFC导致闪烁、不刷新等问题的解决方法
- MFC 双缓冲 绘图时屏幕闪烁问题
- findContours导致MFC程序崩溃的问题
- recyclerView调用notifyItemChanged导致屏幕闪烁的问题
- MFC双缓冲解决图象闪烁
- MFC List Control快速更新时闪烁问题的解决办法
- MFC中屏幕刷新闪烁问题解决方法总结
- 有关MFC中使用CButton类后位图按钮闪烁的问题
- 【旧资料整理】MFC--滚动视图窗口(CScrollView)使用双缓冲问题
- 使用双缓冲解决图片切换时的闪烁问题
- 解决MFC中CListCtrl(virtual)控件闪烁问题
- 双缓冲加重载onpaint,OnEraseBkgnd解决屏幕闪烁问题
- MFC绘图闪烁问题
- 三星手机调用系统意图拍照裁剪图片导致图片旋转90度的问题记录
- 游戏开发中双缓冲解决屏幕闪烁问题
- Android 解决SurfaceView切换导致界面闪烁,短暂黑屏问题。