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

简介: 转载请说明原出处,谢谢~~        今天下午群友的网友让我帮忙看一下的duilib程序的问题,程序中包含了List控件,会定时清除所有子项目然后重新添加。

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

       今天下午群友的网友让我帮忙看一下的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

目录
相关文章
|
API C#
WinCE平台下C#引用API(GDI)一个值得警惕的内存泄漏
由于C#精简框架集绘图函数不支持圆角矩形,所以引用了相关的API。  [DllImport("//windows//coredll.
506 0
|
Java 测试技术 分布式数据库
对开发中常见的内存泄露,GDI泄露进行检测
对开发中常见的内存泄露,GDI泄露进行检测 一、GDI泄露检测方法: 在软件测试阶段,可以通过procexp.exe 工具,或是通过任务管理器中选择GDI对象来查看软件GDI的对象是使用情况。
1163 0
查GDI对象泄露的利器:GDIView
查GDI对象泄露的利器:GDIView可以很详细的查到进程的GDI对象的总个数,详细的GDI对象的个数,以及其增减数量。其GDI对象类型也可以很详细的得知,以及其内存地址,句柄。实在是好使!下载地址:http://www.
1007 0
VC GDI双缓冲机制绘图防屏幕闪烁实现步骤
在OnDraw(CDC* pDC) 中添加如下代码      CDC MemDC; //首先定义一个显示设备对象  CBitmap MemBitmap;//定义一个位图对象  //随后建立与屏幕显示兼容的内存显示设备  MemDC.
1003 0
|
消息中间件 程序员 Windows
|
消息中间件 Windows C++
深入剖析MFC中Windows消息处理机制
本人对Windows系统、MFC谈不上有深入的了解,但对MFC本身包装API的机制很有兴趣,特别是读了候老师的《深入浅出MFC》后,感觉到Visual C++的Application FrameWork十分精制。
1022 0
|
9月前
MFC窗口创建机制
MFC窗口创建机制
44 0
|
API Windows 消息中间件
Windows应用程序框架之窗口、句柄、消息
      深入MFC类库,需要先从windows应用程序的基本结构入手。 windows应用程序框架:       windows操作系统采用了图形用户界面,借助与它提供的API函数,用户可以编出具有漂亮图形界面的windows应用程序,这些程序都有着相同的窗口风格和菜单结构。
922 0
修复duilib库UISlider控件的4个bug
转载级请注明原出处,谢谢~·          昨天封装好一个音频类,我在为dulib做音频播放demo时发现了一些问题,由CSliderUI控件导致的,进而发现了这个控件的好几样不足,他无法满 足我们做一个播放器的进度控件和音量控制控件...
973 0

热门文章

最新文章