在使用SHGetFileInfo后销毁图标?

3
我正在使用SHGetFileInfo来获取特定文件类型的图标。MSDN关于SHFILEINFO说:
hIcon
类型:HICON
表示文件的图标句柄。在不再需要它时,您必须使用DestroyIcon销毁此句柄。
要从HIcon中获取图标,我使用Icon.FromHandle。同样,MSDN说:
备注
使用此方法时,您必须使用Win32 API中的DestroyIcon方法处理原始图标,以确保释放资源。
这更加令人困惑,因为SGHFI_ICON的描述包含以下信息:
SHGFI_ICON(0x000000100)
检索表示文件的图标和系统映像列表中图标的索引的句柄。将句柄复制到由psfi指定的结构的hIcon成员中,并将索引复制到iIcon成员中。
从这个描述中,似乎句柄是由操作系统保留的,我实际上不应该销毁它。
我的问题是:如果可以的话,何时应该处理图标句柄?
立即在Icon.FromHandle()之后?
当我不再需要从Icon.FromHandle()创建的图标时?(在这种情况下,我想我会复制图标,释放原始图标并返回副本,以避免泄漏句柄)
永远不要(它会以某种方式自动完成吗?许多SHGetFileInfo的示例 - 甚至在SO上 - 都不包括任何释放图标句柄的代码)?
2个回答

3
系统不会保留图标句柄,而是保留图像列表。当您使用 SHGFI_ICON 标志时,SHGetFileInfo 通过针对系统图像列表调用 ImageList_GetIcon 来创建图标。您可以自己执行此操作,只需传递 SHGFI_SYSICONINDEX 标志即可检索图标索引。
当您完成后应该销毁该图标。

好的,我猜这意味着选择2? - Spook

3
不,你确实需要自己调用DestroyIcon。Icon.FromHandle()方法无法帮助你做到这一点,它仍然需要你调用DestroyIcon。你必须实现自己的垃圾收集器代码来知道图标不再使用,以便安全地调用pinvoke DestroyIcon。
这真是残忍而不寻常的惩罚。事实上,Icon类确实有一个构造函数,可以从句柄创建一个Icon对象,并拥有该句柄,当Icon对象被处理或完成时会自动调用DestroyIcon。但由于不可理喻的原因,他们使其不可访问,这真是个大失策。通过反射,您可以绕过这个愚蠢的限制,仍然使用构造函数,在此答案中找到代码

1
我想,我的第二种方法也是可行的:获取句柄,使用Icon.FromHandle,将其复制到位图或另一个图标中,释放句柄并返回副本。虽然效率较低。 - Spook

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接