Fix default Windows window icon not suiting the DPI.

For whatever reason, `ExtractIconEx` returns icons whose sizes are
inappropriate for the current DPI, resulting in terribly-blurry
window icons at higher DPIs.

To solve this, the window icon is now set to the first icon group
that is present in the executable. This behaviour should match what
Explorer does. By selecting an icon group instead of a specific icon,
Windows is free to select the icon within the group that best suits
the current DPI.

(cherry picked from commit 1fa6142903b88007c7b77d324ee78fad9966871a)
main
Clownacy 2024-04-02 17:59:37 +01:00 committed by Sam Lantinga
parent 143b070074
commit 65e7c8e265
1 changed files with 16 additions and 4 deletions

View File

@ -2098,13 +2098,26 @@ static void WIN_CleanRegisterApp(WNDCLASSEX wcex)
SDL_Appname = NULL; SDL_Appname = NULL;
} }
static BOOL CALLBACK WIN_ResourceNameCallback(HMODULE hModule, LPCTSTR lpType, LPTSTR lpName, LONG_PTR lParam)
{
WNDCLASSEX *wcex = (WNDCLASSEX *)lParam;
(void)lpType; /* We already know that the resource type is RT_GROUP_ICON. */
/* We leave hIconSm as NULL as it will allow Windows to automatically
choose the appropriate small icon size to suit the current DPI. */
wcex->hIcon = LoadIcon(hModule, lpName);
/* Do not bother enumerating any more. */
return FALSE;
}
/* Register the class for this application */ /* Register the class for this application */
int SDL_RegisterApp(const char *name, Uint32 style, void *hInst) int SDL_RegisterApp(const char *name, Uint32 style, void *hInst)
{ {
WNDCLASSEX wcex; WNDCLASSEX wcex;
#if !defined(SDL_PLATFORM_XBOXONE) && !defined(SDL_PLATFORM_XBOXSERIES) #if !defined(SDL_PLATFORM_XBOXONE) && !defined(SDL_PLATFORM_XBOXSERIES)
const char *hint; const char *hint;
TCHAR path[MAX_PATH];
#endif #endif
/* Only do this once... */ /* Only do this once... */
@ -2147,9 +2160,8 @@ int SDL_RegisterApp(const char *name, Uint32 style, void *hInst)
wcex.hIconSm = LoadIcon(SDL_Instance, MAKEINTRESOURCE(SDL_atoi(hint))); wcex.hIconSm = LoadIcon(SDL_Instance, MAKEINTRESOURCE(SDL_atoi(hint)));
} }
} else { } else {
/* Use the first icon as a default icon, like in the Explorer */ /* Use the first icon as a default icon, like in the Explorer. */
GetModuleFileName(SDL_Instance, path, MAX_PATH); EnumResourceNames(SDL_Instance, RT_GROUP_ICON, WIN_ResourceNameCallback, (LONG_PTR)&wcex);
ExtractIconEx(path, 0, &wcex.hIcon, &wcex.hIconSm, 1);
} }
#endif /*!defined(SDL_PLATFORM_XBOXONE) && !defined(SDL_PLATFORM_XBOXSERIES)*/ #endif /*!defined(SDL_PLATFORM_XBOXONE) && !defined(SDL_PLATFORM_XBOXSERIES)*/