转载请说明原出处,谢谢~~

今天下午群友的网友让我帮忙看一下的duilib程序的问题,程序中包含了List控件,会定时清除所有子项目然后重新添加。但是程序运行一段时间后会自己崩溃!我编译了源码运行后在任务管理器里发现,程序的gdi句柄数一直增加而不减少,不到半分钟的时候gdi句柄数居然增加到10000个!!当时我就惊呆了,然后程序直接崩溃,如图:

很明显发生了gdi泄漏。随后我也看了自己的仿酷狗程序,居然也发现了gdi泄漏。当音乐项目增加到几百个之后gdi句柄暴涨,程序崩溃。随后进入debug模式开始调试。

经过3个小时的奋战,终于发现uilib库中有一处地方造成gdi泄漏!过程我就不再赘述了。直接说明问题。

bug是uilib库的CControlUI控件的构造函数的函数体创建了一个gdi对象:

CControlUI::CControlUI() : m_pManager(NULL),
//省略无用代码
{
//省略无用代码 ::ZeroMemory(&m_rcPadding, sizeof(m_rcPadding));
::ZeroMemory(&m_rcItem, sizeof(RECT));
::ZeroMemory(&m_rcPaint, sizeof(RECT));
::ZeroMemory(&m_rcBorderSize, sizeof(RECT));
::ZeroMemory(&m_tRelativePos, sizeof(TRelativePosUI)); m_hRgn = CreateRectRgn(0,0,0,0); //定义新的空的HRGN.不能初始化为NULL }

可以看到最后一句m_hRgn = CreateRectRgn(0,0,0,0);创建了gdi对象,m_hRgn变量的说明为:

HRGN m_hRgn;			//当启用不规则区域时,此变量保存该对象的区域

这个gdi对象在CControlUI控件的构造函数中被创建,析构函数释放。而大家知道,CControlUI控件是所有duilib控件的基类,这就意味了每创建一个控件就会增加一个gdi对象。而恰恰是List控件,有可能会一次性添加上千条子项目,而这些子项目在程序结束时才会被销毁,这样就导致程序增加上千个gdi对象,而一般程序的gdi对象都保持在50个左右,300个gdi对象已经算很多了!

我看了看和m_hRgn变量相关的代码,发现在uilib库中这个变量目前还没有什么实际用途,所以我把与他相关的代码都删除了,使用uilib库的朋友可以自己删除,也可能下载我修改好的。下载地址:点击打开链接

以上是说明了uilib库的bug,还没有解决群友的基于duilib库的gdi泄漏的问题。调试他的代码后发现duilib库中并没有gdi泄漏,最终发现是这样的问题出在用于创建自定义控件的xml文件中:

1)c++调用代码动态增加子项目到List中

2)每个子项目都是自定义控件,通过xml文件创建。

问题出在xml文件中,用xml文件动态创建控件是用duilib时的常用功能,而我们千万不要在创建自定义控件的xml文件中使用<Font>标签,否则每次创建一个自定义控件,就会增加相应数量的font对象,而font对象是直接在CPaintManager类中增加的,同样也是在程序结束时才会被释放。偶尔一两个这样的控件无所谓,但是如果用在List中被创建了成千上百个,gdi泄漏就太明显!所以<Font>标签最好统一声明到主xml文件或者专门声明资源的xml文件中!切记

      2014.8.12 Redrain

uilib库gdi句柄泄漏bug修复,duilib防止gdi泄漏的小提醒的更多相关文章

  1. Redrain个人维护并使用的DuiLib和UiLib库源代码下载地址

    转载请说明原出处:http://blog.csdn.net/zhuhongshu/article/details/40740353,谢谢~~ 首先说明一下Duilib和Uilib的差别:UiLIb是D ...

  2. Redrain个人维护并使用的DuiLib和UiLib库源码下载地址

    转载请说明原出处:http://blog.csdn.net/zhuhongshu/article/details/40740353,谢谢~~ 我把我自己使用的Duilib库和Uilib库都上传到了Gi ...

  3. duilib relativepos属性导致控件错误的bug修复

    转载请说明出处,谢谢~~ 我在仿酷狗音乐播放器的开发日志系列里,曾经提到了这个bug,文章地址为:http://blog.csdn.net/zhuhongshu/article/details/381 ...

  4. 修复duilib CEditUI控件和CWebBrowserUI控件中按Tab键无法切换焦点的bug

    转载请说明原出处,谢谢~~:http://blog.csdn.net/zhuhongshu/article/details/41556615 在duilib中,按tab键会让焦点在Button一类的控 ...

  5. duilib CDateTimeUI 在Xp下的bug修复

    转自:http://my.oschina.net/u/343244/blog/370131 CDateTimeUI 的bug修复.修改CDateTimeWnd的HandleMessage方法 ? 1 ...

  6. 仿酷狗音乐播放器开发日志十九——CTreeNodeUI的bug修复二(附源码)

    转载请说明原出处,谢谢 今天本来打算把仿酷狗播放列表的子控件拖动插入功能做一下,但是仔细使用播放列表控件时发现了几个逻辑错误,由于我的播放 列表控件是基于CTreeViewUI和CTreeNodeUI ...

  7. RHSA-2017:2029-中危: openssh 安全和BUG修复更新(存在EXP、代码执行、本地提权)

    [root@localhost ~]# cat /etc/redhat-release CentOS Linux release 7.2.1511 (Core) 修复命令: 使用root账号登陆She ...

  8. RHSA-2018:3032-低危: binutils 安全和BUG修复更新

    [root@localhost ~]# cat /etc/redhat-release CentOS Linux release 7.2.1511 (Core) 修复命令: 使用root账号登陆She ...

  9. OJ2.0userInfo页面Modify逻辑bug修复,search功能逻辑实现

    这周的主要任务:userInfo页面Modify逻辑bug修复,search功能逻辑实现. (一)Modify逻辑bug修复: 这里存在的bug就是在我们不重置password的时候依照前面的逻辑是不 ...

随机推荐

  1. TopCoder 649 div1 & div2

    最近一场TC,做得是在是烂,不过最后challenge阶段用一个随机数据cha了一个明显错误的代码,最后免于暴跌rating,还涨了一点.TC题目质量还是很高的,非常锻炼思维,拓展做题的视野,老老实实 ...

  2. 在win7之后安装Ubuntu14.04系统后,丢失对win7的引导

    安装完ubuntu 14.04后,开机直接进入ubuntu.但是win7下的分区还在,只是未显示引导菜单. 恢复步骤: (前提是机器上确实存在win7的引导) $ sudo update-grub G ...

  3. lintcode:Valid Sudoku 判断数独是否合法

    题目: 判断数独是否合法 请判定一个数独是否有效.该数独可能只填充了部分数字,其中缺少的数字用 . 表示. 样例 下列就是一个合法数独的样例. 注意 一个合法的数独(仅部分填充)并不一定是可解的.我们 ...

  4. Hibernate逍遥游记-第10章 映射继承关系-003继承关系树中的每个类对应一个表(joined-subclass)

    1. 2. <?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate ...

  5. Hibernate逍遥游记-第7章 Hibernate的检索策略和检索方式(<set lazy="false" fetch="join">、left join fetch、FetchMode.JOIN、)

    1. <?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hi ...

  6. 64位下好神奇啊(增加了PatchGuard技术保护自己,SSDT是相对地址,参数通过寄存器与rdi来传递)

    近期可能会有一个64位平台的驱动开发任务,找了些资料,对64位平台下的驱动开发略知一二了,好神奇. 一.在64位系统下,有一项PatchGuard技术,它是微软为了防止自己的代码被Patch,进而影响 ...

  7. 爬虫Larbin解析(一)——Larbin配置与使用

    介绍 功能:网络爬虫 开发语言:c++ 开发者:Sébastien Ailleret(法国) 特点:只抓取网页,高效(一个简单的larbin的爬虫可以每天获取500万的网页) 安装 安装平台:Ubun ...

  8. ifdebug

    #if DEBUG 首先,大小写不能写错. 其次,解决方案配置设为:Debug,才会执行该语句,如果在条件里面搭配Debug.Assert等,效果甚佳.而如果要设置为Release模式,就不会执行条件 ...

  9. [HDOJ1811]Rank of Tetris(并查集、拓扑排序)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1811 求一堆数据的拓扑序. 处理:x>y就是x到y一条边,x<y就是y到x一条边.关键问题 ...

  10. 【转载】Java垃圾回收内存清理相关(虚拟机书第三章),GC日志的理解,CPU时间、墙钟时间的介绍

    主要看<深入理解Java虚拟机> 第三张 P84 开始是垃圾收集相关. 1. 1960年诞生于MIT的Lisp是第一门采用垃圾回收的语言. 2. 程序计数器.虚拟机栈.本地方法栈3个区域随 ...