By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
440,963 Members | 1,749 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 440,963 IT Pros & Developers. It's quick & easy.

Of Icon handle lifetime and when is it truly disposed

P: n/a
There are a number of things about using unmanaged resources in Windows
Forms programming that is unclear to me.

In C++, if you loaded an icon resource using "ExtractIcon()", the resource
was valid until you called "DestroyIcon()". If you didn't, you had a leak.

In C#, I need to load icons from unmanaged programs (.exe, dll) at run time
and I want to make sure I'm not leaking resources, but it's not clear to me
how to insure that I'm not.

I've imported "ExtractIcon" and "DestroyIcon" like so:

[DllImport("Shell32.dll", CharSet=CharSet.Auto)]
public static extern IntPtr ExtractIcon(IntPtr hInstance, string
strFileName, uint uiIconIndex);

[DllImport("User32.dll", CharSet=CharSet.Auto)]
public static extern bool DestroyIcon(IntPtr hIcon);

I load a number of icons from the file system and stuff them into an "Icon"
object and then into an ImageList.

public static Icon extractIcon(string strPath, int nIndex)
{
Icon icon = null;
IntPtr hIcon = WindowsAPI.ExtractIcon(IntPtr.Zero, strPath,
(uint)nIndex);
if (IntPtr.Zero != hIcon)
{
icon = Icon.FromHandle(hIcon);
}
return icon;
}

At this point, I've got an unmanaged recource being held by that "Icon"
object. What exactly is going on here? Does the "FromHandle()" call make a
copy of the resource into a *managed* resource? i.e. can I call
"DestroyIcon" on the unmanaged hIcon at this point? Or would that destroy
something that particular Icon object needs yet?

Let's say I never call "DestroyIcon" - will the unmanaged Icon resource get
cleaned up when the Icon's "Dispose()" method is called? (I know not to
rely on the Dispose for resource cleanup, I'm just asking out of curiosity).

Could someone please clear this up? I want to do this right.

Thanks,

Terry
Nov 15 '05 #1
Share this Question
Share on Google+
4 Replies


P: n/a
Terry,

You don't need the call to DestroyHandle. If you get a handle to an
icon, and then pass it to an Icon instance (through a call to the static
FromHandle method on the Icon class), then the Icon class will be
responsible for calling DestroyHandle.

If you want to destroy the handle, you can call the Dispose method on
the Icon class. If the instance is part of an imagelist, then you will have
to still call the Dispose method, as I believe the imagelist creates
duplicates of the images to work with.

Hope this helps.
--
- Nicholas Paldino [.NET/C# MVP]
- mv*@spam.guard.caspershouse.com

"Terry" <ch**********@hotmail.com> wrote in message
news:ef*************@TK2MSFTNGP10.phx.gbl...
There are a number of things about using unmanaged resources in Windows
Forms programming that is unclear to me.

In C++, if you loaded an icon resource using "ExtractIcon()", the resource
was valid until you called "DestroyIcon()". If you didn't, you had a leak.
In C#, I need to load icons from unmanaged programs (.exe, dll) at run time and I want to make sure I'm not leaking resources, but it's not clear to me how to insure that I'm not.

I've imported "ExtractIcon" and "DestroyIcon" like so:

[DllImport("Shell32.dll", CharSet=CharSet.Auto)]
public static extern IntPtr ExtractIcon(IntPtr hInstance, string
strFileName, uint uiIconIndex);

[DllImport("User32.dll", CharSet=CharSet.Auto)]
public static extern bool DestroyIcon(IntPtr hIcon);

I load a number of icons from the file system and stuff them into an "Icon" object and then into an ImageList.

public static Icon extractIcon(string strPath, int nIndex)
{
Icon icon = null;
IntPtr hIcon = WindowsAPI.ExtractIcon(IntPtr.Zero, strPath,
(uint)nIndex);
if (IntPtr.Zero != hIcon)
{
icon = Icon.FromHandle(hIcon);
}
return icon;
}

At this point, I've got an unmanaged recource being held by that "Icon"
object. What exactly is going on here? Does the "FromHandle()" call make a copy of the resource into a *managed* resource? i.e. can I call
"DestroyIcon" on the unmanaged hIcon at this point? Or would that destroy
something that particular Icon object needs yet?

Let's say I never call "DestroyIcon" - will the unmanaged Icon resource get cleaned up when the Icon's "Dispose()" method is called? (I know not to
rely on the Dispose for resource cleanup, I'm just asking out of curiosity).
Could someone please clear this up? I want to do this right.

Thanks,

Terry

Nov 15 '05 #2

P: n/a
Awesome! Thank you! Would anyone have a recommendation or a pointer to a
good article/book that explains this behavior? The SDK docs for the
ImageList and Icon classes really don't say anything about it.

(PS - Your name looks familiar - are you involved with the Mono project?)

"Nicholas Paldino [.NET/C# MVP]" <mv*@spam.guard.caspershouse.com> wrote in
message news:e8**************@TK2MSFTNGP09.phx.gbl...
Terry,

You don't need the call to DestroyHandle. If you get a handle to an
icon, and then pass it to an Icon instance (through a call to the static
FromHandle method on the Icon class), then the Icon class will be
responsible for calling DestroyHandle.

If you want to destroy the handle, you can call the Dispose method on
the Icon class. If the instance is part of an imagelist, then you will have to still call the Dispose method, as I believe the imagelist creates
duplicates of the images to work with.

Hope this helps.
--
- Nicholas Paldino [.NET/C# MVP]
- mv*@spam.guard.caspershouse.com

"Terry" <ch**********@hotmail.com> wrote in message
news:ef*************@TK2MSFTNGP10.phx.gbl...
There are a number of things about using unmanaged resources in Windows
Forms programming that is unclear to me.

In C++, if you loaded an icon resource using "ExtractIcon()", the resource was valid until you called "DestroyIcon()". If you didn't, you had a leak.

In C#, I need to load icons from unmanaged programs (.exe, dll) at run

time
and I want to make sure I'm not leaking resources, but it's not clear to

me
how to insure that I'm not.

I've imported "ExtractIcon" and "DestroyIcon" like so:

[DllImport("Shell32.dll", CharSet=CharSet.Auto)]
public static extern IntPtr ExtractIcon(IntPtr hInstance, string
strFileName, uint uiIconIndex);

[DllImport("User32.dll", CharSet=CharSet.Auto)]
public static extern bool DestroyIcon(IntPtr hIcon);

I load a number of icons from the file system and stuff them into an

"Icon"
object and then into an ImageList.

public static Icon extractIcon(string strPath, int nIndex)
{
Icon icon = null;
IntPtr hIcon = WindowsAPI.ExtractIcon(IntPtr.Zero, strPath,
(uint)nIndex);
if (IntPtr.Zero != hIcon)
{
icon = Icon.FromHandle(hIcon);
}
return icon;
}

At this point, I've got an unmanaged recource being held by that "Icon"
object. What exactly is going on here? Does the "FromHandle()" call make a
copy of the resource into a *managed* resource? i.e. can I call
"DestroyIcon" on the unmanaged hIcon at this point? Or would that

destroy something that particular Icon object needs yet?

Let's say I never call "DestroyIcon" - will the unmanaged Icon resource

get
cleaned up when the Icon's "Dispose()" method is called? (I know not to
rely on the Dispose for resource cleanup, I'm just asking out of

curiosity).

Could someone please clear this up? I want to do this right.

Thanks,

Terry


Nov 15 '05 #3

P: n/a
Terry,

I have not done anything for the Mono project, although if you look
around here, you might see it from time to time.

As for books explaining this behavior, there isn't a guideline per se.
Unless the documentation says so, it basically comes down to intuition and a
lot of trial and error to figure out what it is (and for those who are more
unscrupulous, a decompiling as well).

However, a book on interop might be a good idea. You can try ".NET and
COM: The Complete Interoperability Guide" by Adam Nathan, located at (watch
for line wrap):

http://www.amazon.com/exec/obidos/tg...books&n=507846

--
- Nicholas Paldino [.NET/C# MVP]
- mv*@spam.guard.caspershouse.com

"Terry" <ch**********@hotmail.com> wrote in message
news:%2****************@TK2MSFTNGP12.phx.gbl...
Awesome! Thank you! Would anyone have a recommendation or a pointer to a
good article/book that explains this behavior? The SDK docs for the
ImageList and Icon classes really don't say anything about it.

(PS - Your name looks familiar - are you involved with the Mono project?)

"Nicholas Paldino [.NET/C# MVP]" <mv*@spam.guard.caspershouse.com> wrote in message news:e8**************@TK2MSFTNGP09.phx.gbl...
Terry,

You don't need the call to DestroyHandle. If you get a handle to an
icon, and then pass it to an Icon instance (through a call to the static
FromHandle method on the Icon class), then the Icon class will be
responsible for calling DestroyHandle.

If you want to destroy the handle, you can call the Dispose method on
the Icon class. If the instance is part of an imagelist, then you will

have
to still call the Dispose method, as I believe the imagelist creates
duplicates of the images to work with.

Hope this helps.
--
- Nicholas Paldino [.NET/C# MVP]
- mv*@spam.guard.caspershouse.com

"Terry" <ch**********@hotmail.com> wrote in message
news:ef*************@TK2MSFTNGP10.phx.gbl...
There are a number of things about using unmanaged resources in Windows Forms programming that is unclear to me.

In C++, if you loaded an icon resource using "ExtractIcon()", the resource was valid until you called "DestroyIcon()". If you didn't, you had a

leak.

In C#, I need to load icons from unmanaged programs (.exe, dll) at run

time
and I want to make sure I'm not leaking resources, but it's not clear to me
how to insure that I'm not.

I've imported "ExtractIcon" and "DestroyIcon" like so:

[DllImport("Shell32.dll", CharSet=CharSet.Auto)]
public static extern IntPtr ExtractIcon(IntPtr hInstance, string
strFileName, uint uiIconIndex);

[DllImport("User32.dll", CharSet=CharSet.Auto)]
public static extern bool DestroyIcon(IntPtr hIcon);

I load a number of icons from the file system and stuff them into an

"Icon"
object and then into an ImageList.

public static Icon extractIcon(string strPath, int nIndex)
{
Icon icon = null;
IntPtr hIcon = WindowsAPI.ExtractIcon(IntPtr.Zero, strPath,
(uint)nIndex);
if (IntPtr.Zero != hIcon)
{
icon = Icon.FromHandle(hIcon);
}
return icon;
}

At this point, I've got an unmanaged recource being held by that
"Icon" object. What exactly is going on here? Does the "FromHandle()" call make
a
copy of the resource into a *managed* resource? i.e. can I call
"DestroyIcon" on the unmanaged hIcon at this point? Or would that

destroy something that particular Icon object needs yet?

Let's say I never call "DestroyIcon" - will the unmanaged Icon resource get
cleaned up when the Icon's "Dispose()" method is called? (I know not

to rely on the Dispose for resource cleanup, I'm just asking out of

curiosity).

Could someone please clear this up? I want to do this right.

Thanks,

Terry



Nov 15 '05 #4

P: n/a
Sorry to keep flogging this, but after some playing around, I'm not quite
sure I understand what's happening. Either the resources are not really
getting cleaned up like I thought they would or what I'm using to measure
the resources isn't accurate, or there's something else going on.

I'm using Task Manager and added the column for "GDI Objects". I created a
little test Form and added some code to load an icon in various ways, and
then Dispose(). I basically performed three tests.

1. Load an icon using "ExtractIcon()" (the IconLoader.extractIcon is just a
static method I wrote that does the actual ExtractIcon and then creates an
"Icon" object using FromHandle() and returns the icon)

Icon icon = IconLoader.extractIcon(@"F:\Media\Icons\go.ico", 0);
icon.Dispose();

What happens is on the "extractIcon()" call I see the GDI handle count go up
by 2. The GDI handle count remains the same after the "Dispose()".

2. Load an icon using "ExtractIcon()" but use "DestroyIcon()" to clean up
the icon resource
Icon icon = IconLoader.extractIcon(@"F:\Media\Icons\go.ico", 0);
IconLoader.destroyIcon(icon.Handle);

What happens here, is on the "extractIcon()" call the GDI handle count goes
up by 2 and on the "destroyIcon()" call, it goes down by 2.

3. Load an icon from an embedded resource and call "Dispose()"
Stream s =
this.GetType().Assembly.GetManifestResourceStream( "TestResourceUsage.go.ico"
);
Icon icon = new Icon( s );
icon.Dispose();

What happens here is on the "new Icon(s)" line, the GDI handle count goes up
by 2 and on the "Dispose()" call it goes down by 2.

The way I'm reading the results of these three tests is that if you load a
resource using a Win32 API call like "ExtractIcon()" then you *must* call
"DestroyIcon()" to free the resource.

I'm still confused when it comes to ImageLists. When I watch the GDI Handle
count as I'm adding an image or icon to an ImageList, I see the GDI handle
count go up by 2 (which corresponds to what Nicholas had said about the
ImageList making a copy of the resource) but no matter what I do, I'm unable
to recover the resources that are allocated by the ImageList. Even if I
clear the Images collection, call "Dispose()" on the ImageList and set it's
reference to "null" the allocated GDI handles are never recovered - even if
the image is loaded from the managed manifest. I would expect that clearing
the ImageList would also call Dispose() on each of the images contained in
the ImageList (but maybe it doesn't).

Maybe what I'm doing is not a valid test, but it makes me uncomfortable when
I get behavior that doesn't seem consistent. Are my tests invalid? My
conclusions wrong? Or is there something else going on here that I'm
unaware of?

Thanks,
Terry

"Nicholas Paldino [.NET/C# MVP]" <mv*@spam.guard.caspershouse.com> wrote in
message news:#Q**************@TK2MSFTNGP11.phx.gbl...
Terry,

I have not done anything for the Mono project, although if you look
around here, you might see it from time to time.

As for books explaining this behavior, there isn't a guideline per se.
Unless the documentation says so, it basically comes down to intuition and a lot of trial and error to figure out what it is (and for those who are more unscrupulous, a decompiling as well).

However, a book on interop might be a good idea. You can try ".NET and COM: The Complete Interoperability Guide" by Adam Nathan, located at (watch for line wrap):

http://www.amazon.com/exec/obidos/tg...075146976//ref
=sr_8_xs_ap_i7_xgl14/104-8621847-0671969?v=glance&s=books&n=507846
--
- Nicholas Paldino [.NET/C# MVP]
- mv*@spam.guard.caspershouse.com

"Terry" <ch**********@hotmail.com> wrote in message
news:%2****************@TK2MSFTNGP12.phx.gbl...
Awesome! Thank you! Would anyone have a recommendation or a pointer to a
good article/book that explains this behavior? The SDK docs for the
ImageList and Icon classes really don't say anything about it.

(PS - Your name looks familiar - are you involved with the Mono project?)
"Nicholas Paldino [.NET/C# MVP]" <mv*@spam.guard.caspershouse.com> wrote in
message news:e8**************@TK2MSFTNGP09.phx.gbl...
Terry,

You don't need the call to DestroyHandle. If you get a handle to an icon, and then pass it to an Icon instance (through a call to the static FromHandle method on the Icon class), then the Icon class will be
responsible for calling DestroyHandle.

If you want to destroy the handle, you can call the Dispose method on the Icon class. If the instance is part of an imagelist, then you will have
to still call the Dispose method, as I believe the imagelist creates
duplicates of the images to work with.

Hope this helps.
--
- Nicholas Paldino [.NET/C# MVP]
- mv*@spam.guard.caspershouse.com

"Terry" <ch**********@hotmail.com> wrote in message
news:ef*************@TK2MSFTNGP10.phx.gbl...
> There are a number of things about using unmanaged resources in Windows > Forms programming that is unclear to me.
>
> In C++, if you loaded an icon resource using "ExtractIcon()", the

resource
> was valid until you called "DestroyIcon()". If you didn't, you had
a leak.
>
> In C#, I need to load icons from unmanaged programs (.exe, dll) at run time
> and I want to make sure I'm not leaking resources, but it's not
clear to me
> how to insure that I'm not.
>
> I've imported "ExtractIcon" and "DestroyIcon" like so:
>
> [DllImport("Shell32.dll", CharSet=CharSet.Auto)]
> public static extern IntPtr ExtractIcon(IntPtr hInstance, string
> strFileName, uint uiIconIndex);
>
> [DllImport("User32.dll", CharSet=CharSet.Auto)]
> public static extern bool DestroyIcon(IntPtr hIcon);
>
> I load a number of icons from the file system and stuff them into an
"Icon"
> object and then into an ImageList.
>
> public static Icon extractIcon(string strPath, int nIndex)
> {
> Icon icon = null;
> IntPtr hIcon = WindowsAPI.ExtractIcon(IntPtr.Zero, strPath,
> (uint)nIndex);
> if (IntPtr.Zero != hIcon)
> {
> icon = Icon.FromHandle(hIcon);
> }
> return icon;
> }
>
> At this point, I've got an unmanaged recource being held by that "Icon" > object. What exactly is going on here? Does the "FromHandle()"
call make
a
> copy of the resource into a *managed* resource? i.e. can I call
> "DestroyIcon" on the unmanaged hIcon at this point? Or would that destroy
> something that particular Icon object needs yet?
>
> Let's say I never call "DestroyIcon" - will the unmanaged Icon

resource get
> cleaned up when the Icon's "Dispose()" method is called? (I know
not to > rely on the Dispose for resource cleanup, I'm just asking out of
curiosity).
>
> Could someone please clear this up? I want to do this right.
>
>
>
> Thanks,
>
> Terry
>
>



Nov 15 '05 #5

This discussion thread is closed

Replies have been disabled for this discussion.