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

今天下午群友的网友让我帮忙看一下的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. hdu 1753 大明A+B

    题目:http://acm.hdu.edu.cn/showproblem.php?pid=1753 容易出错的事例: 0.1 0.2 1.88 22.22 1 0.01 大概出错的几个点,做久了思维根 ...

  2. lintcode:哈希函数

    题目: 哈希函数 在数据结构中,哈希函数是用来将一个字符串(或任何其他类型)转化为小于哈希表大小且大于等于零的整数.一个好的哈希函数可以尽可能少地产生冲突.一种广泛使用的哈希函数算法是使用数值33,假 ...

  3. jvm调优具体参数配置

    3.JVM参数 在JVM启动参数中,可以设置跟内存.垃圾回收相关的一些参数设置,默认情况不做任何设置JVM会工作的很好,但对一些配置很好的Server和具体的应用必须仔细调优才能获得最佳性能.通过设置 ...

  4. C内存分配函数

    C语言跟内存分配方式(1) 从静态存储区域分配.内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在.例如全局变量,static变量.(2) 在栈上创建.在执行函数时,函数内局部变量的 ...

  5. esriControlsMousePointer 控制鼠标指针

    axMapControl1.MousePointer = esriControlsMousePointer.esriPointerHourglass; 控制鼠标指针选项. 不变 值 描述 esriPo ...

  6. centos 安装openssl 以及库文件

    yum install openssl yum install openssl-devel

  7. QTP10&QTP11&UFT11.5的安装和破解

    QTP10的安装和破解方法 下载QTP10.0并安装. 安装成功后,在C:\Program Files\Common Files\Mercury Interactive下创建文件夹:License M ...

  8. javascript 字符转义汇总

    在开发中经常遇到需要字符转义的,我将一一把遇到的转义列举出来 1.今天中午做项目的时候遇到一个字符串链接的问题,需要链接的的是一个函数的参数 时间字符串:"2014-04-08 16:37: ...

  9. TeeChart的X轴,使用伪装的时间

    TeeChart曲线的X轴是时间,但是频率很高.没法完全显示. 例如,一秒钟有2000个点,那么点与点的间隔为0.5毫秒. 使用TChart类的GetAxisLabel事件, 函数手册上对此事件的解释 ...

  10. Android 中Activity生命周期分析:Android中横竖屏切换时的生命周期过程

    最近在面试Android,今天出了一个这样的题目,即如题: 我当时以为生命周期是这样的: onCreate --> onStart -- ---> onResume ---> onP ...