|
Post by anixx on Oct 2, 2023 3:13:05 GMT -8
Here is the full version of the mod. I removed the parts that were intended to remove the progress indicator, because they are not necessary, it is not displayed ayway. The spacing is now correct and applied only if the taskbar is horizontal.
// ==WindhawkMod== // @id classic-taskbar-fix // @name Classic Taskbar Fix // @description Fixes the taskbar items in classic theme // @version 1.1.1 // @author aubymori // @github https://github.com/aubymori // @include explorer.exe // @architecture x86-64 // @compilerOptions -lgdi32 // ==/WindhawkMod==
// ==WindhawkModReadme== /* # Classic Taskbar Fix Fixes the taskbar items in classic theme! */ // ==/WindhawkModReadme==
// ==WindhawkModSettings== /* - xp: false $name: Windows XP style $description: Windows XP handled active taskbar items a bit differently than 2000. Enable this if you want the XP style. */ // ==/WindhawkModSettings==
#include <windhawk_utils.h>
struct { BOOL xp; } settings;
typedef struct tagBUTTONRENDERINFOSTATES { char data[12]; } BUTTONRENDERINFOSTATES, *PBUTTONRENDERINFOSTATES;
/* Remove clock hover effect */ typedef void (* GDIHelpers_FillRectARGB_t)(HDC, LPCRECT, BYTE, DWORD, bool); GDIHelpers_FillRectARGB_t GDIHelpers_FillRectARGB_orig; void __cdecl GDIHelpers_FillRectARGB_hook( HDC hDC, LPCRECT lprc, BYTE btUnknown, DWORD dwUnknown, bool bUnknown ) { return; }
/* Draw taskbar item */ typedef void (* CTaskBtnGroup__DrawBar_t)(void *, HDC, void *, void *); CTaskBtnGroup__DrawBar_t CTaskBtnGroup__DrawBar_orig; void __cdecl CTaskBtnGroup__DrawBar_hook( void *pThis, HDC hDC, void *pRenderInfo, PBUTTONRENDERINFOSTATES pRenderStates ) { LPRECT lprcDest = (LPRECT)((char *)pRenderInfo + 4);
UINT uState = DFCS_BUTTONPUSH; if (pRenderStates->data[2]) { uState |= DFCS_CHECKED; } else if (pRenderStates->data[4]) { uState |= DFCS_PUSHED; }
DrawFrameControl( hDC, lprcDest, DFC_BUTTON, uState );
/* If button is pushed in, offset the rect for the icon and text draw */ if (pRenderStates->data[2] || pRenderStates->data[4]) { lprcDest->top++; lprcDest->bottom++; if (settings.xp) { lprcDest->left++; lprcDest->right++; } }
return; }
/* Add spacing between taskbar items */ typedef long (* CTaskBtnGroup_SetLocation_t)(void *, int, int, LPRECT); CTaskBtnGroup_SetLocation_t CTaskBtnGroup_SetLocation_orig; long __cdecl CTaskBtnGroup_SetLocation_hook( void *pThis, int i1, int i2, LPRECT lprc ) { RECT rect; HWND taskBar = FindWindow(L"Shell_traywnd", NULL); if(taskBar && GetWindowRect(taskBar, &rect)) { if ((rect.right - rect.left)>(rect.bottom - rect.top)){ lprc->right--; } } return CTaskBtnGroup_SetLocation_orig(pThis, i1, i2, lprc); }
void LoadSettings(void) { settings.xp = Wh_GetIntSetting(L"xp"); }
BOOL Wh_ModInit(void) { HMODULE hExplorer = GetModuleHandleW(NULL); LoadSettings();
WindhawkUtils::SYMBOL_HOOK hooks[] = { { { L"void __cdecl GDIHelpers::FillRectARGB(struct HDC__ *,struct tagRECT const *,unsigned char,unsigned long,bool)" }, (void **)&GDIHelpers_FillRectARGB_orig, (void *)GDIHelpers_FillRectARGB_hook, FALSE }, { { L"private: void __cdecl CTaskBtnGroup::_DrawBar(struct HDC__ *,struct BUTTONRENDERINFO const &,struct BUTTONRENDERINFOSTATES const &)" }, (void **)&CTaskBtnGroup__DrawBar_orig, (void *)CTaskBtnGroup__DrawBar_hook, FALSE },
{ { L"public: virtual long __cdecl CTaskBtnGroup::SetLocation(int,int,struct tagRECT const *)" }, (void **)&CTaskBtnGroup_SetLocation_orig, (void*)CTaskBtnGroup_SetLocation_hook, FALSE } };
if (!WindhawkUtils::HookSymbols(hExplorer, hooks, ARRAYSIZE(hooks))) { Wh_Log(L"Failed to hook one or more functions"); return FALSE; }
return TRUE; }
void Wh_ModSettingsChanged(void) { LoadSettings(); }
|
|
|
Post by anixx on Oct 2, 2023 3:17:40 GMT -8
Possibly, searching taskbar window on any button redraw is suboptimal though.
|
|
|
Post by anixx on Oct 2, 2023 3:47:14 GMT -8
There is also an issue with pinned items not always showing the icon.
|
|
craft
Sophomore Member
UWP stands for unwanted pile of trash
Posts: 167
OS: Windows 11 & Windows 10 LTSC 2021
Theme: Classic Theme on Windows 10 LTSC host and micaforeveryone with a custom theme on 11 host
CPU: AMD Ryzen 5 3500U with 4 Cores
RAM: 8GB of DDR4 ram
GPU: AMD Raedon Vega 8 Graphics
|
Post by craft on Oct 2, 2023 6:23:46 GMT -8
Here is the full version of the mod. I removed the parts that were intended to remove the progress indicator, because they are not necessary, it is not displayed ayway. The spacing is now correct and applied only if the taskbar is horizontal.
// ==WindhawkMod== // @id classic-taskbar-fix // @name Classic Taskbar Fix // @description Fixes the taskbar items in classic theme // @version 1.1.1 // @author aubymori // @github https://github.com/aubymori // @include explorer.exe // @architecture x86-64 // @compilerOptions -lgdi32 // ==/WindhawkMod==
// ==WindhawkModReadme== /* # Classic Taskbar Fix Fixes the taskbar items in classic theme! */ // ==/WindhawkModReadme==
// ==WindhawkModSettings== /* - xp: false $name: Windows XP style $description: Windows XP handled active taskbar items a bit differently than 2000. Enable this if you want the XP style. */ // ==/WindhawkModSettings==
#include <windhawk_utils.h>
struct { BOOL xp; } settings;
typedef struct tagBUTTONRENDERINFOSTATES { char data[12]; } BUTTONRENDERINFOSTATES, *PBUTTONRENDERINFOSTATES;
/* Remove clock hover effect */ typedef void (* GDIHelpers_FillRectARGB_t)(HDC, LPCRECT, BYTE, DWORD, bool); GDIHelpers_FillRectARGB_t GDIHelpers_FillRectARGB_orig; void __cdecl GDIHelpers_FillRectARGB_hook( HDC hDC, LPCRECT lprc, BYTE btUnknown, DWORD dwUnknown, bool bUnknown ) { return; }
/* Draw taskbar item */ typedef void (* CTaskBtnGroup__DrawBar_t)(void *, HDC, void *, void *); CTaskBtnGroup__DrawBar_t CTaskBtnGroup__DrawBar_orig; void __cdecl CTaskBtnGroup__DrawBar_hook( void *pThis, HDC hDC, void *pRenderInfo, PBUTTONRENDERINFOSTATES pRenderStates ) { LPRECT lprcDest = (LPRECT)((char *)pRenderInfo + 4);
UINT uState = DFCS_BUTTONPUSH; if (pRenderStates->data[2]) { uState |= DFCS_CHECKED; } else if (pRenderStates->data[4]) { uState |= DFCS_PUSHED; }
DrawFrameControl( hDC, lprcDest, DFC_BUTTON, uState );
/* If button is pushed in, offset the rect for the icon and text draw */ if (pRenderStates->data[2] || pRenderStates->data[4]) { lprcDest->top++; lprcDest->bottom++; if (settings.xp) { lprcDest->left++; lprcDest->right++; } }
return; }
/* Add spacing between taskbar items */ typedef long (* CTaskBtnGroup_SetLocation_t)(void *, int, int, LPRECT); CTaskBtnGroup_SetLocation_t CTaskBtnGroup_SetLocation_orig; long __cdecl CTaskBtnGroup_SetLocation_hook( void *pThis, int i1, int i2, LPRECT lprc ) { RECT rect; HWND taskBar = FindWindow(L"Shell_traywnd", NULL); if(taskBar && GetWindowRect(taskBar, &rect)) { if ((rect.right - rect.left)>(rect.bottom - rect.top)){ lprc->right--; } } return CTaskBtnGroup_SetLocation_orig(pThis, i1, i2, lprc); }
void LoadSettings(void) { settings.xp = Wh_GetIntSetting(L"xp"); }
BOOL Wh_ModInit(void) { HMODULE hExplorer = GetModuleHandleW(NULL); LoadSettings();
WindhawkUtils::SYMBOL_HOOK hooks[] = { { { L"void __cdecl GDIHelpers::FillRectARGB(struct HDC__ *,struct tagRECT const *,unsigned char,unsigned long,bool)" }, (void **)&GDIHelpers_FillRectARGB_orig, (void *)GDIHelpers_FillRectARGB_hook, FALSE }, { { L"private: void __cdecl CTaskBtnGroup::_DrawBar(struct HDC__ *,struct BUTTONRENDERINFO const &,struct BUTTONRENDERINFOSTATES const &)" }, (void **)&CTaskBtnGroup__DrawBar_orig, (void *)CTaskBtnGroup__DrawBar_hook, FALSE },
{ { L"public: virtual long __cdecl CTaskBtnGroup::SetLocation(int,int,struct tagRECT const *)" }, (void **)&CTaskBtnGroup_SetLocation_orig, (void*)CTaskBtnGroup_SetLocation_hook, FALSE } };
if (!WindhawkUtils::HookSymbols(hExplorer, hooks, ARRAYSIZE(hooks))) { Wh_Log(L"Failed to hook one or more functions"); return FALSE; }
return TRUE; }
void Wh_ModSettingsChanged(void) { LoadSettings(); }
this updated version of the mod works really nice anixx! but they were a few problems i noticed which i wanted to point out the first problem is the labels disappearing problem: In Windows 2000 when the taskbar kept getting full the labels did not disappear instead they kept shrinking but this mod causes the icon to become more spaced out until the only thing left is the icon itself 2k: cdn.discordapp.com/attachments/817412953895731223/1158407598488420423/image.png?ex=651c22a5&is=651ad125&hm=63d4f7efaf328eaa37e792701f7e24487f5f10eb8004446bc4069ae11bec0934&10: cdn.discordapp.com/attachments/817412953895731223/1158407537985605633/image.png?ex=651c2297&is=651ad117&hm=906a79db0ed4395f667fdd6d6e500f141c0b943785d0983284f993b1771b8fb8&Second problem is the spacing problem: While anixx's code did fix it a bit the spacing is still a bit off and also breaks a bit after the 4th program appears in the taskbar windows 10 screenshot showing the spacing being cut off at 4th program: cdn.discordapp.com/attachments/817412953895731223/1158407874159067266/image.png?ex=651c22e7&is=651ad167&hm=e7df4c574eba37f927e310a8e75b7eaf765396b5c024c912ebad66e71ea78952&Windows 2000 screenshot to show the accurate spacing: cdn.discordapp.com/attachments/817412953895731223/1158407825438027868/image.png?ex=651c22db&is=651ad15b&hm=af91b43e2b07d78a3ca5fdf73681190c5046807e4bb69548f2f92d05fd97bbd7&Overall this mod is amazing and i really thank aubrey for making this it finally makes us free from taskbow which was very buggy in my opinion
|
|
|
Post by anixx on Oct 2, 2023 6:30:50 GMT -8
> While anixx's code did fix it a bit the spacing is still a bit off and also breaks a bit after the 4th program appears in the taskbar
This is not spacing issue, it is groupping issue. Disable taskbar groupping in 7+TT or elsewhere. You have buttons of the same app (Notepad) groupped.
|
|
|
Post by anixx on Oct 2, 2023 6:34:24 GMT -8
> In Windows 2000 when the taskbar kept getting full the labels did not disappear instead they kept shrinking but this mod causes the icon to become more spaced out until the only thing left is the icon itself
The mod has nothing to do with it. It is Explorer Patcher behavior, discussed a lot. It gradually moves the icon to the middle of button as the taskbar becomes overcrowded. It happens the same with flat buttons.
|
|
craft
Sophomore Member
UWP stands for unwanted pile of trash
Posts: 167
OS: Windows 11 & Windows 10 LTSC 2021
Theme: Classic Theme on Windows 10 LTSC host and micaforeveryone with a custom theme on 11 host
CPU: AMD Ryzen 5 3500U with 4 Cores
RAM: 8GB of DDR4 ram
GPU: AMD Raedon Vega 8 Graphics
|
Post by craft on Oct 2, 2023 6:36:33 GMT -8
> In Windows 2000 when the taskbar kept getting full the labels did not disappear instead they kept shrinking but this mod causes the icon to become more spaced out until the only thing left is the icon itself The mod has nothing to do with it. It is Explorer Patcher behavior, discussed a lot. It gradually moves the icon to the middle of button as the taskbar becomes overcrowded. It happens the same with flat buttons. Ah sorry my mistake thanks by the way.
|
|
craft
Sophomore Member
UWP stands for unwanted pile of trash
Posts: 167
OS: Windows 11 & Windows 10 LTSC 2021
Theme: Classic Theme on Windows 10 LTSC host and micaforeveryone with a custom theme on 11 host
CPU: AMD Ryzen 5 3500U with 4 Cores
RAM: 8GB of DDR4 ram
GPU: AMD Raedon Vega 8 Graphics
|
Post by craft on Oct 2, 2023 6:53:23 GMT -8
There is already a Windhawk mod doubling the functionality of EP classic theme mitigations. You can comment out the parts you dislike. Precisely, this Windhawks mode still contains this issue, present in the original code : github.com/valinet/ExplorerPatcher/discussions/900It's really annoying if you want to use the classic theme with a Windows 7 style taskbar, without the labels. I tried to modify the mod to correct this problem, and I discovered the responsible section. So, I separated the code into two parts. On the other hand, not activating the part responsible for the bug makes the taskbar less wide, which poses a problem with the board if 16x16 icons are used. Moreover, if this part is not activated you must activate BasicThemer in the background to have a correct result. I advise to activate BasicThemer5, because it is the lightest. View AttachmentThis is not a fix, as there are still display issues, but I imagine it is technically possible to fix this. i tried to compile your mod in windhawk but its keep failing on parsing on some settings yaml.
|
|
aubymori
Sophomore Member
👅👅👅👅👅
Posts: 160
OS: Windows 10 IoT Enterprise LTSC 2021
Theme: Windows 10 Default
CPU: Intel Core i5-9300H
RAM: 8GB
GPU: Intel UHD Graphics 630 / NVIDIA GeForce GTX 1650
|
Post by aubymori on Oct 4, 2023 14:21:27 GMT -8
Here is the full version of the mod. I removed the parts that were intended to remove the progress indicator, because they are not necessary, it is not displayed ayway. The spacing is now correct and applied only if the taskbar is horizontal.
// ==WindhawkMod== // @id classic-taskbar-fix // @name Classic Taskbar Fix // @description Fixes the taskbar items in classic theme // @version 1.1.1 // @author aubymori // @github https://github.com/aubymori // @include explorer.exe // @architecture x86-64 // @compilerOptions -lgdi32 // ==/WindhawkMod==
// ==WindhawkModReadme== /* # Classic Taskbar Fix Fixes the taskbar items in classic theme! */ // ==/WindhawkModReadme==
// ==WindhawkModSettings== /* - xp: false $name: Windows XP style $description: Windows XP handled active taskbar items a bit differently than 2000. Enable this if you want the XP style. */ // ==/WindhawkModSettings==
#include <windhawk_utils.h>
struct { BOOL xp; } settings;
typedef struct tagBUTTONRENDERINFOSTATES { char data[12]; } BUTTONRENDERINFOSTATES, *PBUTTONRENDERINFOSTATES;
/* Remove clock hover effect */ typedef void (* GDIHelpers_FillRectARGB_t)(HDC, LPCRECT, BYTE, DWORD, bool); GDIHelpers_FillRectARGB_t GDIHelpers_FillRectARGB_orig; void __cdecl GDIHelpers_FillRectARGB_hook( HDC hDC, LPCRECT lprc, BYTE btUnknown, DWORD dwUnknown, bool bUnknown ) { return; }
/* Draw taskbar item */ typedef void (* CTaskBtnGroup__DrawBar_t)(void *, HDC, void *, void *); CTaskBtnGroup__DrawBar_t CTaskBtnGroup__DrawBar_orig; void __cdecl CTaskBtnGroup__DrawBar_hook( void *pThis, HDC hDC, void *pRenderInfo, PBUTTONRENDERINFOSTATES pRenderStates ) { LPRECT lprcDest = (LPRECT)((char *)pRenderInfo + 4);
UINT uState = DFCS_BUTTONPUSH; if (pRenderStates->data[2]) { uState |= DFCS_CHECKED; } else if (pRenderStates->data[4]) { uState |= DFCS_PUSHED; }
DrawFrameControl( hDC, lprcDest, DFC_BUTTON, uState );
/* If button is pushed in, offset the rect for the icon and text draw */ if (pRenderStates->data[2] || pRenderStates->data[4]) { lprcDest->top++; lprcDest->bottom++; if (settings.xp) { lprcDest->left++; lprcDest->right++; } }
return; }
/* Add spacing between taskbar items */ typedef long (* CTaskBtnGroup_SetLocation_t)(void *, int, int, LPRECT); CTaskBtnGroup_SetLocation_t CTaskBtnGroup_SetLocation_orig; long __cdecl CTaskBtnGroup_SetLocation_hook( void *pThis, int i1, int i2, LPRECT lprc ) { RECT rect; HWND taskBar = FindWindow(L"Shell_traywnd", NULL); if(taskBar && GetWindowRect(taskBar, &rect)) { if ((rect.right - rect.left)>(rect.bottom - rect.top)){ lprc->right--; } } return CTaskBtnGroup_SetLocation_orig(pThis, i1, i2, lprc); }
void LoadSettings(void) { settings.xp = Wh_GetIntSetting(L"xp"); }
BOOL Wh_ModInit(void) { HMODULE hExplorer = GetModuleHandleW(NULL); LoadSettings();
WindhawkUtils::SYMBOL_HOOK hooks[] = { { { L"void __cdecl GDIHelpers::FillRectARGB(struct HDC__ *,struct tagRECT const *,unsigned char,unsigned long,bool)" }, (void **)&GDIHelpers_FillRectARGB_orig, (void *)GDIHelpers_FillRectARGB_hook, FALSE }, { { L"private: void __cdecl CTaskBtnGroup::_DrawBar(struct HDC__ *,struct BUTTONRENDERINFO const &,struct BUTTONRENDERINFOSTATES const &)" }, (void **)&CTaskBtnGroup__DrawBar_orig, (void *)CTaskBtnGroup__DrawBar_hook, FALSE },
{ { L"public: virtual long __cdecl CTaskBtnGroup::SetLocation(int,int,struct tagRECT const *)" }, (void **)&CTaskBtnGroup_SetLocation_orig, (void*)CTaskBtnGroup_SetLocation_hook, FALSE } };
if (!WindhawkUtils::HookSymbols(hExplorer, hooks, ARRAYSIZE(hooks))) { Wh_Log(L"Failed to hook one or more functions"); return FALSE; }
return TRUE; }
void Wh_ModSettingsChanged(void) { LoadSettings(); }
Thanks for the fix. I've integrated your fix (in a better way) into the main codebase with 1.1.1 (now in the OP).
|
|
|
Post by anixx on Oct 4, 2023 16:46:23 GMT -8
Oh I was wrong about the spacing in classic Windows.
|
|
|
Post by anixx on Oct 4, 2023 16:48:52 GMT -8
Your approach hangs Explorer upon mod restart... I think, there should be easier way to get the handle to taskbar, without initialization hook or taskbar window search.
Or directly get some property about whether it is vertical or horizontal.
|
|
|
Post by anixx on Oct 4, 2023 17:43:24 GMT -8
Here is the better code for retrieving taskbar position. It does not require hooks:
APPBARDATA ab; ab.cbSize=sizeof(APPBARDATA); if(SHAppBarMessage(ABM_GETTASKBARPOS, &ab)) { if ((ab.uEdge==ABE_BOTTOM)||(ab.uEdge==ABE_TOP)){ lprc->right-=2; } }
Full mod code:
// ==WindhawkMod== // @id classic-taskbar-fix-lite // @name Classic Taskbar Fix Lite // @description Fixes the taskbar items in classic theme in a lite way // @version 1.1.1 // @author aubymori, Anixx // @github https://github.com/aubymori // @include explorer.exe // @architecture x86-64 // @compilerOptions -lgdi32 // ==/WindhawkMod==
// ==WindhawkModReadme== /* # Classic Taskbar Fix Fixes the taskbar items in classic theme! */ // ==/WindhawkModReadme==
#include <windhawk_utils.h>
typedef struct tagBUTTONRENDERINFOSTATES { char data[12]; } BUTTONRENDERINFOSTATES, *PBUTTONRENDERINFOSTATES;
/* Remove clock hover effect */ typedef void (* GDIHelpers_FillRectARGB_t)(HDC, LPCRECT, BYTE, DWORD, bool); GDIHelpers_FillRectARGB_t GDIHelpers_FillRectARGB_orig; void __cdecl GDIHelpers_FillRectARGB_hook( HDC hDC, LPCRECT lprc, BYTE btUnknown, DWORD dwUnknown, bool bUnknown ) { return; }
/* Draw taskbar item */ typedef void (* CTaskBtnGroup__DrawBar_t)(void *, HDC, void *, void *); CTaskBtnGroup__DrawBar_t CTaskBtnGroup__DrawBar_orig; void __cdecl CTaskBtnGroup__DrawBar_hook( void *pThis, HDC hDC, void *pRenderInfo, PBUTTONRENDERINFOSTATES pRenderStates ) { LPRECT lprcDest = (LPRECT)((char *)pRenderInfo + 4);
UINT uState = DFCS_BUTTONPUSH; if (pRenderStates->data[2]) { uState |= DFCS_CHECKED; } else if (pRenderStates->data[4]) { uState |= DFCS_PUSHED; }
DrawFrameControl( hDC, lprcDest, DFC_BUTTON, uState );
/* If button is pushed in, offset the rect for the icon and text draw */ if (pRenderStates->data[2] || pRenderStates->data[4]) { lprcDest->top++; lprcDest->bottom++; lprcDest->left++; lprcDest->right++; }
return; }
/* Add spacing between taskbar items */ typedef long (* CTaskBtnGroup_SetLocation_t)(void *, int, int, LPRECT); CTaskBtnGroup_SetLocation_t CTaskBtnGroup_SetLocation_orig; long __cdecl CTaskBtnGroup_SetLocation_hook( void *pThis, int i1, int i2, LPRECT lprc ) { APPBARDATA ab; ab.cbSize=sizeof(APPBARDATA); if(SHAppBarMessage(ABM_GETTASKBARPOS, &ab)) { if ((ab.uEdge==ABE_BOTTOM)||(ab.uEdge==ABE_TOP)){ lprc->right-=2; } } return CTaskBtnGroup_SetLocation_orig(pThis, i1, i2, lprc); }
BOOL Wh_ModInit(void) { HMODULE hExplorer = GetModuleHandleW(NULL);
WindhawkUtils::SYMBOL_HOOK hooks[] = { { { L"void __cdecl GDIHelpers::FillRectARGB(struct HDC__ *,struct tagRECT const *,unsigned char,unsigned long,bool)" }, (void **)&GDIHelpers_FillRectARGB_orig, (void *)GDIHelpers_FillRectARGB_hook, FALSE }, { { L"private: void __cdecl CTaskBtnGroup::_DrawBar(struct HDC__ *,struct BUTTONRENDERINFO const &,struct BUTTONRENDERINFOSTATES const &)" }, (void **)&CTaskBtnGroup__DrawBar_orig, (void *)CTaskBtnGroup__DrawBar_hook, FALSE },
{ { L"public: virtual long __cdecl CTaskBtnGroup::SetLocation(int,int,struct tagRECT const *)" }, (void **)&CTaskBtnGroup_SetLocation_orig, (void*)CTaskBtnGroup_SetLocation_hook, FALSE } };
if (!WindhawkUtils::HookSymbols(hExplorer, hooks, ARRAYSIZE(hooks))) { Wh_Log(L"Failed to hook one or more functions"); return FALSE; }
return TRUE; }
|
|
|
Post by alien750 on Oct 5, 2023 3:54:50 GMT -8
This doesn't seem to work for me. Here is the log:
11:52:13.543 8756 explorer.exe [WH] [local@classic-taskbar-fix-lite] [216:HookSymbols]: Couldn't resolve all symbols from cache 11:52:13.559 8756 explorer.exe [WH] [local@classic-taskbar-fix-lite] [221:HookSymbols]: Wh_FindFirstSymbol failed 11:52:13.559 8756 explorer.exe [WH] [local@classic-taskbar-fix-lite] [137:Wh_ModInit]: Failed to hook one or more function
|
|
|
Post by anixx on Oct 5, 2023 4:49:17 GMT -8
I have no idea why this may not hook, this part was not changed.
|
|
|
Post by alien750 on Oct 5, 2023 5:08:51 GMT -8
I have no idea why this may not hook, this part was not changed. It's not just yours, the original one didn't hook either.
|
|
|
Post by ephemeralViolette on Oct 5, 2023 8:12:43 GMT -8
This doesn't seem to work for me. Here is the log:
11:52:13.543 8756 explorer.exe [WH] [local@classic-taskbar-fix-lite] [216:HookSymbols]: Couldn't resolve all symbols from cache 11:52:13.559 8756 explorer.exe [WH] [local@classic-taskbar-fix-lite] [221:HookSymbols]: Wh_FindFirstSymbol failed 11:52:13.559 8756 explorer.exe [WH] [local@classic-taskbar-fix-lite] [137:Wh_ModInit]: Failed to hook one or more function This is a symbols issue. Perhaps explorer cannot connect to the internet, or maybe your OS version doesn't have symbols available for it.
You can still download the symbols manually with PDB Downloader. Drop the resulting folder named explorer into C:\ProgramData\Windhawk\Engine\Symbols, and then restart the mod.
|
|
|
Post by OrthodoxWin32 on Oct 5, 2023 8:43:30 GMT -8
i tried to compile your mod in windhawk but its keep failing on parsing on some settings yaml. I may have added an old version by mistake. This is the version I'm currently using : {Code}// ==WindhawkMod== // @id classic-theme-explorer // @name Classic Theme Explorer // @description Classic Theme mitigations for Explorer as a Windhawk mod // @version 0.1 // @author Cynosphere - OrthodoxWin32 // @github https://github.com/Cynosphere - https://github.com/OrthodoxWindows // @homepage https://c7.pm/ // @include explorer.exe // @compilerOptions -lcomctl32 -luxtheme -lgdi32 // ==/WindhawkMod==
// ==WindhawkModReadme== /* # Classic Theme Explorer Classic Theme mitigations for Explorer as a Windhawk mod.
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==
// ==WindhawkModSettings== /* - taskbarMitigate: true $name: "Mitigations on the taskbar and the system tray" $description: "Enable the classic theme mitigations on the taskbar and the notifications tray" - taskBand2: true $name: "Taskband2 style on Taskbar" $description: "Enable Taskband2 style on the taskbar" - 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 <windows.h> #include <objbase.h> #include <initguid.h> #include <commctrl.h> #include <dwmapi.h> #include <uxtheme.h> #include <wingdi.h>
#include <string> #include <regex> #include <locale> #include <codecvt>
struct { bool clientEdge; bool rebarBorder; bool rebarFixedHeight; bool hideNavigation; bool addressSync; bool addressSyncFullPath; bool addressHeight; bool hideRefresh; bool taskBand2; bool taskbarMitigate; } 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"); settings.taskBand2 = Wh_GetIntSetting(L"taskBand2"); settings.taskbarMitigate = Wh_GetIntSetting(L"taskbarMitigate"); }
// 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; }
// QtTabBar's hooking taints the wParam for some reason, so we strip off the extra bits if needed. BOOL ShouldApply(WPARAM wParam, BOOL fallback, BOOL checkSix) { Wh_Log(L"0x%x, %d", wParam, fallback); if (wParam > 0xffff) { Wh_Log(L"above 0xffff"); if ((wParam & 1) == 1) { Wh_Log(L"1 set"); return true; } else if (checkSix && (wParam & 6) == 6) { Wh_Log(L"6 set"); return true; } else { Wh_Log(L"falling back"); return fallback; } } else { Wh_Log(L"falling back"); return fallback; } }
VOID ClassicThemeExplorer(HWND hWnd, UINT uMsg, 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);
BOOL shouldApply = uMsg == WM_PARENTNOTIFY && ShouldApply(wParam, wParam == 1 || wParam == 6, false); BOOL shouldApply2 = uMsg == WM_PARENTNOTIFY && ShouldApply(wParam, wParam == 1, true);
if (settings.clientEdge && shouldApply) { Wh_Log(L"applying client edge"); 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 && shouldApply) { Wh_Log(L"applying rebar border"); LONG ClassicRebarStyle = GetWindowLongPtrW(ClassicRebar, GWL_STYLE); ClassicRebarStyle |= RBS_BANDBORDERS; ClassicRebarStyle |= WS_BORDER; SetWindowLongPtrW(ClassicRebar, GWL_STYLE, ClassicRebarStyle); }
if (settings.rebarFixedHeight && shouldApply) { Wh_Log(L"applying rebar fixed height"); LONG ClassicRebarStyle = GetWindowLongPtrW(ClassicRebar, GWL_STYLE); ClassicRebarStyle &= ~RBS_VARHEIGHT; SetWindowLongPtrW(ClassicRebar, GWL_STYLE, ClassicRebarStyle); }
// Apply bar changes if ((settings.rebarBorder || settings.rebarFixedHeight) && shouldApply) { 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 && shouldApply2) { // 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);
// FIXME: codecvt deprecated as of c++17 std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter;
// remove "Address: " // FIXME: support more locales 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 && shouldApply) { 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(L"[Destroy] uMsg: 0x%04x, wParam: 0x%x", uMsg, wParam); RemoveWindowSubclass(hWnd, ClassicThemeExplorerSubClass, 0); } else if (uMsg == g_subclassRegisteredMsg && !wParam) { Wh_Log(L"[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(L"[Target] uMsg: 0x%04x, wParam: 0x%x", uMsg, wParam); ClassicThemeExplorer(hWnd, uMsg, wParam); //} else { //Wh_Log(L"[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(L"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(L"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; }
// 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.taskbarMitigate && (*((WORD*)&(lpClassName)+1)) && !wcscmp(lpClassName, L"TrayNotifyWnd")) { dwExStyle |= WS_EX_STATICEDGE; } if (settings.taskbarMitigate && (*((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.taskbarMitigate && (*((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.taskbarMitigate && (*((WORD*)&(lpClassName)+1)) && !wcscmp(lpClassName, L"TrayNotifyWnd")) { if (nIndex == GWL_EXSTYLE) { dwNewLong |= WS_EX_STATICEDGE; } } if (settings.taskbarMitigate && (*((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.taskbarMitigate && (*((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.taskBand2 && (*((WORD*)&(pszClassList)+1)) && !wcscmp(pszClassList, L"Taskband2")) { Wh_Log(L"Redirecting Taskband2 hTheme"); return (HTHEME)0xDEADBEEF; } else if (settings.taskbarMitigate && (*((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.taskbarMitigate || (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.taskbarMitigate || (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.taskbarMitigate) { 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.taskbarMitigate) { 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.taskbarMitigate) { return TRUE; }
return pOriginalSetWindowCompositionAttribute(hWnd, pData); }
// Windhawk boilerplate BOOL Wh_ModInit() { LoadSettings();
HMODULE hShcore = GetModuleHandle(L"shcore.dll");
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() { if (g_uiThreadId != 0) EnumThreadWindows(g_uiThreadId, EnumBrowserWindowsUnsubclassFunc, 0); }
void Wh_ModSettingsChanged() { LoadSettings(); }
|
|
|
Post by The Jackal on Oct 5, 2023 12:32:02 GMT -8
i tried to compile your mod in windhawk but its keep failing on parsing on some settings yaml. I may have added an old version by mistake. This is the version I'm currently using : {Code}// ==WindhawkMod== // @id classic-theme-explorer // @name Classic Theme Explorer // @description Classic Theme mitigations for Explorer as a Windhawk mod // @version 0.1 // @author Cynosphere - OrthodoxWin32 // @github https://github.com/Cynosphere - https://github.com/OrthodoxWindows // @homepage https://c7.pm/ // @include explorer.exe // @compilerOptions -lcomctl32 -luxtheme -lgdi32 // ==/WindhawkMod==
// ==WindhawkModReadme== /* # Classic Theme Explorer Classic Theme mitigations for Explorer as a Windhawk mod.
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==
// ==WindhawkModSettings== /* - taskbarMitigate: true $name: "Mitigations on the taskbar and the system tray" $description: "Enable the classic theme mitigations on the taskbar and the notifications tray" - taskBand2: true $name: "Taskband2 style on Taskbar" $description: "Enable Taskband2 style on the taskbar" - 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 <windows.h> #include <objbase.h> #include <initguid.h> #include <commctrl.h> #include <dwmapi.h> #include <uxtheme.h> #include <wingdi.h>
#include <string> #include <regex> #include <locale> #include <codecvt>
struct { bool clientEdge; bool rebarBorder; bool rebarFixedHeight; bool hideNavigation; bool addressSync; bool addressSyncFullPath; bool addressHeight; bool hideRefresh; bool taskBand2; bool taskbarMitigate; } 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"); settings.taskBand2 = Wh_GetIntSetting(L"taskBand2"); settings.taskbarMitigate = Wh_GetIntSetting(L"taskbarMitigate"); }
// 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; }
// QtTabBar's hooking taints the wParam for some reason, so we strip off the extra bits if needed. BOOL ShouldApply(WPARAM wParam, BOOL fallback, BOOL checkSix) { Wh_Log(L"0x%x, %d", wParam, fallback); if (wParam > 0xffff) { Wh_Log(L"above 0xffff"); if ((wParam & 1) == 1) { Wh_Log(L"1 set"); return true; } else if (checkSix && (wParam & 6) == 6) { Wh_Log(L"6 set"); return true; } else { Wh_Log(L"falling back"); return fallback; } } else { Wh_Log(L"falling back"); return fallback; } }
VOID ClassicThemeExplorer(HWND hWnd, UINT uMsg, 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);
BOOL shouldApply = uMsg == WM_PARENTNOTIFY && ShouldApply(wParam, wParam == 1 || wParam == 6, false); BOOL shouldApply2 = uMsg == WM_PARENTNOTIFY && ShouldApply(wParam, wParam == 1, true);
if (settings.clientEdge && shouldApply) { Wh_Log(L"applying client edge"); 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 && shouldApply) { Wh_Log(L"applying rebar border"); LONG ClassicRebarStyle = GetWindowLongPtrW(ClassicRebar, GWL_STYLE); ClassicRebarStyle |= RBS_BANDBORDERS; ClassicRebarStyle |= WS_BORDER; SetWindowLongPtrW(ClassicRebar, GWL_STYLE, ClassicRebarStyle); }
if (settings.rebarFixedHeight && shouldApply) { Wh_Log(L"applying rebar fixed height"); LONG ClassicRebarStyle = GetWindowLongPtrW(ClassicRebar, GWL_STYLE); ClassicRebarStyle &= ~RBS_VARHEIGHT; SetWindowLongPtrW(ClassicRebar, GWL_STYLE, ClassicRebarStyle); }
// Apply bar changes if ((settings.rebarBorder || settings.rebarFixedHeight) && shouldApply) { 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 && shouldApply2) { // 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);
// FIXME: codecvt deprecated as of c++17 std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter;
// remove "Address: " // FIXME: support more locales 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 && shouldApply) { 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(L"[Destroy] uMsg: 0x%04x, wParam: 0x%x", uMsg, wParam); RemoveWindowSubclass(hWnd, ClassicThemeExplorerSubClass, 0); } else if (uMsg == g_subclassRegisteredMsg && !wParam) { Wh_Log(L"[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(L"[Target] uMsg: 0x%04x, wParam: 0x%x", uMsg, wParam); ClassicThemeExplorer(hWnd, uMsg, wParam); //} else { //Wh_Log(L"[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(L"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(L"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; }
// 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.taskbarMitigate && (*((WORD*)&(lpClassName)+1)) && !wcscmp(lpClassName, L"TrayNotifyWnd")) { dwExStyle |= WS_EX_STATICEDGE; } if (settings.taskbarMitigate && (*((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.taskbarMitigate && (*((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.taskbarMitigate && (*((WORD*)&(lpClassName)+1)) && !wcscmp(lpClassName, L"TrayNotifyWnd")) { if (nIndex == GWL_EXSTYLE) { dwNewLong |= WS_EX_STATICEDGE; } } if (settings.taskbarMitigate && (*((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.taskbarMitigate && (*((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.taskBand2 && (*((WORD*)&(pszClassList)+1)) && !wcscmp(pszClassList, L"Taskband2")) { Wh_Log(L"Redirecting Taskband2 hTheme"); return (HTHEME)0xDEADBEEF; } else if (settings.taskbarMitigate && (*((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.taskbarMitigate || (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.taskbarMitigate || (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.taskbarMitigate) { 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.taskbarMitigate) { 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.taskbarMitigate) { return TRUE; }
return pOriginalSetWindowCompositionAttribute(hWnd, pData); }
// Windhawk boilerplate BOOL Wh_ModInit() { LoadSettings();
HMODULE hShcore = GetModuleHandle(L"shcore.dll");
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() { if (g_uiThreadId != 0) EnumThreadWindows(g_uiThreadId, EnumBrowserWindowsUnsubclassFunc, 0); }
void Wh_ModSettingsChanged() { LoadSettings(); }
Somewhere along the line. some of the characters is getting corrupted/altered and it's throwing errors when I try to compile it, most likely caused by the forum reformated it. Can you post the cpp file please?
|
|
|
Post by OrthodoxWin32 on Oct 5, 2023 15:32:28 GMT -8
Somewhere along the line. some of the characters is getting corrupted/altered and it's throwing errors when I try to compile it, most likely caused by the forum reformated it. Can you post the cpp file please? Here is the file : classic-theme-explorer.c (33.57 KB)
|
|
|
Post by The Jackal on Oct 5, 2023 16:22:21 GMT -8
Somewhere along the line. some of the characters is getting corrupted/altered and it's throwing errors when I try to compile it, most likely caused by the forum reformated it. Can you post the cpp file please? Here is the file : View AttachmentThank you very much.
|
|