找回密码
 立即注册→加入我们

QQ登录

只需一步,快速开始

搜索
热搜: 下载 VB C 实现 编写
查看: 3788|回复: 1

【GDI】讨论一下SelectObject与DeleteObject

[复制链接]

1109

主题

1649

回帖

7万

积分

用户组: 管理员

一只技术宅

UID
1
精华
244
威望
743 点
宅币
24180 个
贡献
46222 次
宅之契约
0 份
在线时间
2294 小时
注册时间
2014-1-26
发表于 2015-11-23 17:31:20 | 显示全部楼层 |阅读模式

欢迎访问技术宅的结界,请注册或者登录吧。

您需要 登录 才可以下载或查看,没有账号?立即注册→加入我们

×
我在stackoverflow上面看到的内容:http://stackoverflow.com/questio ... eteobject-on-bitmap
以前我都是采取在DeleteDC后再逐个将自己用SelectObject选入的对象进行DeleteObject销毁处理。然而我发现很多人都不是我这样写的。

原文中给的伪代码:
  1. HDC hDC = ::CreateCompatibleDC(hDCWnd);
  2. HANDLE hFileMap = ::CreateFileMapping(INVALID_HANDLE_VALUE, 0, PAGE_READWRITE, 0, dwSize, FileMapName);
  3. HBITMAP hBmp = ::CreateDIBSection(hDCWnd, &zBI, DIB_RGB_COLORS, &pvNull, hFileMap, 0);

  4. ::SelectObject(hDC, hBmp);
  5. ::DeleteObject(hBmp);
  6. ::CloseHandle(hFileMap);

  7. //用这个hDC绘图什么的

  8. ::DeleteDC(hDC);
复制代码
提问者说:“这让我感到哪里不对。。有没有谁能出来帮我解释一下这哪里错了?”
解答的人一开始说“任何时候你都不能用DeleteObject将一个已经选入hDC的对象销毁,在这个对象正在被使用的时候,你调用DeleteObject会失败,然后这个hBmp就泄露了。”而且还提供了MSDN的DeleteObject的函数说明:
https://msdn.microsoft.com/en-us/library/dd183539(v=vs.85).aspx

结果这个人做了几次测试后发现,“经过我的测试,在我将hBitmap选入hDC后调用DeleteObject,它给我返回了个1,表示执行成功。有意思的是,这个位图其实并没有被销毁。调用GetObject来取得这个位图是能够成功的!然而,在我把这个已经删除了的位图选出hDC后,它就真的被销毁了,调用GetObject也会失败。对此我也在任务管理器的GDI句柄监视里面看到了这个现象。这样我认为DeleteObject会根据情况来帮你删除对象,即使我觉得这完全没有被任何文档所记载。”
  1. HDC hdc = CreateCompatibleDC(NULL);
  2. if (hdc != NULL) {
  3.     HBITMAP hBitmap = LoadBitmap(hInst, MAKEINTRESOURCE(IDB_SAMPLE));

  4.     BITMAP bm = { 0 };
  5.     int numBytes;

  6.     //这句肯定能执行成功。
  7.     numBytes = GetObject(hBitmap, sizeof(BITMAP), &bm);

  8.     HBITMAP hOldBitmap = SelectBitmap(hdc, hBitmap);

  9.     DeleteObject(hBitmap);

  10.     //这句出乎意料地能执行成功。
  11.     numBytes = GetObject(hBitmap, sizeof(BITMAP), &bm);

  12.     SelectBitmap(hdc, hOldBitmap);

  13.     //这句肯定不能执行成功。
  14.     numBytes = GetObject(hBitmap, sizeof(BITMAP), &bm);

  15.     DeleteDC(hdc);
  16. }
复制代码
最后得出的结论是:
当你用DeleteObject删除一个GDI对象的时候,其实只是减少了这个GDI对象的引用而已。它实际上如果还在被使用的话,它其实还是存在的。
用SelectObject将其选出后,如果它没有任何引用了,它就会被销毁。
估计DeleteDC也会做相同的处理呢。
回复

使用道具 举报

5

主题

43

回帖

197

积分

用户组: 小·技术宅

UID
167
精华
0
威望
3 点
宅币
132 个
贡献
11 次
宅之契约
0 份
在线时间
30 小时
注册时间
2014-3-30
发表于 2015-11-24 08:50:42 | 显示全部楼层
回复

使用道具 举报

QQ|Archiver|小黑屋|技术宅的结界 ( 滇ICP备16008837号 )|网站地图

GMT+8, 2024-3-28 19:58 , Processed in 0.053556 second(s), 32 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表