From 4fb0921302a5e0ff277047aefb534bed038a23e2 Mon Sep 17 00:00:00 2001 From: SimplestStudio Date: Sat, 14 Sep 2024 08:45:03 +0300 Subject: [PATCH] [win] online-installer: fix top border color for win10 --- .../src/uiclasses/baseutils.cpp | 113 +++++++++++++----- 1 file changed, 80 insertions(+), 33 deletions(-) diff --git a/win-linux/extras/online-installer/src/uiclasses/baseutils.cpp b/win-linux/extras/online-installer/src/uiclasses/baseutils.cpp index c0e6189b1..fd67c84da 100644 --- a/win-linux/extras/online-installer/src/uiclasses/baseutils.cpp +++ b/win-linux/extras/online-installer/src/uiclasses/baseutils.cpp @@ -1,4 +1,7 @@ #include "baseutils.h" +#include +#include +#include static int getLuma(COLORREF color) @@ -6,6 +9,54 @@ static int getLuma(COLORREF color) return int(0.299 * GetRValue(color) + 0.587 * GetGValue(color) + 0.114 * GetBValue(color)); } +static COLORREF LighterColor(COLORREF color, WORD factor) +{ + WORD h = 0, l = 0, s = 0; + ColorRGBToHLS(color, &h, &l, &s); + double k = (double)factor/100; + l = min(240, (unsigned)round(k * l)); + return ColorHLSToRGB(h, l, s); +} + +static std::wstring GetCurrentUserSID() +{ + static std::wstring user_sid; + if (user_sid.empty()) { + HANDLE hToken = NULL; + if (OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken)) { + DWORD tokenLen = 0; + GetTokenInformation(hToken, TokenUser, NULL, 0, &tokenLen); + if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) { + if (PTOKEN_USER pTokenUser = (PTOKEN_USER)malloc(tokenLen)) { + if (GetTokenInformation(hToken, TokenUser, pTokenUser, tokenLen, &tokenLen)) { + LPWSTR sid = NULL; + if (ConvertSidToStringSid(pTokenUser->User.Sid, &sid)) { + user_sid = sid; + LocalFree(sid); + } + } + free(pTokenUser); + } + } + CloseHandle(hToken); + } + } + return user_sid; +} + +static DWORD RegQueryDwordValue(HKEY rootKey, LPCWSTR subkey, LPCWSTR value) +{ + HKEY hKey; + DWORD dwValue = 0; + if (RegOpenKeyEx(rootKey, subkey, 0, KEY_READ, &hKey) == ERROR_SUCCESS) { + DWORD dwType = REG_DWORD; + DWORD dwSize = sizeof(DWORD); + RegQueryValueEx(hKey, value, nullptr, &dwType, (LPBYTE)&dwValue, &dwSize); + RegCloseKey(hKey); + } + return dwValue; +} + Utils::WinVer Utils::getWinVersion() { static WinVer winVer = WinVer::Undef; @@ -37,40 +88,36 @@ Utils::WinVer Utils::getWinVersion() COLORREF Utils::getColorizationColor(bool isActive, COLORREF topColor) { - HKEY hKey; - DWORD dwValue = 0; - if (RegOpenKeyEx(HKEY_CURRENT_USER, L"SOFTWARE\\Microsoft\\Windows\\DWM", 0, KEY_READ, &hKey) == ERROR_SUCCESS) { - DWORD dwType = REG_DWORD; - DWORD dwSize = sizeof(DWORD); - if (RegQueryValueEx(hKey, L"ColorPrevalence", nullptr, &dwType, (LPBYTE)&dwValue, &dwSize) == ERROR_SUCCESS) { - } - RegCloseKey(hKey); - } - if (isActive && dwValue != 0) { - DWORD dwcolor = 0; - BOOL opaque = TRUE; - HRESULT(WINAPI *DwmGetColorizationColor)(DWORD*, BOOL*) = NULL; - if (HMODULE module = LoadLibrary(L"dwmapi")) { - *(FARPROC*)&DwmGetColorizationColor = GetProcAddress(module, "DwmGetColorizationColor"); - if (DwmGetColorizationColor && !SUCCEEDED(DwmGetColorizationColor(&dwcolor, &opaque))) { - dwcolor = 0; - } - FreeLibrary(module); - if (dwcolor) - return RGB((dwcolor & 0xff0000) >> 16, (dwcolor & 0xff00) >> 8, dwcolor & 0xff); - } - } -#define BORDER_ACTIVE_DARK RGB(0x2a, 0x2a, 0x2a) // Dark theme -#define BORDER_INACTIVE_DARK RGB(0x3a, 0x3a, 0x3a) -#define BORDER_ACTIVE_LIGHT_V1 RGB(0x58, 0x58, 0x58) // Light theme and colored background -#define BORDER_ACTIVE_LIGHT_V2 RGB(0x77, 0x77, 0x77) // Light theme and white background -#define BORDER_INACTIVE_LIGHT_V1 RGB(0x60, 0x60, 0x60) -#define BORDER_INACTIVE_LIGHT_V2 RGB(0xaa, 0xaa, 0xaa) int luma = getLuma(topColor); - COLORREF color = luma < 85 ? (isActive ? BORDER_ACTIVE_DARK : BORDER_INACTIVE_DARK) : - luma < 170 ? (isActive ? BORDER_ACTIVE_LIGHT_V1 : BORDER_INACTIVE_LIGHT_V1) : - (isActive ? BORDER_ACTIVE_LIGHT_V2 : BORDER_INACTIVE_LIGHT_V2); - return color; + if (isActive) { + if (RegQueryDwordValue(HKEY_CURRENT_USER, L"SOFTWARE\\Microsoft\\Windows\\DWM", L"ColorPrevalence") != 0) { + DWORD dwcolor = 0; + BOOL opaque = TRUE; + HRESULT(WINAPI *DwmGetColorizationColor)(DWORD*, BOOL*) = NULL; + if (HMODULE module = LoadLibrary(L"dwmapi")) { + *(FARPROC*)&DwmGetColorizationColor = GetProcAddress(module, "DwmGetColorizationColor"); + if (DwmGetColorizationColor && !SUCCEEDED(DwmGetColorizationColor(&dwcolor, &opaque))) { + dwcolor = 0; + } + FreeLibrary(module); + if (dwcolor) + return RGB((dwcolor & 0xff0000) >> 16, (dwcolor & 0xff00) >> 8, dwcolor & 0xff); + } + } else { + if (RegQueryDwordValue(HKEY_CURRENT_USER, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize", L"SystemUsesLightTheme") != 0) { + std::wstring userSid = GetCurrentUserSID(); + if (!userSid.empty()) { + userSid.append(L"\\Control Panel\\Desktop"); + if (RegQueryDwordValue(HKEY_USERS, userSid.c_str(), L"AutoColorization") != 0) + return LighterColor(topColor, 95); + } + } + } + int res = -0.002*luma*luma + 0.93*luma + 6; + return RGB(res, res, res); + } + int res = -0.0007*luma*luma + 0.78*luma + 25; + return RGB(res, res, res); } bool Utils::isColorDark(COLORREF color)