Skip to content

Commit 9793227

Browse files
committed
Common Controls Hook v1.0.1
* Only apply the common controls to windows, not to controls such as buttons. Improves stability, and fixes a crash in Device Manager.
1 parent b472df5 commit 9793227

1 file changed

Lines changed: 45 additions & 16 deletions

File tree

mods/common-controls-hook.wh.cpp

Lines changed: 45 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
// @id common-controls-hook
33
// @name Common Controls Hook
44
// @description Force-enable Common Controls v6 visual styles for legacy Win32 applications
5-
// @version 1.0
5+
// @version 1.0.1
66
// @author m417z
77
// @github https://github.com/m417z
88
// @twitter https://twitter.com/m417z
@@ -58,12 +58,16 @@ bool InitActCtx() {
5858
}
5959

6060
class ActCtxGuard {
61-
ULONG_PTR cookie;
62-
BOOL activated;
61+
ULONG_PTR cookie = 0;
62+
BOOL activated = FALSE;
63+
64+
ActCtxGuard(const ActCtxGuard&) = delete;
65+
ActCtxGuard& operator=(const ActCtxGuard&) = delete;
66+
ActCtxGuard(ActCtxGuard&&) = delete;
67+
ActCtxGuard& operator=(ActCtxGuard&&) = delete;
6368

6469
public:
6570
ActCtxGuard() {
66-
activated = FALSE;
6771
if (g_hActCtx != INVALID_HANDLE_VALUE) {
6872
activated = ActivateActCtx(g_hActCtx, &cookie);
6973
}
@@ -85,12 +89,32 @@ class ActCtxGuard {
8589

8690
// clang-format off
8791

88-
DEFINE_HOOK(HWND, CreateWindowExW,
89-
(DWORD dwExStyle, LPCWSTR lpClassName, LPCWSTR lpWindowName, DWORD dwStyle, int X, int Y, int nWidth, int nHeight, HWND hWndParent, HMENU hMenu, HINSTANCE hInstance, LPVOID lpParam),
90-
(dwExStyle, lpClassName, lpWindowName, dwStyle, X, Y, nWidth, nHeight, hWndParent, hMenu, hInstance, lpParam))
91-
DEFINE_HOOK(HWND, CreateWindowExA,
92-
(DWORD dwExStyle, LPCSTR lpClassName, LPCSTR lpWindowName, DWORD dwStyle, int X, int Y, int nWidth, int nHeight, HWND hWndParent, HMENU hMenu, HINSTANCE hInstance, LPVOID lpParam),
93-
(dwExStyle, lpClassName, lpWindowName, dwStyle, X, Y, nWidth, nHeight, hWndParent, hMenu, hInstance, lpParam))
92+
// CreateWindowEx is not defined through DEFINE_HOOK because the activation
93+
// context is only applied to top-level windows. Child windows inherit their
94+
// parent's activation context, so activating ours for them is unnecessary, and
95+
// it also avoids churning the activation stack for the many child controls a
96+
// window creates.
97+
typedef HWND(WINAPI* CreateWindowExW_t)(DWORD dwExStyle, LPCWSTR lpClassName, LPCWSTR lpWindowName, DWORD dwStyle, int X, int Y, int nWidth, int nHeight, HWND hWndParent, HMENU hMenu, HINSTANCE hInstance, LPVOID lpParam);
98+
CreateWindowExW_t CreateWindowExW_orig;
99+
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) {
100+
if (dwStyle & WS_CHILD) {
101+
return CreateWindowExW_orig(dwExStyle, lpClassName, lpWindowName, dwStyle, X, Y, nWidth, nHeight, hWndParent, hMenu, hInstance, lpParam);
102+
}
103+
104+
ActCtxGuard guard;
105+
return CreateWindowExW_orig(dwExStyle, lpClassName, lpWindowName, dwStyle, X, Y, nWidth, nHeight, hWndParent, hMenu, hInstance, lpParam);
106+
}
107+
108+
typedef HWND(WINAPI* CreateWindowExA_t)(DWORD dwExStyle, LPCSTR lpClassName, LPCSTR lpWindowName, DWORD dwStyle, int X, int Y, int nWidth, int nHeight, HWND hWndParent, HMENU hMenu, HINSTANCE hInstance, LPVOID lpParam);
109+
CreateWindowExA_t CreateWindowExA_orig;
110+
HWND WINAPI CreateWindowExA_hook(DWORD dwExStyle, LPCSTR lpClassName, LPCSTR lpWindowName, DWORD dwStyle, int X, int Y, int nWidth, int nHeight, HWND hWndParent, HMENU hMenu, HINSTANCE hInstance, LPVOID lpParam) {
111+
if (dwStyle & WS_CHILD) {
112+
return CreateWindowExA_orig(dwExStyle, lpClassName, lpWindowName, dwStyle, X, Y, nWidth, nHeight, hWndParent, hMenu, hInstance, lpParam);
113+
}
114+
115+
ActCtxGuard guard;
116+
return CreateWindowExA_orig(dwExStyle, lpClassName, lpWindowName, dwStyle, X, Y, nWidth, nHeight, hWndParent, hMenu, hInstance, lpParam);
117+
}
94118

95119
DEFINE_HOOK(INT_PTR, DialogBoxParamW,
96120
(HINSTANCE hInstance, LPCWSTR lpTemplateName, HWND hWndParent, DLGPROC lpDialogFunc, LPARAM dwInitParam),
@@ -159,12 +183,15 @@ BOOL Wh_ModInit() {
159183
return FALSE;
160184
}
161185

162-
#define INSTALL_HOOK(name) \
163-
do { \
164-
auto addr = (name##_t)GetProcAddress(hUser32, #name); \
165-
if (addr) { \
166-
WindhawkUtils::SetFunctionHook(addr, name##_hook, &name##_orig); \
167-
} \
186+
#define INSTALL_HOOK(name) \
187+
do { \
188+
auto addr = (name##_t)GetProcAddress(hUser32, #name); \
189+
if (addr) { \
190+
if (!WindhawkUtils::SetFunctionHook(addr, name##_hook, \
191+
&name##_orig)) { \
192+
Wh_Log(L"Failed to set hook for " TEXT(#name)); \
193+
} \
194+
} \
168195
} while (0)
169196

170197
INSTALL_HOOK(CreateWindowExW);
@@ -186,6 +213,8 @@ BOOL Wh_ModInit() {
186213
INSTALL_HOOK(MessageBoxTimeoutW);
187214
INSTALL_HOOK(MessageBoxTimeoutA);
188215

216+
#undef INSTALL_HOOK
217+
189218
return TRUE;
190219
}
191220

0 commit comments

Comments
 (0)