LoadImage
is designed to automatically load the icon with the most appropriate color bit depth that has the size you request. By "most appropriate", I mean the one that is the best match for your current display settings. This is almost always exactly what you want, so the function is one of those that "Just Works". Tell it what size (pixel dimensions) icon you want, and it handles the rest. There is no way of telling it which color bit depth you want to use.
If there isn't an icon of that size, it scales up a smaller one. Since this isn't ideal, recent versions of Windows offer the LoadIconWithScaleDown
API, which does exactly what it says on the tin. This produces better-looking results. See David Heffernan's answer here for a usage example.
Anyway. Your problem here is unrelated to the LoadImage
function. The problem is the LR_LOADREALSIZE
flag that you're passing to the function. I can't find a definition of that constant in the Windows SDK header files, but it looks like it is defined by either the Delphi or C++ Builder libraries. The definition is something like:
LR_LOADREALSIZE = $80;
or
#define LR_LOADREALSIZE (Byte)(128)
It is a constant with a hexadecimal value of 0x80. The problem is, when you look at the documentation for the LoadImage
function, you see that a hex value of 0x80 is actually the constant LR_VGACOLOR
:
LR_VGACOLOR
0x00000080
Uses true VGA colors.
The description is a bit oblique here—you have to know what "true VGA colors" are. The original VGA was a 16-color display system, and that's what is meant here. So, you're getting a 16-color version of the icon because you're specifically asking for it. Remove the LR_LOADREALSIZE
flag (which is actually the LR_VGACOLOR
flag), and everything will work properly. Just pass 0
as the flag (or LR_DEFAULTCOLOR
, which is defined to be 0).
Note: You should not be hard-coding pixel dimensions like 32. Instead, you should be calling the GetSystemMetrics
function with the SM_CXICON
and SM_CYICON
flags. These will give you the actual size of a "normal"-sized icons on the system. "Normally", these icons have a size of 32x32 pixels, but that's not guaranteed, especially in the current era of high-DPI displays. They might be even larger. If you want small icons (normally 16x16), use SM_CXSMICON
and SM_CYSMICON
, instead.
In the rare case where you actually want to load an icon from a resource or ICO file with a specific color bit depth, and not have the system automatically determine the color depth to load, you will have to load it manually using a sequence like FindResource
→ LoadResource
→ LockResource
→ CreateIconFromResourceEx
. See also "Icons" by John Hornick on MSDN (an old article, but still accurate for this stuff), and this blog post by Raymond Chen.