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函数都会造成影响。
MFC双缓冲和裁剪问题导致闪烁的更多相关文章
- MFC双缓冲解决图象闪烁[转]
转载网上找到的一篇双缓冲的文章,很好用.http://www.cnblogs.com/piggger/archive/2009/05/02/1447917.html__________________ ...
- MFC中的双缓冲技术(解决绘图闪烁问题)
转自 MFC绘图不闪烁——双缓冲技术[转] 在VC/MFC用CDC绘图时,频繁的刷新,屏幕会出现闪烁的现象,CPU时间占用率相当高,绘图效率极低,很容易出现程序崩溃. 所谓双缓冲技术,下面是百度百科的 ...
- MFC双缓冲绘图(2015.09.24)
问题引入: 最近在尝试编写贪吃蛇游戏时遇到这么一个问题:当系统以较快频率向窗口发送WM_PAINT消息时,调用OnPaint()函数在窗口中绘制图形就会发生闪烁现象. 问题分析: 当我们把绘图过程放在 ...
- MFC双缓冲绘图实例
本人之前一直了解双缓冲绘图的基本原理,但是在研究很久之后才大概知道具体的使用过程,本文将详细介绍本人在实际项目中使用双缓冲绘图的案例. 实现功能:主界面显示某张包含人脸的图片,通过dlib detec ...
- c++双缓冲技术,以避免闪烁绘图
当数据量非常大时,画图可能须要几秒钟甚至更长的时间,并且有时还会出现闪烁现象,为了解决这些问题.可採用双缓冲技术来画图. 双缓冲即在内存中创建一个与屏幕画图区域一致的对象,先将图形绘制到内存中的这个对 ...
- mfc双缓冲绘图
1.要求 在界面加载本地图片并显示,每过100ms改变一张图片显示 2.现象 通过定时器控制CImage,Load,Draw,Destroy,会非常的卡顿.因为Load图片时,会是非常大的数据[所有C ...
- MFC双缓冲
大家都知道包括windows桌面在内我们看到的一切都是系统画上去的,windows桌面就相当于一个黑板: <1>普通绘图就是直接在我们看得到的黑板上绘图 <2>双缓冲就是先在一 ...
- MFC 双缓冲加载背景
首先定义DCmemDc和Bitmap CDC DCmemDc: CBitmap memBitmap; CBitmap *oldBitmap; 然后创建一个适应当前内存的DCmemDc CDC * dc ...
- VC GDI双缓冲机制绘图防屏幕闪烁实现步骤
在OnDraw(CDC* pDC) 中添加如下代码 CDC MemDC; //首先定义一个显示设备对象 CBitmap MemBitmap;//定义一个位图对象 //随后建立与屏幕显示兼容的内存显示设 ...
随机推荐
- jsScript中的一些操作方法
1.采用dom方式对script标签进行操作 var h = document.getElementsByTagName('HEAD').item(0); var s = document.creat ...
- HDU 4946 Area of Mushroom 凸包 第八次多校
题目链接:hdu 4946 题意:一大神有N个学生,各个都是小神,大神有个二次元空间,每一个小神都有一个初始坐标,如今大神把这些空间分给徒弟们,规则是假设这个地方有一个人比谁都先到这,那么这个地方就是 ...
- strncpy和strcpy
实体化代码运行图: 实现代码: #include <stdio.h> #include <string.h> #include <math.h> #include ...
- 框架搭建资源 (二) 添加M(模型)
applicationContext.xml <?xml version="1.0" encoding="UTF-8"?> <beans xm ...
- 经典算法题每日演练——第六题 协同推荐SlopeOne 算法
原文:经典算法题每日演练--第六题 协同推荐SlopeOne 算法 相信大家对如下的Category都很熟悉,很多网站都有类似如下的功能,“商品推荐”,"猜你喜欢“,在实体店中我们有导购来为 ...
- [dp] hdu 4472 Count
意甲冠军: 鉴于n节点,满足子节点的相同的树节点号的同一层较少不同的形式. 思考: dp[i][j] 代表i节点.最后,一个层j方法节点 由于满足同层节点,所以j一层又一层必须是j 整数倍 所以就能得 ...
- oracle_SQL 实验查询及删除重复记录 依据条件 (row)
除数据库表中的重复记录 根据条件 ① 创建表准备数据 创建表 tab_test -- Create table create table TAB_TEST ( ID NUMBER, NAME NVAR ...
- 兼容安卓的javaproject1.0
<pre class="java" name="code"> //兼容安卓的系统package cn.com.likeshow; import ja ...
- iOS开展 - 中国 iOS/Mac 开发博客列表
博客地址 RSS地址 OneV's Den http://onevcat.com/atom.xml 破船之家 http://beyondvincent.com/atom.xml NSHipster h ...
- IOS被遗忘的知识
IOS ARC项目使用非ARC文件 1.自己的旧项目没有使用ARC,可是引入的第三方库却是使用了ARC的. 对于第一个情况,给採用了ARC的源文件,加入-fobjc-arc选项 2.自己的新项目使用了 ...