February 10th, 2025

How does Explorer find the “first” icon in a file

An old MSDN article from 1995 talks about how Explorer chooses the icon to use for an executable.

Windows NT simply chooses the first resource listed in the application’s RC script. On the other hand, Windows 95’s algorithm is to choose the alphabetically first named group icon if one exists. If one such group resource does not exist, Windows chooses the icon with the numerically lowest identifier.

The first thing I want to do is make a correction. The description of the Windows NT algorithm is incorrect. Both Windows NT and Windows 95 use the same algorithm:

  • Choose the alphabetically first named group icon, if available.
  • Else, choose the group icon with the numerically lowest identifier.

The reason for this is that the Portable Executable file format requires resources to be listed in the resource dictionary with named resources first (sorted alphabetically), followed by numbered resources (sorted numerically). Explorer calls Enum­Resource­Names and grabs the first one, and since the icon groups are enumerated in the order they appear in the resource dictionary, the effect is the one described above.

If you want to replicate this algorithm, it’s not hard.

HICON FindFirstIcon(HMODULE hmod)
{
    HICON icon = nullptr;
    EnumResourceNamesW(hmod, RT_GROUP_ICON,
        [](HMODULE, PCWSTR, PCWSTR id, LONG_PTR param)
    {
        *reinterpret_cast<HICON*>(param) =
            LoadIconW(hmod, id);
        return FALSE;
    }, reinterpret_cast<LONG_PTR>(&icon);
    return icon;
}

The callback function tries to load the first icon it finds, and then returns FALSE to stop the enumeration. This returns control to Find­First­Icon, which returns the icon that the callback function loaded (or at least tried to load).

Topics
Code

Author

Raymond has been involved in the evolution of Windows for more than 30 years. In 2003, he began a Web site known as The Old New Thing which has grown in popularity far beyond his wildest imagination, a development which still gives him the heebie-jeebies. The Web site spawned a book, coincidentally also titled The Old New Thing (Addison Wesley 2007). He occasionally appears on the Windows Dev Docs Twitter account to tell stories which convey no useful information.

1 comment

  • Marco Comerci 7 hours ago

    Hello,
    I think that the closing parenthesis of EnumResourceNamesW is missing. Should be … , reinterpret_cast(&icon));

    Regards.