Windows – How to set HICON on a window (.ICO with multiple sizes)

iconswinapiwindows

I would like to define the application icon of a Win32 window, e.g. through a call to SetClassLong with GCL_HICON and passing in a handle to an icon (see SetClassLong Function on MSDN).

This works great, but I have not figured out how I should load an icon (from an ICO file) in order to keep all available sizes (e.g. 16×16, 32×32, 48×48 and full size PNG icon). When I load the icon file through LoadImage into memory to get the HICON, I have to specify which size I want (see my reply to a related question).

My ICO file contains a small sized image which should be used as the window icon (top left corner of the title bar) and has been designed to be very crisp, but also larger variants which should show up in the Alt-Tab dialog, but…

  1. Loading the 16×16 icon shows the proper icon in the title bar, but – of course – an ugly stretched version of it when I Alt-Tab. And the one showing up in the task bar is not very pretty either.

  2. Loading the 48×48 icon shows a nice icon when I Alt-Tab, but the icon which shows up in the title bar is blurry, since it is a scaled down version of the 48×48 icon.

Is there any means of telling Windows that my Windows has a multi-sized icon? Is there some obvious API which I have missed?

Best Answer

an .ICO file has multiple images in it. but a HICON is only one of those images. if you use LR_DEFAULTSIZE, then there may be some magical behavior that preserves a link to the .ico file and uses the appropriate image from it, but I doubt it.

If this doesn't do it, then nothing will.

HICON hicon = LoadImage(NULL, "filename.ico", IMAGE_ICON, 
                        0, 0, LR_DEFAULTSIZE | LR_LOADFROMFILE);

A little background.

When a .ico file is included in a application's resources, the file is cracked open and each image from the file becomes a separate resource. The file header is modified and it becomes the ICON resource. So when LoadIcon/LoadImage is passed the resource id of an ICON resource, it's really being passed a directory of other resources. It chooses the image that fits the request at that point in time and turns it into an HICON. The function that actually does this is called LookupIconIdFromDirectory

This is why when you GetIconInfo for an HICON, you get back only a single ICONINFO structure.

typedef struct _ICONINFO {
    BOOL fIcon;
    DWORD xHotspot;
    DWORD yHotspot;
    HBITMAP hbmMask;
    HBITMAP hbmColor;
} ICONINFO;
Related Topic