Set default window icon from host executable during window creation#11054
Open
yeelam-gordon wants to merge 2 commits intomicrosoft:mainfrom
Open
Set default window icon from host executable during window creation#11054yeelam-gordon wants to merge 2 commits intomicrosoft:mainfrom
yeelam-gordon wants to merge 2 commits intomicrosoft:mainfrom
Conversation
WinUI's DesktopWindowImpl registers its window class (WinUIDesktopWin32WindowClass) with hIcon=NULL because g_hInstance refers to the WinUI framework DLL, not the application's executable. This causes windows to display no icon (or the system default) in the taskbar, Alt+Tab, and title bar. Fix: During OnCreate(), after AppWindow initialization, enumerate the first RT_GROUP_ICON resource from the host executable via GetModuleHandleW(nullptr) and set it on the window via WM_SETICON. This approach: - Works for any resource ID (uses EnumResourceNamesW instead of hardcoded ID) - Handles both packaged and unpackaged apps - Uses LR_SHARED for system-managed icon lifetime (no leak) - Silently skips if no icon resource exists (preserving current behavior) - Does not interfere with AppWindow.SetIcon() which can override later Fixes: microsoft#10856 Relates: WinUI-Gallery#1512 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Author
|
/azp run |
|
Commenter does not have sufficient privileges for PR 11054 in repo microsoft/microsoft-ui-xaml |
- Use GetDpiForWindow + GetSystemMetricsForDpi instead of GetSystemMetrics to load icons at the correct size for the window's DPI - Remove unused HMODULE field from IconSearchContext struct Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
WinUI desktop windows show no icon (or the system default) in the taskbar, Alt+Tab, and title bar. This PR fixes the issue by loading the application's icon from the host executable during window creation.
The Problem
As reported in WinUI-Gallery#1512, WinUI apps display the default Windows icon instead of the app's own icon in Alt+Tab / taskbar:

(Screenshot from WinUI-Gallery#1512 -- the WinUI Gallery app shows a default icon in Alt+Tab instead of its actual icon)
Currently the workaround is for every app to manually call
AppWindow.SetIcon("path/to/icon.ico")after window creation. But this is:Root Cause
DesktopWindowImpl::RegisterDesktopWindowClass()registersWinUIDesktopWin32WindowClasswithhIcon = NULL:WNDCLASSEXW wndClassEx = {}; // zero-initialized -- hIcon and hIconSm are NULL wndClassEx.cbSize = sizeof(WNDCLASSEX); wndClassEx.style = CS_HREDRAW | CS_VREDRAW; wndClassEx.hCursor = LoadCursor(nullptr, IDC_ARROW); wndClassEx.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); wndClassEx.lpszClassName = s_windowClassName; // hIcon is NEVER set -- remains NULLThis is because
g_hInstancerefers to the WinUI framework DLL, not the application's executable. The DLL has no icon resources.After window creation in
OnCreate(), even though theAppWindowobject is obtained, no icon is ever loaded or set. Every WinUI window starts with a blank/default icon.Fix
In
OnCreate(), afterAppWindowinitialization, we now load the app's own icon:GetModuleHandleW(nullptr)EnumResourceNamesWwithRT_GROUP_ICONLoadImageWwithLR_SHAREDWM_SETICONWhy this is better than the
AppWindow.SetIcon()workaroundAppWindow.SetIcon()workaroundAppWindow.SetIcon()to overrideWhy
EnumResourceNamesWinstead of a hardcoded resource IDDifferent project templates use different icon resource IDs (1, 101, 107, 128, etc.).
EnumResourceNamesW(hExeModule, RT_GROUP_ICON, ...)dynamically finds the first icon group -- the same icon the Windows shell displays for the .exe -- regardless of its numeric ID.Compatibility
AppWindow.SetIcon()laterWM_SETICONoverrides)Performance
Runs once per window during
OnCreate()-- all calls are trivial:GetModuleHandleW(nullptr)-- no module load, just returns cached handleEnumResourceNamesW-- scans PE resource directory, stops at first hitLoadImageWwithLR_SHARED-- system-cachedSendMessageWto own window on same thread -- synchronous, no marshalingMemory and Thread Safety
LR_SHAREDicons are system-managed -- noDestroyIcon()needed, no leakOnCreate()runs synchronously duringCreateWindowExW()on the creating thread -- no threading concernsFixes #10856
Relates to microsoft/WinUI-Gallery#1512