From 2f4a7bbcedaaf49c8bf87e34081120a6a49a0d26 Mon Sep 17 00:00:00 2001 From: Clownacy Date: Tue, 2 Apr 2024 17:59:37 +0100 Subject: [PATCH] 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) --- src/video/windows/SDL_windowsevents.c | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/src/video/windows/SDL_windowsevents.c b/src/video/windows/SDL_windowsevents.c index adc47a530e418..b034bf7ec414b 100644 --- a/src/video/windows/SDL_windowsevents.c +++ b/src/video/windows/SDL_windowsevents.c @@ -1962,13 +1962,26 @@ static void WIN_CleanRegisterApp(WNDCLASSEX wcex) 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 */ int SDL_RegisterApp(const char *name, Uint32 style, void *hInst) { WNDCLASSEX wcex; #if !defined(__XBOXONE__) && !defined(__XBOXSERIES__) const char *hint; - TCHAR path[MAX_PATH]; #endif /* Only do this once... */ @@ -2011,9 +2024,8 @@ int SDL_RegisterApp(const char *name, Uint32 style, void *hInst) wcex.hIconSm = LoadIcon(SDL_Instance, MAKEINTRESOURCE(SDL_atoi(hint))); } } else { - /* Use the first icon as a default icon, like in the Explorer */ - GetModuleFileName(SDL_Instance, path, MAX_PATH); - ExtractIconEx(path, 0, &wcex.hIcon, &wcex.hIconSm, 1); + /* Use the first icon as a default icon, like in the Explorer. */ + EnumResourceNames(SDL_Instance, RT_GROUP_ICON, WIN_ResourceNameCallback, (LONG_PTR)&wcex); } #endif /*!defined(__XBOXONE__) && !defined(__XBOXSERIES__)*/