SDL: Fix default Windows window icon not suiting the DPI. (65e7c)

From 65e7c8e26578968b597ce4426af4e82fe8a2e908 Mon Sep 17 00:00:00 2001
From: Clownacy <[EMAIL REDACTED]>
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 e456c2efa7e1c..841261d3ddcfc 100644
--- a/src/video/windows/SDL_windowsevents.c
+++ b/src/video/windows/SDL_windowsevents.c
@@ -2098,13 +2098,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(SDL_PLATFORM_XBOXONE) && !defined(SDL_PLATFORM_XBOXSERIES)
     const char *hint;
-    TCHAR path[MAX_PATH];
 #endif
 
     /* 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)));
         }
     } 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(SDL_PLATFORM_XBOXONE) && !defined(SDL_PLATFORM_XBOXSERIES)*/