问题描述:

应用场景:在对话框中,自定义一个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双缓冲和裁剪问题导致闪烁的更多相关文章

  1. MFC双缓冲解决图象闪烁[转]

    转载网上找到的一篇双缓冲的文章,很好用.http://www.cnblogs.com/piggger/archive/2009/05/02/1447917.html__________________ ...

  2. MFC中的双缓冲技术(解决绘图闪烁问题)

    转自 MFC绘图不闪烁——双缓冲技术[转] 在VC/MFC用CDC绘图时,频繁的刷新,屏幕会出现闪烁的现象,CPU时间占用率相当高,绘图效率极低,很容易出现程序崩溃. 所谓双缓冲技术,下面是百度百科的 ...

  3. MFC双缓冲绘图(2015.09.24)

    问题引入: 最近在尝试编写贪吃蛇游戏时遇到这么一个问题:当系统以较快频率向窗口发送WM_PAINT消息时,调用OnPaint()函数在窗口中绘制图形就会发生闪烁现象. 问题分析: 当我们把绘图过程放在 ...

  4. MFC双缓冲绘图实例

    本人之前一直了解双缓冲绘图的基本原理,但是在研究很久之后才大概知道具体的使用过程,本文将详细介绍本人在实际项目中使用双缓冲绘图的案例. 实现功能:主界面显示某张包含人脸的图片,通过dlib detec ...

  5. c++双缓冲技术,以避免闪烁绘图

    当数据量非常大时,画图可能须要几秒钟甚至更长的时间,并且有时还会出现闪烁现象,为了解决这些问题.可採用双缓冲技术来画图. 双缓冲即在内存中创建一个与屏幕画图区域一致的对象,先将图形绘制到内存中的这个对 ...

  6. mfc双缓冲绘图

    1.要求 在界面加载本地图片并显示,每过100ms改变一张图片显示 2.现象 通过定时器控制CImage,Load,Draw,Destroy,会非常的卡顿.因为Load图片时,会是非常大的数据[所有C ...

  7. MFC双缓冲

    大家都知道包括windows桌面在内我们看到的一切都是系统画上去的,windows桌面就相当于一个黑板: <1>普通绘图就是直接在我们看得到的黑板上绘图 <2>双缓冲就是先在一 ...

  8. MFC 双缓冲加载背景

    首先定义DCmemDc和Bitmap CDC DCmemDc: CBitmap memBitmap; CBitmap *oldBitmap; 然后创建一个适应当前内存的DCmemDc CDC * dc ...

  9. VC GDI双缓冲机制绘图防屏幕闪烁实现步骤

    在OnDraw(CDC* pDC) 中添加如下代码 CDC MemDC; //首先定义一个显示设备对象 CBitmap MemBitmap;//定义一个位图对象 //随后建立与屏幕显示兼容的内存显示设 ...

随机推荐

  1. springMVC注解优化

    本文是本人在学习网络视频的过程中的一些总结. 本文是对关于一些springMVC在使用注解的优化. 使用以下的标签,会自己主动引入Annotation的配置 <mvc:annotation-dr ...

  2. robot framework环境搭建(转)

    一. robot framework环境搭建: 官网:http://robotframework.org/ 序号 安装包名 安装方法 下载地址 备注 1 python exe文件,直接双击安装 htt ...

  3. BestCoder-Round#33

    写在前面 这是我第一次做BestCoder, 熟悉的外观BestCoder模式. BC上不仅能看到英文, 背部Chinese view是中文题目 交的次数是会影响得分的. 所以有了把握再交. 至少例子 ...

  4. Android监视返回键

    android在发展中,监视键返回到后事件经常被用来,在下面的例子来说明什么android返回键事件监听器. public class BackKeyTest extends Activity { / ...

  5. 关于访问MSMQ远端私有队列的一点经验

    这里应该将私有队列称做"专用队列"好像更贴切一些了,O(∩_∩)O 可以访问远程主机的MSMQ的私有队列的,这个是毋庸置疑的,但需要说明的是不能通过代码创建私有队列,关于这一点,我 ...

  6. I2C驱动程序框架probe道路

    基于Linux的I2C驱动器.采纳probe道路.根据这个框架,如下面就可以写任何支持I2C总线设备Linux驱动器. I2C设备连接到cpu具体i2c接口.被安装在cpu的i2c适配器.i2c设备和 ...

  7. FMDB与GCD

    郝萌主倾心贡献.尊重作者的劳动成果,请勿转载. 假设文章对您有所帮助,欢迎给作者捐赠.支持郝萌主,捐赠数额任意,重在心意^_^ 我要捐赠: 点击捐赠 Cocos2d-X源代码下载:点我传送 因为FMD ...

  8. 泛型方法动态生成表达式树 Expression

    public string GetGridJSON(TraderInfo model) { IQueryable<TraderInfo> Temp = db.TraderInfo; if ...

  9. MS SQL Server递归查询

    原文:MS SQL Server递归查询 刚才在论坛上看到网友一个要求.参考如下,Insus.NET分析一下,可以使用MS SQL Server的递归查询,得到结果.准备一张表: 根据网友提供的数据, ...

  10. UiAutomator源码分析之注入事件

    上一篇文章<UiAutomator源码分析之UiAutomatorBridge框架>中我们把UiAutomatorBridge以及它相关的类进行的描述,往下我们会尝试根据两个实例将这些类给 ...