473,387 Members | 3,810 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,387 software developers and data experts.

Of Icon handle lifetime and when is it truly disposed

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
4 3697
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
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
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
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 thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

2
by: Mamatha | last post by:
Hi I want to add an icon to the textbox's text. I don't know how to display icon in textbox in VB.NET. If any one knows please let me know. Thanks in advance. Mamatha
5
by: IcingDeath via DotNetMonster.com | last post by:
I am building this SQL Server database app in which i can store files. In order to display files I want to have the app show the associated icon for the extension of the file that is in the...
0
by: Mythran | last post by:
I wrote some code that is supposed to enumerate through the specified file's win32 resources and return a string-array of all icon names. When it runs, it returns a string-array with a bunch of...
16
by: anonymous.user0 | last post by:
The way I understand it, if I have an object Listener that has registered as a listener for some event Event that's produced by an object Emitter, as long as Emitter is still allocated Listener...
0
by: Smokey Grindle | last post by:
I keep getting this message System.ObjectDisposedException: Cannot access a disposed object. Object name: 'Icon'. at System.Drawing.Icon.get_Handle() at System.Drawing.Icon.get_Size()
0
by: Kürşat | last post by:
Hi all, I want to host a remote object in a windows service. This remote object fires events about service state. Clients connect and consume this events. The service configures and marshal...
6
by: Pieter | last post by:
Hi, I need to have the icon of the assembly that is calling my Control.Library. Using 2.0 Framework the "Drawing.Icon.ExtractAssociatedIcon" does the trick. But this fucntion doesn't exist in...
2
by: semedao | last post by:
Hi , someone know the reason and how to handle it? thanks
0
by: =?Utf-8?B?aGVyYmVydA==?= | last post by:
I read from a serialport using a worker thread. Because the worker thread t does not loop often, I cannot wait to terminate the worker thread using a boolean in the While condition. So I have a...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.