uilib库gdi句柄泄漏bug修复,duilib防止gdi泄漏的小提醒

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

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


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

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

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

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库的朋友能够本身删除,也可能下载我修改好的。下载地址:点击打开连接
debug

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

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

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

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


      2014.8.12 Redrain

相关文章
相关标签/搜索