我正在編寫一些代碼來幫助跟蹤GDI泄漏並更好地瞭解WINAPI。我通過繞開所有GDI functions並記錄列出的所有手柄的創建和銷燬來做到這一點。有沒有一種方法可以刪除HBITMAP而不是使用DeleteObject()?
原來,一個HBITMAP
正在使用CreateDIBitmap()
創建和使用DeleteObject()
不被破壞(或任何列出的其他破壞函數調用的),和然後晚些時候一個CreateBitmap()
調用導致相同的句柄如前面提到的功能。在它們之間創建了很多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
- 第一列是序列數(試圖訂購塞克時有用多個線程中的事件)。
- 第二個是從第一個日誌項開始的時間(ms)。
:
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()
打得不好,並且正在使用一些未公開的功能。我將不得不調查其餘的日誌。
我認爲你觀察到的是Windows操作系統的一些處理高速緩存功能。 – VuVirt
@VuVirt,以及如何工作。這些不是命名對象。它將如何確定應該使用* same *句柄? – Adrian
HGDIOBJ不是一個地址(意思不是唯一的),而是一些有限大小的表中的一個槽的索引。所以從技術上講,當表溢出時,你可以得到相同的HGDIOBJ值。 –