LoadIconWithScaleDown and LoadIconMetric fail when loading .ico for the SM_CXICON/SM_CYICON size

Heads up. The Windows API calls LoadIconWithScaleDown() and LoadIconMetric() fail when they try to load a 32×32 icon from an .ico file, when the current DPI is 96; that is, GetSystemMetrics(SM_CXICON) == 32. They work with resources and other image sizes.

Debugging the call LoadIconWithScaleDown(0, L"sample.ico", 32, 32, &hIcon) ends up in the following code path when run with a standard DPI screen:

708f709a 56           push esi
708f709b ff7508       push dword ptr [ebp+8]
708f709e ff15f0a29f70 call dword ptr [comctl32!_imp__LoadIconW (709fa2f0)]

This just cannot work, because of LoadIcon() only supports loading from resources, and not from .ico files.

This is simply a bug in Windows Vista through Windows 10. A suggested workaround is as follows:

if(!SUCCEEDED(LoadIconWithScaleDown(NULL, L"sample.ico", cx, cy, &hIcon)) {
  hIcon = LoadImage(NULL, L"sample.ico", IMAGE_ICON, cx, cy, LR_LOADFROMFILE);
}
// you should do further error checking here

Leave a Reply

Your email address will not be published. Required fields are marked *