首先应明确一个概念 句柄, 关于句柄的详细介绍请见这里

对于句柄的使用小结:借来的要归还,创建的要释放,选出的要选入【尤其是针对GDI的一些句柄而言,如HPEN,HBRUSH等】

1. 使用GetDC() 获取的设备上下文指针在不使用的时候必须调用ReleaseDC()进行释放

例如:

 CDC *pDC = GetDlgItem(IDC_TEST)->GetDC();

 /*...............*/

 GetDlgItem(IDC_TEST)->ReleaseDC(pDC);

2. 在创建了DC或其他GDI资源后,如果不再使用则需要将所创建的资源进行释放

例如:

 CDC dcMem;

 dcMem.CreateCompatibleDC(NULL);

 /*..............*/

 dcMem.DeleteDC();

3. 在将创建的GDI绘图对象选入了设备上下文后,如果使用完毕则需要将之前选出的旧有的GDI绘图对象选入,然后在删除所创建的GDI对象

例如:

 CBitmap bmp;

 bmp.CreateCompatibleBitmap(pDC, nWidht, nHeight);

 CBitmap *pBmpOld = memDC.SelectObject(&bmp);

 /*..................................*/

 memDC.SelectObject(pBmpOld);

 bmp.DeleteObject();

说明:一定要注意SelectObject的操作通常要成对出现,否则可能会导致GDI资源泄露。例如上面的例子,如果在最后我们没有执行语句

memDC.SelectObject(pBmpOld);只是调用了bmp.DeleteObject(),此时对于bmp资源的释放是失败的,即无法将之前所创建的位图图像删除。

Attach 的需要Detach

例如:

 CImage img;

 if (SUCCEEDED(img.Load(strFileName)))

 {

   HBITMAP hBitmap = img.Detach();

   /*......................*/

   img.Attach(hBitmap);

 }

 img.Destroy();
1. 被选入的绘图对象(如:bitmap、brush等)无法删除,只有当调用SelectObject将对象选出后才可以删除
2. 对于SelectObject()成对出现的原因?
例如:
 bitmap = CreateCompatibleBitmap(...);
 HBITMAP oldbitmap = SelectObject(hdc, bitmap);
 ...
 SelectObject(hdc, oldbitmap);
 DeleteObject(&bitmap) 
注意:
1. SelectObject必须成对存在
2. 对于上面代码段的第四行,调用SelectObject将oldbitmap选入之后不需要将返回值再赋给bitmap,此时bitmap已经是最新的位图对象了(哪怕在语句3对选入的位图进行了操作)
3. 对于GDI绘图资源的释放一定要注意,一旦有资源没有得到释放,而且执行的频率又非常频繁的情况下,就很容易导致资源无法创建的问题。尤其是在OnCtlColor中一定不要创建画刷等绘图对象,而是应该将需要用到的绘图对象定义为类的成员变量。
4. 由于对于GDI而言,windows只使用了16位字段来指明句柄,因此所能创建的GDI句柄总数应不大于64K个,实际上受其他一些限制,整个windwos系统中大概可以容纳约16384(0x4000)个GDI对象。一旦超过这个总数,就会使得Windows抛出ResourceException

关于操作DC时的资源泄露的更多相关文章

  1. webview加载h5,关闭activity时,窗体泄露问题

    问题描述: webview加载一个含有input控件的html页面,当点击input控件是回调app的closepage方法[closepage中只有一个finish操作],出现窗体泄露问题. 分析: ...

  2. Spring Boot 2 (七):Spring Boot 如何解决项目启动时初始化资源

    Spring Boot 2 (七):Spring Boot 如何解决项目启动时初始化资源 在项目启动的时候需要做一些初始化的操作,比如初始化线程池,提前加载好加密证书等.今天就给大家介绍一个 Spri ...

  3. .NET资源泄露与处理方案

    .NET虽然拥有强大易用的垃圾回收机制,但并不是因为这样,你就可以对资源管理放任不管,其实在稍不注意的时候,可能就造成了资源泄露,甚至因此导致系统崩溃,到那时再来排查问题就已经是困难重重. 一.知识点 ...

  4. PySpark操作HBase时设置scan参数

    在用PySpark操作HBase时默认是scan操作,通常情况下我们希望加上rowkey指定范围,即只获取一部分数据参加运算.翻遍了spark的python相关文档,搜遍了google和stackov ...

  5. thinkphp使用模块/控制器/操作访问时出现No input file specified.解决方式

    thinkphp使用 http://serverName/index.php/模块/控制器/操作 访问时,出现了 No input file specified. 的错误 解决办法: 一: 开启cgi ...

  6. .net操作PDF的一些资源(downmoon收集)

    因为业务需要,搜集了一些.net操作pdf的一些资源,特在此分享. 1.如何从 Adobe 可移植文档格式 (PDF) 文件中复制文本和图形 http://support.microsoft.com/ ...

  7. 使用固件库操作STM32F4时的必要配置(转)

    源:使用固件库操作STM32F4时的必要配置 使用STM32F4的固件库时,默认的晶振为25Mhz晶振,因此需要做一定的修改.之前因为一直没有注意这个问题,我捣腾了许久,发现工作时钟总是不对,查阅了一 ...

  8. Kafka中操作topic时 Error:Failed to parse the broker info from zookeeper

      Kafka中操作topic时 Error: Failed to parse the broker info from zookeeper 1.问题描述   2.问题原因     kafka在启动后 ...

  9. 使用SQL Server Management Studio操作replication时,要用机器名登录,不要用IP地址

    如果你在使用SSMS(SQL Server Management Studio)登录SQL Server时,使用的是IP地址,如下图所示: 当你操作replication时,会报错: 从上面的错误提示 ...

随机推荐

  1. Java 保留两位小数

    在实际项目开发中,经常会存在浮点数四舍五入保留几位小数的问题,故收集了几种常用方法: 直接上代码(保留两位小数). Format.java: import java.math.BigDecimal; ...

  2. udp丢包原因分析

    1.  发送方没有进行频率控制(令牌桶算法),短时间内大量的包发送到server端,server端是单线程,先epoll wait,再process,就会造程process时丢掉server传过来的包 ...

  3. 吃了单片机GPIO端口工作模式的大亏 ——关于强推挽输出和准双向口(弱上拉)的实际应用

    最近公司在进行一个项目,需要用到超声波测距的功能,于是在做好硬件电路,但在写控制程序时,却遇上了令我费解的事情. 当在单片机最小系统上调好输出频率40kHz,占空比50%的方波输出信号后,将程序烧至超 ...

  4. 树形dp+MST-hdu-4126-Genghis Khan the Conqueror

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4126 题目意思: 给一图,n个点,m条边,每条边有个花费,给出q条可疑的边,每条边有新的花费,每条可 ...

  5. openStack 云平台使用一般杂记

    1. To launch an instance,you must at least specify the flavor,image name,network,security group,keyp ...

  6. 共享一个防止脚本重复启动的shell脚本

    项目的一个需求:为防止脚本重复调度,导致同时运行时相互冲突,需要在脚本运行开始前创建一个文件,结束时删除. 脚本启动时判断一下文件是否存在,如果存在则退出. 最开始这样做没发现问题,但跑一段时间后,发 ...

  7. win7安装ruby on rails

    开发机:win7 旗舰版 - 64位 1,安装ruby,下载rubyinstaller-2.0.0-p451.exe 下载地址:http://rubyinstaller.org/downloads/ ...

  8. eclipse打开一闪而过,环境安装正确

    一:查看错误信息 开始,运行->cmd.execd 进入eclipse目录D:\JavaTools\eclipse\eclipse.exe>eclipsec.exe,看console输出是 ...

  9. Android Monkey具体解释

    Monkey是一个执行在Android设备或者虚拟机上的程序,它能随机模拟一系列用户的操作.点击,滑动,能够用它来做压力測试. 在Monkey执行的过程中,它会产生并发送一系列的事件给系统,而且监听系 ...

  10. C primer plus 读书笔记第四章

    本章的标题是字符串的格式化输入/输出,重点介绍输入和输出. 本章的第一段示例代码和上一张示例代码很相近,代码就不贴了,新出现的特性是使用了一个数组来存放字符串,C预处理命令和strlen()函数. 下 ...