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
11 USERAPIHOOK user32ApiHook
;
12 BYTE gabDWPmessages
[UAHOWP_MAX_SIZE
];
13 BYTE gabMSGPmessages
[UAHOWP_MAX_SIZE
];
14 BOOL gbThemeHooksActive
= FALSE
;
16 PWND_CONTEXT
ThemeGetWndContext(HWND hWnd
)
18 PWND_CONTEXT pcontext
;
20 pcontext
= (PWND_CONTEXT
)GetPropW(hWnd
, (LPCWSTR
)MAKEINTATOM(atWndContrext
));
23 pcontext
= HeapAlloc(GetProcessHeap(),
31 SetPropW( hWnd
, (LPCWSTR
)MAKEINTATOM(atWndContrext
), pcontext
);
37 void ThemeDetroyWndContext(HWND hWnd
)
39 PWND_CONTEXT pContext
;
42 /*Do not destroy WND_CONTEXT of a window that belong to another process */
43 GetWindowThreadProcessId(hWnd
, &ProcessId
);
44 if(ProcessId
!= GetCurrentProcessId())
49 pContext
= (PWND_CONTEXT
)GetPropW(hWnd
, (LPCWSTR
)MAKEINTATOM(atWndContrext
));
55 if(pContext
->HasThemeRgn
)
57 user32ApiHook
.SetWindowRgn(hWnd
, 0, TRUE
);
60 HeapFree(GetProcessHeap(), 0, pContext
);
62 SetPropW( hWnd
, (LPCWSTR
)MAKEINTATOM(atWndContrext
), NULL
);
65 static BOOL CALLBACK
ThemeCleanupChildWndContext (HWND hWnd
, LPARAM msg
)
67 ThemeDetroyWndContext(hWnd
);
71 static BOOL CALLBACK
ThemeCleanupWndContext(HWND hWnd
, LPARAM msg
)
75 EnumWindows (ThemeCleanupWndContext
, 0);
79 ThemeDetroyWndContext(hWnd
);
80 EnumChildWindows (hWnd
, ThemeCleanupChildWndContext
, 0);
86 void SetThemeRegion(HWND hWnd
, PWND_CONTEXT pcontext
)
91 int CaptionHeight
, iPart
;
96 if(pcontext
->HasThemeRgn
)
98 pcontext
->HasThemeRgn
= FALSE
;
99 user32ApiHook
.SetWindowRgn(hWnd
, 0, TRUE
);
104 wi
.cbSize
= sizeof(wi
);
106 GetWindowInfo(hWnd
, &wi
);
108 if((wi
.dwStyle
& WS_CAPTION
)!=WS_CAPTION
)
113 /* Get the caption part id */
114 if (wi
.dwExStyle
& WS_EX_TOOLWINDOW
)
115 iPart
= WP_SMALLCAPTION
;
116 else if (wi
.dwStyle
& WS_MAXIMIZE
)
117 iPart
= WP_MAXCAPTION
;
121 pcontext
->HasThemeRgn
= TRUE
;
123 CaptionHeight
= wi
.cyWindowBorders
;
124 CaptionHeight
+= GetSystemMetrics(wi
.dwExStyle
& WS_EX_TOOLWINDOW
? SM_CYSMCAPTION
: SM_CYCAPTION
);
126 GetWindowRect(hWnd
, &rcWindow
);
127 rcWindow
.right
-= rcWindow
.left
;
128 rcWindow
.bottom
= CaptionHeight
;
132 hTheme
= OpenThemeData (hWnd
, L
"WINDOW");
134 GetThemeBackgroundRegion(hTheme
, 0, iPart
, FS_ACTIVE
, &rcWindow
, &hrgn
);
136 CloseThemeData(hTheme
);
138 GetWindowRect(hWnd
, &rcWindow
);
139 rcWindow
.right
-= rcWindow
.left
;
140 rcWindow
.bottom
-= rcWindow
.top
;
141 rcWindow
.top
= CaptionHeight
;
143 hrgn1
= CreateRectRgnIndirect(&rcWindow
);
145 CombineRgn(hrgn
, hrgn
, hrgn1
, RGN_OR
);
149 user32ApiHook
.SetWindowRgn(hWnd
, hrgn
, TRUE
);
152 int OnPostWinPosChanged(HWND hWnd
)
154 PWND_CONTEXT pcontext
= ThemeGetWndContext(hWnd
);
157 pcontext
->HasAppDefinedRgn
== FALSE
&&
158 pcontext
->UpdatingRgn
== FALSE
)
160 pcontext
->UpdatingRgn
= TRUE
;
161 SetThemeRegion(hWnd
, pcontext
);
162 pcontext
= ThemeGetWndContext(hWnd
);
163 pcontext
->UpdatingRgn
= FALSE
;
168 /**********************************************************************
172 static LRESULT CALLBACK
173 ThemeDefWindowProcW(HWND hWnd
, UINT Msg
, WPARAM wParam
, LPARAM lParam
)
177 return user32ApiHook
.DefWindowProcW(hWnd
,
183 return ThemeWndProc(hWnd
,
187 user32ApiHook
.DefWindowProcW
);
190 static LRESULT CALLBACK
191 ThemeDefWindowProcA(HWND hWnd
, UINT Msg
, WPARAM wParam
, LPARAM lParam
)
195 return user32ApiHook
.DefWindowProcA(hWnd
,
201 return ThemeWndProc(hWnd
,
205 user32ApiHook
.DefWindowProcA
);
208 static LRESULT CALLBACK
209 ThemePreWindowProc(HWND hWnd
, UINT Msg
, WPARAM wParam
, LPARAM lParam
, ULONG_PTR ret
,PDWORD unknown
)
213 case WM_THEMECHANGED
:
214 UXTHEME_LoadTheme(TRUE
);
222 static LRESULT CALLBACK
223 ThemePostWindowProc(HWND hWnd
, UINT Msg
, WPARAM wParam
, LPARAM lParam
, ULONG_PTR ret
,PDWORD unknown
)
227 case WM_WINDOWPOSCHANGED
:
229 return OnPostWinPosChanged(hWnd
);
233 ThemeDetroyWndContext(hWnd
);
241 int WINAPI
ThemeSetWindowRgn(HWND hWnd
, HRGN hRgn
, BOOL bRedraw
)
243 PWND_CONTEXT pcontext
= ThemeGetWndContext(hWnd
);
246 pcontext
->HasAppDefinedRgn
= TRUE
;
247 pcontext
->HasThemeRgn
= FALSE
;
250 return user32ApiHook
.SetWindowRgn(hWnd
, hRgn
, bRedraw
);
253 /**********************************************************************
258 ThemeInitApiHook(UAPIHK State
, PUSERAPIHOOK puah
)
260 if (!puah
|| State
!= uahLoadInit
)
262 UXTHEME_LoadTheme(FALSE
);
263 ThemeCleanupWndContext(NULL
, 0);
264 gbThemeHooksActive
= FALSE
;
268 gbThemeHooksActive
= TRUE
;
270 /* Store the original functions from user32 */
271 user32ApiHook
= *puah
;
273 puah
->DefWindowProcA
= ThemeDefWindowProcA
;
274 puah
->DefWindowProcW
= ThemeDefWindowProcW
;
275 puah
->PreWndProc
= ThemePreWindowProc
;
276 puah
->PostWndProc
= ThemePostWindowProc
;
277 puah
->PreDefDlgProc
= ThemePreWindowProc
;
278 puah
->PostDefDlgProc
= ThemePostWindowProc
;
279 puah
->DefWndProcArray
.MsgBitArray
= gabDWPmessages
;
280 puah
->DefWndProcArray
.Size
= UAHOWP_MAX_SIZE
;
281 puah
->WndProcArray
.MsgBitArray
= gabMSGPmessages
;
282 puah
->WndProcArray
.Size
= UAHOWP_MAX_SIZE
;
283 puah
->DlgProcArray
.MsgBitArray
= gabMSGPmessages
;
284 puah
->DlgProcArray
.Size
= UAHOWP_MAX_SIZE
;
286 puah
->SetWindowRgn
= ThemeSetWindowRgn
;
288 UAH_HOOK_MESSAGE(puah
->DefWndProcArray
, WM_NCPAINT
);
289 UAH_HOOK_MESSAGE(puah
->DefWndProcArray
, WM_NCACTIVATE
);
290 UAH_HOOK_MESSAGE(puah
->DefWndProcArray
, WM_NCMOUSEMOVE
);
291 UAH_HOOK_MESSAGE(puah
->DefWndProcArray
, WM_NCMOUSELEAVE
);
292 UAH_HOOK_MESSAGE(puah
->DefWndProcArray
, WM_NCHITTEST
);
293 UAH_HOOK_MESSAGE(puah
->DefWndProcArray
, WM_NCLBUTTONDOWN
);
294 UAH_HOOK_MESSAGE(puah
->DefWndProcArray
, WM_NCUAHDRAWCAPTION
);
295 UAH_HOOK_MESSAGE(puah
->DefWndProcArray
, WM_NCUAHDRAWFRAME
);
296 UAH_HOOK_MESSAGE(puah
->DefWndProcArray
, WM_SETTEXT
);
297 UAH_HOOK_MESSAGE(puah
->DefWndProcArray
, WM_WINDOWPOSCHANGED
);
298 UAH_HOOK_MESSAGE(puah
->DefWndProcArray
, WM_CONTEXTMENU
);
299 UAH_HOOK_MESSAGE(puah
->DefWndProcArray
, WM_STYLECHANGED
);
300 UAH_HOOK_MESSAGE(puah
->DefWndProcArray
, WM_SETICON
);
301 UAH_HOOK_MESSAGE(puah
->DefWndProcArray
, WM_NCDESTROY
);
302 UAH_HOOK_MESSAGE(puah
->DefWndProcArray
, WM_SYSCOMMAND
);
303 UAH_HOOK_MESSAGE(puah
->DefWndProcArray
, WM_CTLCOLORMSGBOX
);
304 UAH_HOOK_MESSAGE(puah
->DefWndProcArray
, WM_CTLCOLORBTN
);
305 UAH_HOOK_MESSAGE(puah
->DefWndProcArray
, WM_CTLCOLORSTATIC
);
307 UAH_HOOK_MESSAGE(puah
->WndProcArray
, WM_CREATE
);
308 UAH_HOOK_MESSAGE(puah
->WndProcArray
, WM_SETTINGCHANGE
);
309 UAH_HOOK_MESSAGE(puah
->WndProcArray
, WM_DRAWITEM
);
310 UAH_HOOK_MESSAGE(puah
->WndProcArray
, WM_MEASUREITEM
);
311 UAH_HOOK_MESSAGE(puah
->WndProcArray
, WM_WINDOWPOSCHANGING
);
312 UAH_HOOK_MESSAGE(puah
->WndProcArray
, WM_WINDOWPOSCHANGED
);
313 UAH_HOOK_MESSAGE(puah
->WndProcArray
, WM_STYLECHANGING
);
314 UAH_HOOK_MESSAGE(puah
->WndProcArray
, WM_STYLECHANGED
);
315 UAH_HOOK_MESSAGE(puah
->WndProcArray
, WM_NCCREATE
);
316 UAH_HOOK_MESSAGE(puah
->WndProcArray
, WM_NCDESTROY
);
317 UAH_HOOK_MESSAGE(puah
->WndProcArray
, WM_NCPAINT
);
318 UAH_HOOK_MESSAGE(puah
->WndProcArray
, WM_MENUCHAR
);
319 UAH_HOOK_MESSAGE(puah
->WndProcArray
, WM_MDISETMENU
);
320 UAH_HOOK_MESSAGE(puah
->WndProcArray
, WM_THEMECHANGED
);
321 UAH_HOOK_MESSAGE(puah
->WndProcArray
, WM_UAHINIT
);
323 UXTHEME_LoadTheme(TRUE
);
328 typedef BOOL (WINAPI
* PREGISTER_UAH_WINXP
)(HINSTANCE hInstance
, USERAPIHOOKPROC CallbackFunc
);
329 typedef BOOL (WINAPI
* PREGISTER_UUAH_WIN2003
)(PUSERAPIHOOKINFO puah
);
338 lpFunc
= GetProcAddress(GetModuleHandle("user32.dll"), "RegisterUserApiHook");
340 ZeroMemory(&osvi
, sizeof(OSVERSIONINFO
));
341 osvi
.dwOSVersionInfoSize
= sizeof(OSVERSIONINFO
);
344 if ( osvi
.dwMajorVersion
== 5 && osvi
.dwMinorVersion
== 1)
346 PREGISTER_UAH_WINXP lpfuncxp
= (PREGISTER_UAH_WINXP
)lpFunc
;
347 ret
= lpfuncxp(hDllInst
, ThemeInitApiHook
);
349 else if ( osvi
.dwMajorVersion
== 5 && osvi
.dwMinorVersion
== 2)
351 PREGISTER_UUAH_WIN2003 lpfunc2003
= (PREGISTER_UUAH_WIN2003
)lpFunc
;
354 uah
.m_size
= sizeof(uah
);
355 uah
.m_dllname1
= L
"uxtheme.dll";
356 uah
.m_funname1
= L
"ThemeInitApiHook";
357 uah
.m_dllname2
= NULL
;
358 uah
.m_funname2
= NULL
;
360 ret
= lpfunc2003(&uah
);
368 UXTHEME_broadcast_msg (NULL
, WM_THEMECHANGED
);
378 ret
= UnregisterUserApiHook();
380 UXTHEME_broadcast_msg (NULL
, WM_THEMECHANGED
);