Restore the old System Tray
Nov 3, 2023 10:08:17 GMT -8
Post by Erizur on Nov 3, 2023 10:08:17 GMT -8
WARNING! THIS MOD HAS BEEN DEPRECATED. READ EDIT Nº4.
Today I finally got something interesting to showcase. The following mod (tries to) restore the old Hidden Icons Tray used in different Windows versions (7, 8, 8.1) by hooking into some of Explorer's functions. Some graphical bugs may happen inside the system tray, so in case you find one, let me know so I can try and fix it!
There are some issues with this mod if you're running older versions of windows. The borders of the tray might be affected. (It isn't hooking apparently?)
I recommend you to restart explorer after installing the mod for best results (changing the mod settings restart explorer too).
Edit Nº3: Thanks to YukisCoffee (Taniko), the Customize link has actual functionality and you don't need to patch SIB++ (incase you use it) for the mod to work!
Edit Nº4: THE MOD HAS BEEN DISCONTINUED AND REPLACED WITH AUBYMORI'S ALTERNATIVE. LINK HERE: windhawk.net/mods/aero-tray
The mod has finally reached v.1.0! Updates won't be required anymore unless someone requests an additional feature or any critical bug is found.
MOD CODE
{Spoiler (click to show)}
// ==WindhawkMod==
// @id restore-system-tray
// @name Restore Old System Tray
// @description Restores the old Taskbar System Tray from 8.1 and lower
// @version 1.1
// @author Erizur
// @github https://github.com/Erizur
// @include explorer.exe
// @architecture x86-64
// @compilerOptions -ldwmapi -luser32 -luxtheme -lgdi32 -lshell32 -lcomctl32
// ==/WindhawkMod==
// ==WindhawkModReadme==
/*
# Restore Old System Tray
Mod that tries to restore the old System Tray. Used in different Windows versions (7, 8, 8.1).
It works with both Classic Theme and Themed Windows.
Only tested on an x64 environment, if someone manages to run this on an x32 version of Windows, let me know!
As a recommendation, you should restart explorer once installing the mod for best results.
## Aditional Info
The icons DO get highlighted, but they are controlled by Windows itself. This could be different by changing how this behavior works.
BIG THANKS TO YUKISCOFFEE (Taniko) FOR ADDING THE CUSTOMIZE LINK FUNCTIONALITY BACK (and also for fixing some bugs)!
Sorry if my code is a mess! It's my first Windhawk mod. Ever.
Credits to schm1dt in the Windhawk Server for fixing the DWM borders in older versions of Windows 10.
*/
// ==/WindhawkModReadme==
// ==WindhawkModSettings==
/*
- ForceClassicFallback: false
$name: Force Fallback Tray
$description: Ignores the system theme and draws the tray using GDI. Useful for a Classic Theme look.
- DisableBuffered: false
$name: Disable BufferedPaint
$description: Only disable it incase you get transparent icons or weird graphical issues.
- ForceThickFrames: false
$name: Force Thick Frames
$description: Forces WS_THICKFRAME incase the hook that manages the borders does not work correctly. DON'T ENABLE THIS IF IT WORKS ALREADY!
- RemoveThickFrames: false
$name: Replace Thick Frames with Border
$description: Remove WS_THICKFRAME incase you don't need the following window style and adds the WS_BORDER property. Useful for a Classic/Basic Theme look.
- RiseDialog: true
$name: Rise System Tray Dialog
$description: Prevents the system tray dialog from rising even if composition and theme are correctly implemented. Useful for a Classic/Basic Theme look.
- DisableCustomizeLink: false
$name: Remove Customize Text
$description: Removes the Customize... Text to save space if necessary.
- CustomizeText: "Customize..."
$name: Change Customize Text
$description: Change the Customize link text.
- SIBPath: "%PROGRAMFILES(X86)%\\StartIsBack\\StartIsBack64.dll"
$name: StartIsBack64.dll Path Location
$description: Place the path where your SIB++ dll (64-bit) is located to prevent hook override.
- PaddingWidth: 18
$name: Toolbar Buttons Padding Width
$description: Change the padding width of the toolbar icons.
- PaddingHeight: 18
$name: Toolbar Buttons Padding Height
$description: Change the padding height of the toolbar icons.
*/
// ==/WindhawkModSettings==
#include <memoryapi.h>
#include <minwindef.h>
#include <processenv.h>
#include <windef.h>
#include <windhawk_api.h>
#include <windhawk_utils.h>
#include <libloaderapi.h>
#include <windows.h>
#include <windowsx.h>
#include <shellapi.h>
#include <dwmapi.h>
#include <winnt.h>
#include <winuser.h>
#include <uxtheme.h>
#include <vsstyle.h>
#include <wingdi.h>
#include <cstddef>
#include <cstdlib>
#include <string>
#include <shellapi.h>
#include <psapi.h>
#define RECTWIDTH(rect) (rect.right - rect.left)
#define RECTHEIGHT(rect) (rect.bottom - rect.top)
bool g_cfgForceClassicFallback;
bool g_cfgForceThickFrames;
bool g_cfgRemoveThickFrames;
bool g_cfgDisableCustomizeLink;
bool g_cfgDisableBufferedPaint;
bool g_cfgRiseDialog;
LPCWSTR g_cfgCustomizeText = L"Customize...";
LPCWSTR g_cfgSIBPath = L"Customize...";
int g_cfgButtonPadWidth, g_cfgButtonPadHeight, g_cfgCaptionRise;
const int LINK_AREA_HEIGHT = 42;
struct CustomizeLinkElement
{
HWND ownerHwnd = NULL;
SIZE size = { 0 };
RECT boundingRect = { 0 };
bool hovered = false;
bool pressed = false;
void setHovered(bool value)
{
hovered = value;
InvalidateRect(ownerHwnd, &boundingRect, TRUE);
}
RECT getLinkBounds()
{
RECT out;
out.left = boundingRect.left + ((RECTWIDTH(boundingRect) - size.cx) / 2) - 6;
out.top = boundingRect.top + ((RECTHEIGHT(boundingRect) - size.cy) / 2) - 6;
out.right = out.left + size.cx + 12;
out.bottom = out.top + size.cy + 12;
return out;
}
bool isPointInLinkBounds(int x, int y)
{
RECT bounds = getLinkBounds();
if (x > bounds.left && x < bounds.right && y > bounds.top && y < bounds.bottom)
{
return true;
}
return false;
}
} g_customizeLinkElement;
struct ACCENTPOLICY
{
int nAccentState;
int nFlags;
int nColor;
int nAnimationId;
};
enum WINDOWCOMPOSITIONATTRIB
{
WCA_ACCENT_POLICY = 19
};
struct WINDOWCOMPOSITIONATTRIBDATA
{
WINDOWCOMPOSITIONATTRIB Attrib;
PVOID pvData;
SIZE_T cbData;
};
struct ACCENTPOLICY policy = {
0,
0,
0,
0
};
LRESULT CALLBACK OverflowWindowSubclassProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData)
{
switch (uMsg)
{
case WM_ACTIVATE:
{
if (wParam == WA_INACTIVE)
{
g_customizeLinkElement.setHovered(false);
}
}
break;
case WM_MOUSELEAVE:
{
g_customizeLinkElement.setHovered(false);
}
break;
case WM_MOUSEMOVE:
{
int x = GET_X_LPARAM(lParam);
int y = GET_Y_LPARAM(lParam);
if (!g_cfgDisableCustomizeLink)
{
if (g_customizeLinkElement.isPointInLinkBounds(x, y))
{
g_customizeLinkElement.setHovered(true);
}
else
{
g_customizeLinkElement.setHovered(false);
}
}
}
break;
case WM_LBUTTONDOWN:
{
if (!g_cfgDisableCustomizeLink)
{
if (g_customizeLinkElement.hovered)
{
g_customizeLinkElement.pressed = true;
}
}
}
break;
case WM_LBUTTONUP:
{
if (!g_cfgDisableCustomizeLink)
{
// Handle link click event:
if (g_customizeLinkElement.pressed && g_customizeLinkElement.hovered)
{
// Easiest way to force a regular close is simply to send
// ourself an escape key event.
INPUT inputs[2];
inputs[0] = { 0 };
inputs[0].type = INPUT_KEYBOARD;
inputs[0].ki.wVk = VK_ESCAPE;
inputs[1] = { 0 };
inputs[1].type = INPUT_KEYBOARD;
inputs[1].ki.wVk = VK_ESCAPE;
inputs[1].ki.dwFlags = KEYEVENTF_KEYUP;
SendInput(ARRAYSIZE(inputs), inputs, sizeof(INPUT));
// Open the "Notifications Area Icons" CPL
ShellExecuteW(
hWnd,
NULL,
L"Shell:::{26EE0668-A00A-44D7-9371-BEB064C98683}\\0\\::{05D7B0F4-2121-4EFF-BF6B-ED3F69B894D9}",
NULL,
NULL,
SW_SHOWNORMAL
);
}
// No action, because the button wasn't hovered over:
else if (!g_customizeLinkElement.hovered)
{
g_customizeLinkElement.pressed = false;
}
}
}
break;
case WM_SETCURSOR:
{
if (!g_cfgDisableCustomizeLink)
{
if (g_customizeLinkElement.hovered)
{
HCURSOR cursor = LoadCursor(NULL, IDC_HAND);
SetCursor(cursor);
return TRUE;
}
else
{
return DefSubclassProc(hWnd, uMsg, wParam, lParam);
}
}
}
break;
case WM_DESTROY:
{
RemovePropW(hWnd, L"RestoreSystemTray_SubclassIsApplied");
}
break;
}
return DefSubclassProc(hWnd, uMsg, wParam, lParam);
}
using fnSetWindowCompositionAttribute = BOOL (WINAPI *)(HWND hWnd, WINDOWCOMPOSITIONATTRIBDATA*);
fnSetWindowCompositionAttribute _SetWindowCompositionAttribute = nullptr;
HWND CTrayOverflow_GetHwnd(void *pTrayOverflow)
{
return *((HWND *)pTrayOverflow + 3);
}
typedef void (__fastcall *CTrayOverflow__PositionWindow_t)(void *);
CTrayOverflow__PositionWindow_t CTrayOverflow__PositionWindow_orig;
void __fastcall CTrayOverflow__PositionWindow_hook(
void *pThis
)
{
int risePos = g_cfgRiseDialog ? 8 : 0;
HWND hWnd = CTrayOverflow_GetHwnd(pThis);
/* Do stuff maybe */
CTrayOverflow__PositionWindow_orig(
pThis
);
APPBARDATA abd;
abd.cbSize = sizeof(APPBARDATA);
SHAppBarMessage(ABM_GETTASKBARPOS, &abd);
HDC hDC;
RECT dRect;
GetWindowRect(hWnd, &dRect);
hDC = GetDC(hWnd);
if (IsCompositionActive())
{
const int PADDING_10_PX = MulDiv(10, GetDeviceCaps(hDC, LOGPIXELSY), 96);
switch (abd.uEdge)
{
case ABE_BOTTOM:
dRect.top -= MulDiv((g_cfgDisableCustomizeLink ? risePos : (risePos + 42)), GetDeviceCaps(hDC, LOGPIXELSY), 96);
break;
case ABE_LEFT:
dRect.left += PADDING_10_PX;
dRect.top -= PADDING_10_PX;
break;
case ABE_RIGHT:
dRect.left -= PADDING_10_PX;
dRect.top -= PADDING_10_PX;
break;
case ABE_TOP:
dRect.top += PADDING_10_PX;
break;
}
}
else
{
switch (abd.uEdge)
{
case ABE_BOTTOM:
if (!g_cfgDisableCustomizeLink)
{
dRect.top -= MulDiv(LINK_AREA_HEIGHT, GetDeviceCaps(hDC, LOGPIXELSY), 96);
}
break;
default:
break;
}
}
SetWindowPos(hWnd, HWND_TOP, dRect.left, dRect.top, 0, 0, SWP_NOSIZE | SWP_NOZORDER);
/* Maybe also do stuff */
}
typedef void (__fastcall *CTrayOverflow__UpdateColors_t)(void *);
CTrayOverflow__UpdateColors_t CTrayOverflow__UpdateColors_orig;
void __fastcall CTrayOverflow__UpdateColors_hook(
void *pThis
)
{
/* I ain't doing anything with you*/
/* Maybe not */
return;
}
typedef void (__fastcall *CTrayOverflow__UpdateButtonMetrics_t)(void *);
CTrayOverflow__UpdateButtonMetrics_t CTrayOverflow__UpdateButtonMetrics_orig;
void __fastcall CTrayOverflow__UpdateButtonMetrics_hook(
void *pThis
)
{
// This uses a different HWND than the other ones.
SendMessageW(*((HWND *)pThis + 11), TB_SETPADDING, 0, MAKELPARAM(g_cfgButtonPadWidth, g_cfgButtonPadHeight));
/* I ain't doing anything with you*/
/* Maybe not */
return;
}
typedef void (__fastcall *CTrayOverflow__EnsureBorder_t)(void *, HWND);
CTrayOverflow__EnsureBorder_t CTrayOverflow__EnsureBorder_orig;
void __fastcall CTrayOverflow__EnsureBorder_hook(
void *pThis,
HWND a2
)
{
HWND hWnd = CTrayOverflow_GetHwnd(pThis);
/* CTrayOverflow EnsureBorder rizz be like */
/* You force all the THICK of my frames */
DWORD dwStyle = GetWindowLongPtrW(hWnd, GWL_STYLE);
if(!g_cfgForceThickFrames && !g_cfgRemoveThickFrames)
{
SetWindowLongPtrW(hWnd, GWL_STYLE, dwStyle | WS_THICKFRAME);
}
else if(g_cfgRemoveThickFrames){
SetWindowLongPtrW(hWnd, GWL_STYLE, dwStyle | WS_BORDER);
}
return;
}
// Also responsible for initializing state of g_customizeLinkElement
// and for setting up subclass.
typedef bool (__fastcall *CTrayOverflow__SizeWindows_t)(void *);
CTrayOverflow__SizeWindows_t CTrayOverflow__SizeWindows_orig;
bool __fastcall CTrayOverflow__SizeWindows_hook(
void *pThis
)
{
HWND hWnd = CTrayOverflow_GetHwnd(pThis);
if (hWnd)
{
g_customizeLinkElement.ownerHwnd = hWnd;
if (NULL == GetPropW(hWnd, L"RestoreSystemTray_SubclassIsApplied"))
{
SetWindowSubclass(hWnd, OverflowWindowSubclassProc, 0, NULL);
SetPropW(hWnd, L"RestoreSystemTray_SubclassIsApplied", (HANDLE)TRUE);
}
}
DWORD dwStyle = GetWindowLongPtrW(hWnd, GWL_STYLE);
if(g_cfgForceThickFrames && !g_cfgRemoveThickFrames)
{
SetWindowLongPtrW(hWnd, GWL_STYLE, dwStyle | WS_THICKFRAME);
HWND notifyWindowHwnd = FindWindowA("NotifyIconOverflowWindow", NULL);
WINDOWCOMPOSITIONATTRIBDATA data = { WCA_ACCENT_POLICY, &policy, sizeof(policy) };
_SetWindowCompositionAttribute(notifyWindowHwnd, &data);
}
else if(g_cfgRemoveThickFrames){
SetWindowLongPtrW(hWnd, GWL_STYLE, dwStyle | WS_BORDER);
HWND notifyWindowHwnd = FindWindowA("NotifyIconOverflowWindow", NULL);
WINDOWCOMPOSITIONATTRIBDATA data = { WCA_ACCENT_POLICY, &policy, sizeof(policy) };
_SetWindowCompositionAttribute(notifyWindowHwnd, &data);
}
CTrayOverflow__SizeWindows_orig(
pThis
);
HDC hDC;
RECT dRect;
SIZE textSize;
int textWidth;
GetWindowRect(hWnd, &dRect);
hDC = GetDC(hWnd);
HTHEME hTheme = OpenThemeData(hWnd, L"Flyout");
if (hTheme)
{
RECT tempTextSize;
GetThemeTextExtent(
hTheme,
hDC,
FLYOUT_LINK,
FLYOUTLINK_NORMAL,
g_cfgCustomizeText,
-1,
DT_CENTER | DT_VCENTER | DT_SINGLELINE,
NULL,
&tempTextSize
);
textSize.cx = RECTWIDTH(tempTextSize);
textSize.cy = RECTHEIGHT(tempTextSize);
CloseThemeData(hTheme);
}
else
{
GetTextExtentPoint32W(hDC, g_cfgCustomizeText, wcslen(g_cfgCustomizeText), &textSize);
}
if (RECTWIDTH(dRect) >= textSize.cx + 8 || g_cfgDisableCustomizeLink)
{
textWidth = RECTWIDTH(dRect);
}
else
{
textWidth = textSize.cx + 8;
}
SetWindowPos(
hWnd,
0, 0, 0, textWidth,
(dRect.bottom - dRect.top) + (
g_cfgDisableCustomizeLink
? 0
: MulDiv(LINK_AREA_HEIGHT, GetDeviceCaps(hDC, LOGPIXELSY), 96)
),
SWP_NOMOVE | SWP_NOZORDER
);
ReleaseDC(hWnd, hDC);
g_customizeLinkElement.size = textSize;
return 1;
}
typedef __int64 (__fastcall *CTrayOverflow__OnPaint_t)(void *, HDC);
CTrayOverflow__OnPaint_t CTrayOverflow__OnPaint_orig;
__int64 __fastcall CTrayOverflow__OnPaint_hook(
void *pThis,
HDC argDc
)
{
HWND hWnd = CTrayOverflow_GetHwnd(pThis);
RECT clientRect, linkAreaRect;
PAINTSTRUCT ps;
HPAINTBUFFER bufferedPaintDc;
HDC hDC; // working HDC
HTHEME hTheme = OpenThemeData(hWnd, L"Flyout");
DTTOPTS opts;
opts.dwSize = 64;
opts.dwFlags = 0x2000;
if (argDc)
{
GetClipBox(argDc, &ps.rcPaint);
hDC = argDc;
}
else
{
HDC beginPaintDc = BeginPaint(hWnd, &ps);
hDC = beginPaintDc;
}
if (!g_cfgDisableBufferedPaint)
{
HDC newHdc;
bufferedPaintDc = BeginBufferedPaint(hDC, &ps.rcPaint, BPBF_COMPATIBLEBITMAP, 0, &newHdc);
if (bufferedPaintDc)
{
hDC = newHdc;
}
}
GetClientRect(hWnd, &clientRect);
CopyRect(&linkAreaRect, &clientRect);
if (!g_cfgDisableCustomizeLink)
{
linkAreaRect.top = linkAreaRect.bottom - MulDiv(LINK_AREA_HEIGHT, GetDeviceCaps(hDC, LOGPIXELSY), 96);
}
if (hTheme && !g_cfgForceClassicFallback)
{
DrawThemeBackground(hTheme, hDC, 6, 0, &clientRect, 0);
if (!g_cfgDisableCustomizeLink)
{
DrawThemeBackground(hTheme, hDC, 7, 0, &linkAreaRect, 0);
DrawThemeTextEx(
hTheme,
hDC,
FLYOUT_LINK,
g_customizeLinkElement.hovered
? FLYOUTLINK_HOVER
: FLYOUTLINK_NORMAL,
g_cfgCustomizeText,
-1,
DT_CENTER | DT_VCENTER | DT_SINGLELINE,
&linkAreaRect,
&opts
);
}
}
else // classic theme:
{
FillRect(hDC, &clientRect, (HBRUSH)(COLOR_WINDOW + 1));
if (!g_cfgDisableCustomizeLink)
{
FillRect(hDC, &linkAreaRect, (HBRUSH)(COLOR_3DFACE + 1));
NONCLIENTMETRICSW ncm;
ncm.cbSize = sizeof(NONCLIENTMETRICSW);
SystemParametersInfoW(
SPI_GETNONCLIENTMETRICS,
sizeof(NONCLIENTMETRICSW),
&ncm,
NULL
);
LOGFONTW lf;
memcpy(&lf, &ncm.lfCaptionFont, sizeof(LOGFONTW));
lf.lfWeight = FW_NORMAL;
if (g_customizeLinkElement.hovered)
{
lf.lfUnderline = TRUE;
}
HFONT hfLink = CreateFontIndirectW(&lf);
HFONT hfOld = (HFONT)SelectObject(hDC, hfLink);
SetBkMode(hDC, TRANSPARENT);
SetTextColor(hDC, GetSysColor(COLOR_HOTLIGHT));
DrawTextW(hDC, g_cfgCustomizeText, -1, &linkAreaRect, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
SelectObject(hDC, hfOld);
DeleteObject(hfLink);
}
}
g_customizeLinkElement.boundingRect = linkAreaRect;
if (hTheme)
{
CloseThemeData(hTheme);
}
if (bufferedPaintDc)
{
EndBufferedPaint(bufferedPaintDc, TRUE);
}
EndPaint(hWnd, &ps);
return 0;
}
void LoadSettings(void)
{
g_cfgForceClassicFallback = Wh_GetIntSetting(L"ForceClassicFallback");
g_cfgForceThickFrames = Wh_GetIntSetting(L"ForceThickFrames");
g_cfgRemoveThickFrames = Wh_GetIntSetting(L"RemoveThickFrames");
g_cfgDisableCustomizeLink = Wh_GetIntSetting(L"DisableCustomizeLink");
g_cfgDisableBufferedPaint = Wh_GetIntSetting(L"DisableBuffered");
g_cfgRiseDialog = Wh_GetIntSetting(L"RiseDialog");
g_cfgButtonPadWidth = Wh_GetIntSetting(L"PaddingWidth");
g_cfgButtonPadHeight = Wh_GetIntSetting(L"PaddingHeight");
g_cfgCustomizeText = Wh_GetStringSetting(L"CustomizeText");
g_cfgSIBPath = Wh_GetStringSetting(L"SIBPath");
}
/*
* Patch StartIsBack in memory to prevent it from overriding standard explorer
* behavior and thus breaking the mod.
*/
void PatchStartIsBack(HMODULE hModule)
{
Wh_Log(L"Found SIB module. Going to patch.");
const wchar_t *pattern = L"NotifyIconOverflowWindow";
MODULEINFO info = {0};
GetModuleInformation(
GetCurrentProcess(),
hModule,
&info,
sizeof(MODULEINFO)
);
DWORD_PTR base = (size_t)info.lpBaseOfDll;
size_t size = (size_t)info.SizeOfImage;
size_t patternLen = wcslen(pattern) * 2;
Wh_Log(L"[SIB] memory base: %x", base);
Wh_Log(L"[SIB] size: %d bytes", size);
Wh_Log(L"[SIB] pattern (wide str): %ls", pattern);
Wh_Log(L"[SIB] pattern length in memory: %d", patternLen);
for (size_t i = 0; i < size - patternLen; i++)
{
bool found = true;
for (size_t j = 0; j < patternLen; j++)
{
found = *((char *)pattern + j) == *(char *)(base + i + j);
if (!found)
{
break;
}
}
if (found)
{
size_t ptr = base + i;
Wh_Log(L"[SIB] pattern location in mem: %x", ptr);
MEMORY_BASIC_INFORMATION mbi;
VirtualQuery((wchar_t *)ptr, &mbi, sizeof(MEMORY_BASIC_INFORMATION));
if (!VirtualProtect(mbi.BaseAddress, mbi.RegionSize, PAGE_READWRITE, &mbi.Protect))
{
return;
}
wcsncpy((wchar_t *)ptr, L"BYEBYEBYEBYEBYEBYEBYEBYE", patternLen);
DWORD dwOldProtect;
VirtualProtect(mbi.BaseAddress, mbi.RegionSize, mbi.Protect, &dwOldProtect);
return;
}
}
}
void CheckForStartIsBack()
{
const wchar_t *SIB_PATH = g_cfgSIBPath;
wchar_t workingSibPath[1024] = { 0 };
ExpandEnvironmentStringsW(SIB_PATH, workingSibPath, 1024);
HMODULE hStartIsBackModule = LoadLibraryW(workingSibPath);
if (hStartIsBackModule)
{
PatchStartIsBack(hStartIsBackModule);
}
}
// The mod is being initialized, load settings, hook functions, and do other
// initialization stuff if required.
BOOL Wh_ModInit(void)
{
Wh_Log(L"Init " WH_MOD_ID L" version " WH_MOD_VERSION);
HMODULE hUser32Module = GetModuleHandleW(L"user32.dll");
if (hUser32Module)
{
_SetWindowCompositionAttribute = reinterpret_cast<fnSetWindowCompositionAttribute>(GetProcAddress(hUser32Module, "SetWindowCompositionAttribute"));
}
CheckForStartIsBack();
HMODULE hExplorer = GetModuleHandleW(NULL);
LoadSettings();
//i should start here
WindhawkUtils::SYMBOL_HOOK hooks[] = {
{
{
L"private: void __cdecl CTrayOverflow::_PositionWindow(void)"
},
(void **)&CTrayOverflow__PositionWindow_orig,
(void *)CTrayOverflow__PositionWindow_hook,
false
},
{
{
L"private: void __cdecl CTrayOverflow::_EnsureBorder(struct HWND__ *)"
},
(void **)&CTrayOverflow__EnsureBorder_orig,
(void *)CTrayOverflow__EnsureBorder_hook,
false
},
{
{
L"private: void __cdecl CTrayOverflow::_UpdateColors(void)"
},
(void **)&CTrayOverflow__UpdateColors_orig,
(void *)CTrayOverflow__UpdateColors_hook,
false
},
{
{
L"public: bool __cdecl CTrayOverflow::SizeWindows(void)"
},
(void **)&CTrayOverflow__SizeWindows_orig,
(void *)CTrayOverflow__SizeWindows_hook,
false
},
{
{
L"private: __int64 __cdecl CTrayOverflow::_OnPaint(struct HDC__ *)"
},
(void **)&CTrayOverflow__OnPaint_orig,
(void *)CTrayOverflow__OnPaint_hook,
false
},
{
{
L"private: void __cdecl CTrayOverflow::UpdateButtonMetrics(void)"
},
(void **)&CTrayOverflow__UpdateButtonMetrics_orig,
(void *)CTrayOverflow__UpdateButtonMetrics_hook,
false
}
};
if (!WindhawkUtils::HookSymbols(
hExplorer,
hooks,
ARRAYSIZE(hooks)
))
{
Wh_Log(L"Failed to hook, oh noes!");
return FALSE;
}
return TRUE;
}
void Wh_ModSettingsChanged(void)
{
LoadSettings();
system("tskill explorer");
}