1 /* 2 * COPYRIGHT: See COPYING in the top level directory 3 * PROJECT: ReactOS user32.dll 4 * PURPOSE: Window management 5 * PROGRAMMER: 2001 Casper S. Hornstrup <chorns@users.sourceforge.net> 6 */ 7 8 #include <user32.h> 9 #include <immdev.h> 10 11 WINE_DEFAULT_DEBUG_CHANNEL(user32); 12 13 /* 14 * @implemented 15 */ 16 DWORD 17 WINAPI 18 DECLSPEC_HOTPATCH 19 GetSysColor(int nIndex) 20 { 21 if(nIndex >= 0 && nIndex < NUM_SYSCOLORS) 22 { 23 return gpsi->argbSystem[nIndex]; 24 } 25 26 SetLastError(ERROR_INVALID_PARAMETER); 27 return 0; 28 } 29 30 /* 31 * @implemented 32 */ 33 HBRUSH 34 WINAPI 35 DECLSPEC_HOTPATCH 36 GetSysColorBrush(int nIndex) 37 { 38 if(nIndex >= 0 && nIndex < NUM_SYSCOLORS) 39 { 40 return gpsi->ahbrSystem[nIndex]; 41 } 42 43 return NULL; 44 } 45 46 /* 47 * @implemented 48 */ 49 BOOL 50 WINAPI 51 SetSysColors( 52 int cElements, 53 CONST INT *lpaElements, 54 CONST COLORREF *lpaRgbValues) 55 { 56 return NtUserSetSysColors(cElements, lpaElements, lpaRgbValues, 0); 57 } 58 59 BOOL 60 FASTCALL 61 DefSetText(HWND hWnd, PCWSTR String, BOOL Ansi) 62 { 63 BOOL Ret; 64 LARGE_STRING lsString; 65 66 if ( String ) 67 { 68 if ( Ansi ) 69 RtlInitLargeAnsiString((PLARGE_ANSI_STRING)&lsString, (PCSZ)String, 0); 70 else 71 RtlInitLargeUnicodeString((PLARGE_UNICODE_STRING)&lsString, String, 0); 72 } 73 Ret = NtUserDefSetText(hWnd, (String ? &lsString : NULL)); 74 75 return Ret; 76 } 77 78 HWND FASTCALL 79 IntFindChildWindowToOwner(HWND hRoot, HWND hOwner) 80 { 81 HWND Ret; 82 PWND Child, OwnerWnd, Root, Owner; 83 84 Root = ValidateHwnd(hRoot); 85 Owner = ValidateHwnd(hOwner); 86 87 for( Child = Root->spwndChild ? DesktopPtrToUser(Root->spwndChild) : NULL; 88 Child; 89 Child = Child->spwndNext ? DesktopPtrToUser(Child->spwndNext) : NULL ) 90 { 91 OwnerWnd = Child->spwndOwner ? DesktopPtrToUser(Child->spwndOwner) : NULL; 92 if(!OwnerWnd) 93 continue; 94 95 if (!(Child->style & WS_POPUP) || !(Child->style & WS_VISIBLE)) 96 continue; 97 98 if(OwnerWnd == Owner) 99 { 100 Ret = Child->head.h; 101 return Ret; 102 } 103 } 104 ERR("IDCWTO Nothing found\n"); 105 return NULL; 106 } 107 108 /*********************************************************************** 109 * DefWndTrackScrollBar 110 * 111 * Track a mouse button press on the horizontal or vertical scroll-bar. 112 */ 113 static VOID 114 DefWndTrackScrollBar(HWND Wnd, WPARAM wParam, POINT Pt) 115 { 116 INT ScrollBar; 117 118 if (SC_HSCROLL == (wParam & 0xfff0)) 119 { 120 if (HTHSCROLL != (wParam & 0x0f)) 121 { 122 return; 123 } 124 ScrollBar = SB_HORZ; 125 } 126 else /* SC_VSCROLL */ 127 { 128 if (HTVSCROLL != (wParam & 0x0f)) 129 { 130 return; 131 } 132 ScrollBar = SB_VERT; 133 } 134 ScrollTrackScrollBar(Wnd, ScrollBar, Pt ); 135 } 136 137 LRESULT WINAPI DoAppSwitch( WPARAM wParam, LPARAM lParam); 138 139 LRESULT 140 DefWndHandleSysCommand(HWND hWnd, WPARAM wParam, LPARAM lParam) 141 { 142 POINT Pt; 143 LRESULT lResult; 144 145 if (!IsWindowEnabled( hWnd )) return 0; 146 147 switch (wParam & 0xfff0) 148 { 149 case SC_MOVE: 150 case SC_SIZE: 151 // case SC_DEFAULT: 152 case SC_MOUSEMENU: 153 case SC_KEYMENU: 154 case SC_SCREENSAVE: 155 case SC_MINIMIZE: 156 case SC_MAXIMIZE: 157 case SC_RESTORE: 158 case SC_CLOSE: 159 case SC_HOTKEY: 160 NtUserMessageCall(hWnd, WM_SYSCOMMAND, wParam, lParam, (ULONG_PTR)&lResult, FNID_DEFWINDOWPROC, FALSE); 161 return 0; 162 163 default: 164 break; 165 } 166 167 if (ISITHOOKED(WH_CBT)) 168 { 169 NtUserMessageCall(hWnd, WM_SYSCOMMAND, wParam, lParam, (ULONG_PTR)&lResult, FNID_DEFWINDOWPROC, FALSE); 170 if (lResult) return 0; 171 } 172 173 switch (wParam & 0xfff0) 174 { 175 case SC_VSCROLL: 176 case SC_HSCROLL: 177 { 178 Pt.x = (short)LOWORD(lParam); 179 Pt.y = (short)HIWORD(lParam); 180 DefWndTrackScrollBar(hWnd, wParam, Pt); 181 } 182 break; 183 184 case SC_TASKLIST: 185 WinExec( "taskman.exe", SW_SHOWNORMAL ); 186 break; 187 188 189 case SC_NEXTWINDOW: 190 case SC_PREVWINDOW: 191 DoAppSwitch( wParam, lParam); 192 break; 193 194 default: 195 FIXME("Unimplemented DefWndHandleSysCommand wParam 0x%x\n",wParam); 196 break; 197 } 198 199 return(0); 200 } 201 202 /*********************************************************************** 203 * DefWndControlColor 204 * 205 * Default colors for control painting. 206 */ 207 HBRUSH 208 DefWndControlColor(HDC hDC, UINT ctlType) 209 { 210 if (ctlType == CTLCOLOR_SCROLLBAR) 211 { 212 HBRUSH hb = GetSysColorBrush(COLOR_SCROLLBAR); 213 COLORREF bk = GetSysColor(COLOR_3DHILIGHT); 214 SetTextColor(hDC, GetSysColor(COLOR_3DFACE)); 215 SetBkColor(hDC, bk); 216 217 /* if COLOR_WINDOW happens to be the same as COLOR_3DHILIGHT 218 * we better use 0x55aa bitmap brush to make scrollbar's background 219 * look different from the window background. 220 */ 221 if ( bk == GetSysColor(COLOR_WINDOW)) 222 return gpsi->hbrGray; 223 224 UnrealizeObject( hb ); 225 return hb; 226 } 227 228 SetTextColor(hDC, GetSysColor(COLOR_WINDOWTEXT)); 229 230 if ((ctlType == CTLCOLOR_EDIT) || (ctlType == CTLCOLOR_LISTBOX)) 231 { 232 SetBkColor(hDC, GetSysColor(COLOR_WINDOW)); 233 } 234 else 235 { 236 SetBkColor(hDC, GetSysColor(COLOR_3DFACE)); 237 return GetSysColorBrush(COLOR_3DFACE); 238 } 239 240 return GetSysColorBrush(COLOR_WINDOW); 241 } 242 243 static BOOL CALLBACK 244 UserSendUiUpdateMsg(HWND hwnd, LPARAM lParam) 245 { 246 SendMessageW(hwnd, WM_UPDATEUISTATE, (WPARAM)lParam, 0); 247 return TRUE; 248 } 249 250 /* WARNING: Redundant with /ntuser/defwnd.c!UserPaintCaption !! 251 Use TWOPARAM_ROUTINE_REDRAWTITLE/REDRAWFRAME or HWNDLOCK_ROUTINE_REDRAWFRAMEANDHOOK . 252 */ 253 static void 254 UserPaintCaption(PWND pwnd, INT Flags) 255 { 256 if ( pwnd->style & WS_VISIBLE && (pwnd->style & WS_CAPTION) == WS_CAPTION ) 257 { 258 if (pwnd->state & WNDS_HASCAPTION && NtUserQueryWindow(UserHMGetHandle(pwnd), QUERY_WINDOW_FOREGROUND)) 259 Flags |= DC_ACTIVE; 260 /* 261 * When themes are not enabled we can go on and paint the non client area. 262 * However if we do that with themes enabled we will draw a classic frame. 263 * This is solved by sending a themes specific message to notify the themes 264 * engine that the caption needs to be redrawn 265 */ 266 if(gpsi->dwSRVIFlags & SRVINFO_APIHOOK) 267 { 268 /* 269 * This will cause uxtheme to either paint the themed caption or call 270 * RealUserDrawCaption in order to draw the classic caption when themes 271 * are disabled but the themes service is enabled 272 */ 273 SendMessageW(UserHMGetHandle(pwnd), WM_NCUAHDRAWCAPTION, Flags, 0); 274 } 275 else 276 { 277 RECT rc = {0,0,0,0}; 278 HDC hDC = GetDCEx(UserHMGetHandle(pwnd), NULL, DCX_WINDOW|DCX_USESTYLE); 279 NtUserDrawCaption(UserHMGetHandle(pwnd), hDC, &rc, DC_DRAWCAPTIONMD|Flags); 280 ReleaseDC(UserHMGetHandle(pwnd), hDC); 281 } 282 } 283 //NtUserCallTwoParam((DWORD_PTR)UserHMGetHandle(pwnd),Flags,TWOPARAM_ROUTINE_REDRAWTITLE) 284 } 285 286 LRESULT FASTCALL 287 DefWndGetIcon(PWND pWnd, WPARAM wParam, LPARAM lParam) 288 { 289 HICON hIconRet; 290 if ( wParam > ICON_SMALL2 ) 291 { 292 SetLastError(ERROR_INVALID_PARAMETER); 293 return 0; 294 } 295 switch(wParam) 296 { 297 case ICON_BIG: 298 hIconRet = UserGetProp(UserHMGetHandle(pWnd), gpsi->atomIconProp, TRUE); 299 break; 300 case ICON_SMALL: 301 case ICON_SMALL2: 302 hIconRet = UserGetProp(UserHMGetHandle(pWnd), gpsi->atomIconSmProp, TRUE); 303 break; 304 default: 305 break; 306 } 307 return (LRESULT)hIconRet; 308 } 309 310 311 LRESULT WINAPI 312 User32DefWindowProc(HWND hWnd, 313 UINT Msg, 314 WPARAM wParam, 315 LPARAM lParam, 316 BOOL bUnicode) 317 { 318 PWND pWnd = NULL; 319 if (hWnd) 320 { 321 pWnd = ValidateHwnd(hWnd); 322 if (!pWnd) return 0; 323 } 324 325 switch (Msg) 326 { 327 case WM_DEVICECHANGE: 328 return TRUE; 329 330 case WM_POPUPSYSTEMMENU: 331 { 332 /* This is an undocumented message used by the windows taskbar to 333 display the system menu of windows that belong to other processes. */ 334 HMENU menu = GetSystemMenu(hWnd, FALSE); 335 ERR("WM_POPUPSYSTEMMENU\n"); 336 if (menu) 337 { 338 SetForegroundWindow(hWnd); 339 TrackPopupMenu(menu, TPM_LEFTBUTTON|TPM_RIGHTBUTTON|TPM_SYSTEM_MENU, 340 LOWORD(lParam), HIWORD(lParam), 0, hWnd, NULL); 341 } 342 return 0; 343 } 344 345 case WM_RBUTTONUP: 346 { 347 POINT Pt; 348 Pt.x = GET_X_LPARAM(lParam); 349 Pt.y = GET_Y_LPARAM(lParam); 350 ClientToScreen(hWnd, &Pt); 351 lParam = MAKELPARAM(Pt.x, Pt.y); 352 if (bUnicode) 353 { 354 SendMessageW(hWnd, WM_CONTEXTMENU, (WPARAM)hWnd, lParam); 355 } 356 else 357 { 358 SendMessageA(hWnd, WM_CONTEXTMENU, (WPARAM)hWnd, lParam); 359 } 360 break; 361 } 362 363 case WM_NCRBUTTONUP: 364 /* 365 * FIXME : we must NOT send WM_CONTEXTMENU on a WM_NCRBUTTONUP (checked 366 * in Windows), but what _should_ we do? According to MSDN : 367 * "If it is appropriate to do so, the system sends the WM_SYSCOMMAND 368 * message to the window". When is it appropriate? 369 */ 370 ERR("WM_NCRBUTTONUP\n"); 371 break; 372 373 case WM_XBUTTONUP: 374 case WM_NCXBUTTONUP: 375 if (HIWORD(wParam) == XBUTTON1 || HIWORD(wParam) == XBUTTON2) 376 { 377 SendMessageW(hWnd, WM_APPCOMMAND, (WPARAM)hWnd, 378 MAKELPARAM(LOWORD(wParam), FAPPCOMMAND_MOUSE | HIWORD(wParam))); 379 } 380 break; 381 382 case WM_CONTEXTMENU: 383 { 384 if (GetWindowLongPtrW(hWnd, GWL_STYLE) & WS_CHILD) 385 { 386 if (bUnicode) 387 { 388 SendMessageW(GetParent(hWnd), Msg, (WPARAM)hWnd, lParam); 389 } 390 else 391 { 392 SendMessageA(GetParent(hWnd), Msg, (WPARAM)hWnd, lParam); 393 } 394 } 395 else 396 { 397 goto GoSS; 398 } 399 break; 400 } 401 402 case WM_CLOSE: 403 DestroyWindow(hWnd); 404 return (0); 405 406 case WM_MOUSEACTIVATE: 407 if (GetWindowLongPtrW(hWnd, GWL_STYLE) & WS_CHILD) 408 { 409 LONG Ret = SendMessageW(GetParent(hWnd), WM_MOUSEACTIVATE, wParam, lParam); 410 if (Ret) return (Ret); 411 } 412 return ( (HIWORD(lParam) == WM_LBUTTONDOWN && LOWORD(lParam) == HTCAPTION) ? MA_NOACTIVATE : MA_ACTIVATE ); 413 414 case WM_ACTIVATE: 415 /* The default action in Windows is to set the keyboard focus to 416 * the window, if it's being activated and not minimized */ 417 if (LOWORD(wParam) != WA_INACTIVE && 418 !(GetWindowLongPtrW(hWnd, GWL_STYLE) & WS_MINIMIZE)) 419 { 420 //ERR("WM_ACTIVATE %p\n",hWnd); 421 SetFocus(hWnd); 422 } 423 break; 424 425 case WM_MOUSEWHEEL: 426 if (GetWindowLongPtrW(hWnd, GWL_STYLE) & WS_CHILD) 427 return SendMessageW( GetParent(hWnd), WM_MOUSEWHEEL, wParam, lParam); 428 break; 429 430 case WM_ERASEBKGND: 431 case WM_ICONERASEBKGND: 432 { 433 RECT Rect; 434 HBRUSH hBrush = (HBRUSH)GetClassLongPtrW(hWnd, GCL_HBRBACKGROUND); 435 436 if (NULL == hBrush) 437 { 438 return 0; 439 } 440 if (GetClassLongPtrW(hWnd, GCL_STYLE) & CS_PARENTDC) 441 { 442 /* can't use GetClipBox with a parent DC or we fill the whole parent */ 443 GetClientRect(hWnd, &Rect); 444 DPtoLP((HDC)wParam, (LPPOINT)&Rect, 2); 445 } 446 else 447 { 448 GetClipBox((HDC)wParam, &Rect); 449 } 450 FillRect((HDC)wParam, &Rect, hBrush); 451 return (1); 452 } 453 454 case WM_CTLCOLORMSGBOX: 455 case WM_CTLCOLOREDIT: 456 case WM_CTLCOLORLISTBOX: 457 case WM_CTLCOLORBTN: 458 case WM_CTLCOLORDLG: 459 case WM_CTLCOLORSTATIC: 460 case WM_CTLCOLORSCROLLBAR: 461 return (LRESULT) DefWndControlColor((HDC)wParam, Msg - WM_CTLCOLORMSGBOX); 462 463 case WM_CTLCOLOR: 464 return (LRESULT) DefWndControlColor((HDC)wParam, HIWORD(lParam)); 465 466 case WM_SYSCOMMAND: 467 return (DefWndHandleSysCommand(hWnd, wParam, lParam)); 468 469 case WM_VKEYTOITEM: 470 case WM_CHARTOITEM: 471 return (-1); 472 /* 473 case WM_DROPOBJECT: 474 return DRAG_FILE; 475 */ 476 case WM_QUERYDROPOBJECT: 477 { 478 if (GetWindowLongPtrW(hWnd, GWL_EXSTYLE) & WS_EX_ACCEPTFILES) 479 { 480 return(1); 481 } 482 break; 483 } 484 485 case WM_QUERYDRAGICON: 486 { 487 UINT Len; 488 HICON hIcon; 489 490 hIcon = (HICON)GetClassLongPtrW(hWnd, GCL_HICON); 491 if (hIcon) 492 { 493 return ((LRESULT)hIcon); 494 } 495 for (Len = 1; Len < 64; Len++) 496 { 497 if ((hIcon = LoadIconW(NULL, MAKEINTRESOURCEW(Len))) != NULL) 498 { 499 return((LRESULT)hIcon); 500 } 501 } 502 return ((LRESULT)LoadIconW(0, IDI_APPLICATION)); 503 } 504 505 case WM_ISACTIVEICON: 506 { 507 BOOL isai; 508 isai = (pWnd->state & WNDS_ACTIVEFRAME) != 0; 509 return isai; 510 } 511 512 case WM_NOTIFYFORMAT: 513 { 514 if (lParam == NF_QUERY) 515 return IsWindowUnicode(hWnd) ? NFR_UNICODE : NFR_ANSI; 516 break; 517 } 518 519 case WM_GETICON: 520 { 521 return DefWndGetIcon(pWnd, wParam, lParam); 522 } 523 524 case WM_HELP: 525 { 526 if (bUnicode) 527 { 528 SendMessageW(GetParent(hWnd), Msg, wParam, lParam); 529 } 530 else 531 { 532 SendMessageA(GetParent(hWnd), Msg, wParam, lParam); 533 } 534 break; 535 } 536 537 case WM_QUERYOPEN: 538 case WM_QUERYENDSESSION: 539 { 540 return (1); 541 } 542 543 case WM_INPUTLANGCHANGEREQUEST: 544 { 545 HKL hNewKL; 546 HWND hwndFocus; 547 548 if ((wParam & INPUTLANGCHANGE_BACKWARD) && (wParam & INPUTLANGCHANGE_FORWARD)) 549 return FALSE; 550 551 hwndFocus = GetFocus(); 552 if (hwndFocus && hwndFocus != hWnd && 553 GetClassLongPtrW(hWnd, GCW_ATOM) != (ULONG_PTR)WC_DIALOG) 554 { 555 return SendMessageW(hwndFocus, Msg, wParam, lParam); 556 } 557 558 if (wParam & INPUTLANGCHANGE_FORWARD) 559 hNewKL = (HKL)UlongToHandle(HKL_NEXT); 560 else if (wParam & INPUTLANGCHANGE_BACKWARD) 561 hNewKL = (HKL)UlongToHandle(HKL_PREV); 562 else 563 hNewKL = (HKL)lParam; 564 565 NtUserActivateKeyboardLayout(hNewKL, KLF_SETFORPROCESS); 566 return TRUE; 567 } 568 569 case WM_INPUTLANGCHANGE: 570 { 571 int count = 0; 572 HWND *win_array = WIN_ListChildren( hWnd ); 573 574 if (!win_array) 575 break; 576 while (win_array[count]) 577 SendMessageW( win_array[count++], WM_INPUTLANGCHANGE, wParam, lParam); 578 HeapFree(GetProcessHeap(),0,win_array); 579 break; 580 } 581 582 case WM_QUERYUISTATE: 583 { 584 LRESULT Ret = 0; 585 PWND Wnd = ValidateHwnd(hWnd); 586 if (Wnd != NULL) 587 { 588 if (Wnd->HideFocus) 589 Ret |= UISF_HIDEFOCUS; 590 if (Wnd->HideAccel) 591 Ret |= UISF_HIDEACCEL; 592 } 593 return Ret; 594 } 595 596 case WM_CHANGEUISTATE: 597 { 598 BOOL AlwaysShowCues = FALSE; 599 WORD Action = LOWORD(wParam); 600 WORD Flags = HIWORD(wParam); 601 PWND Wnd; 602 603 SystemParametersInfoW(SPI_GETKEYBOARDCUES, 0, &AlwaysShowCues, 0); 604 if (AlwaysShowCues) 605 break; 606 607 Wnd= ValidateHwnd(hWnd); 608 if (!Wnd || lParam != 0) 609 break; 610 611 if (Flags & ~(UISF_HIDEFOCUS | UISF_HIDEACCEL | UISF_ACTIVE)) 612 break; 613 614 if (Flags & UISF_ACTIVE) 615 { 616 WARN("WM_CHANGEUISTATE does not yet support UISF_ACTIVE\n"); 617 } 618 619 if (Action == UIS_INITIALIZE) 620 { 621 PDESKTOPINFO Desk = GetThreadDesktopInfo(); 622 if (Desk == NULL) 623 break; 624 625 Action = Desk->LastInputWasKbd ? UIS_CLEAR : UIS_SET; 626 Flags = UISF_HIDEFOCUS | UISF_HIDEACCEL; 627 628 /* We need to update wParam in case we need to send out messages */ 629 wParam = MAKEWPARAM(Action, Flags); 630 } 631 632 switch (Action) 633 { 634 case UIS_SET: 635 /* See if we actually need to change something */ 636 if ((Flags & UISF_HIDEFOCUS) && !Wnd->HideFocus) 637 break; 638 if ((Flags & UISF_HIDEACCEL) && !Wnd->HideAccel) 639 break; 640 641 /* Don't need to do anything... */ 642 return 0; 643 644 case UIS_CLEAR: 645 /* See if we actually need to change something */ 646 if ((Flags & UISF_HIDEFOCUS) && Wnd->HideFocus) 647 break; 648 if ((Flags & UISF_HIDEACCEL) && Wnd->HideAccel) 649 break; 650 651 /* Don't need to do anything... */ 652 return 0; 653 654 default: 655 WARN("WM_CHANGEUISTATE: Unsupported Action 0x%x\n", Action); 656 break; 657 } 658 659 if ((Wnd->style & WS_CHILD) && Wnd->spwndParent != NULL) 660 { 661 /* We're a child window and we need to pass this message down until 662 we reach the root */ 663 hWnd = UserHMGetHandle((PWND)DesktopPtrToUser(Wnd->spwndParent)); 664 } 665 else 666 { 667 /* We're a top level window, we need to change the UI state */ 668 Msg = WM_UPDATEUISTATE; 669 } 670 671 if (bUnicode) 672 return SendMessageW(hWnd, Msg, wParam, lParam); 673 else 674 return SendMessageA(hWnd, Msg, wParam, lParam); 675 } 676 677 case WM_UPDATEUISTATE: 678 { 679 BOOL Change = TRUE; 680 BOOL AlwaysShowCues = FALSE; 681 WORD Action = LOWORD(wParam); 682 WORD Flags = HIWORD(wParam); 683 PWND Wnd; 684 685 SystemParametersInfoW(SPI_GETKEYBOARDCUES, 0, &AlwaysShowCues, 0); 686 if (AlwaysShowCues) 687 break; 688 689 Wnd = ValidateHwnd(hWnd); 690 if (!Wnd || lParam != 0) 691 break; 692 693 if (Flags & ~(UISF_HIDEFOCUS | UISF_HIDEACCEL | UISF_ACTIVE)) 694 break; 695 696 if (Flags & UISF_ACTIVE) 697 { 698 WARN("WM_UPDATEUISTATE does not yet support UISF_ACTIVE\n"); 699 } 700 701 if (Action == UIS_INITIALIZE) 702 { 703 PDESKTOPINFO Desk = GetThreadDesktopInfo(); 704 if (Desk == NULL) 705 break; 706 707 Action = Desk->LastInputWasKbd ? UIS_CLEAR : UIS_SET; 708 Flags = UISF_HIDEFOCUS | UISF_HIDEACCEL; 709 710 /* We need to update wParam for broadcasting the update */ 711 wParam = MAKEWPARAM(Action, Flags); 712 } 713 714 switch (Action) 715 { 716 case UIS_SET: 717 /* See if we actually need to change something */ 718 if ((Flags & UISF_HIDEFOCUS) && !Wnd->HideFocus) 719 break; 720 if ((Flags & UISF_HIDEACCEL) && !Wnd->HideAccel) 721 break; 722 723 /* Don't need to do anything... */ 724 Change = FALSE; 725 break; 726 727 case UIS_CLEAR: 728 /* See if we actually need to change something */ 729 if ((Flags & UISF_HIDEFOCUS) && Wnd->HideFocus) 730 break; 731 if ((Flags & UISF_HIDEACCEL) && Wnd->HideAccel) 732 break; 733 734 /* Don't need to do anything... */ 735 Change = FALSE; 736 break; 737 738 default: 739 WARN("WM_UPDATEUISTATE: Unsupported Action 0x%x\n", Action); 740 return 0; 741 } 742 743 /* Pack the information and call win32k */ 744 if (Change) 745 { 746 if (!NtUserxUpdateUiState(hWnd, Flags | ((DWORD)Action << 3))) 747 break; 748 } 749 750 /* Always broadcast the update to all children */ 751 EnumChildWindows(hWnd, 752 UserSendUiUpdateMsg, 753 (LPARAM)wParam); 754 755 break; 756 } 757 758 case WM_COPYGLOBALDATA: 759 { 760 TRACE("WM_COPYGLOBALDATA hGlobal %p Size %d Flags 0x%x\n",lParam,wParam,GlobalFlags((HGLOBAL)lParam)); 761 return lParam; 762 } 763 764 /* Move to Win32k !*/ 765 case WM_SHOWWINDOW: 766 if (!lParam) break; // Call when it is necessary. 767 case WM_LBUTTONDOWN: 768 case WM_RBUTTONDOWN: 769 case WM_MBUTTONDOWN: 770 case WM_NCLBUTTONDOWN: 771 case WM_NCRBUTTONDOWN: 772 case WM_LBUTTONDBLCLK: 773 case WM_NCLBUTTONDBLCLK: 774 case WM_KEYF1: 775 case WM_KEYUP: 776 case WM_SYSKEYUP: 777 case WM_KEYDOWN: 778 case WM_SYSKEYDOWN: 779 case WM_SYSCHAR: 780 case WM_CANCELMODE: 781 case WM_PAINTICON: 782 case WM_PAINT: 783 case WM_PRINT: 784 case WM_SETICON: 785 case WM_SYSCOLORCHANGE: 786 case WM_NCUAHDRAWCAPTION: 787 case WM_NCUAHDRAWFRAME: 788 case WM_NCPAINT: 789 case WM_NCACTIVATE: 790 case WM_NCCALCSIZE: 791 case WM_NCHITTEST: 792 case WM_SYNCPAINT: 793 case WM_SETREDRAW: 794 case WM_CLIENTSHUTDOWN: 795 case WM_GETHOTKEY: 796 case WM_SETHOTKEY: 797 case WM_WINDOWPOSCHANGING: 798 case WM_WINDOWPOSCHANGED: 799 case WM_APPCOMMAND: 800 case WM_SETCURSOR: 801 GoSS: 802 { 803 LRESULT lResult; 804 NtUserMessageCall(hWnd, Msg, wParam, lParam, (ULONG_PTR)&lResult, FNID_DEFWINDOWPROC, !bUnicode); 805 return lResult; 806 } 807 } 808 return 0; 809 } 810 811 812 LRESULT WINAPI 813 RealDefWindowProcA(HWND hWnd, 814 UINT Msg, 815 WPARAM wParam, 816 LPARAM lParam) 817 { 818 LRESULT Result = 0; 819 PWND Wnd; 820 821 Wnd = ValidateHwnd(hWnd); 822 823 if ( !Wnd && 824 Msg != WM_CTLCOLORMSGBOX && 825 Msg != WM_CTLCOLORBTN && 826 Msg != WM_CTLCOLORDLG && 827 Msg != WM_CTLCOLORSTATIC ) 828 return 0; 829 830 SPY_EnterMessage(SPY_DEFWNDPROC, hWnd, Msg, wParam, lParam); 831 switch (Msg) 832 { 833 case WM_NCCREATE: 834 { 835 if ( Wnd && 836 Wnd->style & (WS_HSCROLL | WS_VSCROLL) ) 837 { 838 if (!Wnd->pSBInfo) 839 { 840 SCROLLINFO si = {sizeof si, SIF_ALL, 0, 100, 0, 0, 0}; 841 SetScrollInfo( hWnd, SB_HORZ, &si, FALSE ); 842 SetScrollInfo( hWnd, SB_VERT, &si, FALSE ); 843 } 844 } 845 846 if (lParam) 847 { 848 LPCREATESTRUCTA cs = (LPCREATESTRUCTA)lParam; 849 /* check for string, as static icons, bitmaps (SS_ICON, SS_BITMAP) 850 * may have child window IDs instead of window name */ 851 if (HIWORD(cs->lpszName)) 852 { 853 DefSetText(hWnd, (PCWSTR)cs->lpszName, TRUE); 854 } 855 Result = 1; 856 } 857 break; 858 } 859 860 case WM_GETTEXTLENGTH: 861 { 862 PWSTR buf; 863 ULONG len; 864 865 if (Wnd != NULL && Wnd->strName.Length != 0) 866 { 867 buf = DesktopPtrToUser(Wnd->strName.Buffer); 868 if (buf != NULL && 869 NT_SUCCESS(RtlUnicodeToMultiByteSize(&len, 870 buf, 871 Wnd->strName.Length))) 872 { 873 Result = (LRESULT) len; 874 } 875 } 876 else Result = 0L; 877 878 break; 879 } 880 881 case WM_GETTEXT: 882 { 883 PWSTR buf = NULL; 884 PSTR outbuf = (PSTR)lParam; 885 SIZE_T copy; 886 887 if (Wnd != NULL && wParam != 0) 888 { 889 if (Wnd->strName.Buffer != NULL) 890 buf = DesktopPtrToUser(Wnd->strName.Buffer); 891 else 892 outbuf[0] = L'\0'; 893 894 if (buf != NULL) 895 { 896 if (Wnd->strName.Length != 0) 897 { 898 copy = min(Wnd->strName.Length / sizeof(WCHAR), wParam - 1); 899 Result = WideCharToMultiByte(CP_ACP, 900 0, 901 buf, 902 copy, 903 outbuf, 904 wParam, 905 NULL, 906 NULL); 907 outbuf[Result] = '\0'; 908 } 909 else 910 outbuf[0] = '\0'; 911 } 912 } 913 break; 914 } 915 916 case WM_SETTEXT: 917 { 918 DefSetText(hWnd, (PCWSTR)lParam, TRUE); 919 920 if ((GetWindowLongPtrW(hWnd, GWL_STYLE) & WS_CAPTION) == WS_CAPTION) 921 { 922 UserPaintCaption(Wnd, DC_TEXT); 923 IntNotifyWinEvent(EVENT_OBJECT_NAMECHANGE, hWnd, OBJID_WINDOW, CHILDID_SELF, 0); 924 } 925 Result = 1; 926 break; 927 } 928 929 case WM_IME_KEYDOWN: 930 { 931 Result = PostMessageA(hWnd, WM_KEYDOWN, wParam, lParam); 932 break; 933 } 934 935 case WM_IME_KEYUP: 936 { 937 Result = PostMessageA(hWnd, WM_KEYUP, wParam, lParam); 938 break; 939 } 940 941 case WM_IME_CHAR: 942 { 943 if (HIBYTE(wParam)) 944 PostMessageA(hWnd, WM_CHAR, HIBYTE(wParam), lParam); 945 PostMessageA(hWnd, WM_CHAR, LOBYTE(wParam), lParam); 946 break; 947 } 948 949 case WM_IME_COMPOSITION: 950 if (lParam & GCS_RESULTSTR) 951 { 952 LONG size, i; 953 unsigned char lead = 0; 954 char *buf = NULL; 955 HIMC himc = IMM_FN(ImmGetContext)( hWnd ); 956 957 if (himc) 958 { 959 if ((size = IMM_FN(ImmGetCompositionStringA)( himc, GCS_RESULTSTR, NULL, 0 ))) 960 { 961 if (!(buf = HeapAlloc( GetProcessHeap(), 0, size ))) size = 0; 962 else size = IMM_FN(ImmGetCompositionStringA)( himc, GCS_RESULTSTR, buf, size ); 963 } 964 IMM_FN(ImmReleaseContext)( hWnd, himc ); 965 966 for (i = 0; i < size; i++) 967 { 968 unsigned char c = buf[i]; 969 if (!lead) 970 { 971 if (IsDBCSLeadByte( c )) 972 lead = c; 973 else 974 SendMessageA( hWnd, WM_IME_CHAR, c, 1 ); 975 } 976 else 977 { 978 SendMessageA( hWnd, WM_IME_CHAR, MAKEWORD(c, lead), 1 ); 979 lead = 0; 980 } 981 } 982 HeapFree( GetProcessHeap(), 0, buf ); 983 } 984 } 985 /* fall through */ 986 case WM_IME_STARTCOMPOSITION: 987 case WM_IME_ENDCOMPOSITION: 988 case WM_IME_SELECT: 989 case WM_IME_NOTIFY: 990 case WM_IME_CONTROL: 991 case WM_IME_SETCONTEXT: 992 NormalImeMsgHandling: 993 { 994 HWND hwndIME; 995 996 if (GetWin32ClientInfo()->dwTIFlags & TIF_DISABLEIME) 997 { 998 TRACE("This thread's IME is disabled\n"); 999 break; 1000 } 1001 1002 hwndIME = IMM_FN(ImmGetDefaultIMEWnd)(hWnd); 1003 if (!hwndIME) 1004 { 1005 ERR("hwndIME was NULL\n"); 1006 break; 1007 } 1008 1009 if (hwndIME == hWnd) 1010 { 1011 ImeWndProc_common(hwndIME, Msg, wParam, lParam, FALSE); 1012 break; 1013 } 1014 1015 Result = SendMessageA(hwndIME, Msg, wParam, lParam); 1016 break; 1017 } 1018 1019 case WM_IME_SYSTEM: 1020 { 1021 if (wParam == 4) 1022 break; 1023 1024 goto NormalImeMsgHandling; 1025 } 1026 1027 default: 1028 Result = User32DefWindowProc(hWnd, Msg, wParam, lParam, FALSE); 1029 } 1030 1031 SPY_ExitMessage(SPY_RESULT_DEFWND, hWnd, Msg, Result, wParam, lParam); 1032 return Result; 1033 } 1034 1035 1036 LRESULT WINAPI 1037 RealDefWindowProcW(HWND hWnd, 1038 UINT Msg, 1039 WPARAM wParam, 1040 LPARAM lParam) 1041 { 1042 LRESULT Result = 0; 1043 PWND Wnd; 1044 1045 Wnd = ValidateHwnd(hWnd); 1046 1047 if ( !Wnd && 1048 Msg != WM_CTLCOLORMSGBOX && 1049 Msg != WM_CTLCOLORBTN && 1050 Msg != WM_CTLCOLORDLG && 1051 Msg != WM_CTLCOLORSTATIC ) 1052 return 0; 1053 1054 SPY_EnterMessage(SPY_DEFWNDPROC, hWnd, Msg, wParam, lParam); 1055 switch (Msg) 1056 { 1057 case WM_NCCREATE: 1058 { 1059 if ( Wnd && 1060 Wnd->style & (WS_HSCROLL | WS_VSCROLL) ) 1061 { 1062 if (!Wnd->pSBInfo) 1063 { 1064 SCROLLINFO si = {sizeof si, SIF_ALL, 0, 100, 0, 0, 0}; 1065 if (Wnd->style & WS_HSCROLL) 1066 SetScrollInfo(hWnd, SB_HORZ, &si, FALSE); 1067 if (Wnd->style & WS_VSCROLL) 1068 SetScrollInfo(hWnd, SB_VERT, &si, FALSE); 1069 } 1070 } 1071 1072 if (lParam) 1073 { 1074 LPCREATESTRUCTW cs = (LPCREATESTRUCTW)lParam; 1075 /* check for string, as static icons, bitmaps (SS_ICON, SS_BITMAP) 1076 * may have child window IDs instead of window name */ 1077 if (HIWORD(cs->lpszName)) 1078 { 1079 DefSetText(hWnd, cs->lpszName, FALSE); 1080 } 1081 Result = 1; 1082 } 1083 break; 1084 } 1085 1086 case WM_GETTEXTLENGTH: 1087 { 1088 PWSTR buf; 1089 ULONG len; 1090 1091 if (Wnd != NULL && Wnd->strName.Length != 0) 1092 { 1093 buf = DesktopPtrToUser(Wnd->strName.Buffer); 1094 if (buf != NULL && 1095 NT_SUCCESS(RtlUnicodeToMultiByteSize(&len, 1096 buf, 1097 Wnd->strName.Length))) 1098 { 1099 Result = (LRESULT) (Wnd->strName.Length / sizeof(WCHAR)); 1100 } 1101 } 1102 else Result = 0L; 1103 1104 break; 1105 } 1106 1107 case WM_GETTEXT: 1108 { 1109 PWSTR buf = NULL; 1110 PWSTR outbuf = (PWSTR)lParam; 1111 1112 if (Wnd != NULL && wParam != 0) 1113 { 1114 if (Wnd->strName.Buffer != NULL) 1115 buf = DesktopPtrToUser(Wnd->strName.Buffer); 1116 else 1117 outbuf[0] = L'\0'; 1118 1119 if (buf != NULL) 1120 { 1121 if (Wnd->strName.Length != 0) 1122 { 1123 Result = min(Wnd->strName.Length / sizeof(WCHAR), wParam - 1); 1124 RtlCopyMemory(outbuf, 1125 buf, 1126 Result * sizeof(WCHAR)); 1127 outbuf[Result] = L'\0'; 1128 } 1129 else 1130 outbuf[0] = L'\0'; 1131 } 1132 } 1133 break; 1134 } 1135 1136 case WM_SETTEXT: 1137 { 1138 DefSetText(hWnd, (PCWSTR)lParam, FALSE); 1139 1140 if ((GetWindowLongPtrW(hWnd, GWL_STYLE) & WS_CAPTION) == WS_CAPTION) 1141 UserPaintCaption(Wnd, DC_TEXT); 1142 Result = 1; 1143 break; 1144 } 1145 1146 case WM_IME_CHAR: 1147 { 1148 PostMessageW(hWnd, WM_CHAR, wParam, lParam); 1149 Result = 0; 1150 break; 1151 } 1152 1153 case WM_IME_KEYDOWN: 1154 { 1155 Result = PostMessageW(hWnd, WM_KEYDOWN, wParam, lParam); 1156 break; 1157 } 1158 1159 case WM_IME_KEYUP: 1160 { 1161 Result = PostMessageW(hWnd, WM_KEYUP, wParam, lParam); 1162 break; 1163 } 1164 1165 case WM_IME_COMPOSITION: 1166 if (lParam & GCS_RESULTSTR) 1167 { 1168 LONG size, i; 1169 WCHAR *buf = NULL; 1170 HIMC himc = IMM_FN(ImmGetContext)( hWnd ); 1171 1172 if (himc) 1173 { 1174 if ((size = IMM_FN(ImmGetCompositionStringW)( himc, GCS_RESULTSTR, NULL, 0 ))) 1175 { 1176 if (!(buf = HeapAlloc( GetProcessHeap(), 0, size * sizeof(WCHAR) ))) size = 0; 1177 else size = IMM_FN(ImmGetCompositionStringW)( himc, GCS_RESULTSTR, buf, size * sizeof(WCHAR) ); 1178 } 1179 IMM_FN(ImmReleaseContext)( hWnd, himc ); 1180 1181 for (i = 0; i < size / sizeof(WCHAR); i++) 1182 SendMessageW( hWnd, WM_IME_CHAR, buf[i], 1 ); 1183 HeapFree( GetProcessHeap(), 0, buf ); 1184 } 1185 } 1186 /* fall through */ 1187 case WM_IME_STARTCOMPOSITION: 1188 case WM_IME_ENDCOMPOSITION: 1189 case WM_IME_SELECT: 1190 case WM_IME_NOTIFY: 1191 case WM_IME_CONTROL: 1192 case WM_IME_SETCONTEXT: 1193 NormalImeMsgHandling: 1194 { 1195 HWND hwndIME; 1196 1197 if (GetWin32ClientInfo()->dwTIFlags & TIF_DISABLEIME) 1198 { 1199 TRACE("This thread's IME is disabled\n"); 1200 break; 1201 } 1202 1203 hwndIME = IMM_FN(ImmGetDefaultIMEWnd)(hWnd); 1204 if (!hwndIME) 1205 { 1206 ERR("hwndIME was NULL\n"); 1207 break; 1208 } 1209 1210 if (hwndIME == hWnd) 1211 { 1212 ImeWndProc_common(hwndIME, Msg, wParam, lParam, TRUE); 1213 break; 1214 } 1215 1216 Result = SendMessageW(hwndIME, Msg, wParam, lParam); 1217 break; 1218 } 1219 1220 case WM_IME_SYSTEM: 1221 { 1222 if (wParam == 4) 1223 break; 1224 1225 goto NormalImeMsgHandling; 1226 } 1227 1228 default: 1229 Result = User32DefWindowProc(hWnd, Msg, wParam, lParam, TRUE); 1230 } 1231 SPY_ExitMessage(SPY_RESULT_DEFWND, hWnd, Msg, Result, wParam, lParam); 1232 1233 return Result; 1234 } 1235 1236 LRESULT WINAPI 1237 DefWindowProcA(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) 1238 { 1239 BOOL Hook, msgOverride = FALSE; 1240 LRESULT Result = 0; 1241 1242 LoadUserApiHook(); 1243 1244 Hook = BeginIfHookedUserApiHook(); 1245 if (Hook) 1246 { 1247 msgOverride = IsMsgOverride(Msg, &guah.DefWndProcArray); 1248 if(msgOverride == FALSE) 1249 { 1250 EndUserApiHook(); 1251 } 1252 } 1253 1254 /* Bypass SEH and go direct. */ 1255 if (!Hook || !msgOverride) 1256 return RealDefWindowProcA(hWnd, Msg, wParam, lParam); 1257 1258 _SEH2_TRY 1259 { 1260 Result = guah.DefWindowProcA(hWnd, Msg, wParam, lParam); 1261 } 1262 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 1263 { 1264 ERR("Got exception in hooked DefWindowProcA\n"); 1265 } 1266 _SEH2_END; 1267 1268 EndUserApiHook(); 1269 1270 return Result; 1271 } 1272 1273 LRESULT WINAPI 1274 DefWindowProcW(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) 1275 { 1276 BOOL Hook, msgOverride = FALSE; 1277 LRESULT Result = 0; 1278 1279 LoadUserApiHook(); 1280 1281 Hook = BeginIfHookedUserApiHook(); 1282 if (Hook) 1283 { 1284 msgOverride = IsMsgOverride(Msg, &guah.DefWndProcArray); 1285 if(msgOverride == FALSE) 1286 { 1287 EndUserApiHook(); 1288 } 1289 } 1290 1291 /* Bypass SEH and go direct. */ 1292 if (!Hook || !msgOverride) 1293 return RealDefWindowProcW(hWnd, Msg, wParam, lParam); 1294 1295 _SEH2_TRY 1296 { 1297 Result = guah.DefWindowProcW(hWnd, Msg, wParam, lParam); 1298 } 1299 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 1300 { 1301 ERR("Got exception in hooked DefWindowProcW\n"); 1302 } 1303 _SEH2_END; 1304 1305 EndUserApiHook(); 1306 1307 return Result; 1308 } 1309