Page 1 of 1

How to properly create a wxIconBundle under Windows?

Posted: Thu Apr 22, 2021 8:53 pm
by a little bit
I would like to create a wxIconBundle for a given file extension / MIME type under Windows.

I tried the following for a given wxString ext (e.g., "pdf"):

Code: Select all

// simplified; no error checking

if (auto const file_type = wxTheMimeTypesManager::GetFileTypeFromExtension(ext)) {
	if (wxIconLocation icon_loc; file_type->GetIcon(&icon_loc))
		icon_bundle.AddIcon(icon_loc.GetFileName(), /* whatever */);
However, this fails if GetIcon(...) returns a so called "indirect string" in icon_loc. It seems that wxWidgets does not properly parse these. I tried to handle them via native function SHLoadIndirectString(...). But then a PNG file is often returned for the icon with improper size. Eventually, I threw the towel and implemented it all natively for that platform:

Code: Select all

    wxIconBundle&   icon_bundle,
    wxFileType&     file_type
) {
    if (wxArrayString file_exts; !file_type.GetExtensions(file_exts)) // XXX: see API doc for potential shortcomings

    else {
        for (auto const& file_ext: file_exts) {
            SHFILEINFO file_info;

            if (!SUCCEEDED(SHGetFileInfo(file_ext.c_str(), FILE_ATTRIBUTE_NORMAL, &file_info, sizeof(file_info), SHGFI_USEFILEATTRIBUTES|SHGFI_ICON)))

            else if (wxIcon icon; !icon.CreateFromHICON(static_cast<WXHICON>(file_info.hIcon)))

            else {
While this works, it is not cross-platform. Now, I find the whole icon-related stuff in wxWidgets a little bit overwhelming, so I might have done it wrong. Hence, my question:

How to create an icon bundle under Windows (or better yet, any platform) containing the same kind of icon but with different sizes for a given file extension / MIME type? My ultimate goal is to retrieve a (native, if possible) icon via wxArtProvider::GetIcon(...) for that extension (= wxArtID), e.g., to be usable in the wxImageList of a wxTreeCtrl.