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