Search code examples
windowswinapishell-extensions

Loading a bitmap icon from resources in an icon handler shell extension


I need to load a .bmp icon from resources in IExtractIcon::Extract, but I cannot figure out why it is not working. I keep getting a black or white rectangle where the icon is supposed to be.

enter image description here

I have two icons declared in project resources .rc file: ICON_16_BITMAP and ICON_BITMAP. The icons should definitely be loaded as they are not null after LoadImageW.

// IExtractIcon

HRESULT icon_handler::GetIconLocation(UINT u_flags, PWSTR psz_icon_file, UINT cch_max, int* pi_index, UINT* pw_flags)
{
    *pw_flags = GIL_NOTFILENAME | GIL_DONTCACHE;
    return S_OK;
}

extern HINSTANCE global_h_instance;

HRESULT icon_handler::Extract(PCWSTR psz_file, UINT n_icon_index, HICON* phicon_large, HICON* phicon_small, UINT n_icon_size)
{
    const int small_size = HIWORD(n_icon_size);
    const int large_size = LOWORD(n_icon_size);

    if (phicon_large != nullptr)
    {
        OutputDebugStringW((L"Extract large icon: " + std::to_wstring(large_size)).c_str());

        *phicon_large = HICON(LoadImageW(global_h_instance, MAKEINTRESOURCE(ICON_BITMAP), IMAGE_BITMAP, large_size, large_size,
            LR_SHARED));
    }
    if (phicon_small != nullptr)
    {
        OutputDebugStringW((L"Extract small icon: " + std::to_wstring(small_size)).c_str());

        *phicon_small = HICON(LoadImageW(global_h_instance, MAKEINTRESOURCE(ICON_16_BITMAP), IMAGE_BITMAP, small_size, small_size,
            LR_SHARED));
    }

    return S_OK;
}

I've tried to follow many tutorials, but this seems as simple I can go but so far it's not working out. Is there anything that sticks out that could be the reason the icon is not working?


Solution

  • BMP is not the same as the icon format.

    It cannot be forced to convert with HICON.

    The easiest way is to convert the BMP file into an icon file by converting the image tool and then load it into the resource.