Vista Icons in .Net 2.0


I recently started working on a new project where we decided to make good use of icons in the applications. Early in the project we decided that Icons were a great way to help the user navigate the different parts and concepts of the product. As a result we purchased a brand new set of Vista Icons suitable for our product, and started putting them to good use.

We devised several uses for the icons by modeling the UI and how Icons should be used in the application. In the end we had a good idea of what the general layout of the application should be like, and it resulted in using all of the functionality introduced by Vista for Icons. What I found out as I started creating the UI is that .Net 2.0 isn’t really up to date when it comes to working with the new Icons.

Vista introduced the possibility to have Icons that are 256*256 pixels in size. But accessing such an Icon using .Net 2.0 is quite interesting work.

Say that you have a variable containing an Icon in the size 32*32 pixels. This is a normal sized Icon. An Icon however holds all the sizes of the Icon in the same file, so you should be able to access all the sizes of the Icon from an Icon variable. Naturally there is no way to express the display size of an Icon, instead you need to construct an new Icon object based on the old one, using the Icon constructor. The example method below explains how to get the Icon in a different size:

private Icon getNewIconSize(Icon normalIconsize, Size newIconSize) {
return new Icon(normalIconsize, newIconSize);
}

Now consider that you want to retrieve the 256*256 pixel icon using this method. Naturally you would call it with something like.

Icon largeIcon = getNewIconSize(myIcon, new Size(256, 256))

This however results in an Icon sized 128 by 128 pixels, not quite the large 256*256 Icon you were hoping for.

So what happened here?

Well it seems that the different Icons sizes in an .ico file are indexed using one byte. This naturally means that the maximum number represented by one byte is 255, and poor 256 would result in the number 0.
Alright its backwards but lets try:

Icon largeIcon = getNewIconSize(myIcon, new Size(0, 0));

Naturally this does not give a 256 times 256 pixel icon, instead what you need to do is

Icon largeIcon = getNewIconSize(myIcon, new Size(1, 1));

Since a 0*0 pixel icon is illogical the 0*0 call is ignored, but calling the 1*1 pixel icon returns the best match for the requested size. In this case 0*0 = 256*256.

The end is near, but the trouble is not over.

Since 256*256 pixel images are quite large, the Vista Icons of size 256*256 are compressed with the PNG format. This is an excellent idea, with the only side effect that suddenly .Net 2.0 can no longer decode the Image. There is a workaround on this by using an Icon editor to edit the .ico file and turn of the compression of the 256*256 icon size. However this makes the Icon file quite large, but it will work.

Last but not least:
On windows XP accessing a 256*256 icon will result in an exception. If your application should run on XP, I recommend using Images for large graphics than 128*128, at least until Microsoft does something to solve it. Which probably is not likely. Unless you use third party software for handling icons, instead of .Net 2.0 for working with Icons.

For more information:
http://www.codeproject.com/useritems/IconLib.asp

Bookmark and Share
  1. No comments yet.
(will not be published)