2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS uxtheme.dll
4 * FILE: dll/win32/uxtheme/themehooks.c
5 * PURPOSE: uxtheme user api hook functions
6 * PROGRAMMER: Giannis Adamopoulos
10 #include <wine/debug.h>
12 WINE_DEFAULT_DEBUG_CHANNEL(uxtheme
);
14 USERAPIHOOK user32ApiHook
;
15 BYTE gabDWPmessages
[UAHOWP_MAX_SIZE
];
16 BYTE gabMSGPmessages
[UAHOWP_MAX_SIZE
];
17 BOOL gbThemeHooksActive
= FALSE
;
19 PWND_CONTEXT
ThemeGetWndContext(HWND hWnd
)
21 PWND_CONTEXT pcontext
;
23 pcontext
= (PWND_CONTEXT
)GetPropW(hWnd
, (LPCWSTR
)MAKEINTATOM(atWndContrext
));
26 pcontext
= HeapAlloc(GetProcessHeap(),
34 SetPropW( hWnd
, (LPCWSTR
)MAKEINTATOM(atWndContrext
), pcontext
);
40 void ThemeDetroyWndContext(HWND hWnd
)
42 PWND_CONTEXT pContext
;
45 /*Do not destroy WND_CONTEXT of a window that belong to another process */
46 GetWindowThreadProcessId(hWnd
, &ProcessId
);
47 if(ProcessId
!= GetCurrentProcessId())
52 pContext
= (PWND_CONTEXT
)GetPropW(hWnd
, (LPCWSTR
)MAKEINTATOM(atWndContrext
));
58 if(pContext
->HasThemeRgn
)
60 user32ApiHook
.SetWindowRgn(hWnd
, 0, TRUE
);
63 HeapFree(GetProcessHeap(), 0, pContext
);
65 SetPropW( hWnd
, (LPCWSTR
)MAKEINTATOM(atWndContrext
), NULL
);
68 static BOOL CALLBACK
ThemeCleanupChildWndContext (HWND hWnd
, LPARAM msg
)
70 ThemeDetroyWndContext(hWnd
);
74 static BOOL CALLBACK
ThemeCleanupWndContext(HWND hWnd
, LPARAM msg
)
78 EnumWindows (ThemeCleanupWndContext
, 0);
82 ThemeDetroyWndContext(hWnd
);
83 EnumChildWindows (hWnd
, ThemeCleanupChildWndContext
, 0);
89 void SetThemeRegion(HWND hWnd
, PWND_CONTEXT pcontext
)
94 int CaptionHeight
, iPart
;
99 if(pcontext
->HasThemeRgn
)
101 pcontext
->HasThemeRgn
= FALSE
;
102 user32ApiHook
.SetWindowRgn(hWnd
, 0, TRUE
);
107 wi
.cbSize
= sizeof(wi
);
109 GetWindowInfo(hWnd
, &wi
);
111 if((wi
.dwStyle
& WS_CAPTION
)!=WS_CAPTION
)
116 /* Get the caption part id */
117 if (wi
.dwExStyle
& WS_EX_TOOLWINDOW
)
118 iPart
= WP_SMALLCAPTION
;
119 else if (wi
.dwStyle
& WS_MAXIMIZE
)
120 iPart
= WP_MAXCAPTION
;
124 pcontext
->HasThemeRgn
= TRUE
;
126 CaptionHeight
= wi
.cyWindowBorders
;
127 CaptionHeight
+= GetSystemMetrics(wi
.dwExStyle
& WS_EX_TOOLWINDOW
? SM_CYSMCAPTION
: SM_CYCAPTION
);
129 GetWindowRect(hWnd
, &rcWindow
);
130 rcWindow
.right
-= rcWindow
.left
;
131 rcWindow
.bottom
= CaptionHeight
;
135 hTheme
= OpenThemeData (hWnd
, L
"WINDOW");
137 GetThemeBackgroundRegion(hTheme
, 0, iPart
, FS_ACTIVE
, &rcWindow
, &hrgn
);
139 CloseThemeData(hTheme
);
141 GetWindowRect(hWnd
, &rcWindow
);
142 rcWindow
.right
-= rcWindow
.left
;
143 rcWindow
.bottom
-= rcWindow
.top
;
144 rcWindow
.top
= CaptionHeight
;
146 hrgn1
= CreateRectRgnIndirect(&rcWindow
);
148 CombineRgn(hrgn
, hrgn
, hrgn1
, RGN_OR
);
152 user32ApiHook
.SetWindowRgn(hWnd
, hrgn
, TRUE
);
155 int OnPostWinPosChanged(HWND hWnd
)
157 PWND_CONTEXT pcontext
= ThemeGetWndContext(hWnd
);
160 pcontext
->HasAppDefinedRgn
== FALSE
&&
161 pcontext
->UpdatingRgn
== FALSE
)
163 pcontext
->UpdatingRgn
= TRUE
;
164 SetThemeRegion(hWnd
, pcontext
);
165 pcontext
= ThemeGetWndContext(hWnd
);
166 pcontext
->UpdatingRgn
= FALSE
;
171 /**********************************************************************
175 static LRESULT CALLBACK
176 ThemeDefWindowProcW(HWND hWnd
, UINT Msg
, WPARAM wParam
, LPARAM lParam
)
180 return user32ApiHook
.DefWindowProcW(hWnd
,
186 return ThemeWndProc(hWnd
,
190 user32ApiHook
.DefWindowProcW
);
193 static LRESULT CALLBACK
194 ThemeDefWindowProcA(HWND hWnd
, UINT Msg
, WPARAM wParam
, LPARAM lParam
)
198 return user32ApiHook
.DefWindowProcA(hWnd
,
204 return ThemeWndProc(hWnd
,
208 user32ApiHook
.DefWindowProcA
);
211 static LRESULT CALLBACK
212 ThemePreWindowProc(HWND hWnd
, UINT Msg
, WPARAM wParam
, LPARAM lParam
, ULONG_PTR ret
,PDWORD unknown
)
216 case WM_THEMECHANGED
:
217 UXTHEME_LoadTheme(TRUE
);
225 static LRESULT CALLBACK
226 ThemePostWindowProc(HWND hWnd
, UINT Msg
, WPARAM wParam
, LPARAM lParam
, ULONG_PTR ret
,PDWORD unknown
)
230 case WM_WINDOWPOSCHANGED
:
232 return OnPostWinPosChanged(hWnd
);
236 ThemeDetroyWndContext(hWnd
);
244 int WINAPI
ThemeSetWindowRgn(HWND hWnd
, HRGN hRgn
, BOOL bRedraw
)
246 PWND_CONTEXT pcontext
= ThemeGetWndContext(hWnd
);
249 pcontext
->HasAppDefinedRgn
= TRUE
;
250 pcontext
->HasThemeRgn
= FALSE
;
253 return user32ApiHook
.SetWindowRgn(hWnd
, hRgn
, bRedraw
);
256 /**********************************************************************
261 ThemeInitApiHook(UAPIHK State
, PUSERAPIHOOK puah
)
263 if (!puah
|| State
!= uahLoadInit
)
265 UXTHEME_LoadTheme(FALSE
);
266 ThemeCleanupWndContext(NULL
, 0);
267 gbThemeHooksActive
= FALSE
;
271 gbThemeHooksActive
= TRUE
;
273 /* Store the original functions from user32 */
274 user32ApiHook
= *puah
;
276 puah
->DefWindowProcA
= ThemeDefWindowProcA
;
277 puah
->DefWindowProcW
= ThemeDefWindowProcW
;
278 puah
->PreWndProc
= ThemePreWindowProc
;
279 puah
->PostWndProc
= ThemePostWindowProc
;
280 puah
->PreDefDlgProc
= ThemePreWindowProc
;
281 puah
->PostDefDlgProc
= ThemePostWindowProc
;
282 puah
->DefWndProcArray
.MsgBitArray
= gabDWPmessages
;
283 puah
->DefWndProcArray
.Size
= UAHOWP_MAX_SIZE
;
284 puah
->WndProcArray
.MsgBitArray
= gabMSGPmessages
;
285 puah
->WndProcArray
.Size
= UAHOWP_MAX_SIZE
;
286 puah
->DlgProcArray
.MsgBitArray
= gabMSGPmessages
;
287 puah
->DlgProcArray
.Size
= UAHOWP_MAX_SIZE
;
289 puah
->SetWindowRgn
= ThemeSetWindowRgn
;
291 UAH_HOOK_MESSAGE(puah
->DefWndProcArray
, WM_NCPAINT
);
292 UAH_HOOK_MESSAGE(puah
->DefWndProcArray
, WM_NCACTIVATE
);
293 UAH_HOOK_MESSAGE(puah
->DefWndProcArray
, WM_NCMOUSEMOVE
);
294 UAH_HOOK_MESSAGE(puah
->DefWndProcArray
, WM_NCMOUSELEAVE
);
295 UAH_HOOK_MESSAGE(puah
->DefWndProcArray
, WM_NCHITTEST
);
296 UAH_HOOK_MESSAGE(puah
->DefWndProcArray
, WM_NCLBUTTONDOWN
);
297 UAH_HOOK_MESSAGE(puah
->DefWndProcArray
, WM_NCUAHDRAWCAPTION
);
298 UAH_HOOK_MESSAGE(puah
->DefWndProcArray
, WM_NCUAHDRAWFRAME
);
299 UAH_HOOK_MESSAGE(puah
->DefWndProcArray
, WM_SETTEXT
);
300 UAH_HOOK_MESSAGE(puah
->DefWndProcArray
, WM_WINDOWPOSCHANGED
);
301 UAH_HOOK_MESSAGE(puah
->DefWndProcArray
, WM_CONTEXTMENU
);
302 UAH_HOOK_MESSAGE(puah
->DefWndProcArray
, WM_STYLECHANGED
);
303 UAH_HOOK_MESSAGE(puah
->DefWndProcArray
, WM_SETICON
);
304 UAH_HOOK_MESSAGE(puah
->DefWndProcArray
, WM_NCDESTROY
);
305 UAH_HOOK_MESSAGE(puah
->DefWndProcArray
, WM_SYSCOMMAND
);
306 UAH_HOOK_MESSAGE(puah
->DefWndProcArray
, WM_CTLCOLORMSGBOX
);
307 UAH_HOOK_MESSAGE(puah
->DefWndProcArray
, WM_CTLCOLORBTN
);
308 UAH_HOOK_MESSAGE(puah
->DefWndProcArray
, WM_CTLCOLORSTATIC
);
310 UAH_HOOK_MESSAGE(puah
->WndProcArray
, WM_CREATE
);
311 UAH_HOOK_MESSAGE(puah
->WndProcArray
, WM_SETTINGCHANGE
);
312 UAH_HOOK_MESSAGE(puah
->WndProcArray
, WM_DRAWITEM
);
313 UAH_HOOK_MESSAGE(puah
->WndProcArray
, WM_MEASUREITEM
);
314 UAH_HOOK_MESSAGE(puah
->WndProcArray
, WM_WINDOWPOSCHANGING
);
315 UAH_HOOK_MESSAGE(puah
->WndProcArray
, WM_WINDOWPOSCHANGED
);
316 UAH_HOOK_MESSAGE(puah
->WndProcArray
, WM_STYLECHANGING
);
317 UAH_HOOK_MESSAGE(puah
->WndProcArray
, WM_STYLECHANGED
);
318 UAH_HOOK_MESSAGE(puah
->WndProcArray
, WM_NCCREATE
);
319 UAH_HOOK_MESSAGE(puah
->WndProcArray
, WM_NCDESTROY
);
320 UAH_HOOK_MESSAGE(puah
->WndProcArray
, WM_NCPAINT
);
321 UAH_HOOK_MESSAGE(puah
->WndProcArray
, WM_MENUCHAR
);
322 UAH_HOOK_MESSAGE(puah
->WndProcArray
, WM_MDISETMENU
);
323 UAH_HOOK_MESSAGE(puah
->WndProcArray
, WM_THEMECHANGED
);
324 UAH_HOOK_MESSAGE(puah
->WndProcArray
, WM_UAHINIT
);
326 UXTHEME_LoadTheme(TRUE
);
331 typedef BOOL (WINAPI
* PREGISTER_UAH_WINXP
)(HINSTANCE hInstance
, USERAPIHOOKPROC CallbackFunc
);
332 typedef BOOL (WINAPI
* PREGISTER_UUAH_WIN2003
)(PUSERAPIHOOKINFO puah
);
341 lpFunc
= GetProcAddress(GetModuleHandle("user32.dll"), "RegisterUserApiHook");
343 ZeroMemory(&osvi
, sizeof(OSVERSIONINFO
));
344 osvi
.dwOSVersionInfoSize
= sizeof(OSVERSIONINFO
);
347 if ( osvi
.dwMajorVersion
== 5 && osvi
.dwMinorVersion
== 1)
349 PREGISTER_UAH_WINXP lpfuncxp
= (PREGISTER_UAH_WINXP
)lpFunc
;
350 ret
= lpfuncxp(hDllInst
, ThemeInitApiHook
);
352 else if ( osvi
.dwMajorVersion
== 5 && osvi
.dwMinorVersion
== 2)
354 PREGISTER_UUAH_WIN2003 lpfunc2003
= (PREGISTER_UUAH_WIN2003
)lpFunc
;
357 uah
.m_size
= sizeof(uah
);
358 uah
.m_dllname1
= L
"uxtheme.dll";
359 uah
.m_funname1
= L
"ThemeInitApiHook";
360 uah
.m_dllname2
= NULL
;
361 uah
.m_funname2
= NULL
;
363 ret
= lpfunc2003(&uah
);
371 UXTHEME_broadcast_msg (NULL
, WM_THEMECHANGED
);
381 ret
= UnregisterUserApiHook();
383 UXTHEME_broadcast_msg (NULL
, WM_THEMECHANGED
);