我正在编写一些代码来帮助跟踪GDI泄漏并更好地理解WINAPI。我这样做是通过绕过所有GDI functions并记录所列出的所有句柄的创建和销毁。
原来使用HBITMAP
正在创建CreateDIBitmap()
并且未使用DeleteObject()
(或列出的任何其他销毁函数调用)销毁,然后在某个时间后CreateBitmap()
1}}调用与前面提到的函数相同的句柄。在它们之间创建了很多HBITMAP
个(和其他句柄)。
我只是想知道是否有其他方法可以销毁未在文档中列出的HBITMAP
?或者是否有某种方法可以生成相同的HBITMAP
?
有人知道吗?
我有点担心我发现了某种GDI腐败。
只是为了更新,这是我在日志中看到的(这只是一个实例,没有检查所有其他实例是否相同):
21133 107110: |>Creating HBITMAP # 707/782 with function CreateDIBSection 21134 107110: |<Created HBITMAP # 707/782 0xAC057A00 with function CreateDIBSection 21135 107125: |>Creating HBITMAP # 708/783 with function CreateBitmap 21136 107125: |<Created HBITMAP # 708/783 0xA9057B85 with function CreateBitmap 21137 107125: |>Creating HDC # 16/16 with function CreateCompatibleDC 21138 107125: |<Created HDC # 16/16 0x5F01466B with function CreateCompatibleDC 21139 107125: |>Creating HICON # 35/35 with function CreateIconIndirect 21140 107125: |>Creating HBITMAP # 709/784 with function CreateDIBitmap 21141 107125: |<Created HBITMAP # 709/784 0x67055812 with function CreateDIBitmap 21142 107141: |>Creating HBITMAP # 710/785 with function CreateBitmap 21143 107141: |<Created HBITMAP # 710/785 0x9605596F with function CreateBitmap 21144 107141: |>Creating HDC # 17/17 with function CreateCompatibleDC 21145 107141: |<Created HDC # 17/17 0xD7011ACD with function CreateCompatibleDC 21146 107141: |>Destroying HDC # 17/17 0xD7011ACD with function DeleteDC 21147 107156: |<Destroyed handle 0xD7011ACD with function DeleteDC 21148 107156: |<Created HICON # 35/35 0x653526D3 with function CreateIconIndirect 21149 107156: |>Destroying HBITMAP # 710/785 0xA9057B85 with function DeleteObject 21150 107156: |<Destroyed handle 0xA9057B85 with function DeleteObject 21151 107156: |>Destroying HDC # 16/16 0x5F01466B with function DeleteDC 21152 107156: |<Destroyed handle 0x5F01466B with function DeleteDC
......一段时间后(大约9秒钟)...
25319 118172: |>Creating HBITMAP # 862/937 with function CreateBitmap 25320 118172: |<Created HBITMAP # 862/937 0x9605596F with function CreateBitmap * 25321 118172: |>Creating HDC # 16/16 with function CreateCompatibleDC 25322 118172: |<Created HDC # 16/16 0x39013C5B with function CreateCompatibleDC 25323 118172: |>Creating HICON # 36/36 with function CreateIconIndirect 25324 118172: |>Creating HBITMAP # 862/937 with function CreateDIBitmap 25325 118188: |<Created HBITMAP # 862/937 0x27056374 with function CreateDIBitmap 25326 118188: |>Creating HBITMAP # 863/938 with function CreateBitmap 25327 118188: |<Created HBITMAP # 863/938 0xD20538B5 with function CreateBitmap 25328 118188: |>Creating HDC # 17/17 with function CreateCompatibleDC 25329 118188: |<Created HDC # 17/17 0xD9015812 with function CreateCompatibleDC 25330 118188: |>Destroying HDC # 17/17 0xD9015812 with function DeleteDC 25331 118188: |<Destroyed handle 0xD9015812 with function DeleteDC 25332 118203: |<Created HICON # 36/36 0x087718AD with function CreateIconIndirect 25333 118203: |>Destroying HBITMAP # 863/938 0x9605596F with function DeleteObject 25334 118219: |<Destroyed handle 0x9605596F with function DeleteObject
:
spaces
|
是一个可视化图表,用于查看调用嵌套的距离,相对于我正在查看的所有内容。>
表示进入函数之前,<
表示刚离开函数之后。x/y
其中x
是即将创建的对象的数量或被销毁后存在的剩余数量,y
是相同的,除了它代表基本类型(删除的类型)。*
结尾,则意味着此句柄之前已经发出但尚未销毁。有趣的是,有多少信息以及嵌套如何工作(非常适合跟踪窗口消息)。
我注意到的另一件事是:
25349 118250: |>Destroying HICON # 36/36 0x087718AD with function DestroyIcon 25350 118250: |<Destroyed handle 0x087718AD with function DestroyIcon
HICON
被破坏,但所包含的HBITMAP
没有被破坏,并且它们在日志中的任何地方都不再被引用(除非它们被意外地回收)。因此,如果这只发生在HICON
s,则可能是DestroyIcon()
不能正常运行并使用一些未记录的函数。我将不得不调查其余的日志。
答案 0 :(得分:1)
确定。仔细查看日志,并使用GetGuiResources()
记录有多少GDI对象,看起来在创建HBITMAP
时会创建HICON
。但是,DestroyIcon()
函数在销毁时会绕过DestoryObject()
函数调用。
我想MS的某个人想通过这样做来节省几个周期?不管。
尽管如此,这是一项有趣的练习,而且日志记录看起来效果很好。