From 62dcb98cb291b14b96f1681121b6ab3e162524f0 Mon Sep 17 00:00:00 2001 From: Amrsatrio Date: Sat, 29 Jun 2024 13:15:24 +0700 Subject: [PATCH] Taskbar10: Use uxtheme.dll's immersive color functions --- ExplorerPatcher/ExplorerPatcher.vcxproj | 1 + ExplorerPatcher/ImmersiveColor.h | 108 ++++++++++++++++++++ ExplorerPatcher/Taskbar10.cpp | 7 +- ExplorerPatcher/dllmain.c | 129 ++++-------------------- ExplorerPatcher/symbols.c | 11 +- ExplorerPatcher/symbols.h | 19 ++-- ExplorerPatcher/utility.h | 2 - 7 files changed, 142 insertions(+), 135 deletions(-) create mode 100644 ExplorerPatcher/ImmersiveColor.h diff --git a/ExplorerPatcher/ExplorerPatcher.vcxproj b/ExplorerPatcher/ExplorerPatcher.vcxproj index d973142e2..cbad6c562 100644 --- a/ExplorerPatcher/ExplorerPatcher.vcxproj +++ b/ExplorerPatcher/ExplorerPatcher.vcxproj @@ -341,6 +341,7 @@ + diff --git a/ExplorerPatcher/ImmersiveColor.h b/ExplorerPatcher/ImmersiveColor.h new file mode 100644 index 000000000..5c002fe17 --- /dev/null +++ b/ExplorerPatcher/ImmersiveColor.h @@ -0,0 +1,108 @@ +#pragma once + +#include + +enum IMMERSIVE_COLOR_TYPE +{ + // Defining only used ones + IMCLR_SystemAccentLight2 = 2, + IMCLR_SystemAccentDark2 = 6 +}; + +struct IMMERSIVE_COLOR_PREFERENCE +{ + DWORD crStartColor; + DWORD crAccentColor; +}; + +enum IMMERSIVE_HC_CACHE_MODE +{ + IHCM_USE_CACHED_VALUE = 0, + IHCM_REFRESH = 1 +}; + +typedef bool (*RefreshImmersiveColorPolicyState_t)(); // 104 +inline bool RefreshImmersiveColorPolicyState() +{ + static RefreshImmersiveColorPolicyState_t fn; + if (!fn) + { + HMODULE h = GetModuleHandleW(L"uxtheme.dll"); + if (h) + fn = (RefreshImmersiveColorPolicyState_t)GetProcAddress(h, MAKEINTRESOURCEA(104)); + } + return fn ? fn() : false; +} + +typedef bool (*GetIsImmersiveColorUsingHighContrast_t)(IMMERSIVE_HC_CACHE_MODE); // 106 +inline bool GetIsImmersiveColorUsingHighContrast(IMMERSIVE_HC_CACHE_MODE mode) +{ + static GetIsImmersiveColorUsingHighContrast_t fn; + if (!fn) + { + HMODULE h = GetModuleHandleW(L"uxtheme.dll"); + if (h) + fn = (GetIsImmersiveColorUsingHighContrast_t)GetProcAddress(h, MAKEINTRESOURCEA(106)); + } + return fn ? fn(mode) : false; +} + +typedef HRESULT (*GetUserColorPreference_t)(IMMERSIVE_COLOR_PREFERENCE*, bool); // 120 +inline HRESULT GetUserColorPreference(IMMERSIVE_COLOR_PREFERENCE* pcpColorPreference, bool fForceReload) +{ + static GetUserColorPreference_t fn; + if (!fn) + { + HMODULE h = GetModuleHandleW(L"uxtheme.dll"); + if (h) + fn = (GetUserColorPreference_t)GetProcAddress(h, MAKEINTRESOURCEA(120)); + } + return fn ? fn(pcpColorPreference, fForceReload) : E_FAIL; +} + +typedef DWORD (*GetColorFromPreference_t)(const IMMERSIVE_COLOR_PREFERENCE*, IMMERSIVE_COLOR_TYPE, bool, IMMERSIVE_HC_CACHE_MODE); // 121 +inline DWORD GetColorFromPreference(const IMMERSIVE_COLOR_PREFERENCE* cpcpPreference, IMMERSIVE_COLOR_TYPE colorType, bool fNoHighContrast, IMMERSIVE_HC_CACHE_MODE mode) +{ + static GetColorFromPreference_t fn; + if (!fn) + { + HMODULE h = GetModuleHandleW(L"uxtheme.dll"); + if (h) + fn = (GetColorFromPreference_t)GetProcAddress(h, MAKEINTRESOURCEA(121)); + } + return fn ? fn(cpcpPreference, colorType, fNoHighContrast, mode) : 0; +} + +class CImmersiveColor +{ +public: + static DWORD GetColor(IMMERSIVE_COLOR_TYPE colorType) + { + IMMERSIVE_COLOR_PREFERENCE icp; + icp.crStartColor = 0; + icp.crAccentColor = 0; + GetUserColorPreference(&icp, false/*, true*/); + return GetColorFromPreference(&icp, colorType, false, IHCM_REFRESH); + } + + static bool IsColorSchemeChangeMessage(UINT uMsg, LPARAM lParam) + { + bool bRet = false; + if (uMsg == WM_SETTINGCHANGE && lParam && CompareStringOrdinal((WCHAR*)lParam, -1, L"ImmersiveColorSet", -1, TRUE) == CSTR_EQUAL) + { + RefreshImmersiveColorPolicyState(); + bRet = true; + } + GetIsImmersiveColorUsingHighContrast(IHCM_REFRESH); + return bRet; + } +}; + +class CImmersiveColorImpl +{ +public: + static HRESULT GetColorPreferenceImpl(IMMERSIVE_COLOR_PREFERENCE* pcpPreference, bool fForceReload, bool fUpdateCached) + { + return GetUserColorPreference(pcpPreference, fForceReload); + } +}; diff --git a/ExplorerPatcher/Taskbar10.cpp b/ExplorerPatcher/Taskbar10.cpp index f738602ea..62648a5ce 100644 --- a/ExplorerPatcher/Taskbar10.cpp +++ b/ExplorerPatcher/Taskbar10.cpp @@ -1,4 +1,5 @@ #include "utility.h" +#include "ImmersiveColor.h" #include @@ -6,8 +7,6 @@ #include #include -extern "C" DWORD (*CImmersiveColor_GetColorFunc)(int colorType); - #pragma region "Enable old taskbar" /*** Our target is in `CTray::Init()`. It constructs either the Windows 11 or the Windows 10 taskbar based on the result of @@ -242,9 +241,9 @@ DWORD GetTaskbarColor() if (tt.IsHighContrast()) return GetSysColor(COLOR_WINDOW); - if (tt.bColorPrevalence && CImmersiveColor_GetColorFunc) + if (tt.bColorPrevalence) { - DWORD result = CImmersiveColor_GetColorFunc(tt.IsDark() ? 6 /*IMCLR_SystemAccentDark2*/ : 2 /*IMCLR_SystemAccentLight2*/); + DWORD result = CImmersiveColor::GetColor(tt.IsDark() ? IMCLR_SystemAccentDark2 : IMCLR_SystemAccentLight2); if (tt.bEnableTransparency) return (result & 0xFFFFFF) | 0xCC000000; return result; diff --git a/ExplorerPatcher/dllmain.c b/ExplorerPatcher/dllmain.c index 22194cfd8..dc4598026 100644 --- a/ExplorerPatcher/dllmain.c +++ b/ExplorerPatcher/dllmain.c @@ -1606,8 +1606,6 @@ INT64 CLauncherTipContextMenu_ShowLauncherTipContextMenuHook( #pragma region "Windows 10 Taskbar Hooks" #ifdef _WIN64 -DWORD (*CImmersiveColor_GetColorFunc)(int colorType); - // credits: https://github.com/m417z/7-Taskbar-Tweaker DEFINE_GUID(IID_ITaskGroup, @@ -10731,86 +10729,6 @@ inline BOOL FollowJnz(PBYTE pJnz, PBYTE* pTarget, DWORD* pJnzSize) void TryToFindExplorerOffsets(HANDLE hExplorer, MODULEINFO* pmiExplorer, DWORD* pOffsets) { if (!pOffsets[0] || pOffsets[0] == 0xFFFFFFFF) - { - // CImmersiveColor::GetColor() - - // Ref: Anything `CImmersiveColor::GetColor(colorTheme == CT_Light ? IMCLR_LightAltMediumLow : IMCLR_DarkListLow)` - // = 1 = 323 = 298 - // 8D 41 19 0F 44 C8 E8 ?? ?? ?? ?? 44 8B - // ^^^^^^^^^^^ - PBYTE match = FindPattern( - hExplorer, pmiExplorer->SizeOfImage, - "\x8D\x41\x19\x0F\x44\xC8\xE8\x00\x00\x00\x00\x44\x8B", - "xxxxxxx????xx" - ); - if (match) - { - match += 6; - pOffsets[0] = match + 5 + *(int*)(match + 1) - (PBYTE)hExplorer; - } - else - { - // Ref: Anything `CImmersiveColor::GetColor(colorTheme != CT_Light ? IMCLR_DarkListLow : IMCLR_LightAltMediumLow)` - // = 1 = 298 = 323 - // 8D 41 E7 0F 45 C8 E8 ?? ?? ?? ?? 44 8B - // ^^^^^^^^^^^ - match = FindPattern( - hExplorer, pmiExplorer->SizeOfImage, - "\x8D\x41\xE7\x0F\x45\xC8\xE8\x00\x00\x00\x00\x44\x8B", - "xxxxxxx????xx" - ); - if (match) - { - match += 6; - pOffsets[0] = match + 5 + *(int*)(match + 1) - (PBYTE)hExplorer; - } - } - if (match) - { - printf("explorer.exe!CImmersiveColor::GetColor() = %lX\n", pOffsets[0]); - } - } - - if (!pOffsets[1] || pOffsets[1] == 0xFFFFFFFF) - { - // CImmersiveColor::IsColorSchemeChangeMessage() - // Ref: Anything `if (CImmersiveColor::IsColorSchemeChangeMessage(WM_SETTINGCHANGE, lParam)) { ... }` - // = 0x1A - // B9 1A 00 00 00 E8 ?? ?? ?? ?? 84 C0 - // ^^^^^^^^^^^ - PBYTE match = FindPattern( - hExplorer, pmiExplorer->SizeOfImage, - "\xB9\x1A\x00\x00\x00\xE8\x00\x00\x00\x00\x84\xC0", - "xxxxxx????xx" - ); - if (match) - { - match += 5; - pOffsets[1] = match + 5 + *(int*)(match + 1) - (PBYTE)hExplorer; - printf("explorer.exe!CImmersiveColor::IsColorSchemeChangeMessage() = %lX\n", pOffsets[1]); - } - } - - if (!pOffsets[2] || pOffsets[2] == 0xFFFFFFFF) - { - // CImmersiveColorImpl::GetColorPreferenceImpl() - // Ref: CImmersiveColorImpl::SetColorPreferenceImpl() - // 48 83 64 24 ?? 00 45 33 C0 33 D2 48 8D 4C 24 ?? E8 ?? ?? ?? ?? - // ^^^^^^^^^^^ - PBYTE match = FindPattern( - hExplorer, pmiExplorer->SizeOfImage, - "\x48\x83\x64\x24\x00\x00\x45\x33\xC0\x33\xD2\x48\x8D\x4C\x24\x00\xE8", - "xxxx?xxxxxxxxxx?x" - ); - if (match) - { - match += 16; - pOffsets[2] = match + 5 + *(int*)(match + 1) - (PBYTE)hExplorer; - printf("explorer.exe!CImmersiveColorImpl::GetColorPreferenceImpl() = %lX\n", pOffsets[2]); - } - } - - if (!pOffsets[3] || pOffsets[3] == 0xFFFFFFFF) { // ImmersiveTray::AttachWindowToTray() // Ref: CTaskListThumbnailWnd::SetSite() @@ -10824,12 +10742,12 @@ void TryToFindExplorerOffsets(HANDLE hExplorer, MODULEINFO* pmiExplorer, DWORD* if (match) { match += 14; - pOffsets[3] = match + 5 + *(int*)(match + 1) - (PBYTE)hExplorer; - printf("explorer.exe!ImmersiveTray::AttachWindowToTray() = %lX\n", pOffsets[3]); + pOffsets[0] = match + 5 + *(int*)(match + 1) - (PBYTE)hExplorer; + printf("explorer.exe!ImmersiveTray::AttachWindowToTray() = %lX\n", pOffsets[0]); } } - if (!pOffsets[4] || pOffsets[4] == 0xFFFFFFFF) + if (!pOffsets[1] || pOffsets[1] == 0xFFFFFFFF) { // ImmersiveTray::RaiseWindow() // Ref: CTaskListThumbnailWnd::_RaiseWindowForLivePreviewIfNeeded() @@ -10843,12 +10761,12 @@ void TryToFindExplorerOffsets(HANDLE hExplorer, MODULEINFO* pmiExplorer, DWORD* if (match) { match += 13; - pOffsets[4] = match + 5 + *(int*)(match + 1) - (PBYTE)hExplorer; - printf("explorer.exe!ImmersiveTray::RaiseWindow() = %lX\n", pOffsets[4]); + pOffsets[1] = match + 5 + *(int*)(match + 1) - (PBYTE)hExplorer; + printf("explorer.exe!ImmersiveTray::RaiseWindow() = %lX\n", pOffsets[1]); } } - if (!pOffsets[5] || pOffsets[5] == 0xFFFFFFFF) + if (!pOffsets[2] || pOffsets[2] == 0xFFFFFFFF) { // CTaskBand_CreateInstance() // Ref: CTrayBandSite::_AddRequiredBands() @@ -10865,7 +10783,7 @@ void TryToFindExplorerOffsets(HANDLE hExplorer, MODULEINFO* pmiExplorer, DWORD* if (match) { match += 14; - pOffsets[5] = match + 5 + *(int*)(match + 1) - (PBYTE)hExplorer; + pOffsets[2] = match + 5 + *(int*)(match + 1) - (PBYTE)hExplorer; } else { @@ -10881,16 +10799,16 @@ void TryToFindExplorerOffsets(HANDLE hExplorer, MODULEINFO* pmiExplorer, DWORD* if (match) { match += 13; - pOffsets[5] = match + 5 + *(int*)(match + 1) - (PBYTE)hExplorer; + pOffsets[2] = match + 5 + *(int*)(match + 1) - (PBYTE)hExplorer; } } if (match) { - printf("explorer.exe!CTaskBand_CreateInstance() = %lX\n", pOffsets[5]); + printf("explorer.exe!CTaskBand_CreateInstance() = %lX\n", pOffsets[2]); } } - if (!pOffsets[6] || pOffsets[6] == 0xFFFFFFFF) + if (!pOffsets[3] || pOffsets[3] == 0xFFFFFFFF) { // HandleFirstTimeLegacy() // Ref: TrayUI::WndProc() @@ -10907,7 +10825,7 @@ void TryToFindExplorerOffsets(HANDLE hExplorer, MODULEINFO* pmiExplorer, DWORD* if (match) { match += 11; - pOffsets[6] = match + 5 + *(int*)(match + 1) - (PBYTE)hExplorer; + pOffsets[3] = match + 5 + *(int*)(match + 1) - (PBYTE)hExplorer; } else { @@ -10923,16 +10841,16 @@ void TryToFindExplorerOffsets(HANDLE hExplorer, MODULEINFO* pmiExplorer, DWORD* if (match) { match += 15; - pOffsets[6] = match + 5 + *(int*)(match + 1) - (PBYTE)hExplorer; + pOffsets[3] = match + 5 + *(int*)(match + 1) - (PBYTE)hExplorer; } } if (match) { - printf("explorer.exe!HandleFirstTimeLegacy() = %lX\n", pOffsets[6]); + printf("explorer.exe!HandleFirstTimeLegacy() = %lX\n", pOffsets[3]); } } - if (!pOffsets[7] || pOffsets[7] == 0xFFFFFFFF) + if (!pOffsets[4] || pOffsets[4] == 0xFFFFFFFF) { // SetColorPreferenceForLogonUI() // Ref: TrayUI::_HandleSettingChange() @@ -10946,8 +10864,8 @@ void TryToFindExplorerOffsets(HANDLE hExplorer, MODULEINFO* pmiExplorer, DWORD* if (match) { match += 17; - pOffsets[7] = match + 5 + *(int*)(match + 1) - (PBYTE)hExplorer; - printf("explorer.exe!SetColorPreferenceForLogonUI() = %lX\n", pOffsets[7]); + pOffsets[4] = match + 5 + *(int*)(match + 1) - (PBYTE)hExplorer; + printf("explorer.exe!SetColorPreferenceForLogonUI() = %lX\n", pOffsets[4]); } } } @@ -11911,13 +11829,13 @@ BOOL CrashCounterHandleEntryPoint() BOOL CheckExplorerSymbols(symbols_addr* symbols_PTRS) { BOOL bAllValid = TRUE; - for (SIZE_T j = 0; j < ARRAYSIZE(symbols_PTRS->explorer_PTRS) - 1; ++j) + /*for (SIZE_T j = 0; j < ARRAYSIZE(symbols_PTRS->explorer_PTRS) - 1; ++j) { DWORD i = symbols_PTRS->explorer_PTRS[j]; bAllValid &= i && i != 0xFFFFFFFF; if (!bAllValid) break; - } + }*/ return bAllValid; } @@ -11963,7 +11881,7 @@ void PrepareAlternateTaskbarImplementation(symbols_addr* symbols_PTRS, const WCH typedef DWORD (*GetVersion_t)(); GetVersion_t GetVersion = (GetVersion_t)GetProcAddress(hMyTaskbar, "GetVersion"); DWORD version = GetVersion ? GetVersion() : 0; - if (version != 1) + if (version != 2) { wprintf(L"[TB] '%s' with version %d is not compatible\n", pszTaskbarDll, version); return; @@ -12450,11 +12368,6 @@ DWORD Inject(BOOL bIsExplorer) { TryToFindExplorerOffsets(hExplorer, &miExplorer, symbols_PTRS.explorer_PTRS); - if (symbols_PTRS.explorer_PTRS[0] && symbols_PTRS.explorer_PTRS[0] != 0xFFFFFFFF) - { - CImmersiveColor_GetColorFunc = (DWORD(*)(int))((uintptr_t)hExplorer + symbols_PTRS.explorer_PTRS[0]); - } - #if 0 if (global_rovi.dwBuildNumber >= 26002) { @@ -12599,9 +12512,9 @@ DWORD Inject(BOOL bIsExplorer) // Enable Windows 10 taskbar search box on 22621+ if (IsWindows11Version22H2OrHigher()) { - if (symbols_PTRS.explorer_PTRS[8] && symbols_PTRS.explorer_PTRS[8] != 0xFFFFFFFF) + if (symbols_PTRS.explorer_PTRS[5] && symbols_PTRS.explorer_PTRS[5] != 0xFFFFFFFF) { - TrayUI__UpdatePearlSizeFunc = (PBYTE)hExplorer + symbols_PTRS.explorer_PTRS[8]; + TrayUI__UpdatePearlSizeFunc = (PBYTE)hExplorer + symbols_PTRS.explorer_PTRS[5]; } UpdateSearchBox(); } diff --git a/ExplorerPatcher/symbols.c b/ExplorerPatcher/symbols.c index 57a6ec797..8704a73cb 100644 --- a/ExplorerPatcher/symbols.c +++ b/ExplorerPatcher/symbols.c @@ -6,10 +6,7 @@ const char* explorer_SN[EXPLORER_SB_CNT] = { EXPLORER_SB_2, EXPLORER_SB_3, EXPLORER_SB_4, - EXPLORER_SB_5, - EXPLORER_SB_6, - EXPLORER_SB_7, - EXPLORER_SB_8 + EXPLORER_SB_5 }; const char* twinui_pcshell_SN[TWINUI_PCSHELL_SB_CNT] = { TWINUI_PCSHELL_SB_0, @@ -134,9 +131,6 @@ static BOOL ProcessExplorerSymbols(const char* pszSettingsPath, DWORD* pOffsets) RegSetValueExW(hKey, TEXT(EXPLORER_SB_3), 0, REG_DWORD, &pOffsets[3], sizeof(DWORD)); RegSetValueExW(hKey, TEXT(EXPLORER_SB_4), 0, REG_DWORD, &pOffsets[4], sizeof(DWORD)); RegSetValueExW(hKey, TEXT(EXPLORER_SB_5), 0, REG_DWORD, &pOffsets[5], sizeof(DWORD)); - RegSetValueExW(hKey, TEXT(EXPLORER_SB_6), 0, REG_DWORD, &pOffsets[6], sizeof(DWORD)); - RegSetValueExW(hKey, TEXT(EXPLORER_SB_7), 0, REG_DWORD, &pOffsets[7], sizeof(DWORD)); - RegSetValueExW(hKey, TEXT(EXPLORER_SB_8), 0, REG_DWORD, &pOffsets[8], sizeof(DWORD)); RegSetValueExA(hKey, "Hash", 0, REG_SZ, szHash, strlen(szHash) + 1); SaveVersion(hKey, EXPLORER_SB_VERSION); @@ -672,9 +666,6 @@ LoadSymbolsResult LoadSymbols(symbols_addr* symbols_PTRS) RegQueryValueExW(hKey, TEXT(EXPLORER_SB_3), 0, NULL, &symbols_PTRS->explorer_PTRS[3], &dwSize); RegQueryValueExW(hKey, TEXT(EXPLORER_SB_4), 0, NULL, &symbols_PTRS->explorer_PTRS[4], &dwSize); RegQueryValueExW(hKey, TEXT(EXPLORER_SB_5), 0, NULL, &symbols_PTRS->explorer_PTRS[5], &dwSize); - RegQueryValueExW(hKey, TEXT(EXPLORER_SB_6), 0, NULL, &symbols_PTRS->explorer_PTRS[6], &dwSize); - RegQueryValueExW(hKey, TEXT(EXPLORER_SB_7), 0, NULL, &symbols_PTRS->explorer_PTRS[7], &dwSize); - RegQueryValueExW(hKey, TEXT(EXPLORER_SB_8), 0, NULL, &symbols_PTRS->explorer_PTRS[8], &dwSize); bOffsetsValid = TRUE; } else diff --git a/ExplorerPatcher/symbols.h b/ExplorerPatcher/symbols.h index 4467f2f20..3b06c281c 100644 --- a/ExplorerPatcher/symbols.h +++ b/ExplorerPatcher/symbols.h @@ -14,17 +14,14 @@ #define EXIT_CODE_EXPLORER 1 #define EXPLORER_SB_NAME "explorer" -#define EXPLORER_SB_0 "CImmersiveColor::GetColor" -#define EXPLORER_SB_1 "CImmersiveColor::IsColorSchemeChangeMessage" -#define EXPLORER_SB_2 "CImmersiveColorImpl::GetColorPreferenceImpl" -#define EXPLORER_SB_3 "ImmersiveTray::AttachWindowToTray" -#define EXPLORER_SB_4 "ImmersiveTray::RaiseWindow" -#define EXPLORER_SB_5 "CTaskBand_CreateInstance" -#define EXPLORER_SB_6 "HandleFirstTimeLegacy" -#define EXPLORER_SB_7 "SetColorPreferenceForLogonUI" -#define EXPLORER_SB_8 "TrayUI::_UpdatePearlSize" -#define EXPLORER_SB_CNT 9 -#define EXPLORER_SB_VERSION 2 +#define EXPLORER_SB_0 "ImmersiveTray::AttachWindowToTray" +#define EXPLORER_SB_1 "ImmersiveTray::RaiseWindow" +#define EXPLORER_SB_2 "CTaskBand_CreateInstance" +#define EXPLORER_SB_3 "HandleFirstTimeLegacy" +#define EXPLORER_SB_4 "SetColorPreferenceForLogonUI" +#define EXPLORER_SB_5 "TrayUI::_UpdatePearlSize" +#define EXPLORER_SB_CNT 6 +#define EXPLORER_SB_VERSION 3 #define TWINUI_PCSHELL_SB_NAME "twinui.pcshell" #define TWINUI_PCSHELL_SB_0 "CImmersiveContextMenuOwnerDrawHelper::s_ContextMenuWndProc" diff --git a/ExplorerPatcher/utility.h b/ExplorerPatcher/utility.h index 45ef3eb64..100327b91 100644 --- a/ExplorerPatcher/utility.h +++ b/ExplorerPatcher/utility.h @@ -265,8 +265,6 @@ static bool(*ShouldSystemUseDarkMode)(); static void(*GetThemeName)(void*, void*, void*); -extern DWORD (*CImmersiveColor_GetColorFunc)(int colorType); - void* ReadFromFile(wchar_t* wszFileName, DWORD* dwSize); int ComputeFileHash(LPCWSTR filename, LPSTR hash, DWORD dwHash);