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
);
16 extern HINSTANCE hDllInst
;
18 LRESULT CALLBACK
ThemeWndProc(HWND hWnd
, UINT Msg
, WPARAM wParam
, LPARAM lParam
, WNDPROC DefWndProc
);
20 USERAPIHOOK user32ApiHook
;
21 BYTE gabDWPmessages
[UAHOWP_MAX_SIZE
];
22 BYTE gabMSGPmessages
[UAHOWP_MAX_SIZE
];
25 PWND_CONTEXT
ThemeGetWndContext(HWND hWnd
)
27 PWND_CONTEXT pcontext
;
29 pcontext
= (PWND_CONTEXT
)GetPropW(hWnd
, (LPCWSTR
)MAKEINTATOM(atWndContrext
));
32 pcontext
= HeapAlloc(GetProcessHeap(),
40 SetPropW( hWnd
, (LPCWSTR
)MAKEINTATOM(atWndContrext
), pcontext
);
46 void ThemeDetroyWndContext(HWND hWnd
)
48 PWND_CONTEXT pContext
;
51 /*Do not destroy WND_CONTEXT of a window that belong to another process */
52 GetWindowThreadProcessId(hWnd
, &ProcessId
);
53 if(ProcessId
!= GetCurrentProcessId())
58 pContext
= (PWND_CONTEXT
)GetPropW(hWnd
, (LPCWSTR
)MAKEINTATOM(atWndContrext
));
64 if(pContext
->HasThemeRgn
)
66 user32ApiHook
.SetWindowRgn(hWnd
, 0, TRUE
);
69 HeapFree(GetProcessHeap(), 0, pContext
);
71 SetPropW( hWnd
, (LPCWSTR
)MAKEINTATOM(atWndContrext
), NULL
);
74 static BOOL CALLBACK
ThemeCleanupChildWndContext (HWND hWnd
, LPARAM msg
)
76 ThemeDetroyWndContext(hWnd
);
80 static BOOL CALLBACK
ThemeCleanupWndContext(HWND hWnd
, LPARAM msg
)
84 EnumWindows (ThemeCleanupWndContext
, 0);
88 ThemeDetroyWndContext(hWnd
);
89 EnumChildWindows (hWnd
, ThemeCleanupChildWndContext
, 0);
95 void SetThemeRegion(HWND hWnd
, PWND_CONTEXT pcontext
)
100 int CaptionHeight
, iPart
;
105 if(pcontext
->HasThemeRgn
)
107 pcontext
->HasThemeRgn
= FALSE
;
108 user32ApiHook
.SetWindowRgn(hWnd
, 0, TRUE
);
113 wi
.cbSize
= sizeof(wi
);
115 GetWindowInfo(hWnd
, &wi
);
117 if((wi
.dwStyle
& WS_CAPTION
)!=WS_CAPTION
)
122 /* Get the caption part id */
123 if (wi
.dwExStyle
& WS_EX_TOOLWINDOW
)
124 iPart
= WP_SMALLCAPTION
;
125 else if (wi
.dwStyle
& WS_MAXIMIZE
)
126 iPart
= WP_MAXCAPTION
;
130 pcontext
->HasThemeRgn
= TRUE
;
132 CaptionHeight
= wi
.cyWindowBorders
;
133 CaptionHeight
+= GetSystemMetrics(wi
.dwExStyle
& WS_EX_TOOLWINDOW
? SM_CYSMCAPTION
: SM_CYCAPTION
);
135 GetWindowRect(hWnd
, &rcWindow
);
136 rcWindow
.right
-= rcWindow
.left
;
137 rcWindow
.bottom
= CaptionHeight
;
141 hTheme
= OpenThemeData (hWnd
, L
"WINDOW");
143 GetThemeBackgroundRegion(hTheme
, 0, iPart
, FS_ACTIVE
, &rcWindow
, &hrgn
);
145 CloseThemeData(hTheme
);
147 GetWindowRect(hWnd
, &rcWindow
);
148 rcWindow
.right
-= rcWindow
.left
;
149 rcWindow
.bottom
-= rcWindow
.top
;
150 rcWindow
.top
= CaptionHeight
;
152 hrgn1
= CreateRectRgnIndirect(&rcWindow
);
154 CombineRgn(hrgn
, hrgn
, hrgn1
, RGN_OR
);
158 user32ApiHook
.SetWindowRgn(hWnd
, hrgn
, TRUE
);
161 int OnPostWinPosChanged(HWND hWnd
)
163 PWND_CONTEXT pcontext
= ThemeGetWndContext(hWnd
);
166 pcontext
->HasAppDefinedRgn
== FALSE
&&
167 pcontext
->UpdatingRgn
== FALSE
)
169 pcontext
->UpdatingRgn
= TRUE
;
170 SetThemeRegion(hWnd
, pcontext
);
171 pcontext
= ThemeGetWndContext(hWnd
);
172 pcontext
->UpdatingRgn
= FALSE
;
177 /**********************************************************************
181 static LRESULT CALLBACK
182 ThemeDefWindowProcW(HWND hWnd
, UINT Msg
, WPARAM wParam
, LPARAM lParam
)
186 return user32ApiHook
.DefWindowProcW(hWnd
,
192 return ThemeWndProc(hWnd
,
196 user32ApiHook
.DefWindowProcW
);
199 static LRESULT CALLBACK
200 ThemeDefWindowProcA(HWND hWnd
, UINT Msg
, WPARAM wParam
, LPARAM lParam
)
204 return user32ApiHook
.DefWindowProcA(hWnd
,
210 return ThemeWndProc(hWnd
,
214 user32ApiHook
.DefWindowProcA
);
217 static LRESULT CALLBACK
218 ThemePreWindowProc(HWND hWnd
, UINT Msg
, WPARAM wParam
, LPARAM lParam
, ULONG_PTR ret
,PDWORD unknown
)
222 case WM_THEMECHANGED
:
223 UXTHEME_LoadTheme(TRUE
);
231 static LRESULT CALLBACK
232 ThemePostWindowProc(HWND hWnd
, UINT Msg
, WPARAM wParam
, LPARAM lParam
, ULONG_PTR ret
,PDWORD unknown
)
236 case WM_WINDOWPOSCHANGED
:
238 return OnPostWinPosChanged(hWnd
);
242 ThemeDetroyWndContext(hWnd
);
250 int WINAPI
ThemeSetWindowRgn(HWND hWnd
, HRGN hRgn
, BOOL bRedraw
)
252 PWND_CONTEXT pcontext
= ThemeGetWndContext(hWnd
);
255 pcontext
->HasAppDefinedRgn
= TRUE
;
256 pcontext
->HasThemeRgn
= FALSE
;
259 return user32ApiHook
.SetWindowRgn(hWnd
, hRgn
, bRedraw
);
262 /**********************************************************************
267 ThemeInitApiHook(UAPIHK State
, PUSERAPIHOOK puah
)
269 /* Sanity checks for the caller */
270 if (!puah
|| State
!= uahLoadInit
)
272 UXTHEME_LoadTheme(FALSE
);
273 ThemeCleanupWndContext(NULL
, 0);
277 /* Store the original functions from user32 */
278 user32ApiHook
= *puah
;
280 puah
->DefWindowProcA
= ThemeDefWindowProcA
;
281 puah
->DefWindowProcW
= ThemeDefWindowProcW
;
282 puah
->PreWndProc
= ThemePreWindowProc
;
283 puah
->PostWndProc
= ThemePostWindowProc
;
284 puah
->PreDefDlgProc
= ThemePreWindowProc
;
285 puah
->PostDefDlgProc
= ThemePostWindowProc
;
286 puah
->DefWndProcArray
.MsgBitArray
= gabDWPmessages
;
287 puah
->DefWndProcArray
.Size
= UAHOWP_MAX_SIZE
;
288 puah
->WndProcArray
.MsgBitArray
= gabMSGPmessages
;
289 puah
->WndProcArray
.Size
= UAHOWP_MAX_SIZE
;
290 puah
->DlgProcArray
.MsgBitArray
= gabMSGPmessages
;
291 puah
->DlgProcArray
.Size
= UAHOWP_MAX_SIZE
;
293 puah
->SetWindowRgn
= ThemeSetWindowRgn
;
295 UAH_HOOK_MESSAGE(puah
->DefWndProcArray
, WM_NCPAINT
);
296 UAH_HOOK_MESSAGE(puah
->DefWndProcArray
, WM_NCACTIVATE
);
297 UAH_HOOK_MESSAGE(puah
->DefWndProcArray
, WM_NCMOUSEMOVE
);
298 UAH_HOOK_MESSAGE(puah
->DefWndProcArray
, WM_NCMOUSELEAVE
);
299 UAH_HOOK_MESSAGE(puah
->DefWndProcArray
, WM_NCHITTEST
);
300 UAH_HOOK_MESSAGE(puah
->DefWndProcArray
, WM_NCLBUTTONDOWN
);
301 UAH_HOOK_MESSAGE(puah
->DefWndProcArray
, WM_NCUAHDRAWCAPTION
);
302 UAH_HOOK_MESSAGE(puah
->DefWndProcArray
, WM_NCUAHDRAWFRAME
);
303 UAH_HOOK_MESSAGE(puah
->DefWndProcArray
, WM_SETTEXT
);
304 UAH_HOOK_MESSAGE(puah
->DefWndProcArray
, WM_WINDOWPOSCHANGED
);
305 UAH_HOOK_MESSAGE(puah
->DefWndProcArray
, WM_CONTEXTMENU
);
306 UAH_HOOK_MESSAGE(puah
->DefWndProcArray
, WM_STYLECHANGED
);
307 UAH_HOOK_MESSAGE(puah
->DefWndProcArray
, WM_SETICON
);
308 UAH_HOOK_MESSAGE(puah
->DefWndProcArray
, WM_NCDESTROY
);
309 UAH_HOOK_MESSAGE(puah
->DefWndProcArray
, WM_SYSCOMMAND
);
310 UAH_HOOK_MESSAGE(puah
->DefWndProcArray
, WM_CTLCOLORMSGBOX
);
311 UAH_HOOK_MESSAGE(puah
->DefWndProcArray
, WM_CTLCOLORBTN
);
312 UAH_HOOK_MESSAGE(puah
->DefWndProcArray
, WM_CTLCOLORSTATIC
);
314 UAH_HOOK_MESSAGE(puah
->WndProcArray
, WM_CREATE
);
315 UAH_HOOK_MESSAGE(puah
->WndProcArray
, WM_SETTINGCHANGE
);
316 UAH_HOOK_MESSAGE(puah
->WndProcArray
, WM_DRAWITEM
);
317 UAH_HOOK_MESSAGE(puah
->WndProcArray
, WM_MEASUREITEM
);
318 UAH_HOOK_MESSAGE(puah
->WndProcArray
, WM_WINDOWPOSCHANGING
);
319 UAH_HOOK_MESSAGE(puah
->WndProcArray
, WM_WINDOWPOSCHANGED
);
320 UAH_HOOK_MESSAGE(puah
->WndProcArray
, WM_STYLECHANGING
);
321 UAH_HOOK_MESSAGE(puah
->WndProcArray
, WM_STYLECHANGED
);
322 UAH_HOOK_MESSAGE(puah
->WndProcArray
, WM_NCCREATE
);
323 UAH_HOOK_MESSAGE(puah
->WndProcArray
, WM_NCDESTROY
);
324 UAH_HOOK_MESSAGE(puah
->WndProcArray
, WM_NCPAINT
);
325 UAH_HOOK_MESSAGE(puah
->WndProcArray
, WM_MENUCHAR
);
326 UAH_HOOK_MESSAGE(puah
->WndProcArray
, WM_MDISETMENU
);
327 UAH_HOOK_MESSAGE(puah
->WndProcArray
, WM_THEMECHANGED
);
328 UAH_HOOK_MESSAGE(puah
->WndProcArray
, WM_UAHINIT
);
330 UXTHEME_LoadTheme(TRUE
);
335 typedef BOOL (WINAPI
* PREGISTER_UAH_WINXP
)(HINSTANCE hInstance
, USERAPIHOOKPROC CallbackFunc
);
336 typedef BOOL (WINAPI
* PREGISTER_UUAH_WIN2003
)(PUSERAPIHOOKINFO puah
);
345 lpFunc
= GetProcAddress(GetModuleHandle("user32.dll"), "RegisterUserApiHook");
347 ZeroMemory(&osvi
, sizeof(OSVERSIONINFO
));
348 osvi
.dwOSVersionInfoSize
= sizeof(OSVERSIONINFO
);
351 if ( osvi
.dwMajorVersion
== 5 && osvi
.dwMinorVersion
== 1)
353 PREGISTER_UAH_WINXP lpfuncxp
= (PREGISTER_UAH_WINXP
)lpFunc
;
354 ret
= lpfuncxp(hDllInst
, ThemeInitApiHook
);
356 else if ( osvi
.dwMajorVersion
== 5 && osvi
.dwMinorVersion
== 2)
358 PREGISTER_UUAH_WIN2003 lpfunc2003
= (PREGISTER_UUAH_WIN2003
)lpFunc
;
361 uah
.m_size
= sizeof(uah
);
362 uah
.m_dllname1
= L
"uxtheme.dll";
363 uah
.m_funname1
= L
"ThemeInitApiHook";
364 uah
.m_dllname2
= NULL
;
365 uah
.m_funname2
= NULL
;
367 ret
= lpfunc2003(&uah
);
375 UXTHEME_broadcast_msg (NULL
, WM_THEMECHANGED
);
385 ret
= UnregisterUserApiHook();
387 UXTHEME_broadcast_msg (NULL
, WM_THEMECHANGED
);