terminal/src/cascadia/WindowsTerminal/icon.cpp
Dustin L. Howett 5a1c931f77
Update WT's icon at runtime to match high-contrast as applicable (#7971)
This commit introduces 8 more variants of the .ICO file, embeds the
right ones into WindowsTerminal.exe, and adds code that will select the
most appropriate icon at runtime.

Since we're a Centennial application, the "application" icon inside our
package isn't used by the shell for the taskbar thumbnails or the
Alt-Tab window.

To quote J. Tippet,
> I believe there are two possible fixes:
>
> 1. Fix the OS shell to prefer the MRT icon instead of preferring the
>    win32 icon
> 2. Add alternate versions of /res/terminal.ico
> The 1st fix is clearly better, since it benefits any hybrid app. But
> the 2nd fix is much easier, since it'd just take about an hour to gin up
> a new .ico file and hack the .RC file to refer to it when building the
> preview flavor.

... and to quote Michael Ratanapintha,

> Basically, if your MSIX-packaged desktop app's image resources are
> separate files or even separate MSIX packages, they may be loaded by
> MRT. If they're embedded in the .exe, they're the old-fashioned Win32
> resources Mr. Tippet is referring to.

This is the "2nd fix."

Fixes #6777

Co-authored-by: Jeffrey Tippet <jtippet@ntdev.microsoft.com>
2020-10-28 00:39:38 +00:00

50 lines
1.6 KiB
C++

// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
#include "pch.h"
#include "resource.h"
static int _GetActiveAppIconResource()
{
auto iconResource{ IDI_APPICON };
HIGHCONTRASTW hcInfo{};
hcInfo.cbSize = sizeof(hcInfo);
if (SystemParametersInfoW(SPI_GETHIGHCONTRAST, sizeof(hcInfo), &hcInfo, 0))
{
if (WI_IsFlagSet(hcInfo.dwFlags, HCF_HIGHCONTRASTON))
{
iconResource = IDI_APPICON_HC_BLACK;
if (0x00FFFFFF == GetSysColor(COLOR_WINDOW)) // white window color == white high contrast
{
iconResource = IDI_APPICON_HC_WHITE;
}
}
}
return iconResource;
}
void UpdateWindowIconForActiveMetrics(HWND window)
{
auto iconResource{ MAKEINTRESOURCEW(_GetActiveAppIconResource()) };
// These handles are loaded with LR_SHARED, so they are safe to "leak".
HANDLE smallIcon{ LoadImageW(wil::GetModuleInstanceHandle(), iconResource, IMAGE_ICON, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), LR_SHARED) };
LOG_LAST_ERROR_IF_NULL(smallIcon);
HANDLE largeIcon{ LoadImageW(wil::GetModuleInstanceHandle(), iconResource, IMAGE_ICON, GetSystemMetrics(SM_CXICON), GetSystemMetrics(SM_CYICON), LR_SHARED) };
LOG_LAST_ERROR_IF_NULL(largeIcon);
if (smallIcon)
{
SendMessageW(window, WM_SETICON, ICON_SMALL, reinterpret_cast<LPARAM>(smallIcon));
}
if (largeIcon)
{
SendMessageW(window, WM_SETICON, ICON_BIG, reinterpret_cast<LPARAM>(largeIcon));
}
}