From fd4f98e6d8db0d45474b8d566db718e6a6464cf8 Mon Sep 17 00:00:00 2001 From: Cynthia Foxwell Date: Sun, 26 Feb 2023 15:08:55 -0700 Subject: [PATCH] Initial commit 2 --- README.md | 11 +- classic-theme-explorer.wh.cpp | 456 ++++++++++++++++++++++++++++++++++ classic-theme-windows.wh.cpp | 61 +++++ 3 files changed, 527 insertions(+), 1 deletion(-) create mode 100644 classic-theme-explorer.wh.cpp create mode 100644 classic-theme-windows.wh.cpp diff --git a/README.md b/README.md index 175a8eb..94a0bd1 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,12 @@ # WindhawkMods +Mods for Windhawk -Mods for Windhawk \ No newline at end of file +## 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. + +## Classic Theme Windows +Forces Classic Theme on all Windows + +Written by WinClassic user Travis. Nothing is functionally edited here, just a bunch of sane defaults to make things work properly. \ No newline at end of file diff --git a/classic-theme-explorer.wh.cpp b/classic-theme-explorer.wh.cpp new file mode 100644 index 0000000..b15c9cc --- /dev/null +++ b/classic-theme-explorer.wh.cpp @@ -0,0 +1,456 @@ +// ==WindhawkMod== +// @id classic-theme-explorer +// @name Classic Theme Explorer +// @description Classic Theme mitigations for Explorer as a Windhawk mod +// @version 0.1 +// @author Cynosphere +// @github https://github.com/Cynosphere +// @homepage https://c7.pm/ +// @include explorer.exe +// @compilerOptions -lcomctl32 +// ==/WindhawkMod== + +// ==WindhawkModReadme== +/* +# 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. +*/ +// ==/WindhawkModReadme== + +// ==WindhawkModSettings== +/* +- clientEdge: true + $name: "Client Edge" + $description: "Adds Client Edge styling" +- rebarBorder: true + $name: "Bar Borders" + $description: "Adds borders to RebarWindow32 controls" +- rebarFixedHeight: false + $name: "Fixed Bar Height" + $description: "Resizes all toolbars to the tallest bar's height" +- hideNavigation: true + $name: "Hide Navigation" + $description: "Hide default navigation for use with Classic Explorer Bar and Classic Address Bar/Quero" +- addressSync: true + $name: "Classic Address Bar Sync" + $description: "Syncs address bar location on folder change" +- addressSyncFullPath: true + $name: "Address Sync: Use full path" + $description: "Uses full path instead of folder name" +- addressHeight: true + $name: "Classic Address Bar Height" + $description: "Resizes address bar to 22px" +- hideRefresh: true + $name: "Hide Refresh Button" + $description: "Hides the refresh button from Classic Address Bar" +*/ +// ==/WindhawkModSettings== + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct { + bool clientEdge; + bool rebarBorder; + bool rebarFixedHeight; + bool hideNavigation; + bool addressSync; + bool addressSyncFullPath; + bool addressHeight; + bool hideRefresh; +} settings; + +void LoadSettings() { + settings.clientEdge = Wh_GetIntSetting(L"clientEdge"); + settings.rebarBorder = Wh_GetIntSetting(L"rebarBorder"); + settings.rebarFixedHeight = Wh_GetIntSetting(L"rebarFixedHeight"); + settings.hideNavigation = Wh_GetIntSetting(L"hideNavigation"); + settings.addressSync = Wh_GetIntSetting(L"addressSync"); + settings.addressSyncFullPath = Wh_GetIntSetting(L"addressSyncFullPath"); + settings.addressHeight = Wh_GetIntSetting(L"addressHeight"); + settings.hideRefresh = Wh_GetIntSetting(L"hideRefresh"); +} + +// Explorer modifications +typedef struct EnumChildProcData +{ + HWND result; + int index; + int instancesFound; + const wchar_t* className; +}; +BOOL CALLBACK EnumChildProc(_In_ HWND hwnd, _In_ LPARAM lParam) +{ + wchar_t buffer[256]; + EnumChildProcData* data = (EnumChildProcData*)lParam; + GetClassNameW(hwnd, buffer, 256); + if (lstrcmpW(buffer, data->className) == 0) + { + if (data->instancesFound + 1 == data->index) + { + data->result = hwnd; + return FALSE; + } + else + { + data->instancesFound++; + } + } + return TRUE; +}; +HWND GetChildWindow(HWND parent, const wchar_t* className, int index) +{ + EnumChildProcData data = { 0 }; + data.className = className; + data.index = index; + EnumChildWindows(parent, EnumChildProc, (LPARAM)&data); + return data.result; +} + +VOID ClassicThemeExplorer(HWND hWnd, WPARAM wParam) +{ + wchar_t classNameBuffer[256]; + wchar_t pathBuffer[MAX_PATH]; + HKEY key; + RECT rect; + + HWND NavBarParent = GetChildWindow((HWND)hWnd, L"WorkerW", 1); + HWND NavBarAddressBandRoot = GetChildWindow(NavBarParent, L"Address Band Root", 1); + HWND NavBarToolBar = GetChildWindow(NavBarAddressBandRoot, L"ToolbarWindow32", 2); + HWND ClassicAddressBandRoot = GetChildWindow((HWND)hWnd, L"Address Band Root", 2); + HWND ClassicProgressControl = GetChildWindow(ClassicAddressBandRoot, L"msctls_progress32", 1); + HWND ClassicComboBox = GetChildWindow(ClassicAddressBandRoot, L"ComboBoxEx32", 1); + HWND ClassicRebar = GetChildWindow((HWND)hWnd, L"ReBarWindow32", 2); + + if (settings.clientEdge && (wParam == 1 || wParam == 6)) { + HWND TreeView = GetChildWindow((HWND)hWnd, L"SysTreeView32", 1); + LONG TreeViewExtendedStyle = GetWindowLongPtrW(TreeView, GWL_EXSTYLE); + TreeViewExtendedStyle |= WS_EX_CLIENTEDGE; + SetWindowLongPtrW(TreeView, GWL_EXSTYLE, TreeViewExtendedStyle); + + HWND FolderView = GetChildWindow((HWND)hWnd, L"FolderView", 1); + LONG FolderViewExtendedStyle = GetWindowLongPtrW(FolderView, GWL_EXSTYLE); + FolderViewExtendedStyle |= WS_EX_CLIENTEDGE; + SetWindowLongPtrW(FolderView, GWL_EXSTYLE, FolderViewExtendedStyle); + + HWND ShellTabWindowClass = GetChildWindow((HWND)hWnd, L"ShellTabWindowClass", 1); + GetWindowRect(ShellTabWindowClass, &rect); + SetWindowPos(ShellTabWindowClass, NULL, NULL, NULL, rect.right - rect.left + 1, rect.bottom - rect.top, SWP_NOMOVE | SWP_NOZORDER | SWP_DEFERERASE); + SetWindowPos(ShellTabWindowClass, NULL, NULL, NULL, rect.right - rect.left, rect.bottom - rect.top, SWP_NOMOVE | SWP_NOZORDER | SWP_DEFERERASE); + } + + if (settings.rebarBorder && (wParam == 1 || wParam == 6)) { + LONG ClassicRebarStyle = GetWindowLongPtrW(ClassicRebar, GWL_STYLE); + ClassicRebarStyle |= RBS_BANDBORDERS; + ClassicRebarStyle |= WS_BORDER; + SetWindowLongPtrW(ClassicRebar, GWL_STYLE, ClassicRebarStyle); + } + + if (settings.rebarFixedHeight && (wParam == 1 || wParam == 6)) { + LONG ClassicRebarStyle = GetWindowLongPtrW(ClassicRebar, GWL_STYLE); + ClassicRebarStyle &= ~RBS_VARHEIGHT; + SetWindowLongPtrW(ClassicRebar, GWL_STYLE, ClassicRebarStyle); + } + + // Apply bar changes + if ((settings.rebarBorder || settings.rebarFixedHeight) && (wParam == 1 || wParam == 6)) { + GetWindowRect(ClassicRebar, &rect); + SetWindowPos(ClassicRebar, NULL, NULL, NULL, rect.right - rect.left + 1, rect.bottom - rect.top, SWP_NOMOVE | SWP_NOZORDER | SWP_DEFERERASE); + SetWindowPos(ClassicRebar, NULL, NULL, NULL, rect.right - rect.left, rect.bottom - rect.top, SWP_NOMOVE | SWP_NOZORDER | SWP_DEFERERASE); + } + + if (settings.hideNavigation && wParam == 1) { + // Save the location of the Rebar + HWND NavBarRebar = GetChildWindow((HWND)hWnd, L"ReBarWindow32", 1); + GetWindowRect(NavBarRebar, &rect); + LONG xRebar = rect.left; + LONG yRebar = rect.top; + LONG cxRebar = rect.right - rect.left; + LONG cyRebar = rect.bottom - rect.top; + + // Destroy the NC area of the rebar + SendMessageW(NavBarRebar, WM_NCDESTROY, 0, 0); + + // Hide the WorkerW and the Rebar + ShowWindow(NavBarParent, SW_HIDE); + ShowWindow(NavBarRebar, SW_HIDE); + + // Save the location of the ShellTabWindowClass + HWND ShellTabWnd = GetChildWindow((HWND)hWnd, L"ShellTabWindowClass", 1); + GetWindowRect(NavBarRebar, &rect); + LONG xTabWnd = rect.left; + LONG yTabWnd = rect.top; + LONG cxTabWnd = rect.right - rect.left; + LONG cyTabWnd = rect.bottom - rect.top; + + // Move ShellTabWindow to (*; yRebar; *; yTabWnd - yRebar + cyTabWnd) + SetWindowPos(ShellTabWnd, NULL, xTabWnd, yRebar, cxTabWnd, yTabWnd - yRebar + cyTabWnd, SWP_NOZORDER); + + // Move Rebar to (*; *; *; 0) + SetWindowPos(NavBarRebar, NULL, xRebar, yRebar, cxRebar, 0, SWP_NOZORDER); + + // Resize the window to apply + GetWindowRect((HWND)hWnd, &rect); + SetWindowPos((HWND)hWnd, NULL, NULL, NULL, rect.right - rect.left, rect.bottom - rect.top + 1, SWP_NOMOVE | SWP_NOZORDER | SWP_DEFERERASE); + SetWindowPos((HWND)hWnd, NULL, NULL, NULL, rect.right - rect.left, rect.bottom - rect.top, SWP_NOMOVE | SWP_NOZORDER | SWP_DEFERERASE); + + // Redraw the entire explorer window + RedrawWindow((HWND)hWnd, NULL, NULL, RDW_INVALIDATE | RDW_ERASE | RDW_ERASENOW | RDW_UPDATENOW | RDW_ALLCHILDREN); + } + + if (settings.addressSync) { + if (settings.addressSyncFullPath) { + HWND toolbarwindow = GetChildWindow(NavBarAddressBandRoot, L"ToolbarWindow32", 1); + GetWindowTextW(toolbarwindow, pathBuffer, MAX_PATH); + + // remove "Address: " + // FIXME: locale issues, codecvt deprecated as of c++17 + std::wstring_convert> converter; + + std::wstring _pathStr = pathBuffer; + std::string pathStr(_pathStr.begin(), _pathStr.end()); + pathStr = std::regex_replace(pathStr, std::regex("Address: "), ""); + _pathStr = converter.from_bytes(pathStr); + wcscpy(pathBuffer, _pathStr.c_str()); + } else { + HWND shelltabwindow = GetChildWindow((HWND)hWnd, L"ShellTabWindowClass", 1); + GetWindowTextW(shelltabwindow, pathBuffer, MAX_PATH); + } + + HWND AddressBarEdit = GetChildWindow(ClassicAddressBandRoot, L"Edit", 1); + for (int i = 0; i < 3; i++) + SendMessageW(AddressBarEdit, WM_SETTEXT, 0, (LPARAM)pathBuffer); + + // TODO: figure out how to get and set folder icon + } + + if (settings.hideRefresh && (wParam == 1 || wParam == 6)) { + HWND GoButtonToolbar = GetChildWindow(ClassicAddressBandRoot, L"ToolbarWindow32", 1); + SendMessageW(GoButtonToolbar, WM_CLOSE, 0, 0); + } + + if (settings.addressHeight) { + // Allocate memory inside Explorer + DWORD count = SendMessage(GetParent(ClassicAddressBandRoot), RB_GETBANDCOUNT, 0, 0); + SIZE_T bytesRead = 0; + DWORD ExplorerPID = 0; + GetWindowThreadProcessId(ClassicAddressBandRoot, &ExplorerPID); + HANDLE ExplorerProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, ExplorerPID); + void* ExplorerMemoryRebar = VirtualAllocEx(ExplorerProcess, NULL, sizeof(REBARBANDINFO), MEM_COMMIT, PAGE_READWRITE); + void* ExplorerMemoryComboBoxItem = VirtualAllocEx(ExplorerProcess, NULL, sizeof(COMBOBOXEXITEM), MEM_COMMIT, PAGE_READWRITE); + void* ExplorerMemoryToolbarButton = VirtualAllocEx(ExplorerProcess, NULL, sizeof(TBBUTTON), MEM_COMMIT, PAGE_READWRITE); + + // Make the band that's 39 pixels high, 22 pixels high + // MOD: Except this bar isn't always 39 pixels, so lets check between 39-23px instead + REBARBANDINFO bandInfo = { 0 }; + for (int i = 0; i < count; i++) + { + bandInfo = { 0 }; + bandInfo.cbSize = sizeof(REBARBANDINFO); + bandInfo.fMask = RBBIM_CHILDSIZE; + WriteProcessMemory(ExplorerProcess, ExplorerMemoryRebar, &bandInfo, sizeof(REBARBANDINFO), &bytesRead); + SendMessageW(GetParent(ClassicAddressBandRoot), RB_GETBANDINFO, i, (LPARAM)ExplorerMemoryRebar); + ReadProcessMemory(ExplorerProcess, ExplorerMemoryRebar, &bandInfo, sizeof(REBARBANDINFO), &bytesRead); + if (bandInfo.cyMinChild <= 39 && bandInfo.cyMinChild > 22) { + bandInfo.cyMinChild = 22; + WriteProcessMemory(ExplorerProcess, ExplorerMemoryRebar, &bandInfo, sizeof(REBARBANDINFO), &bytesRead); + SendMessageW(GetParent(ClassicAddressBandRoot), RB_SETBANDINFO, i, (LPARAM)ExplorerMemoryRebar); + } + } + + // Free Explorer Memory + VirtualFreeEx(ExplorerProcess, ExplorerMemoryRebar, sizeof(REBARBANDINFO), MEM_DECOMMIT); + VirtualFreeEx(ExplorerProcess, ExplorerMemoryToolbarButton, sizeof(REBARBANDINFO), MEM_DECOMMIT); + CloseHandle(ExplorerProcess); + + // Set ComboBox height + SendMessageW(ClassicComboBox, CB_SETITEMHEIGHT, -1, 22 - 6); + SetParent(ClassicComboBox, ClassicAddressBandRoot); + + // Remove ProgressBsr + SendMessageW(ClassicProgressControl, WM_CLOSE, 0, 0); + + // Fix ComboBox + GetWindowRect(ClassicComboBox, &rect); + SetWindowPos(ClassicComboBox, NULL, NULL, NULL, rect.right - rect.left + 1, rect.bottom - rect.top, SWP_NOMOVE | SWP_NOZORDER | SWP_DEFERERASE); + SetWindowPos(ClassicComboBox, NULL, NULL, NULL, rect.right - rect.left, rect.bottom - rect.top, SWP_NOMOVE | SWP_NOZORDER | SWP_DEFERERASE); + + // Redraw the ComboBox + RedrawWindow(ClassicComboBox, NULL, NULL, RDW_INVALIDATE | RDW_ERASE | RDW_ERASENOW | RDW_UPDATENOW | RDW_ALLCHILDREN); + } +} + +// boilerplate from hide-search-bar +#if defined(__GNUC__) && __GNUC__ > 8 +#define WINAPI_LAMBDA_RETURN(return_t) -> return_t WINAPI +#elif defined(__GNUC__) +#define WINAPI_LAMBDA_RETURN(return_t) WINAPI -> return_t +#else +#define WINAPI_LAMBDA_RETURN(return_t) -> return_t +#endif + +DWORD g_uiThreadId; + +inline LSTATUS SHRegGetValueFromHKCUHKLMWithOpt(PCWSTR pwszKey, PCWSTR pwszValue, REGSAM samDesired, void* pvData, DWORD* pcbData) +{ + LSTATUS lRes = ERROR_FILE_NOT_FOUND; + HKEY hKey = NULL; + + RegOpenKeyExW(HKEY_CURRENT_USER, pwszKey, 0, samDesired, &hKey); + if (hKey == NULL || hKey == INVALID_HANDLE_VALUE) hKey = NULL; + if (hKey) + { + lRes = RegQueryValueExW(hKey, pwszValue, 0, NULL, (LPBYTE) pvData, (LPDWORD) pcbData); + + RegCloseKey(hKey); + if (lRes == ERROR_SUCCESS || lRes == ERROR_MORE_DATA) return lRes; + } + + RegOpenKeyExW(HKEY_LOCAL_MACHINE, pwszKey, 0, samDesired, &hKey); + if (hKey == NULL || hKey == INVALID_HANDLE_VALUE) hKey = NULL; + + if (hKey) + { + lRes = RegQueryValueExW(hKey, pwszValue, 0, NULL, (LPBYTE) pvData, (LPDWORD) pcbData); + RegCloseKey(hKey); + + if (lRes == ERROR_SUCCESS || lRes == ERROR_MORE_DATA) return lRes; + } + + return lRes; +} + +UINT g_subclassRegisteredMsg = RegisterWindowMessage(L"Windhawk_SetWindowSubclassFromAnyThread_classic-theme-explorer"); + +LRESULT CALLBACK ClassicThemeExplorerSubClass(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData) { + if (uMsg == WM_DESTROY) { + Wh_Log("[Destroy] uMsg: 0x%04x, wParam: 0x%x", uMsg, wParam); + RemoveWindowSubclass(hWnd, ClassicThemeExplorerSubClass, 0); + } else if (uMsg == g_subclassRegisteredMsg && !wParam) { + Wh_Log("[Unsub] uMsg: 0x%04x, wParam: 0x%x", uMsg, wParam); + RemoveWindowSubclass(hWnd, ClassicThemeExplorerSubClass, 0); + } else if (uMsg == WM_PARENTNOTIFY || uMsg == WM_SIZE || uMsg == WM_GETICON) { + Wh_Log("[Target] uMsg: 0x%04x, wParam: 0x%x", uMsg, wParam); + ClassicThemeExplorer(hWnd, wParam); + } else { + Wh_Log("[Unknown] uMsg: 0x%04x, wParam: 0x%x", uMsg, wParam); + } + + return DefSubclassProc(hWnd, uMsg, wParam, lParam); +} + +struct SET_WINDOW_SUBCLASS_FROM_ANY_THREAD_PARAM { + SUBCLASSPROC pfnSubclass; + UINT_PTR uIdSubclass; + DWORD_PTR dwRefData; + BOOL result; +}; + +LRESULT CALLBACK CallWndProcForWindowSubclass(int nCode, WPARAM wParam, LPARAM lParam) { + if (nCode == HC_ACTION) { + const CWPSTRUCT* cwp = (const CWPSTRUCT*)lParam; + if (cwp->message == g_subclassRegisteredMsg && cwp->wParam) { + SET_WINDOW_SUBCLASS_FROM_ANY_THREAD_PARAM* param = (SET_WINDOW_SUBCLASS_FROM_ANY_THREAD_PARAM*)cwp->lParam; + param->result = SetWindowSubclass(cwp->hwnd, param->pfnSubclass, param->uIdSubclass, param->dwRefData); + } + } + + return CallNextHookEx(nullptr, nCode, wParam, lParam); +} + +BOOL SetWindowSubclassFromAnyThread(HWND hWnd, SUBCLASSPROC pfnSubclass, UINT_PTR uIdSubclass, DWORD_PTR dwRefData) { + DWORD dwThreadId = GetWindowThreadProcessId(hWnd, nullptr); + + if (dwThreadId == 0) return FALSE; + if (dwThreadId == GetCurrentThreadId()) return SetWindowSubclass(hWnd, pfnSubclass, uIdSubclass, dwRefData); + + HHOOK hook = SetWindowsHookEx(WH_CALLWNDPROC, CallWndProcForWindowSubclass, nullptr, dwThreadId); + + if (!hook) return FALSE; + + SET_WINDOW_SUBCLASS_FROM_ANY_THREAD_PARAM param; + param.pfnSubclass = pfnSubclass; + param.uIdSubclass = uIdSubclass; + param.dwRefData = dwRefData; + param.result = FALSE; + + SendMessage(hWnd, g_subclassRegisteredMsg, TRUE, (WPARAM)¶m); + + UnhookWindowsHookEx(hook); + + return param.result; +} + +BOOL CALLBACK EnumBrowserWindowsUnsubclassFunc(HWND hWnd, LPARAM lParam) { + SendMessage(hWnd, g_subclassRegisteredMsg, FALSE, 0); + + return TRUE; +} + + +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; + LSTATUS lRes = ERROR_FILE_NOT_FOUND; + DWORD dwSize = 0; + + //Wh_Log("g_uiThreadId: %d, GetCurrentThreadId: %d", g_uiThreadId, GetCurrentThreadId()); + + // is this even needed? it changes thread after some time anyways + //if (g_uiThreadId && g_uiThreadId != GetCurrentThreadId()) return pOriginalSHCreateWorkerWindow(wndProc, hWndParent, dwExStyle, dwStyle, hMenu, wnd_extra); + /*if (!g_uiThreadId)*/ g_uiThreadId = GetCurrentThreadId(); + + + if (SHRegGetValueFromHKCUHKLMWithOpt( + TEXT("SOFTWARE\\Classes\\CLSID\\{056440FD-8568-48e7-A632-72157243B55B}\\InProcServer32"), + TEXT(""), + KEY_READ | KEY_WOW64_64KEY, + NULL, + (LPDWORD)(&dwSize) + ) == ERROR_SUCCESS && (dwSize < 4) && dwExStyle == 0x10000 && dwStyle == 1174405120) result = 0; + + else result = pOriginalSHCreateWorkerWindow(wndProc, hWndParent, dwExStyle, dwStyle, hMenu, wnd_extra); + + //Wh_Log("dwExStyle: 0x%x, dwStyle: 0x%x, result: 0x%x", dwExStyle, dwStyle, result); + + if (dwExStyle == 0x10000 && dwStyle == 0x46000000 && result) SetWindowSubclassFromAnyThread(hWndParent, ClassicThemeExplorerSubClass, 0, 0); + + return result; +} + +// 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); + + 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(); +} diff --git a/classic-theme-windows.wh.cpp b/classic-theme-windows.wh.cpp new file mode 100644 index 0000000..74ee2cc --- /dev/null +++ b/classic-theme-windows.wh.cpp @@ -0,0 +1,61 @@ +// ==WindhawkMod== +// @id classic-theme-windows +// @name Classic Theme Windows +// @description Forces Classic Theme on all Windows +// @version 0.1 +// @author Travis +// @include * +// @exclude wininit.exe +// @exclude winlogon.exe +// @exclude taskmgr.exe +// @exclude dwm.exe +// @exclude thunderbird.exe +// @exclude dwm.exe +// @exclude C:\Windows\System32\*.scr +// @exclude svchost.exe +// @exclude taskhostw.exe +// @exclude dllhost.exe +// @exclude conhost.exe +// @exclude sihost.exe +// @exclude lsass.exe +// @exclude C:\Program Files (x86)\Steam\* +// @exclude Code.exe +// @exclude Code - Insiders.exe +// @exclude msedge.exe +// @exclude iexplorer.exe +// @exclude vmware.exe +// @exclude vmware-vmx.exe +// @exclude rundll32.exe +// @exclude Spotify.exe +// @exclude smartscreen.exe +// @exclude RuntimeBroker.exe +// @exclude ApplicationFrameHost.exe +// @exclude SystemSettings.exe +// @exclude SecHealthUI.exe +// @exclude SecurityHealthHost.exe +// @exclude PhoneExperienceHost.exe +// @exclude SecurityHealthTray.exe +// @exclude Window Detective.exe +// @exclude Discord.exe +// @exclude DiscordPTB.exe +// @exclude DiscordCanary.exe +// @exclude DiscordDevelopment.exe +// @compilerOptions -luxtheme +// ==/WindhawkMod== + +// ==WindhawkModReadme== +/* +# Classic Theme Windows +Forces Classic Theme on all Windows +*/ +// ==/WindhawkModReadme== + +#include +#include + +BOOL Wh_ModInit() { + Wh_Log(L"Init"); + + SetThemeAppProperties(0); + return TRUE; +} \ No newline at end of file