[TASKMGR] Process page: Allow using "Open File Location" functionality without runnin...
[reactos.git] / 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 PWND_DATA pwndData;
272
273 pwndData = (PWND_DATA)GetPropW(hWnd, (LPCWSTR)MAKEINTATOM(atWndContext));
274
275 if(!IsAppThemed() ||
276 !(GetThemeAppProperties() & STAP_ALLOW_NONCLIENT) ||
277 (pwndData && pwndData->HasAppDefinedRgn))
278 {
279 return g_user32ApiHook.DefWindowProcW(hWnd,
280 Msg,
281 wParam,
282 lParam);
283 }
284
285 return ThemeWndProc(hWnd,
286 Msg,
287 wParam,
288 lParam,
289 g_user32ApiHook.DefWindowProcW);
290 }
291
292 static LRESULT CALLBACK
293 ThemeDefWindowProcA(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
294 {
295 PWND_DATA pwndData;
296
297 pwndData = (PWND_DATA)GetPropW(hWnd, (LPCWSTR)MAKEINTATOM(atWndContext));
298
299 if(!IsAppThemed() ||
300 !(GetThemeAppProperties() & STAP_ALLOW_NONCLIENT) ||
301 (pwndData && pwndData->HasAppDefinedRgn))
302 {
303 return g_user32ApiHook.DefWindowProcA(hWnd,
304 Msg,
305 wParam,
306 lParam);
307 }
308
309 return ThemeWndProc(hWnd,
310 Msg,
311 wParam,
312 lParam,
313 g_user32ApiHook.DefWindowProcA);
314 }
315
316 static LRESULT CALLBACK
317 ThemePreWindowProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam, ULONG_PTR ret,PDWORD unknown)
318 {
319 switch(Msg)
320 {
321 case WM_CREATE:
322 case WM_STYLECHANGED:
323 case WM_SIZE:
324 case WM_WINDOWPOSCHANGED:
325 {
326 if(IsAppThemed() && (GetThemeAppProperties() & STAP_ALLOW_NONCLIENT))
327 ThemeCalculateCaptionButtonsPos(hWnd, NULL);
328 break;
329 }
330 case WM_THEMECHANGED:
331 {
332 PWND_DATA pwndData = ThemeGetWndData(hWnd);
333
334 if (GetAncestor(hWnd, GA_PARENT) == GetDesktopWindow())
335 UXTHEME_LoadTheme(TRUE);
336
337 if (pwndData == NULL)
338 return 0;
339
340 if (pwndData->hTabBackgroundBrush != NULL)
341 {
342 DeleteObject(pwndData->hTabBackgroundBrush);
343 pwndData->hTabBackgroundBrush = NULL;
344 }
345
346 if (pwndData->hTabBackgroundBmp != NULL)
347 {
348 DeleteObject(pwndData->hTabBackgroundBmp);
349 pwndData->hTabBackgroundBmp = NULL;
350 }
351
352 if (pwndData->hthemeWindow)
353 {
354 CloseThemeData(pwndData->hthemeWindow);
355 pwndData->hthemeWindow = NULL;
356 }
357
358 if (pwndData->hthemeScrollbar)
359 {
360 CloseThemeData(pwndData->hthemeScrollbar);
361 pwndData->hthemeScrollbar = NULL;
362 }
363
364 if(IsAppThemed() && (GetThemeAppProperties() & STAP_ALLOW_NONCLIENT))
365 ThemeCalculateCaptionButtonsPos(hWnd, NULL);
366
367 pwndData->DirtyThemeRegion = TRUE;
368 break;
369 }
370 case WM_NCCREATE:
371 {
372 PWND_DATA pwndData = ThemeGetWndData(hWnd);
373 if (pwndData == NULL)
374 return 0;
375 pwndData->DirtyThemeRegion = TRUE;
376 }
377 }
378
379 return 0;
380 }
381
382
383 static LRESULT CALLBACK
384 ThemePostWindowProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam, ULONG_PTR ret,PDWORD unknown)
385 {
386 switch(Msg)
387 {
388 case WM_WINDOWPOSCHANGED:
389 {
390 return OnPostWinPosChanged(hWnd, (WINDOWPOS*)lParam);
391 }
392 case WM_NCDESTROY:
393 {
394 ThemeDestroyWndData(hWnd);
395 return 0;
396 }
397 }
398
399 return 0;
400 }
401
402 HRESULT GetDiaogTextureBrush(HTHEME theme, HWND hwnd, HDC hdc, HBRUSH* result, BOOL changeOrigin)
403 {
404 PWND_DATA pwndData;
405
406 pwndData = ThemeGetWndData(hwnd);
407 if (pwndData == NULL)
408 return E_FAIL;
409
410 if (pwndData->hTabBackgroundBrush == NULL)
411 {
412 HBITMAP hbmp;
413 RECT dummy, bmpRect;
414 BOOL hasImageAlpha;
415 HRESULT hr;
416
417 hr = UXTHEME_LoadImage(theme, 0, TABP_BODY, 0, &dummy, FALSE, &hbmp, &bmpRect, &hasImageAlpha);
418 if (FAILED(hr))
419 return hr;
420
421 if (changeOrigin)
422 {
423 /* Unfortunately SetBrushOrgEx doesn't work at all */
424 RECT rcWindow, rcParent;
425 UINT y;
426 HDC hdcPattern, hdcHackPattern;
427 HBITMAP hbmpOld1, hbmpold2, hbmpHack;
428
429 GetWindowRect(hwnd, &rcWindow);
430 GetWindowRect(GetParent(hwnd), &rcParent);
431 y = (rcWindow.top - rcParent.top) % bmpRect.bottom;
432
433 hdcPattern = CreateCompatibleDC(hdc);
434 hbmpOld1 = (HBITMAP)SelectObject(hdcPattern, hbmp);
435
436 hdcHackPattern = CreateCompatibleDC(hdc);
437 hbmpHack = CreateCompatibleBitmap(hdc, bmpRect.right, bmpRect.bottom);
438 hbmpold2 = (HBITMAP)SelectObject(hdcHackPattern, hbmpHack);
439
440 BitBlt(hdcHackPattern, 0, 0, bmpRect.right, bmpRect.bottom - y, hdcPattern, 0, y, SRCCOPY);
441 BitBlt(hdcHackPattern, 0, bmpRect.bottom - y, bmpRect.right, y, hdcPattern, 0, 0, SRCCOPY);
442
443 hbmpold2 = (HBITMAP)SelectObject(hdcHackPattern, hbmpold2);
444 hbmpOld1 = (HBITMAP)SelectObject(hdcPattern, hbmpOld1);
445
446 DeleteDC(hdcPattern);
447 DeleteDC(hdcHackPattern);
448
449 /* Keep the handle of the bitmap we created so that it can be used later */
450 pwndData->hTabBackgroundBmp = hbmpHack;
451 hbmp = hbmpHack;
452 }
453
454 /* hbmp is cached so there is no need to free it */
455 pwndData->hTabBackgroundBrush = CreatePatternBrush(hbmp);
456 }
457
458 if (!pwndData->hTabBackgroundBrush)
459 return E_FAIL;
460
461 *result = pwndData->hTabBackgroundBrush;
462 return S_OK;
463 }
464
465 void HackFillStaticBg(HWND hwnd, HDC hdc, HBRUSH* result)
466 {
467 RECT rcStatic;
468
469 GetClientRect(hwnd, &rcStatic);
470 FillRect(hdc, &rcStatic, *result);
471
472 SetBkMode (hdc, TRANSPARENT);
473 *result = GetStockObject (NULL_BRUSH);
474 }
475
476 static LRESULT CALLBACK
477 ThemeDlgPreWindowProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam, ULONG_PTR ret,PDWORD unknown)
478 {
479 return 0;
480 }
481
482 static LRESULT CALLBACK
483 ThemeDlgPostWindowProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam, ULONG_PTR ret,PDWORD unknown)
484 {
485 switch(Msg)
486 {
487 case WM_CTLCOLORDLG:
488 case WM_CTLCOLORBTN:
489 case WM_CTLCOLORSTATIC:
490 {
491 HWND hwndTarget = (HWND)lParam;
492 HDC hdc = (HDC)wParam;
493 HBRUSH* phbrush = (HBRUSH*)ret;
494 HTHEME hTheme;
495
496 if(!IsAppThemed() || !(GetThemeAppProperties() & STAP_ALLOW_NONCLIENT))
497 break;
498
499 if (!IsThemeDialogTextureEnabled (hWnd))
500 break;
501
502 hTheme = GetWindowTheme(hWnd);
503 if (!hTheme)
504 hTheme = OpenThemeData(hWnd, L"TAB");
505
506 if (!hTheme)
507 break;
508
509 GetDiaogTextureBrush(hTheme, hwndTarget, hdc, phbrush, Msg != WM_CTLCOLORDLG);
510
511 #if 1
512 {
513 WCHAR controlClass[32];
514 GetClassNameW (hwndTarget, controlClass, sizeof(controlClass) / sizeof(controlClass[0]));
515
516 /* This is a hack for the static class. Windows have a v6 static class just for this. */
517 if (lstrcmpiW (controlClass, WC_STATICW) == 0)
518 HackFillStaticBg(hwndTarget, hdc, phbrush);
519 }
520 #endif
521 SetBkMode( hdc, TRANSPARENT );
522 break;
523 }
524 }
525
526 return 0;
527 }
528
529 int WINAPI ThemeSetWindowRgn(HWND hWnd, HRGN hRgn, BOOL bRedraw)
530 {
531 PWND_DATA pwndData = ThemeGetWndData(hWnd);
532 if(pwndData)
533 {
534 pwndData->HasAppDefinedRgn = TRUE;
535 pwndData->HasThemeRgn = FALSE;
536 }
537
538 return g_user32ApiHook.SetWindowRgn(hWnd, hRgn, bRedraw);
539 }
540
541 BOOL WINAPI ThemeGetScrollInfo(HWND hwnd, int fnBar, LPSCROLLINFO lpsi)
542 {
543 PWND_DATA pwndData;
544 DWORD style;
545 BOOL ret;
546
547 /* Avoid creating a window context if it is not needed */
548 if(!IsAppThemed() || !(GetThemeAppProperties() & STAP_ALLOW_NONCLIENT))
549 goto dodefault;
550
551 style = GetWindowLongW(hwnd, GWL_STYLE);
552 if((style & (WS_HSCROLL|WS_VSCROLL))==0)
553 goto dodefault;
554
555 pwndData = ThemeGetWndData(hwnd);
556 if (pwndData == NULL)
557 goto dodefault;
558
559 /*
560 * Uxtheme needs to handle the tracking of the scrollbar itself
561 * This means than if an application needs to get the track position
562 * with GetScrollInfo, it will get wrong data. So uxtheme needs to
563 * hook it and set the correct tracking position itself
564 */
565 ret = g_user32ApiHook.GetScrollInfo(hwnd, fnBar, lpsi);
566 if ( lpsi &&
567 (lpsi->fMask & SIF_TRACKPOS) &&
568 pwndData->SCROLL_TrackingWin == hwnd &&
569 pwndData->SCROLL_TrackingBar == fnBar)
570 {
571 lpsi->nTrackPos = pwndData->SCROLL_TrackingVal;
572 }
573 return ret;
574
575 dodefault:
576 return g_user32ApiHook.GetScrollInfo(hwnd, fnBar, lpsi);
577 }
578
579 INT WINAPI ThemeSetScrollInfo(HWND hWnd, int fnBar, LPCSCROLLINFO lpsi, BOOL bRedraw)
580 {
581 PWND_DATA pwndData;
582 SCROLLINFO siout;
583 LPSCROLLINFO lpsiout = &siout;
584 BOOL IsThemed = FALSE;
585
586 pwndData = ThemeGetWndData(hWnd);
587
588 if (!pwndData)
589 goto dodefault;
590
591 if (pwndData->hthemeScrollbar)
592 IsThemed = TRUE;
593
594 memcpy(&siout, lpsi, sizeof(SCROLLINFO));
595 if (IsThemed)
596 siout.fMask |= SIF_THEMED;
597
598 dodefault:
599 return g_user32ApiHook.SetScrollInfo(hWnd, fnBar, lpsiout, bRedraw);
600 }
601
602 /**********************************************************************
603 * Exports
604 */
605
606 BOOL CALLBACK
607 ThemeInitApiHook(UAPIHK State, PUSERAPIHOOK puah)
608 {
609 if (!puah || State != uahLoadInit)
610 {
611 UXTHEME_LoadTheme(FALSE);
612 ThemeCleanupWndContext(NULL, 0);
613 g_bThemeHooksActive = FALSE;
614 return TRUE;
615 }
616
617 g_bThemeHooksActive = TRUE;
618
619 /* Store the original functions from user32 */
620 g_user32ApiHook = *puah;
621
622 puah->DefWindowProcA = ThemeDefWindowProcA;
623 puah->DefWindowProcW = ThemeDefWindowProcW;
624 puah->PreWndProc = ThemePreWindowProc;
625 puah->PostWndProc = ThemePostWindowProc;
626 puah->PreDefDlgProc = ThemeDlgPreWindowProc;
627 puah->PostDefDlgProc = ThemeDlgPostWindowProc;
628 puah->DefWndProcArray.MsgBitArray = gabDWPmessages;
629 puah->DefWndProcArray.Size = UAHOWP_MAX_SIZE;
630 puah->WndProcArray.MsgBitArray = gabMSGPmessages;
631 puah->WndProcArray.Size = UAHOWP_MAX_SIZE;
632 puah->DlgProcArray.MsgBitArray = gabDLGPmessages;
633 puah->DlgProcArray.Size = UAHOWP_MAX_SIZE;
634
635 puah->SetWindowRgn = ThemeSetWindowRgn;
636 puah->GetScrollInfo = ThemeGetScrollInfo;
637 puah->SetScrollInfo = ThemeSetScrollInfo;
638
639 UAH_HOOK_MESSAGE(puah->DefWndProcArray, WM_NCPAINT);
640 UAH_HOOK_MESSAGE(puah->DefWndProcArray, WM_NCACTIVATE);
641 UAH_HOOK_MESSAGE(puah->DefWndProcArray, WM_NCMOUSEMOVE);
642 UAH_HOOK_MESSAGE(puah->DefWndProcArray, WM_NCMOUSELEAVE);
643 UAH_HOOK_MESSAGE(puah->DefWndProcArray, WM_NCHITTEST);
644 UAH_HOOK_MESSAGE(puah->DefWndProcArray, WM_NCLBUTTONDOWN);
645 UAH_HOOK_MESSAGE(puah->DefWndProcArray, WM_NCUAHDRAWCAPTION);
646 UAH_HOOK_MESSAGE(puah->DefWndProcArray, WM_NCUAHDRAWFRAME);
647 UAH_HOOK_MESSAGE(puah->DefWndProcArray, WM_SETTEXT);
648 UAH_HOOK_MESSAGE(puah->DefWndProcArray, WM_WINDOWPOSCHANGED);
649 UAH_HOOK_MESSAGE(puah->DefWndProcArray, WM_CONTEXTMENU);
650 UAH_HOOK_MESSAGE(puah->DefWndProcArray, WM_STYLECHANGED);
651 UAH_HOOK_MESSAGE(puah->DefWndProcArray, WM_SETICON);
652 UAH_HOOK_MESSAGE(puah->DefWndProcArray, WM_NCDESTROY);
653 UAH_HOOK_MESSAGE(puah->DefWndProcArray, WM_SYSCOMMAND);
654 UAH_HOOK_MESSAGE(puah->DefWndProcArray, WM_CTLCOLORMSGBOX);
655 UAH_HOOK_MESSAGE(puah->DefWndProcArray, WM_CTLCOLORBTN);
656 UAH_HOOK_MESSAGE(puah->DefWndProcArray, WM_CTLCOLORSTATIC);
657
658 UAH_HOOK_MESSAGE(puah->WndProcArray, WM_CREATE);
659 UAH_HOOK_MESSAGE(puah->WndProcArray, WM_SETTINGCHANGE);
660 UAH_HOOK_MESSAGE(puah->WndProcArray, WM_DRAWITEM);
661 UAH_HOOK_MESSAGE(puah->WndProcArray, WM_MEASUREITEM);
662 UAH_HOOK_MESSAGE(puah->WndProcArray, WM_WINDOWPOSCHANGING);
663 UAH_HOOK_MESSAGE(puah->WndProcArray, WM_WINDOWPOSCHANGED);
664 UAH_HOOK_MESSAGE(puah->WndProcArray, WM_STYLECHANGING);
665 UAH_HOOK_MESSAGE(puah->WndProcArray, WM_STYLECHANGED);
666 UAH_HOOK_MESSAGE(puah->WndProcArray, WM_NCCREATE);
667 UAH_HOOK_MESSAGE(puah->WndProcArray, WM_NCDESTROY);
668 UAH_HOOK_MESSAGE(puah->WndProcArray, WM_NCPAINT);
669 UAH_HOOK_MESSAGE(puah->WndProcArray, WM_MENUCHAR);
670 UAH_HOOK_MESSAGE(puah->WndProcArray, WM_MDISETMENU);
671 UAH_HOOK_MESSAGE(puah->WndProcArray, WM_THEMECHANGED);
672 UAH_HOOK_MESSAGE(puah->WndProcArray, WM_UAHINIT);
673
674 puah->DlgProcArray.MsgBitArray = gabDLGPmessages;
675 puah->DlgProcArray.Size = UAHOWP_MAX_SIZE;
676
677 UAH_HOOK_MESSAGE(puah->DlgProcArray, WM_INITDIALOG);
678 UAH_HOOK_MESSAGE(puah->DlgProcArray, WM_CTLCOLORMSGBOX);
679 UAH_HOOK_MESSAGE(puah->DlgProcArray, WM_CTLCOLORBTN);
680 UAH_HOOK_MESSAGE(puah->DlgProcArray, WM_CTLCOLORDLG);
681 UAH_HOOK_MESSAGE(puah->DlgProcArray, WM_CTLCOLORSTATIC);
682 UAH_HOOK_MESSAGE(puah->DlgProcArray, WM_PRINTCLIENT);
683
684 UXTHEME_LoadTheme(TRUE);
685
686 return TRUE;
687 }
688
689 typedef BOOL (WINAPI * PREGISTER_UAH_WINXP)(HINSTANCE hInstance, USERAPIHOOKPROC CallbackFunc);
690 typedef BOOL (WINAPI * PREGISTER_UUAH_WIN2003)(PUSERAPIHOOKINFO puah);
691
692 BOOL WINAPI
693 ThemeHooksInstall()
694 {
695 PVOID lpFunc;
696 OSVERSIONINFO osvi;
697 BOOL ret;
698
699 lpFunc = GetProcAddress(GetModuleHandle("user32.dll"), "RegisterUserApiHook");
700
701 ZeroMemory(&osvi, sizeof(OSVERSIONINFO));
702 osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
703 GetVersionEx(&osvi);
704
705 if ( osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 1)
706 {
707 PREGISTER_UAH_WINXP lpfuncxp = (PREGISTER_UAH_WINXP)lpFunc;
708 ret = lpfuncxp(hDllInst, ThemeInitApiHook);
709 }
710 else if ( osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 2)
711 {
712 PREGISTER_UUAH_WIN2003 lpfunc2003 = (PREGISTER_UUAH_WIN2003)lpFunc;
713 USERAPIHOOKINFO uah;
714
715 uah.m_size = sizeof(uah);
716 uah.m_dllname1 = L"uxtheme.dll";
717 uah.m_funname1 = L"ThemeInitApiHook";
718 uah.m_dllname2 = NULL;
719 uah.m_funname2 = NULL;
720
721 ret = lpfunc2003(&uah);
722 }
723 else
724 {
725 UNIMPLEMENTED;
726 ret = FALSE;
727 }
728
729 UXTHEME_broadcast_theme_changed (NULL, TRUE);
730
731 return ret;
732 }
733
734 BOOL WINAPI
735 ThemeHooksRemove()
736 {
737 BOOL ret;
738
739 ret = UnregisterUserApiHook();
740
741 UXTHEME_broadcast_theme_changed (NULL, FALSE);
742
743 return ret;
744 }
745
746 INT WINAPI ClassicSystemParametersInfoW(UINT uiAction, UINT uiParam, PVOID pvParam, UINT fWinIni)
747 {
748 if (g_bThemeHooksActive)
749 {
750 return g_user32ApiHook.SystemParametersInfoW(uiAction, uiParam, pvParam, fWinIni);
751 }
752
753 return SystemParametersInfoW(uiAction, uiParam, pvParam, fWinIni);
754 }
755
756 INT WINAPI ClassicSystemParametersInfoA(UINT uiAction, UINT uiParam, PVOID pvParam, UINT fWinIni)
757 {
758 if (g_bThemeHooksActive)
759 {
760 return g_user32ApiHook.SystemParametersInfoA(uiAction, uiParam, pvParam, fWinIni);
761 }
762
763 return SystemParametersInfoA(uiAction, uiParam, pvParam, fWinIni);
764 }
765
766 INT WINAPI ClassicGetSystemMetrics(int nIndex)
767 {
768 if (g_bThemeHooksActive)
769 {
770 return g_user32ApiHook.GetSystemMetrics(nIndex);
771 }
772
773 return GetSystemMetrics(nIndex);
774 }
775
776 BOOL WINAPI ClassicAdjustWindowRectEx(LPRECT lpRect, DWORD dwStyle, BOOL bMenu, DWORD dwExStyle)
777 {
778 if (g_bThemeHooksActive)
779 {
780 return g_user32ApiHook.AdjustWindowRectEx(lpRect, dwStyle, bMenu, dwExStyle);
781 }
782
783 return AdjustWindowRectEx(lpRect, dwStyle, bMenu, dwExStyle);
784 }