当前位置: 首页 > 编程语言 > C#

Icon.FromHandle:我应该处理它,还是调用DestroyIcon?分享

时间:2023-04-10 15:13:59 C#

Icon.FromHandle:我应该处理它,还是调用DestroyIcon?我使用Win32SHGetFileInfo获取属于文件的图标的句柄。有很多关于如何做到这一点的描述,也在stackoverflow上,例如:获取shell使用的图标调用该函数后,您将拥有一个带有图标图标句柄的结构。使用静态方法Icon.FromHandle我可以将它转换为类System.Drawing.Icon的对象。此类实现System.IDisposable。正确的用法如下:using(Iconicon=Icon.FromHandle(shFileInfo.hIcon)){//做你需要用图标做的事}在离开using语句时,图标对象将被放置。MSDN在Icon.FromHandle(点击查看)的说明中警告:使用该方法时,必须使用Win32API中的DestroyIcon方法销毁原有图标,以保证资源释放。并在Icon.Dispose(点击查看)中释放该Icon使用的所有资源。问题:Dispose()对象够不够用,还是调用Dispose()和DestroyIcon,还是调用DestroyIcon而不是Disposing对象?OP增加。这个回答有错误。由于所有的评论,透过树林看到森林变得严酷。因此我决定编辑这个答案。(对不起,如果我冒犯了某人).net源代码在线:http://referencesource.microsoft.com/#System.Drawing/commonui/System/Drawing/Icon.cs,81a28d20524554ae看看Icon.FromHandle:public静态图标FromHandle(IntPtr句柄){IntSecurity.ObjectFromWin32Handle.Demand();返回新图标(句柄);}internalIcon(IntPtrhandle):this(handle,false){}internalIcon(IntPtrhandle,booltakeOwnership){if(handle==IntPtr.Zero){thrownewArgumentException(SR.GetString(SR.InvalidGDIHandle,(typeof(图标)).名称));}this.handle=handle;this.ownHandle=takeOwnership;请注意,在IconAfter.FromHandle中,ownHandle为false。让我们看一下Dispose:voidDispose(booldisposing){if(handle!=IntPtr.Zero){DestroyHandle();}}internalvoidDestroyHandle(){if(ownHandle){SafeNativeMethods.DestroyIcon(newHandleRef(this,handle));handle=IntPtr.Zero;}}结论:在Icon.FromHandle之后,字段ownHandle为false,所以Dispose/FromHandle不会调用DestroyIcon因此:如果使用Icon.FromHandle创建一个Icon,必须Dispose()Icon并调用DestroyIcon,如备注中所述部分。.NETIcon类非常笨拙,需要自己处理。SHFILEICON的MSDN文章对此没有任何说明,您必须调用DestroyIcon()。Icon.FromHandle()的MSDN文章也是如此。您调用DestroyIcon的确切时间也很重要,它必须延迟到某些代码复制了图标或者您不再需要该图标并且通常会调用其Dispose()方法。请注意MSDN文章中显示对DestroyIcon()的早期调用的代码片段。好的,在那种特殊情况下,因为它已分配给Form.Icon属性。一个角落的情况,肯定不是你想做的。处理此问题的唯一正确方法是覆盖Icon.FromHandle()的行为并强制该对象取得本机图标句柄的所有权。这样,当您处理它时,它会自动调用DestroyIcon()。这需要hack,允许您执行此操作的Icon构造函数是内部的。反思救援,您可以使用这篇文章中的代码,注意GetConstructor()调用。通过编写执行一次一百万次的小单元测试开始感觉良好。如果你不喜欢它,那么编写你自己的IDisposable包装器,这样你就可以处理图标并调用DestroyIcon()。我在这方面并不感到悲伤——我一直在尝试在不泄漏资源的情况下为表单的图标(以及任务栏中的图标)制作动画。当我处理图标资源泄漏时(如MSDN上的建议),当我使用“DestroyIcon”时所有后续更新都会失败。下面的代码以正确的顺序显示所有内容。API声明:[System.Runtime.InteropServices.DllImport("user32.dll",CharSet=CharSet.Auto)]externstaticboolDestroyIcon(IntPtrhandle);最终解决方案:IntPtriconHandle=dynamicBitmap.GetHicon();图标tempManagedRes=Icon.FromHandle(iconHandle);this.Icon=(Icon)tempManagedRes.Clone();tempManagedRes.Dispose();销毁图标(图标句柄);也发在这个问题:Win32.DestroyIconandIcon.Dispose以上是C#学习教程:Icon.FromHandle:是处理还是调用DestroyIcon?如果所有分享的内容对你有用,需要进一步了解C#学习教程,希望大家多多关注。本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处: