Icon.FromHandle: Should I remove it or call DestroyIcon?

I use Win32 SHGetFileInfo to get a handle to an icon belonging to a specific file. There are many descriptions of how to do this, for example, in stackoverflow, for example: Get the icons used by the shell

After calling the function, you have a structure with an icon descriptor. Using the static Icon.FromHandle method I can convert it to an object of the System.Drawing.Icon class. This class implements System.IDisposable. Proper use will look like this:

using (Icon icon = Icon.FromHandle(shFileInfo.hIcon))
{
    // do what you need to do with the icon
}

When you exit the used operator, the icon object is deleted.

MSDN warns in the description of Icon.FromHandle (click to view) :

When using this method, you must remove the original icon using the DestroyIcon method in the Win32 API to ensure that resources are freed.

And in Icon.Dispose (click to view)

Releases all resources used by this icon.

Question:

Is this enough for a Dispose () object, or should I call Dispose () and DestroyIcon, or maybe call DestroyIcon instead of Disposing the object?

+4
source share
4 answers

Calling Dispose is enough.

The .net source code is online: http://referencesource.microsoft.com/#System.Drawing/commonui/System/Drawing/Icon.cs,81a28d20524554ae

Utilization of DestroyHandle calls that calls DestroyIcon. (I cleaned up the code a bit).

   void Dispose(bool disposing)
{
    if (handle != IntPtr.Zero)
    {
        DestroyHandle();
    }
}

internal void DestroyHandle()
{
    if (ownHandle)
    {
        SafeNativeMethods.DestroyIcon(new HandleRef(this, handle));
        handle = IntPtr.Zero;
    }
}


public void Dispose()
{
    Dispose(true);
    GC.SuppressFinalize(this);
}

void Dispose(bool disposing)
{
    if (handle != IntPtr.Zero)
    {
        DestroyHandle();
    }
}
+2

.NET Icon , . MSDN SHFILEICON , DestroyIcon(). MSDN Icon.FromHandle(). , DestroyIcon, , , - Dispose().

MSDN, , DestroyIcon() . , Form.Icon. , , , .

- - Icon.FromHandle() . DestroyIcon(), . , , , . , , GetConstructor(). , unit test, . , IDisposable-, DestroyIcon().

+5

. (, , , ), .

( MSDN), , "DestroyIcon", . .

API:

[System.Runtime.InteropServices.DllImport("user32.dll", CharSet = CharSet.Auto)]
extern static bool DestroyIcon(IntPtr handle);

, :

IntPtr iconHandle = dynamicBitmap.GetHicon();
Icon tempManagedRes = Icon.FromHandle(iconHandle);
this.Icon = (Icon)tempManagedRes.Clone();
tempManagedRes.Dispose();
DestroyIcon(iconHandle);

: Win32.DestroyIcon vs. Icon.Dispose

+3

sourceof.net. Icon.Dispose;

public void Dispose()
{
    Dispose(true);
    GC.SuppressFinalize(this);
}

void Dispose(bool disposing)
{
    if (handle != IntPtr.Zero)
    {
        DestroyHandle();
    }
}

// ... snipped

internal void DestroyHandle()
{
    if (ownHandle)
    {
         SafeNativeMethods.DestroyIcon(new HandleRef(this, handle));
         handle = IntPtr.Zero;
    }
}

You will see that it calls DestroyHandle , which calls again DestroyIcon, so yes, the call Dispose(by packing it in a block using) should do it. No need to name anything else.

0
source

All Articles