From cdefcc6986eb8c96d64d7be3fc70a78715bd54e5 Mon Sep 17 00:00:00 2001 From: Cynthia Foxwell Date: Fri, 17 Mar 2023 10:04:21 -0600 Subject: [PATCH 1/4] i still have no idea what im doing when it comes to trying to disable dwm, this is still unstable... --- README.md | 2 +- classic-theme-windows.wh.cpp | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index d57e4ac..8e0362e 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ Based on [SimpleClassicTheme.FileExplorerHook](https://github.com/AEAEAEAE4343/S ## Classic Theme Windows Forces Classic Theme on all Windows -Originally written by WinClassic user Travis. Added DWM disabler from BasicThemer2 for classic titlebars and Classic File Picker. +Originally written by WinClassic user Travis. ~~Added DWM disabler from BasicThemer2 for classic titlebars~~ (need to find a better method, I just don't know how) and Classic File Picker. ## ~~Classic File Picker~~ ~~Restores pre-Vista file picker. Requires Classic Theme Windows mod or else Windows just upgrades the dialog.~~ diff --git a/classic-theme-windows.wh.cpp b/classic-theme-windows.wh.cpp index 1013a38..bdce86f 100644 --- a/classic-theme-windows.wh.cpp +++ b/classic-theme-windows.wh.cpp @@ -47,7 +47,7 @@ Forces Classic Theme on all Windows DWORD thisPid = -1; // BasicThemer2 reimplementation to render classic titlebars -static const int DisableDWM = DWMNCRP_DISABLED; +/*static const int DisableDWM = DWMNCRP_DISABLED; static const int EnableDWM = DWMNCRP_ENABLED; void BasicThemerEnable(HWND hwnd) { @@ -99,7 +99,7 @@ BOOL CALLBACK DisableBasicThemerForAll(HWND hWnd, LPARAM lParam) { BasicThemerDisable(hWnd); return TRUE; -} +}*/ // File picker template @@ -134,7 +134,7 @@ BOOL Wh_ModInit() { SetThemeAppProperties(0); // BasicThemer hooks - Wh_SetFunctionHook((void*)CreateWindowExW, + /*Wh_SetFunctionHook((void*)CreateWindowExW, (void*)CreateWindowExW_Hook, (void**)&CreateWindowExW_Orig); Wh_SetFunctionHook((void*)CreateWindowExA, @@ -143,7 +143,7 @@ BOOL Wh_ModInit() { // Iterate every window to enable BasicThemer thisPid = GetProcessIdOfThread(GetCurrentThread()); - EnumWindows(EnableBasicThemerForAll, thisPid); + EnumWindows(EnableBasicThemerForAll, thisPid);*/ // File picker Wh_SetFunctionHook((void*)CoCreateInstance, (void*)CoCreateInstance_Hook, @@ -159,6 +159,6 @@ void Wh_ModUninit() { } // Iterate every window to disable BasicThemer - thisPid = GetProcessIdOfThread(GetCurrentThread()); - EnumWindows(DisableBasicThemerForAll, thisPid); + /*thisPid = GetProcessIdOfThread(GetCurrentThread()); + EnumWindows(DisableBasicThemerForAll, thisPid);*/ } \ No newline at end of file From c4d84e84cee8cd9648548f2989aadaa43f98f80d Mon Sep 17 00:00:00 2001 From: Cynthia Foxwell Date: Thu, 30 Mar 2023 20:40:17 -0600 Subject: [PATCH 2/4] Classic Theme Windows: try 3 of dwm disabler, actually stable this time --- classic-theme-windows.wh.cpp | 147 ++++++++++++++++++++++++++--------- 1 file changed, 110 insertions(+), 37 deletions(-) diff --git a/classic-theme-windows.wh.cpp b/classic-theme-windows.wh.cpp index bdce86f..4eebb94 100644 --- a/classic-theme-windows.wh.cpp +++ b/classic-theme-windows.wh.cpp @@ -30,7 +30,7 @@ // @exclude PhoneExperienceHost.exe // @exclude SecurityHealthTray.exe // @exclude Window Detective.exe -// @compilerOptions -luxtheme -ldwmapi -lole32 -lcomdlg32 +// @compilerOptions -luxtheme -ldwmapi -lole32 -lcomdlg32 -lcomctl32 // ==/WindhawkMod== // ==WindhawkModReadme== @@ -43,63 +43,134 @@ Forces Classic Theme on all Windows #include #include #include - -DWORD thisPid = -1; +#include // BasicThemer2 reimplementation to render classic titlebars -/*static const int DisableDWM = DWMNCRP_DISABLED; +static const int DisableDWM = DWMNCRP_DISABLED; static const int EnableDWM = DWMNCRP_ENABLED; -void BasicThemerEnable(HWND hwnd) { +void DisableDWMForHwnd(HWND hwnd) { DwmSetWindowAttribute(hwnd, DWMWA_NCRENDERING_POLICY, &DisableDWM, sizeof(int)); } -void BasicThemerDisable(HWND hwnd) { +void EnableDWMForHwnd(HWND hwnd) { DwmSetWindowAttribute(hwnd, DWMWA_NCRENDERING_POLICY, &EnableDWM, sizeof(int)); } +DWORD g_uiThreadId; + +BOOL CALLBACK DisableDWMForAll(HWND hWnd, LPARAM lParam) { + DWORD dwProcessId = 0; + DWORD dwThreadId = GetWindowThreadProcessId(hWnd, &dwProcessId); + if (!dwThreadId || dwProcessId != GetCurrentProcessId()) { + return TRUE; + } + + if (g_uiThreadId && g_uiThreadId != dwThreadId) { + return TRUE; + } + + if (IsWindow(hWnd)) { + Wh_Log(L"[Init] Window found: %08X", (DWORD)(ULONG_PTR)hWnd); + + if (!g_uiThreadId) { + g_uiThreadId = dwThreadId; + } + + DisableDWMForHwnd(hWnd); + } + + return TRUE; +} + +BOOL CALLBACK EnableDWMForAll(HWND hWnd, LPARAM lParam) { + DWORD dwProcessId = 0; + DWORD dwThreadId = GetWindowThreadProcessId(hWnd, &dwProcessId); + if (!dwThreadId || dwProcessId != GetCurrentProcessId()) { + return TRUE; + } + + if (g_uiThreadId && g_uiThreadId != dwThreadId) { + return TRUE; + } + + if (IsWindow(hWnd)) { + Wh_Log(L"[Cleanup] Window found: %08X", (DWORD)(ULONG_PTR)hWnd); + + if (!g_uiThreadId) { + g_uiThreadId = dwThreadId; + } + + EnableDWMForHwnd(hWnd); + } + + return TRUE; +} + using CreateWindowExW_t = decltype(&CreateWindowExW); CreateWindowExW_t CreateWindowExW_Orig; HWND WINAPI CreateWindowExW_Hook(DWORD dwExStyle,LPCWSTR lpClassName,LPCWSTR lpWindowName,DWORD dwStyle,int X,int Y,int nWidth,int nHeight,HWND hWndParent,HMENU hMenu,HINSTANCE hInstance,LPVOID lpParam) { - HWND res = CreateWindowExW_Orig(dwExStyle,lpClassName,lpWindowName,dwStyle,X,Y,nWidth,nHeight,hWndParent,hMenu,hInstance,lpParam); + HWND hWnd = CreateWindowExW_Orig(dwExStyle,lpClassName,lpWindowName,dwStyle,X,Y,nWidth,nHeight,hWndParent,hMenu,hInstance,lpParam); - if (thisPid != -1) { - DWORD targetPid; - GetWindowThreadProcessId(res, &targetPid); - if (targetPid == thisPid) { - BasicThemerEnable(res); - } + if (!hWnd) { + return hWnd; } - return res; + if (g_uiThreadId && g_uiThreadId != GetCurrentThreadId()) { + return hWnd; + } + + if (IsWindow(hWnd)) { + Wh_Log(L"[CreateWindowExW] Window created: %08X", (DWORD)(ULONG_PTR)hWnd); + + if (!g_uiThreadId) { + g_uiThreadId = GetCurrentThreadId(); + } + + DisableDWMForHwnd(hWnd); + EnumWindows(DisableDWMForAll, 0); + } + + return hWnd; } using CreateWindowExA_t = decltype(&CreateWindowExA); CreateWindowExA_t CreateWindowExA_Orig; HWND WINAPI CreateWindowExA_Hook(DWORD dwExStyle,LPCSTR lpClassName,LPCSTR lpWindowName,DWORD dwStyle,int X,int Y,int nWidth,int nHeight,HWND hWndParent,HMENU hMenu,HINSTANCE hInstance,LPVOID lpParam) { - HWND res = CreateWindowExA_Orig(dwExStyle,lpClassName,lpWindowName,dwStyle,X,Y,nWidth,nHeight,hWndParent,hMenu,hInstance,lpParam); + HWND hWnd = CreateWindowExA_Orig(dwExStyle,lpClassName,lpWindowName,dwStyle,X,Y,nWidth,nHeight,hWndParent,hMenu,hInstance,lpParam); - if (thisPid != -1) { - DWORD targetPid; - GetWindowThreadProcessId(res, &targetPid); - if (targetPid == thisPid) { - BasicThemerEnable(res); - } + if (!hWnd) { + return hWnd; } - return res; + if (g_uiThreadId && g_uiThreadId != GetCurrentThreadId()) { + return hWnd; + } + + if (IsWindow(hWnd)) { + Wh_Log(L"[CreateWindowExA] Window created: %08X", (DWORD)(ULONG_PTR)hWnd); + + if (!g_uiThreadId) { + g_uiThreadId = GetCurrentThreadId(); + } + + DisableDWMForHwnd(hWnd); + EnumWindows(DisableDWMForAll, 0); + } + + return hWnd; } -BOOL CALLBACK EnableBasicThemerForAll(HWND hWnd, LPARAM lParam) { - if (IsWindow(hWnd)) - BasicThemerEnable(hWnd); +HWND(WINAPI *pOriginalSHCreateWorkerWindow)(WNDPROC wndProc, HWND hWndParent, DWORD dwExStyle, DWORD dwStyle, HMENU hMenu, LONG_PTR wnd_extra); +HWND WINAPI SHCreateWorkerWindowHook(WNDPROC wndProc, HWND hWndParent, DWORD dwExStyle, DWORD dwStyle, HMENU hMenu, LONG_PTR wnd_extra) +{ + HWND result = pOriginalSHCreateWorkerWindow(wndProc, hWndParent, dwExStyle, dwStyle, hMenu, wnd_extra); - return TRUE; + if (dwExStyle == 0x10000 && dwStyle == 0x46000000 && result) { + DisableDWMForHwnd(hWndParent); + EnumWindows(DisableDWMForAll, 0); + } + + return result; } -BOOL CALLBACK DisableBasicThemerForAll(HWND hWnd, LPARAM lParam) { - if (IsWindow(hWnd)) - BasicThemerDisable(hWnd); - - return TRUE; -}*/ // File picker template @@ -134,16 +205,19 @@ BOOL Wh_ModInit() { SetThemeAppProperties(0); // BasicThemer hooks - /*Wh_SetFunctionHook((void*)CreateWindowExW, + Wh_SetFunctionHook((void*)CreateWindowExW, (void*)CreateWindowExW_Hook, (void**)&CreateWindowExW_Orig); Wh_SetFunctionHook((void*)CreateWindowExA, (void*)CreateWindowExA_Hook, (void**)&CreateWindowExA_Orig); + HMODULE hShcore = GetModuleHandle(L"shcore.dll"); + void* origFunc = (void*)GetProcAddress(hShcore, (LPCSTR)188); + Wh_SetFunctionHook(origFunc, (void*)SHCreateWorkerWindowHook, (void**)&pOriginalSHCreateWorkerWindow); + // Iterate every window to enable BasicThemer - thisPid = GetProcessIdOfThread(GetCurrentThread()); - EnumWindows(EnableBasicThemerForAll, thisPid);*/ + EnumWindows(DisableDWMForAll, 0); // File picker Wh_SetFunctionHook((void*)CoCreateInstance, (void*)CoCreateInstance_Hook, @@ -159,6 +233,5 @@ void Wh_ModUninit() { } // Iterate every window to disable BasicThemer - /*thisPid = GetProcessIdOfThread(GetCurrentThread()); - EnumWindows(DisableBasicThemerForAll, thisPid);*/ + EnumWindows(EnableDWMForAll, 0); } \ No newline at end of file From fb2d35d21ef8747676935a70041a348c404f3970 Mon Sep 17 00:00:00 2001 From: Cynthia Foxwell Date: Thu, 30 Mar 2023 20:40:29 -0600 Subject: [PATCH 3/4] Classic Theme Explorer: goodbye ExplorerPatcher --- classic-theme-explorer.wh.cpp | 387 +++++++++++++++++++++++++++++++++- 1 file changed, 377 insertions(+), 10 deletions(-) diff --git a/classic-theme-explorer.wh.cpp b/classic-theme-explorer.wh.cpp index 4ae0efa..8d38e04 100644 --- a/classic-theme-explorer.wh.cpp +++ b/classic-theme-explorer.wh.cpp @@ -7,7 +7,7 @@ // @github https://github.com/Cynosphere // @homepage https://c7.pm/ // @include explorer.exe -// @compilerOptions -lcomctl32 +// @compilerOptions -lcomctl32 -luxtheme -lgdi32 // ==/WindhawkMod== // ==WindhawkModReadme== @@ -15,7 +15,7 @@ # Classic Theme Explorer Classic Theme mitigations for Explorer as a Windhawk mod. -Based on [SimpleClassicTheme.FileExplorerHook](https://github.com/AEAEAEAE4343/SimpleClassicTheme.FileExplorerHook) and the AutoHotkey scripts that came before it. +Based on [ExplorerPatcher](https://github.com/valinet/ExplorerPatcher), [SimpleClassicTheme.FileExplorerHook](https://github.com/AEAEAEAE4343/SimpleClassicTheme.FileExplorerHook) and the AutoHotkey scripts that came before it. */ // ==/WindhawkModReadme== @@ -45,6 +45,9 @@ Based on [SimpleClassicTheme.FileExplorerHook](https://github.com/AEAEAEAE4343/S - hideRefresh: true $name: "Hide Refresh Button" $description: "Hides the refresh button from Classic Address Bar" +- epMitigate: true + $name: "ExplorerPatcher's Mitigations" + $description: "ExplorerPatcher's Mitigations" */ // ==/WindhawkModSettings== @@ -53,6 +56,9 @@ Based on [SimpleClassicTheme.FileExplorerHook](https://github.com/AEAEAEAE4343/S #include #include #include +#include +#include + #include #include #include @@ -67,6 +73,7 @@ struct { bool addressSyncFullPath; bool addressHeight; bool hideRefresh; + bool epMitigate; } settings; void LoadSettings() { @@ -78,6 +85,7 @@ void LoadSettings() { settings.addressSyncFullPath = Wh_GetIntSetting(L"addressSyncFullPath"); settings.addressHeight = Wh_GetIntSetting(L"addressHeight"); settings.hideRefresh = Wh_GetIntSetting(L"hideRefresh"); + settings.epMitigate = Wh_GetIntSetting(L"epMitigate"); } // Explorer modifications @@ -457,28 +465,387 @@ HWND WINAPI SHCreateWorkerWindowHook(WNDPROC wndProc, HWND hWndParent, DWORD dwE return result; } +// taskbar fixes from ExplorerPatcher +using CreateWindowExW_t = decltype(&CreateWindowExW); +CreateWindowExW_t CreateWindowExW_Orig; +HWND WINAPI CreateWindowExW_Hook(DWORD dwExStyle,LPCWSTR lpClassName,LPCWSTR lpWindowName,DWORD dwStyle,int X,int Y,int nWidth,int nHeight,HWND hWndParent,HMENU hMenu,HINSTANCE hInstance,LPVOID lpParam) { + if (settings.epMitigate && (*((WORD*)&(lpClassName)+1)) && !wcscmp(lpClassName, L"TrayNotifyWnd")) + { + dwExStyle |= WS_EX_STATICEDGE; + } + if (settings.epMitigate && (*((WORD*)&(lpClassName)+1)) && !wcscmp(lpClassName, L"NotifyIconOverflowWindow")) + { + dwExStyle |= WS_EX_STATICEDGE; + } + if (settings.clientEdge && (*((WORD*)&(lpClassName)+1)) && (!wcscmp(lpClassName, L"SysListView32") || !wcscmp(lpClassName, L"SysTreeView32"))) // !wcscmp(lpClassName, L"FolderView") + { + wchar_t wszClassName[200]; + ZeroMemory(wszClassName, 200); + GetClassNameW(GetAncestor(hWndParent, GA_ROOT), wszClassName, 200); + if (!wcscmp(wszClassName, L"CabinetWClass")) + { + dwExStyle |= WS_EX_CLIENTEDGE; + } + } + if (settings.epMitigate && (*((WORD*)&(lpClassName)+1)) && !wcscmp(lpClassName, L"ReBarWindow32")) + { + wchar_t wszClassName[200]; + ZeroMemory(wszClassName, 200); + GetClassNameW(hWndParent, wszClassName, 200); + if (!wcscmp(wszClassName, L"Shell_TrayWnd")) + { + dwStyle |= RBS_BANDBORDERS; + } + } + + HWND hWnd = CreateWindowExW_Orig(dwExStyle,lpClassName,lpWindowName,dwStyle,X,Y,nWidth,nHeight,hWndParent,hMenu,hInstance,lpParam); + + return hWnd; +} +using SetWindowLongPtrW_t = decltype(&SetWindowLongPtrW); +SetWindowLongPtrW_t SetWindowLongPtrW_Orig; +LONG_PTR SetWindowLongPtrW_Hook(HWND hWnd, int nIndex, LONG_PTR dwNewLong) { + WCHAR lpClassName[200]; + ZeroMemory(lpClassName, 200); + GetClassNameW(hWnd, lpClassName, 200); + HWND hWndParent = GetParent(hWnd); + + if (settings.epMitigate && (*((WORD*)&(lpClassName)+1)) && !wcscmp(lpClassName, L"TrayNotifyWnd")) + { + if (nIndex == GWL_EXSTYLE) + { + dwNewLong |= WS_EX_STATICEDGE; + } + } + if (settings.epMitigate && (*((WORD*)&(lpClassName)+1)) && !wcscmp(lpClassName, L"NotifyIconOverflowWindow")) + { + if (nIndex == GWL_EXSTYLE) + { + dwNewLong |= WS_EX_STATICEDGE; + } + } + if (settings.clientEdge && (*((WORD*)&(lpClassName)+1)) && (!wcscmp(lpClassName, L"SysListView32") || !wcscmp(lpClassName, L"SysTreeView32"))) // !wcscmp(lpClassName, L"FolderView") + { + wchar_t wszClassName[200]; + ZeroMemory(wszClassName, 200); + GetClassNameW(GetAncestor(hWndParent, GA_ROOT), wszClassName, 200); + if (!wcscmp(wszClassName, L"CabinetWClass")) + { + if (nIndex == GWL_EXSTYLE) + { + dwNewLong |= WS_EX_CLIENTEDGE; + } + } + } + if (settings.epMitigate && (*((WORD*)&(lpClassName)+1)) && !wcscmp(lpClassName, L"ReBarWindow32")) + { + wchar_t wszClassName[200]; + ZeroMemory(wszClassName, 200); + GetClassNameW(hWndParent, wszClassName, 200); + if (!wcscmp(wszClassName, L"Shell_TrayWnd")) + { + if (nIndex == GWL_STYLE) + { + dwNewLong |= RBS_BANDBORDERS; + } + } + } + + return SetWindowLongPtrW_Orig(hWnd, nIndex, dwNewLong); +} + +HTHEME(*pOriginalOpenThemeDataForDpi)(HWND hWnd, LPCWSTR pszClassList, UINT dpi); +HTHEME OpenThemeDataForDpiHook(HWND hWnd, LPCWSTR pszClassList, UINT dpi) +{ + if (settings.epMitigate && (*((WORD*)&(pszClassList)+1)) && !wcscmp(pszClassList, L"Taskband2")) { + Wh_Log(L"Redirecting Taskband2 hTheme"); + return (HTHEME)0xDEADBEEF; + } else if (settings.epMitigate && (*((WORD*)&(pszClassList)+1)) && !wcscmp(pszClassList, L"TrayNotifyFlyout")) { + Wh_Log(L"Redirecting TrayNotifyFlyout hTheme"); + return (HTHEME)0xDEADBEFF; + } + + return pOriginalOpenThemeDataForDpi(hWnd, pszClassList, dpi); +} + +HRESULT(*pOriginalGetThemeMetric)(HTHEME hTheme, HDC hdc, int iPartId, int iStateId, int iPropId, int* piVal); +HRESULT GetThemeMetricHook(HTHEME hTheme, HDC hdc, int iPartId, int iStateId, int iPropId, int* piVal) { + Wh_Log(L"hTheme: %08X", hTheme); + + if (!settings.epMitigate || (hTheme != (HTHEME)0xDEADBEFF)) { + return pOriginalGetThemeMetric(hTheme, hdc, iPartId, iStateId, iPropId, piVal); + } + + const int TMT_WIDTH = 2416; + const int TMT_HEIGHT = 2417; + if (hTheme == (HTHEME)0xDEADBEFF && iPropId == TMT_WIDTH && iPartId == 3 && iStateId == 0) + { + *piVal = GetSystemMetrics(SM_CXICON); + } + else if (hTheme == (HTHEME)0xDEADBEFF && iPropId == TMT_HEIGHT && iPartId == 3 && iStateId == 0) + { + *piVal = GetSystemMetrics(SM_CYICON); + } + return S_OK; +} + + +HRESULT(*pOriginalGetThemeMargins)(HTHEME hTheme, HDC hdc, int iPartId, int iStateId, int iPropId, LPCRECT prc, MARGINS* pMargins); +HRESULT GetThemeMarginsHook(HTHEME hTheme, HDC hdc, int iPartId, int iStateId, int iPropId, LPCRECT prc, MARGINS* pMargins) { + Wh_Log(L"hTheme: %08X", hTheme); + + if (!settings.epMitigate || (hTheme != (HTHEME)0xDEADBEEF && hTheme != (HTHEME)0xDEADBEFF)) { + return pOriginalGetThemeMargins(hTheme, hdc, iPartId, iStateId, iPropId, prc, pMargins); + } + + const int TMT_SIZINGMARGINS = 3601; + const int TMT_CONTENTMARGINS = 3602; + HRESULT hr = S_OK; + if (hTheme) + { + hr = pOriginalGetThemeMargins( + hTheme, + hdc, + iPartId, + iStateId, + iPropId, + prc, + pMargins + ); + } + + if (hTheme == (HTHEME)0xDEADBEEF && iPropId == TMT_CONTENTMARGINS && iPartId == 5 && iStateId == 1) { + // task list button measurements + pMargins->cxLeftWidth = 4; + pMargins->cyTopHeight = 3; + pMargins->cxRightWidth = 4; + pMargins->cyBottomHeight = 3; + } else if (hTheme == (HTHEME)0xDEADBEEF && iPropId == TMT_CONTENTMARGINS && iPartId == 1 && iStateId == 0) { + // task list measurements + pMargins->cxLeftWidth = 0; + pMargins->cyTopHeight = 0; + pMargins->cxRightWidth = 4; + pMargins->cyBottomHeight = 0; + } else if (hTheme == (HTHEME)0xDEADBEEF && iPropId == TMT_SIZINGMARGINS && iPartId == 5 && iStateId == 1) { + pMargins->cxLeftWidth = 10; + pMargins->cyTopHeight = 10; + pMargins->cxRightWidth = 10; + pMargins->cyBottomHeight = 10; + } else if (hTheme == (HTHEME)0xDEADBEFF && iPropId == TMT_CONTENTMARGINS && iPartId == 3 && iStateId == 0) { + pMargins->cxLeftWidth = 4; // GetSystemMetrics(SM_CXICONSPACING); + pMargins->cyTopHeight = 4; // GetSystemMetrics(SM_CYICONSPACING); + pMargins->cxRightWidth = 4; //GetSystemMetrics(SM_CXICONSPACING); + pMargins->cyBottomHeight = 4; // GetSystemMetrics(SM_CYICONSPACING); + } + + HWND hShell_TrayWnd = FindWindowEx(NULL, NULL, L"Shell_TrayWnd", NULL); + if (hShell_TrayWnd) { + LONG dwStyle = 0; + dwStyle = GetWindowLongW(hShell_TrayWnd, GWL_STYLE); + dwStyle |= WS_DLGFRAME; + SetWindowLongW(hShell_TrayWnd, GWL_STYLE, dwStyle); + dwStyle &= ~WS_DLGFRAME; + SetWindowLongW(hShell_TrayWnd, GWL_STYLE, dwStyle); + } + + HWND hWnd = NULL; + do { + hWnd = FindWindowEx( + NULL, + hWnd, + L"Shell_SecondaryTrayWnd", + NULL + ); + if (hWnd) { + LONG dwStyle = 0; + dwStyle = GetWindowLongW(hWnd, GWL_STYLE); + dwStyle |= WS_DLGFRAME; + SetWindowLongW(hWnd, GWL_STYLE, dwStyle); + dwStyle &= ~WS_DLGFRAME; + SetWindowLongW(hWnd, GWL_STYLE, dwStyle); + } + } while (hWnd); + + return S_OK; +} + +HRESULT(*pOriginalDrawThemeTextEx)(HTHEME hTheme, HDC hdc, int iPartId, int iStateId, LPCWSTR pszText, int cchText, DWORD dwTextFlags, LPRECT pRect, const DTTOPTS* pOptions); +HRESULT DrawThemeTextExHook(HTHEME hTheme, HDC hdc, int iPartId, int iStateId, LPCWSTR pszText, int cchText, DWORD dwTextFlags, LPRECT pRect, const DTTOPTS* pOptions) { + if (!settings.epMitigate) { + return pOriginalDrawThemeTextEx(hTheme, hdc, iPartId, iStateId, pszText, cchText, dwTextFlags, pRect, pOptions); + } + + COLORREF bc = GetBkColor(hdc); + COLORREF fc = GetTextColor(hdc); + int mode = SetBkMode(hdc, TRANSPARENT); + + wchar_t text[200]; + GetWindowTextW(GetForegroundWindow(), text, 200); + + BOOL bIsActiveUnhovered = (iPartId == 5 && iStateId == 5); + BOOL bIsInactiveUnhovered = (iPartId == 5 && iStateId == 1); + BOOL bIsInactiveHovered = (iPartId == 5 && iStateId == 2); + BOOL bIsActiveHovered = bIsInactiveHovered && !wcscmp(text, pszText); + + SetTextColor(hdc, GetSysColor(COLOR_BTNTEXT)); + + NONCLIENTMETRICSW ncm; + ncm.cbSize = sizeof(NONCLIENTMETRICSW); + SystemParametersInfoW(SPI_GETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICSW), &ncm, 0); + + HFONT hFont = NULL; + if (bIsActiveUnhovered) + { + hFont = CreateFontIndirectW(&(ncm.lfCaptionFont)); + } + else if (bIsInactiveUnhovered) + { + hFont = CreateFontIndirectW(&(ncm.lfMenuFont)); + } + else if (bIsActiveHovered) + { + hFont = CreateFontIndirectW(&(ncm.lfCaptionFont)); + } + else if (bIsInactiveHovered) + { + hFont = CreateFontIndirectW(&(ncm.lfMenuFont)); + } + else + { + hFont = CreateFontIndirectW(&(ncm.lfMenuFont)); + } + + if (iPartId == 5 && iStateId == 0) // clock + { + pRect->top += 2; + } + + HGDIOBJ hOldFont = SelectObject(hdc, hFont); + DrawTextW( + hdc, + pszText, + cchText, + pRect, + dwTextFlags + ); + SelectObject(hdc, hOldFont); + DeleteObject(hFont); + SetBkColor(hdc, bc); + SetTextColor(hdc, fc); + SetBkMode(hdc, mode); + + return S_OK; +} + +HRESULT(*pOriginalDrawThemeBackground)(HTHEME hTheme, HDC hdc, int iPartId, int iStateId, LPRECT pRect, LPCRECT pClipRect); +HRESULT DrawThemeBackgroundHook(HTHEME hTheme, HDC hdc, int iPartId, int iStateId, LPRECT pRect, LPCRECT pClipRect) { + if (settings.epMitigate) { + if (iPartId == 4 && iStateId == 1) { + COLORREF bc = GetBkColor(hdc); + COLORREF fc = GetTextColor(hdc); + int mode = SetBkMode(hdc, TRANSPARENT); + + SetTextColor(hdc, GetSysColor(COLOR_BTNTEXT)); + + NONCLIENTMETRICSW ncm; + ncm.cbSize = sizeof(NONCLIENTMETRICSW); + SystemParametersInfoW(SPI_GETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICSW), &ncm, 0); + + HFONT hFont = CreateFontIndirectW(&(ncm.lfCaptionFont)); + + /*UINT dpiX, dpiY; + HRESULT hr = GetDpiForMonitor( + MonitorFromWindow(WindowFromDC(hdc), MONITOR_DEFAULTTOPRIMARY), + MDT_DEFAULT, + &dpiX, + &dpiY + ); + double dx = dpiX / 96.0, dy = dpiY / 96.0;*/ + + HGDIOBJ hOldFont = SelectObject(hdc, hFont); + DWORD dwTextFlags = DT_SINGLELINE | DT_CENTER | DT_VCENTER; + RECT rc = *pRect; + rc.bottom -= 7; + DrawTextW( + hdc, + L"\u2026", + -1, + &rc, + dwTextFlags + ); + SelectObject(hdc, hOldFont); + DeleteObject(hFont); + SetBkColor(hdc, bc); + SetTextColor(hdc, fc); + SetBkMode(hdc, mode); + } + return S_OK; + } + + return pOriginalDrawThemeBackground(hTheme, hdc, iPartId, iStateId, pRect, pClipRect); +} + +struct WINCOMPATTRDATA +{ + DWORD attribute; + PVOID pData; + ULONG dataSize; +}; + +BOOL (WINAPI *pOriginalSetWindowCompositionAttribute)(HWND hWnd, WINCOMPATTRDATA* pData); +BOOL WINAPI SetWindowCompositionAttributeHook(HWND hWnd, WINCOMPATTRDATA* pData) { + if (settings.epMitigate) { + return TRUE; + } + + return pOriginalSetWindowCompositionAttribute(hWnd, pData); +} + // Windhawk boilerplate BOOL Wh_ModInit() { - Wh_Log(L"Init"); - LoadSettings(); HMODULE hShcore = GetModuleHandle(L"shcore.dll"); - void* origFunc = (void*)GetProcAddress(hShcore, (LPCSTR)188); - Wh_SetFunctionHook(origFunc, (void*)SHCreateWorkerWindowHook, (void**)&pOriginalSHCreateWorkerWindow); + void* origCWW = (void*)GetProcAddress(hShcore, (LPCSTR)188); + Wh_SetFunctionHook(origCWW, (void*)SHCreateWorkerWindowHook, (void**)&pOriginalSHCreateWorkerWindow); + + HMODULE hUxtheme = GetModuleHandle(L"uxtheme.dll"); + + void* origOTDFD = (void*)GetProcAddress(hUxtheme, "OpenThemeDataForDpi"); + Wh_SetFunctionHook(origOTDFD, (void*)OpenThemeDataForDpiHook, (void**)&pOriginalOpenThemeDataForDpi); + + void* origGTMe = (void*)GetProcAddress(hUxtheme, "GetThemeMetric"); + Wh_SetFunctionHook(origGTMe, (void*)GetThemeMetricHook, (void**)&pOriginalGetThemeMetric); + + void* origGTMa = (void*)GetProcAddress(hUxtheme, "GetThemeMargins"); + Wh_SetFunctionHook(origGTMa, (void*)GetThemeMarginsHook, (void**)&pOriginalGetThemeMargins); + + void* origDTTE = (void*)GetProcAddress(hUxtheme, "DrawThemeTextEx"); + Wh_SetFunctionHook(origDTTE, (void*)DrawThemeTextExHook, (void**)&pOriginalDrawThemeTextEx); + + void* origDTB = (void*)GetProcAddress(hUxtheme, "DrawThemeBackground"); + Wh_SetFunctionHook(origDTB, (void*)DrawThemeBackgroundHook, (void**)&pOriginalDrawThemeBackground); + + //HMODULE hUser32 = GetModuleHandle(L"user32.dll"); + + //void* origSWCA = (void*)GetProcAddress(hUser32, "SetWindowCompositionAttribute"); + //Wh_SetFunctionHook(origSWCA, (void*)SetWindowCompositionAttributeHook, (void**)&pOriginalSetWindowCompositionAttribute); + + Wh_SetFunctionHook((void*)CreateWindowExW, + (void*)CreateWindowExW_Hook, + (void**)&CreateWindowExW_Orig); + Wh_SetFunctionHook((void*)SetWindowLongPtrW, + (void*)SetWindowLongPtrW_Hook, + (void**)&SetWindowLongPtrW_Orig); return TRUE; } void Wh_ModUninit() { - Wh_Log(L"Uninit"); - if (g_uiThreadId != 0) EnumThreadWindows(g_uiThreadId, EnumBrowserWindowsUnsubclassFunc, 0); } void Wh_ModSettingsChanged() { - Wh_Log(L"SettingsChanged"); - LoadSettings(); } From 063e7484ab32f7b9ad0bd8546b2cbe9b77310361 Mon Sep 17 00:00:00 2001 From: Cynthia Foxwell Date: Thu, 30 Mar 2023 20:41:11 -0600 Subject: [PATCH 4/4] update README --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 8e0362e..4b4010b 100644 --- a/README.md +++ b/README.md @@ -4,12 +4,12 @@ Mods for Windhawk ## Classic Theme Explorer Classic Theme mitigations for Explorer as a Windhawk mod. -Based on [SimpleClassicTheme.FileExplorerHook](https://github.com/AEAEAEAE4343/SimpleClassicTheme.FileExplorerHook) and the AutoHotkey scripts that came before it. +Based on [ExplorerPatcher](https://github.com/valinet/ExplorerPatcher), [SimpleClassicTheme.FileExplorerHook](https://github.com/AEAEAEAE4343/SimpleClassicTheme.FileExplorerHook) and the AutoHotkey scripts that came before it. ## Classic Theme Windows Forces Classic Theme on all Windows -Originally written by WinClassic user Travis. ~~Added DWM disabler from BasicThemer2 for classic titlebars~~ (need to find a better method, I just don't know how) and Classic File Picker. +Originally written by WinClassic user Travis. Added DWM disabler ala BasicThemer2 for classic titlebars and Classic File Picker. ## ~~Classic File Picker~~ ~~Restores pre-Vista file picker. Requires Classic Theme Windows mod or else Windows just upgrades the dialog.~~