tags:

views:

45

answers:

1

My goal is to display the same icon twice, but each time in different size. I tried the following:

FileStream fs = new FileStream("name_of_the_icon_file.ico", FileMode.Open);
Icon ico = new Icon(fs, 32, 32);     //create an in-memory instance of the icon, size 32x32
Icon ico2 = new Icon(fs, 16, 16);   //create an in-memory instance of the icon, size 16x16  
...
Graphics.DrawIcon(ico, /*some point*/);
Graphics.DrawIcon(ico2, /*some other point*/);

The last line throws an ArgumentException: Value does not fall within the expected range. Can some one explain me whats wrong and whats the way to do this right?

+2  A: 

An icon file contains one or more images of different sizes.

The Icon constructor you are using tries to find an exact match for the size you have given in the icon file. If the icon file does not contain a 16x16 image, it will throw an exception as it can't match that exact size.

Instead, just load the icon (without specifying a size, so that all sizes are loaded) and then use the Graphics.DrawIcon(icon, rectangle) override to draw it at the size you wish it to stretch into. It will render using the best-match size defined within the icon (and then scale it if necessary).

For best quality, edit your icon file (I suggest using IcoFX) to supply specific images at the sizes you want (32x32 and 16x16) so that the icons are not scaled when you draw them.

Jason Williams
Thank you for the answer, I tried your suggestion, but the code is on .Net 3.5 Compact Framework (for windows mobile...) and this override method of DrawIcon doesnt exists there. There is only DrawIcon(Icon icon, int x, int y). Another thing is, when I compile my code without the second line (with 32x32 icon size), it draws the smaller icon (16x16) ok (no exception...), so I dont think that the icon doesnt contain 16x16 image.Maybe do you have another idea under those new assumptions? thanks again.
ET
Does your icon have *both* 16x16 and 32x32 sizes in it?
Jason Williams
Yes, I just checked it using the image editor provided in Visual Studio.
ET
Hmmm. Odd. The only thing I can think of is that ico2 failed to load because you're trying to load it from the same stream as ico (although that should throw an exception, and if it's null, the draw call will throw a NullReferenceException). You could try using separate streams or even separate icon files?
Jason Williams
Using 2 different streams for 2 different copies of the same file works, yet it does not seem the right solution...
ET
If the icon loader were to seek to the beginning of the stream every time, it would read the 2nd icon fine. However, that would mean you couldn't load several things from a file in sequence. Thus, after the first icon is loaded, the stream position points to the end of the file, and when the second icon tries to load from that position, there is no more data for it to read. It's the correct thing to do - but it should throw an exception when loading fails!
Jason Williams