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