zoukankan      html  css  js  c++  java
  • MFC双缓冲和裁剪问题导致闪烁

    问题描述:

        应用场景:在对话框中,自定义一个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函数都会造成影响。 

  • 相关阅读:
    用于 Windows8 的 Wijmo Charts 图表控件
    Silverlight 版 C1OutlookBar 初体验
    TX Text Control文字处理教程(12)MS Word中字段的导入导出操作
    TX Text Control文字处理教程(5)数据库操作
    TX Text Control文字处理教程(10)创建报价单
    TX Text Control文字处理教程(9)XML文件
    在 ActiveReports 中嵌入 Spread 控件
    TX Text Control文字处理教程(8)使用超链接
    TX Text Control文字处理教程(11)使用文本框
    2012春节快到了我们聚会吧!
  • 原文地址:https://www.cnblogs.com/worgeling/p/3419021.html
Copyright © 2011-2022 走看看