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