[UXTHEME] -Rename WND_CONTEXT to WND_DATA to avoid confusion with the DRAW_CONTEXT...
[reactos.git] / reactos / dll / win32 / uxtheme / themehooks.c
1 /*
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
7 */
8
9 #include "uxthemep.h"
10
11 USERAPIHOOK user32ApiHook;
12 BYTE gabDWPmessages[UAHOWP_MAX_SIZE];
13 BYTE gabMSGPmessages[UAHOWP_MAX_SIZE];
14 BYTE gabDLGPmessages[UAHOWP_MAX_SIZE];
15 BOOL gbThemeHooksActive = FALSE;
16
17 PWND_DATA ThemeGetWndData(HWND hWnd)
18 {
19 PWND_DATA pwndData;
20
21 pwndData = (PWND_DATA)GetPropW(hWnd, (LPCWSTR)MAKEINTATOM(atWndContext));
22 if(pwndData == NULL)
23 {
24 pwndData = HeapAlloc(GetProcessHeap(),
25 HEAP_ZERO_MEMORY,
26 sizeof(WND_DATA));
27 if(pwndData == NULL)
28 {
29 return NULL;
30 }
31
32 SetPropW( hWnd, (LPCWSTR)MAKEINTATOM(atWndContext), pwndData);
33 }
34
35 return pwndData;
36 }
37
38 void ThemeDestroyWndData(HWND hWnd)
39 {
40 PWND_DATA pwndData;
41 DWORD ProcessId;
42
43 /*Do not destroy WND_DATA of a window that belong to another process */
44 GetWindowThreadProcessId(hWnd, &ProcessId);
45 if(ProcessId != GetCurrentProcessId())
46 {
47 return;
48 }
49
50 pwndData = (PWND_DATA)GetPropW(hWnd, (LPCWSTR)MAKEINTATOM(atWndContext));
51 if(pwndData == NULL)
52 {
53 return;
54 }
55
56 if(pwndData->HasThemeRgn)
57 {
58 user32ApiHook.SetWindowRgn(hWnd, 0, TRUE);
59 }
60
61 if (pwndData->hTabBackgroundBrush != NULL)
62 {
63 CloseThemeData(GetWindowTheme(hWnd));
64
65 DeleteObject(pwndData->hTabBackgroundBrush);
66 pwndData->hTabBackgroundBrush = NULL;
67 }
68
69 if (pwndData->hTabBackgroundBmp != NULL)
70 {
71 DeleteObject(pwndData->hTabBackgroundBmp);
72 pwndData->hTabBackgroundBmp = NULL;
73 }
74
75 HeapFree(GetProcessHeap(), 0, pwndData);
76
77 SetPropW( hWnd, (LPCWSTR)MAKEINTATOM(atWndContext), NULL);
78 }
79
80 static BOOL CALLBACK ThemeCleanupChildWndContext (HWND hWnd, LPARAM msg)
81 {
82 ThemeDestroyWndData(hWnd);
83 return TRUE;
84 }
85
86 static BOOL CALLBACK ThemeCleanupWndContext(HWND hWnd, LPARAM msg)
87 {
88 if (hWnd == NULL)
89 {
90 EnumWindows (ThemeCleanupWndContext, 0);
91 }
92 else
93 {
94 ThemeDestroyWndData(hWnd);
95 EnumChildWindows (hWnd, ThemeCleanupChildWndContext, 0);
96 }
97
98 return TRUE;
99 }
100
101 void SetThemeRegion(HWND hWnd)
102 {
103 HTHEME hTheme;
104 RECT rcWindow;
105 HRGN hrgn, hrgn1;
106 int CaptionHeight, iPart;
107 WINDOWINFO wi;
108
109 TRACE("SetThemeRegion %d\n", hWnd);
110
111 wi.cbSize = sizeof(wi);
112 GetWindowInfo(hWnd, &wi);
113
114 /* Get the caption part id */
115 if (wi.dwStyle & WS_MINIMIZE)
116 iPart = WP_MINCAPTION;
117 else if (wi.dwExStyle & WS_EX_TOOLWINDOW)
118 iPart = WP_SMALLCAPTION;
119 else if (wi.dwStyle & WS_MAXIMIZE)
120 iPart = WP_MAXCAPTION;
121 else
122 iPart = WP_CAPTION;
123
124 CaptionHeight = wi.cyWindowBorders;
125 CaptionHeight += GetSystemMetrics(wi.dwExStyle & WS_EX_TOOLWINDOW ? SM_CYSMCAPTION : SM_CYCAPTION );
126
127 GetWindowRect(hWnd, &rcWindow);
128 rcWindow.right -= rcWindow.left;
129 rcWindow.bottom = CaptionHeight;
130 rcWindow.top = 0;
131 rcWindow.left = 0;
132
133 hTheme = MSSTYLES_OpenThemeClass(ActiveThemeFile, NULL, L"WINDOW");
134 GetThemeBackgroundRegion(hTheme, 0, iPart, FS_ACTIVE, &rcWindow, &hrgn);
135 CloseThemeData(hTheme);
136
137 GetWindowRect(hWnd, &rcWindow);
138 rcWindow.right -= rcWindow.left;
139 rcWindow.bottom -= rcWindow.top;
140 rcWindow.top = CaptionHeight;
141 rcWindow.left = 0;
142 hrgn1 = CreateRectRgnIndirect(&rcWindow);
143
144 CombineRgn(hrgn, hrgn, hrgn1, RGN_OR );
145
146 DeleteObject(hrgn1);
147
148 user32ApiHook.SetWindowRgn(hWnd, hrgn, TRUE);
149 }
150
151 int OnPostWinPosChanged(HWND hWnd, WINDOWPOS* pWinPos)
152 {
153 PWND_DATA pwndData;
154 DWORD style;
155
156 /* We only proceed to change the window shape if it has a caption */
157 style = GetWindowLongW(hWnd, GWL_STYLE);
158 if((style & WS_CAPTION)!=WS_CAPTION)
159 return 0;
160
161 /* Get theme data for this window */
162 pwndData = ThemeGetWndData(hWnd);
163 if (pwndData == NULL)
164 return 0;
165
166 /* Do not change the region of the window if its size wasn't changed */
167 if ((pWinPos->flags & SWP_NOSIZE) != 0 && pwndData->DirtyThemeRegion == FALSE)
168 return 0;
169
170 /* We don't touch the shape of the window if the application sets it on its own */
171 if (pwndData->HasAppDefinedRgn == TRUE)
172 return 0;
173
174 /* Calling SetWindowRgn will call SetWindowPos again so we need to avoid this recursion */
175 if (pwndData->UpdatingRgn == TRUE)
176 return 0;
177
178 if(!IsAppThemed())
179 {
180 if(pwndData->HasThemeRgn)
181 {
182 pwndData->HasThemeRgn = FALSE;
183 user32ApiHook.SetWindowRgn(hWnd, 0, TRUE);
184 }
185 return 0;
186 }
187
188 pwndData->DirtyThemeRegion = FALSE;
189 pwndData->HasThemeRgn = TRUE;
190 pwndData->UpdatingRgn = TRUE;
191 SetThemeRegion(hWnd);
192 pwndData->UpdatingRgn = FALSE;
193
194 return 0;
195 }
196
197 /**********************************************************************
198 * Hook Functions
199 */
200
201 static LRESULT CALLBACK
202 ThemeDefWindowProcW(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
203 {
204 if(!IsAppThemed())
205 {
206 return user32ApiHook.DefWindowProcW(hWnd,
207 Msg,
208 wParam,
209 lParam);
210 }
211
212 return ThemeWndProc(hWnd,
213 Msg,
214 wParam,
215 lParam,
216 user32ApiHook.DefWindowProcW);
217 }
218
219 static LRESULT CALLBACK
220 ThemeDefWindowProcA(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
221 {
222 if(!IsAppThemed())
223 {
224 return user32ApiHook.DefWindowProcA(hWnd,
225 Msg,
226 wParam,
227 lParam);
228 }
229
230 return ThemeWndProc(hWnd,
231 Msg,
232 wParam,
233 lParam,
234 user32ApiHook.DefWindowProcA);
235 }
236
237 static LRESULT CALLBACK
238 ThemePreWindowProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam, ULONG_PTR ret,PDWORD unknown)
239 {
240 switch(Msg)
241 {
242 case WM_THEMECHANGED:
243 {
244 PWND_DATA pwndData = ThemeGetWndData(hWnd);
245
246 if (GetAncestor(hWnd, GA_PARENT) == GetDesktopWindow())
247 UXTHEME_LoadTheme(TRUE);
248
249 if (pwndData == NULL)
250 return 0;
251
252 if (pwndData->hTabBackgroundBrush != NULL)
253 {
254 DeleteObject(pwndData->hTabBackgroundBrush);
255 pwndData->hTabBackgroundBrush = NULL;
256 }
257
258 if (pwndData->hTabBackgroundBmp != NULL)
259 {
260 DeleteObject(pwndData->hTabBackgroundBmp);
261 pwndData->hTabBackgroundBmp = NULL;
262 }
263 }
264 case WM_NCCREATE:
265 {
266 PWND_DATA pwndData = ThemeGetWndData(hWnd);
267 if (pwndData == NULL)
268 return 0;
269 pwndData->DirtyThemeRegion = TRUE;
270 }
271 }
272
273 return 0;
274 }
275
276
277 static LRESULT CALLBACK
278 ThemePostWindowProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam, ULONG_PTR ret,PDWORD unknown)
279 {
280 switch(Msg)
281 {
282 case WM_WINDOWPOSCHANGED:
283 {
284 return OnPostWinPosChanged(hWnd, (WINDOWPOS*)lParam);
285 }
286 case WM_NCDESTROY:
287 {
288 ThemeDestroyWndData(hWnd);
289 return 0;
290 }
291 }
292
293 return 0;
294 }
295
296 HRESULT GetDiaogTextureBrush(HTHEME theme, HWND hwnd, HDC hdc, HBRUSH* result, BOOL changeOrigin)
297 {
298 PWND_DATA pwndData;
299
300 pwndData = ThemeGetWndData(hwnd);
301 if (pwndData == NULL)
302 return E_FAIL;
303
304 if (pwndData->hTabBackgroundBrush == NULL)
305 {
306 HBITMAP hbmp;
307 RECT dummy, bmpRect;
308 BOOL hasImageAlpha;
309
310 UXTHEME_LoadImage(theme, 0, TABP_BODY, 0, &dummy, FALSE, &hbmp, &bmpRect, &hasImageAlpha);
311 if (changeOrigin)
312 {
313 /* Unfortunately SetBrushOrgEx doesn't work at all */
314 RECT rcWindow, rcParent;
315 UINT y;
316 HDC hdcPattern, hdcHackPattern;
317 HBITMAP hbmpOld1, hbmpold2, hbmpHack;
318
319 GetWindowRect(hwnd, &rcWindow);
320 GetWindowRect(GetParent(hwnd), &rcParent);
321 y = (rcWindow.top - rcParent.top) % bmpRect.bottom;
322
323 hdcPattern = CreateCompatibleDC(hdc);
324 hbmpOld1 = (HBITMAP)SelectObject(hdcPattern, hbmp);
325
326 hdcHackPattern = CreateCompatibleDC(hdc);
327 hbmpHack = CreateCompatibleBitmap(hdc, bmpRect.right, bmpRect.bottom);
328 hbmpold2 = (HBITMAP)SelectObject(hdcHackPattern, hbmpHack);
329
330 BitBlt(hdcHackPattern, 0, 0, bmpRect.right, bmpRect.bottom - y, hdcPattern, 0, y, SRCCOPY);
331 BitBlt(hdcHackPattern, 0, bmpRect.bottom - y, bmpRect.right, y, hdcPattern, 0, 0, SRCCOPY);
332
333 hbmpold2 = (HBITMAP)SelectObject(hdcHackPattern, hbmpold2);
334 hbmpOld1 = (HBITMAP)SelectObject(hdcPattern, hbmpOld1);
335
336 DeleteDC(hdcPattern);
337 DeleteDC(hdcHackPattern);
338
339 /* Keep the handle of the bitmap we created so that it can be used later */
340 pwndData->hTabBackgroundBmp = hbmpHack;
341 hbmp = hbmpHack;
342 }
343
344 /* hbmp is cached so there is no need to free it */
345 pwndData->hTabBackgroundBrush = CreatePatternBrush(hbmp);
346 }
347
348 if (!pwndData->hTabBackgroundBrush)
349 return E_FAIL;
350
351 *result = pwndData->hTabBackgroundBrush;
352 return S_OK;
353 }
354
355 void HackFillStaticBg(HWND hwnd, HDC hdc, HBRUSH* result)
356 {
357 RECT rcStatic;
358
359 GetClientRect(hwnd, &rcStatic);
360 FillRect(hdc, &rcStatic, *result);
361
362 SetBkMode (hdc, TRANSPARENT);
363 *result = GetStockObject (NULL_BRUSH);
364 }
365
366 static LRESULT CALLBACK
367 ThemeDlgPreWindowProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam, ULONG_PTR ret,PDWORD unknown)
368 {
369 return 0;
370 }
371
372 static LRESULT CALLBACK
373 ThemeDlgPostWindowProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam, ULONG_PTR ret,PDWORD unknown)
374 {
375 switch(Msg)
376 {
377 case WM_CTLCOLORDLG:
378 case WM_CTLCOLORBTN:
379 case WM_CTLCOLORSTATIC:
380 {
381 HWND hwndTarget = (HWND)lParam;
382 HDC hdc = (HDC)wParam;
383 HBRUSH* phbrush = (HBRUSH*)ret;
384 HTHEME hTheme;
385
386 if (!IsAppThemed())
387 break;
388
389 if (!IsThemeDialogTextureEnabled (hWnd))
390 break;
391
392 hTheme = GetWindowTheme(hWnd);
393 if (!hTheme)
394 hTheme = OpenThemeData(hWnd, L"TAB");
395
396 if (!hTheme)
397 break;
398
399 GetDiaogTextureBrush(hTheme, hwndTarget, hdc, phbrush, Msg != WM_CTLCOLORDLG);
400
401 #if 1
402 {
403 WCHAR controlClass[32];
404 GetClassNameW (hwndTarget, controlClass, sizeof(controlClass) / sizeof(controlClass[0]));
405
406 /* This is a hack for the static class. Windows have a v6 static class just for this. */
407 if (lstrcmpiW (controlClass, WC_STATICW) == 0)
408 HackFillStaticBg(hwndTarget, hdc, phbrush);
409 }
410 #endif
411 break;
412 }
413 }
414
415 return 0;
416 }
417
418 int WINAPI ThemeSetWindowRgn(HWND hWnd, HRGN hRgn, BOOL bRedraw)
419 {
420 PWND_DATA pwndData = ThemeGetWndData(hWnd);
421 if(pwndData)
422 {
423 pwndData->HasAppDefinedRgn = TRUE;
424 pwndData->HasThemeRgn = FALSE;
425 }
426
427 return user32ApiHook.SetWindowRgn(hWnd, hRgn, bRedraw);
428 }
429
430 BOOL WINAPI ThemeGetScrollInfo(HWND hwnd, int fnBar, LPSCROLLINFO lpsi)
431 {
432 PWND_DATA pwndData;
433 DWORD style;
434 BOOL ret;
435
436 /* Avoid creating a window context if it is not needed */
437 if(!IsAppThemed())
438 goto dodefault;
439
440 style = GetWindowLongW(hwnd, GWL_STYLE);
441 if((style & (WS_HSCROLL|WS_VSCROLL))==0)
442 goto dodefault;
443
444 pwndData = ThemeGetWndData(hwnd);
445 if (pwndData == NULL)
446 goto dodefault;
447
448 /*
449 * Uxtheme needs to handle the tracking of the scrollbar itself
450 * This means than if an application needs to get the track position
451 * with GetScrollInfo, it will get wrong data. So uxtheme needs to
452 * hook it and set the correct tracking position itself
453 */
454 ret = user32ApiHook.GetScrollInfo(hwnd, fnBar, lpsi);
455 if ( lpsi &&
456 (lpsi->fMask & SIF_TRACKPOS) &&
457 pwndData->SCROLL_TrackingWin == hwnd &&
458 pwndData->SCROLL_TrackingBar == fnBar)
459 {
460 lpsi->nTrackPos = pwndData->SCROLL_TrackingVal;
461 }
462 return ret;
463
464 dodefault:
465 return user32ApiHook.GetScrollInfo(hwnd, fnBar, lpsi);
466 }
467
468 /**********************************************************************
469 * Exports
470 */
471
472 BOOL CALLBACK
473 ThemeInitApiHook(UAPIHK State, PUSERAPIHOOK puah)
474 {
475 if (!puah || State != uahLoadInit)
476 {
477 UXTHEME_LoadTheme(FALSE);
478 ThemeCleanupWndContext(NULL, 0);
479 gbThemeHooksActive = FALSE;
480 return TRUE;
481 }
482
483 gbThemeHooksActive = TRUE;
484
485 /* Store the original functions from user32 */
486 user32ApiHook = *puah;
487
488 puah->DefWindowProcA = ThemeDefWindowProcA;
489 puah->DefWindowProcW = ThemeDefWindowProcW;
490 puah->PreWndProc = ThemePreWindowProc;
491 puah->PostWndProc = ThemePostWindowProc;
492 puah->PreDefDlgProc = ThemeDlgPreWindowProc;
493 puah->PostDefDlgProc = ThemeDlgPostWindowProc;
494 puah->DefWndProcArray.MsgBitArray = gabDWPmessages;
495 puah->DefWndProcArray.Size = UAHOWP_MAX_SIZE;
496 puah->WndProcArray.MsgBitArray = gabMSGPmessages;
497 puah->WndProcArray.Size = UAHOWP_MAX_SIZE;
498 puah->DlgProcArray.MsgBitArray = gabDLGPmessages;
499 puah->DlgProcArray.Size = UAHOWP_MAX_SIZE;
500
501 puah->SetWindowRgn = ThemeSetWindowRgn;
502 puah->GetScrollInfo = ThemeGetScrollInfo;
503
504 UAH_HOOK_MESSAGE(puah->DefWndProcArray, WM_NCPAINT);
505 UAH_HOOK_MESSAGE(puah->DefWndProcArray, WM_NCACTIVATE);
506 UAH_HOOK_MESSAGE(puah->DefWndProcArray, WM_NCMOUSEMOVE);
507 UAH_HOOK_MESSAGE(puah->DefWndProcArray, WM_NCMOUSELEAVE);
508 UAH_HOOK_MESSAGE(puah->DefWndProcArray, WM_NCHITTEST);
509 UAH_HOOK_MESSAGE(puah->DefWndProcArray, WM_NCLBUTTONDOWN);
510 UAH_HOOK_MESSAGE(puah->DefWndProcArray, WM_NCUAHDRAWCAPTION);
511 UAH_HOOK_MESSAGE(puah->DefWndProcArray, WM_NCUAHDRAWFRAME);
512 UAH_HOOK_MESSAGE(puah->DefWndProcArray, WM_SETTEXT);
513 UAH_HOOK_MESSAGE(puah->DefWndProcArray, WM_WINDOWPOSCHANGED);
514 UAH_HOOK_MESSAGE(puah->DefWndProcArray, WM_CONTEXTMENU);
515 UAH_HOOK_MESSAGE(puah->DefWndProcArray, WM_STYLECHANGED);
516 UAH_HOOK_MESSAGE(puah->DefWndProcArray, WM_SETICON);
517 UAH_HOOK_MESSAGE(puah->DefWndProcArray, WM_NCDESTROY);
518 UAH_HOOK_MESSAGE(puah->DefWndProcArray, WM_SYSCOMMAND);
519 UAH_HOOK_MESSAGE(puah->DefWndProcArray, WM_CTLCOLORMSGBOX);
520 UAH_HOOK_MESSAGE(puah->DefWndProcArray, WM_CTLCOLORBTN);
521 UAH_HOOK_MESSAGE(puah->DefWndProcArray, WM_CTLCOLORSTATIC);
522
523 UAH_HOOK_MESSAGE(puah->WndProcArray, WM_CREATE);
524 UAH_HOOK_MESSAGE(puah->WndProcArray, WM_SETTINGCHANGE);
525 UAH_HOOK_MESSAGE(puah->WndProcArray, WM_DRAWITEM);
526 UAH_HOOK_MESSAGE(puah->WndProcArray, WM_MEASUREITEM);
527 UAH_HOOK_MESSAGE(puah->WndProcArray, WM_WINDOWPOSCHANGING);
528 UAH_HOOK_MESSAGE(puah->WndProcArray, WM_WINDOWPOSCHANGED);
529 UAH_HOOK_MESSAGE(puah->WndProcArray, WM_STYLECHANGING);
530 UAH_HOOK_MESSAGE(puah->WndProcArray, WM_STYLECHANGED);
531 UAH_HOOK_MESSAGE(puah->WndProcArray, WM_NCCREATE);
532 UAH_HOOK_MESSAGE(puah->WndProcArray, WM_NCDESTROY);
533 UAH_HOOK_MESSAGE(puah->WndProcArray, WM_NCPAINT);
534 UAH_HOOK_MESSAGE(puah->WndProcArray, WM_MENUCHAR);
535 UAH_HOOK_MESSAGE(puah->WndProcArray, WM_MDISETMENU);
536 UAH_HOOK_MESSAGE(puah->WndProcArray, WM_THEMECHANGED);
537 UAH_HOOK_MESSAGE(puah->WndProcArray, WM_UAHINIT);
538
539 puah->DlgProcArray.MsgBitArray = gabDLGPmessages;
540 puah->DlgProcArray.Size = UAHOWP_MAX_SIZE;
541
542 UAH_HOOK_MESSAGE(puah->DlgProcArray, WM_INITDIALOG);
543 UAH_HOOK_MESSAGE(puah->DlgProcArray, WM_CTLCOLORMSGBOX);
544 UAH_HOOK_MESSAGE(puah->DlgProcArray, WM_CTLCOLORBTN);
545 UAH_HOOK_MESSAGE(puah->DlgProcArray, WM_CTLCOLORDLG);
546 UAH_HOOK_MESSAGE(puah->DlgProcArray, WM_CTLCOLORSTATIC);
547 UAH_HOOK_MESSAGE(puah->DlgProcArray, WM_PRINTCLIENT);
548
549 UXTHEME_LoadTheme(TRUE);
550
551 return TRUE;
552 }
553
554 typedef BOOL (WINAPI * PREGISTER_UAH_WINXP)(HINSTANCE hInstance, USERAPIHOOKPROC CallbackFunc);
555 typedef BOOL (WINAPI * PREGISTER_UUAH_WIN2003)(PUSERAPIHOOKINFO puah);
556
557 BOOL WINAPI
558 ThemeHooksInstall()
559 {
560 PVOID lpFunc;
561 OSVERSIONINFO osvi;
562 BOOL ret;
563
564 lpFunc = GetProcAddress(GetModuleHandle("user32.dll"), "RegisterUserApiHook");
565
566 ZeroMemory(&osvi, sizeof(OSVERSIONINFO));
567 osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
568 GetVersionEx(&osvi);
569
570 if ( osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 1)
571 {
572 PREGISTER_UAH_WINXP lpfuncxp = (PREGISTER_UAH_WINXP)lpFunc;
573 ret = lpfuncxp(hDllInst, ThemeInitApiHook);
574 }
575 else if ( osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 2)
576 {
577 PREGISTER_UUAH_WIN2003 lpfunc2003 = (PREGISTER_UUAH_WIN2003)lpFunc;
578 USERAPIHOOKINFO uah;
579
580 uah.m_size = sizeof(uah);
581 uah.m_dllname1 = L"uxtheme.dll";
582 uah.m_funname1 = L"ThemeInitApiHook";
583 uah.m_dllname2 = NULL;
584 uah.m_funname2 = NULL;
585
586 ret = lpfunc2003(&uah);
587 }
588 else
589 {
590 UNIMPLEMENTED;
591 ret = FALSE;
592 }
593
594 UXTHEME_broadcast_msg (NULL, WM_THEMECHANGED);
595
596 return ret;
597 }
598
599 BOOL WINAPI
600 ThemeHooksRemove()
601 {
602 BOOL ret;
603
604 ret = UnregisterUserApiHook();
605
606 UXTHEME_broadcast_msg (NULL, WM_THEMECHANGED);
607
608 return ret;
609 }
610
611 INT WINAPI ClassicSystemParametersInfoW(UINT uiAction, UINT uiParam, PVOID pvParam, UINT fWinIni)
612 {
613 if (gbThemeHooksActive)
614 {
615 return user32ApiHook.SystemParametersInfoW(uiAction, uiParam, pvParam, fWinIni);
616 }
617
618 return SystemParametersInfoW(uiAction, uiParam, pvParam, fWinIni);
619 }
620
621 INT WINAPI ClassicSystemParametersInfoA(UINT uiAction, UINT uiParam, PVOID pvParam, UINT fWinIni)
622 {
623 if (gbThemeHooksActive)
624 {
625 return user32ApiHook.SystemParametersInfoA(uiAction, uiParam, pvParam, fWinIni);
626 }
627
628 return SystemParametersInfoA(uiAction, uiParam, pvParam, fWinIni);
629 }
630
631 INT WINAPI ClassicGetSystemMetrics(int nIndex)
632 {
633 if (gbThemeHooksActive)
634 {
635 return user32ApiHook.GetSystemMetrics(nIndex);
636 }
637
638 return GetSystemMetrics(nIndex);
639 }
640
641 BOOL WINAPI ClassicAdjustWindowRectEx(LPRECT lpRect, DWORD dwStyle, BOOL bMenu, DWORD dwExStyle)
642 {
643 if (gbThemeHooksActive)
644 {
645 return user32ApiHook.AdjustWindowRectEx(lpRect, dwStyle, bMenu, dwExStyle);
646 }
647
648 return AdjustWindowRectEx(lpRect, dwStyle, bMenu, dwExStyle);
649 }