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 #include <ddk/immdev.h> 14 15 WINE_DEFAULT_DEBUG_CHANNEL(user32); 16 17 /* 18 * @implemented 19 */ 20 DWORD 21 WINAPI 22 DECLSPEC_HOTPATCH 23 GetSysColor(int nIndex) 24 { 25 if(nIndex >= 0 && nIndex < NUM_SYSCOLORS) 26 { 27 return gpsi->argbSystem[nIndex]; 28 } 29 30 SetLastError(ERROR_INVALID_PARAMETER); 31 return 0; 32 } 33 34 /* 35 * @implemented 36 */ 37 HBRUSH 38 WINAPI 39 DECLSPEC_HOTPATCH 40 GetSysColorBrush(int nIndex) 41 { 42 if(nIndex >= 0 && nIndex < NUM_SYSCOLORS) 43 { 44 return gpsi->ahbrSystem[nIndex]; 45 } 46 47 return NULL; 48 } 49 50 /* 51 * @implemented 52 */ 53 BOOL 54 WINAPI 55 SetSysColors( 56 int cElements, 57 CONST INT *lpaElements, 58 CONST COLORREF *lpaRgbValues) 59 { 60 return NtUserSetSysColors(cElements, lpaElements, lpaRgbValues, 0); 61 } 62 63 BOOL 64 FASTCALL 65 DefSetText(HWND hWnd, PCWSTR String, BOOL Ansi) 66 { 67 BOOL Ret; 68 LARGE_STRING lsString; 69 70 if ( String ) 71 { 72 if ( Ansi ) 73 RtlInitLargeAnsiString((PLARGE_ANSI_STRING)&lsString, (PCSZ)String, 0); 74 else 75 RtlInitLargeUnicodeString((PLARGE_UNICODE_STRING)&lsString, String, 0); 76 } 77 Ret = NtUserDefSetText(hWnd, (String ? &lsString : NULL)); 78 79 return Ret; 80 } 81 82 HWND FASTCALL 83 IntFindChildWindowToOwner(HWND hRoot, HWND hOwner) 84 { 85 HWND Ret; 86 PWND Child, OwnerWnd, Root, Owner; 87 88 Root = ValidateHwnd(hRoot); 89 Owner = ValidateHwnd(hOwner); 90 91 for( Child = Root->spwndChild ? DesktopPtrToUser(Root->spwndChild) : NULL; 92 Child; 93 Child = Child->spwndNext ? DesktopPtrToUser(Child->spwndNext) : NULL ) 94 { 95 OwnerWnd = Child->spwndOwner ? DesktopPtrToUser(Child->spwndOwner) : NULL; 96 if(!OwnerWnd) 97 continue; 98 99 if (!(Child->style & WS_POPUP) || !(Child->style & WS_VISIBLE)) 100 continue; 101 102 if(OwnerWnd == Owner) 103 { 104 Ret = Child->head.h; 105 return Ret; 106 } 107 } 108 ERR("IDCWTO Nothing found\n"); 109 return NULL; 110 } 111 112 /*********************************************************************** 113 * DefWndTrackScrollBar 114 * 115 * Track a mouse button press on the horizontal or vertical scroll-bar. 116 */ 117 static VOID 118 DefWndTrackScrollBar(HWND Wnd, WPARAM wParam, POINT Pt) 119 { 120 INT ScrollBar; 121 122 if (SC_HSCROLL == (wParam & 0xfff0)) 123 { 124 if (HTHSCROLL != (wParam & 0x0f)) 125 { 126 return; 127 } 128 ScrollBar = SB_HORZ; 129 } 130 else /* SC_VSCROLL */ 131 { 132 if (HTVSCROLL != (wParam & 0x0f)) 133 { 134 return; 135 } 136 ScrollBar = SB_VERT; 137 } 138 ScrollTrackScrollBar(Wnd, ScrollBar, Pt ); 139 } 140 141 LRESULT WINAPI DoAppSwitch( WPARAM wParam, LPARAM lParam); 142 143 LRESULT 144 DefWndHandleSysCommand(HWND hWnd, WPARAM wParam, LPARAM lParam) 145 { 146 POINT Pt; 147 LRESULT lResult; 148 149 if (!IsWindowEnabled( hWnd )) return 0; 150 151 switch (wParam & 0xfff0) 152 { 153 case SC_MOVE: 154 case SC_SIZE: 155 // case SC_DEFAULT: 156 case SC_MOUSEMENU: 157 case SC_KEYMENU: 158 case SC_SCREENSAVE: 159 case SC_MINIMIZE: 160 case SC_MAXIMIZE: 161 case SC_RESTORE: 162 case SC_CLOSE: 163 case SC_HOTKEY: 164 NtUserMessageCall( hWnd, WM_SYSCOMMAND, wParam, lParam, (ULONG_PTR)&lResult, FNID_DEFWINDOWPROC, FALSE); 165 return 0; 166 167 default: 168 break; 169 } 170 171 if (ISITHOOKED(WH_CBT)) 172 { 173 NtUserMessageCall( hWnd, WM_SYSCOMMAND, wParam, lParam, (ULONG_PTR)&lResult, FNID_DEFWINDOWPROC, FALSE); 174 if (lResult) return 0; 175 } 176 177 switch (wParam & 0xfff0) 178 { 179 180 case SC_VSCROLL: 181 case SC_HSCROLL: 182 { 183 Pt.x = (short)LOWORD(lParam); 184 Pt.y = (short)HIWORD(lParam); 185 DefWndTrackScrollBar(hWnd, wParam, Pt); 186 } 187 break; 188 189 case SC_TASKLIST: 190 WinExec( "taskman.exe", SW_SHOWNORMAL ); 191 break; 192 193 194 case SC_NEXTWINDOW: 195 case SC_PREVWINDOW: 196 DoAppSwitch( wParam, lParam); 197 break; 198 199 default: 200 FIXME("Unimplemented DefWndHandleSysCommand wParam 0x%x\n",wParam); 201 break; 202 } 203 204 return(0); 205 } 206 207 /*********************************************************************** 208 * DefWndControlColor 209 * 210 * Default colors for control painting. 211 */ 212 HBRUSH 213 DefWndControlColor(HDC hDC, UINT ctlType) 214 { 215 if (ctlType == CTLCOLOR_SCROLLBAR) 216 { 217 HBRUSH hb = GetSysColorBrush(COLOR_SCROLLBAR); 218 COLORREF bk = GetSysColor(COLOR_3DHILIGHT); 219 SetTextColor(hDC, GetSysColor(COLOR_3DFACE)); 220 SetBkColor(hDC, bk); 221 222 /* if COLOR_WINDOW happens to be the same as COLOR_3DHILIGHT 223 * we better use 0x55aa bitmap brush to make scrollbar's background 224 * look different from the window background. 225 */ 226 if ( bk == GetSysColor(COLOR_WINDOW)) 227 return gpsi->hbrGray; 228 229 UnrealizeObject( hb ); 230 return hb; 231 } 232 233 SetTextColor(hDC, GetSysColor(COLOR_WINDOWTEXT)); 234 235 if ((ctlType == CTLCOLOR_EDIT) || (ctlType == CTLCOLOR_LISTBOX)) 236 { 237 SetBkColor(hDC, GetSysColor(COLOR_WINDOW)); 238 } 239 else 240 { 241 SetBkColor(hDC, GetSysColor(COLOR_3DFACE)); 242 return GetSysColorBrush(COLOR_3DFACE); 243 } 244 245 return GetSysColorBrush(COLOR_WINDOW); 246 } 247 248 static BOOL CALLBACK 249 UserSendUiUpdateMsg(HWND hwnd, LPARAM lParam) 250 { 251 SendMessageW(hwnd, WM_UPDATEUISTATE, (WPARAM)lParam, 0); 252 return TRUE; 253 } 254 255 /* WARNING: Redundant with /ntuser/defwnd.c!UserPaintCaption !! 256 Use TWOPARAM_ROUTINE_REDRAWTITLE/REDRAWFRAME or HWNDLOCK_ROUTINE_REDRAWFRAMEANDHOOK . 257 */ 258 static void 259 UserPaintCaption(PWND pwnd, INT Flags) 260 { 261 if ( pwnd->style & WS_VISIBLE && (pwnd->style & WS_CAPTION) == WS_CAPTION ) 262 { 263 if (pwnd->state & WNDS_HASCAPTION && NtUserQueryWindow(UserHMGetHandle(pwnd), QUERY_WINDOW_FOREGROUND)) 264 Flags |= DC_ACTIVE; 265 /* 266 * When themes are not enabled we can go on and paint the non client area. 267 * However if we do that with themes enabled we will draw a classic frame. 268 * This is solved by sending a themes specific message to notify the themes 269 * engine that the caption needs to be redrawn 270 */ 271 if(gpsi->dwSRVIFlags & SRVINFO_APIHOOK) 272 { 273 /* 274 * This will cause uxtheme to either paint the themed caption or call 275 * RealUserDrawCaption in order to draw the classic caption when themes 276 * are disabled but the themes service is enabled 277 */ 278 SendMessageW(UserHMGetHandle(pwnd), WM_NCUAHDRAWCAPTION, Flags, 0); 279 } 280 else 281 { 282 RECT rc = {0,0,0,0}; 283 HDC hDC = GetDCEx(UserHMGetHandle(pwnd), NULL, DCX_WINDOW|DCX_USESTYLE); 284 NtUserDrawCaption(UserHMGetHandle(pwnd), hDC, &rc, DC_DRAWCAPTIONMD|Flags); 285 ReleaseDC(UserHMGetHandle(pwnd), hDC); 286 } 287 } 288 //NtUserCallTwoParam((DWORD_PTR)UserHMGetHandle(pwnd),Flags,TWOPARAM_ROUTINE_REDRAWTITLE) 289 } 290 291 LRESULT FASTCALL 292 DefWndGetIcon(PWND pWnd, WPARAM wParam, LPARAM lParam) 293 { 294 HICON hIconRet; 295 if ( wParam > ICON_SMALL2 ) 296 { 297 SetLastError(ERROR_INVALID_PARAMETER); 298 return 0; 299 } 300 switch(wParam) 301 { 302 case ICON_BIG: 303 hIconRet = UserGetProp(UserHMGetHandle(pWnd), gpsi->atomIconProp, TRUE); 304 break; 305 case ICON_SMALL: 306 case ICON_SMALL2: 307 hIconRet = UserGetProp(UserHMGetHandle(pWnd), gpsi->atomIconSmProp, TRUE); 308 break; 309 default: 310 break; 311 } 312 return (LRESULT)hIconRet; 313 } 314 315 316 LRESULT WINAPI 317 User32DefWindowProc(HWND hWnd, 318 UINT Msg, 319 WPARAM wParam, 320 LPARAM lParam, 321 BOOL bUnicode) 322 { 323 PWND pWnd = NULL; 324 if (hWnd) 325 { 326 pWnd = ValidateHwnd(hWnd); 327 if (!pWnd) return 0; 328 } 329 330 switch (Msg) 331 { 332 case WM_DEVICECHANGE: 333 return TRUE; 334 335 case WM_POPUPSYSTEMMENU: 336 { 337 /* This is an undocumented message used by the windows taskbar to 338 display the system menu of windows that belong to other processes. */ 339 HMENU menu = GetSystemMenu(hWnd, FALSE); 340 ERR("WM_POPUPSYSTEMMENU\n"); 341 if (menu) 342 { 343 SetForegroundWindow(hWnd); 344 TrackPopupMenu(menu, TPM_LEFTBUTTON|TPM_RIGHTBUTTON|TPM_SYSTEM_MENU, 345 LOWORD(lParam), HIWORD(lParam), 0, hWnd, NULL); 346 } 347 return 0; 348 } 349 350 case WM_RBUTTONUP: 351 { 352 POINT Pt; 353 Pt.x = GET_X_LPARAM(lParam); 354 Pt.y = GET_Y_LPARAM(lParam); 355 ClientToScreen(hWnd, &Pt); 356 lParam = MAKELPARAM(Pt.x, Pt.y); 357 if (bUnicode) 358 { 359 SendMessageW(hWnd, WM_CONTEXTMENU, (WPARAM)hWnd, lParam); 360 } 361 else 362 { 363 SendMessageA(hWnd, WM_CONTEXTMENU, (WPARAM)hWnd, lParam); 364 } 365 break; 366 } 367 368 case WM_NCRBUTTONUP: 369 /* 370 * FIXME : we must NOT send WM_CONTEXTMENU on a WM_NCRBUTTONUP (checked 371 * in Windows), but what _should_ we do? According to MSDN : 372 * "If it is appropriate to do so, the system sends the WM_SYSCOMMAND 373 * message to the window". When is it appropriate? 374 */ 375 ERR("WM_NCRBUTTONUP\n"); 376 break; 377 378 case WM_XBUTTONUP: 379 case WM_NCXBUTTONUP: 380 if (HIWORD(wParam) == XBUTTON1 || HIWORD(wParam) == XBUTTON2) 381 { 382 SendMessageW(hWnd, WM_APPCOMMAND, (WPARAM)hWnd, 383 MAKELPARAM(LOWORD(wParam), FAPPCOMMAND_MOUSE | HIWORD(wParam))); 384 } 385 break; 386 387 case WM_CONTEXTMENU: 388 { 389 if (GetWindowLongPtrW(hWnd, GWL_STYLE) & WS_CHILD) 390 { 391 if (bUnicode) 392 { 393 SendMessageW(GetParent(hWnd), Msg, wParam, lParam); 394 } 395 else 396 { 397 SendMessageA(GetParent(hWnd), WM_CONTEXTMENU, wParam, lParam); 398 } 399 } 400 else 401 { 402 goto GoSS; 403 } 404 break; 405 } 406 407 case WM_CLOSE: 408 DestroyWindow(hWnd); 409 return (0); 410 411 case WM_MOUSEACTIVATE: 412 if (GetWindowLongPtrW(hWnd, GWL_STYLE) & WS_CHILD) 413 { 414 LONG Ret = SendMessageW(GetParent(hWnd), WM_MOUSEACTIVATE, wParam, lParam); 415 if (Ret) return (Ret); 416 } 417 return ( (HIWORD(lParam) == WM_LBUTTONDOWN && LOWORD(lParam) == HTCAPTION) ? MA_NOACTIVATE : MA_ACTIVATE ); 418 419 case WM_ACTIVATE: 420 /* The default action in Windows is to set the keyboard focus to 421 * the window, if it's being activated and not minimized */ 422 if (LOWORD(wParam) != WA_INACTIVE && 423 !(GetWindowLongPtrW(hWnd, GWL_STYLE) & WS_MINIMIZE)) 424 { 425 //ERR("WM_ACTIVATE %p\n",hWnd); 426 SetFocus(hWnd); 427 } 428 break; 429 430 case WM_MOUSEWHEEL: 431 if (GetWindowLongPtrW(hWnd, GWL_STYLE) & WS_CHILD) 432 return SendMessageW( GetParent(hWnd), WM_MOUSEWHEEL, wParam, lParam); 433 break; 434 435 case WM_ERASEBKGND: 436 case WM_ICONERASEBKGND: 437 { 438 RECT Rect; 439 HBRUSH hBrush = (HBRUSH)GetClassLongPtrW(hWnd, GCL_HBRBACKGROUND); 440 441 if (NULL == hBrush) 442 { 443 return 0; 444 } 445 if (GetClassLongPtrW(hWnd, GCL_STYLE) & CS_PARENTDC) 446 { 447 /* can't use GetClipBox with a parent DC or we fill the whole parent */ 448 GetClientRect(hWnd, &Rect); 449 DPtoLP((HDC)wParam, (LPPOINT)&Rect, 2); 450 } 451 else 452 { 453 GetClipBox((HDC)wParam, &Rect); 454 } 455 FillRect((HDC)wParam, &Rect, hBrush); 456 return (1); 457 } 458 459 case WM_CTLCOLORMSGBOX: 460 case WM_CTLCOLOREDIT: 461 case WM_CTLCOLORLISTBOX: 462 case WM_CTLCOLORBTN: 463 case WM_CTLCOLORDLG: 464 case WM_CTLCOLORSTATIC: 465 case WM_CTLCOLORSCROLLBAR: 466 return (LRESULT) DefWndControlColor((HDC)wParam, Msg - WM_CTLCOLORMSGBOX); 467 468 case WM_CTLCOLOR: 469 return (LRESULT) DefWndControlColor((HDC)wParam, HIWORD(lParam)); 470 471 case WM_SYSCOMMAND: 472 return (DefWndHandleSysCommand(hWnd, wParam, lParam)); 473 474 case WM_VKEYTOITEM: 475 case WM_CHARTOITEM: 476 return (-1); 477 /* 478 case WM_DROPOBJECT: 479 return DRAG_FILE; 480 */ 481 case WM_QUERYDROPOBJECT: 482 { 483 if (GetWindowLongPtrW(hWnd, GWL_EXSTYLE) & WS_EX_ACCEPTFILES) 484 { 485 return(1); 486 } 487 break; 488 } 489 490 case WM_QUERYDRAGICON: 491 { 492 UINT Len; 493 HICON hIcon; 494 495 hIcon = (HICON)GetClassLongPtrW(hWnd, GCL_HICON); 496 if (hIcon) 497 { 498 return ((LRESULT)hIcon); 499 } 500 for (Len = 1; Len < 64; Len++) 501 { 502 if ((hIcon = LoadIconW(NULL, MAKEINTRESOURCEW(Len))) != NULL) 503 { 504 return((LRESULT)hIcon); 505 } 506 } 507 return ((LRESULT)LoadIconW(0, IDI_APPLICATION)); 508 } 509 510 case WM_ISACTIVEICON: 511 { 512 BOOL isai; 513 isai = (pWnd->state & WNDS_ACTIVEFRAME) != 0; 514 return isai; 515 } 516 517 case WM_NOTIFYFORMAT: 518 { 519 if (lParam == NF_QUERY) 520 return IsWindowUnicode(hWnd) ? NFR_UNICODE : NFR_ANSI; 521 break; 522 } 523 524 case WM_GETICON: 525 { 526 return DefWndGetIcon(pWnd, wParam, lParam); 527 } 528 529 case WM_HELP: 530 { 531 if (bUnicode) 532 { 533 SendMessageW(GetParent(hWnd), Msg, wParam, lParam); 534 } 535 else 536 { 537 SendMessageA(GetParent(hWnd), Msg, wParam, lParam); 538 } 539 break; 540 } 541 542 case WM_QUERYOPEN: 543 case WM_QUERYENDSESSION: 544 { 545 return (1); 546 } 547 548 case WM_INPUTLANGCHANGEREQUEST: 549 { 550 HKL NewHkl; 551 552 if(wParam & INPUTLANGCHANGE_BACKWARD 553 && wParam & INPUTLANGCHANGE_FORWARD) 554 { 555 return FALSE; 556 } 557 558 //FIXME: What to do with INPUTLANGCHANGE_SYSCHARSET ? 559 560 if(wParam & INPUTLANGCHANGE_BACKWARD) NewHkl = (HKL) HKL_PREV; 561 else if(wParam & INPUTLANGCHANGE_FORWARD) NewHkl = (HKL) HKL_NEXT; 562 else NewHkl = (HKL) lParam; 563 564 NtUserActivateKeyboardLayout(NewHkl, 0); 565 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, 1238 UINT Msg, 1239 WPARAM wParam, 1240 LPARAM lParam) 1241 { 1242 BOOL Hook, msgOverride = FALSE; 1243 LRESULT Result = 0; 1244 1245 LoadUserApiHook(); 1246 1247 Hook = BeginIfHookedUserApiHook(); 1248 if (Hook) 1249 { 1250 msgOverride = IsMsgOverride(Msg, &guah.DefWndProcArray); 1251 if(msgOverride == FALSE) 1252 { 1253 EndUserApiHook(); 1254 } 1255 } 1256 1257 /* Bypass SEH and go direct. */ 1258 if (!Hook || !msgOverride) 1259 return RealDefWindowProcA(hWnd, Msg, wParam, lParam); 1260 1261 _SEH2_TRY 1262 { 1263 Result = guah.DefWindowProcA(hWnd, Msg, wParam, lParam); 1264 } 1265 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 1266 { 1267 ERR("Got exception in hooked DefWindowProcA!\n"); 1268 } 1269 _SEH2_END; 1270 1271 EndUserApiHook(); 1272 1273 return Result; 1274 } 1275 1276 LRESULT WINAPI 1277 DefWindowProcW(HWND hWnd, 1278 UINT Msg, 1279 WPARAM wParam, 1280 LPARAM lParam) 1281 { 1282 BOOL Hook, msgOverride = FALSE; 1283 LRESULT Result = 0; 1284 1285 LoadUserApiHook(); 1286 1287 Hook = BeginIfHookedUserApiHook(); 1288 if (Hook) 1289 { 1290 msgOverride = IsMsgOverride(Msg, &guah.DefWndProcArray); 1291 if(msgOverride == FALSE) 1292 { 1293 EndUserApiHook(); 1294 } 1295 } 1296 1297 /* Bypass SEH and go direct. */ 1298 if (!Hook || !msgOverride) 1299 return RealDefWindowProcW(hWnd, Msg, wParam, lParam); 1300 1301 _SEH2_TRY 1302 { 1303 Result = guah.DefWindowProcW(hWnd, Msg, wParam, lParam); 1304 } 1305 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 1306 { 1307 ERR("Got exception in hooked DefWindowProcW!\n"); 1308 } 1309 _SEH2_END; 1310 1311 EndUserApiHook(); 1312 1313 return Result; 1314 } 1315