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 TrackPopupMenu(menu, TPM_LEFTBUTTON|TPM_RIGHTBUTTON|TPM_SYSTEM_MENU, 342 LOWORD(lParam), HIWORD(lParam), 0, hWnd, NULL); 343 return 0; 344 } 345 346 case WM_RBUTTONUP: 347 { 348 POINT Pt; 349 Pt.x = GET_X_LPARAM(lParam); 350 Pt.y = GET_Y_LPARAM(lParam); 351 ClientToScreen(hWnd, &Pt); 352 lParam = MAKELPARAM(Pt.x, Pt.y); 353 if (bUnicode) 354 { 355 SendMessageW(hWnd, WM_CONTEXTMENU, (WPARAM)hWnd, lParam); 356 } 357 else 358 { 359 SendMessageA(hWnd, WM_CONTEXTMENU, (WPARAM)hWnd, lParam); 360 } 361 break; 362 } 363 364 case WM_NCRBUTTONUP: 365 /* 366 * FIXME : we must NOT send WM_CONTEXTMENU on a WM_NCRBUTTONUP (checked 367 * in Windows), but what _should_ we do? According to MSDN : 368 * "If it is appropriate to do so, the system sends the WM_SYSCOMMAND 369 * message to the window". When is it appropriate? 370 */ 371 ERR("WM_NCRBUTTONUP\n"); 372 break; 373 374 case WM_XBUTTONUP: 375 case WM_NCXBUTTONUP: 376 if (HIWORD(wParam) == XBUTTON1 || HIWORD(wParam) == XBUTTON2) 377 { 378 SendMessageW(hWnd, WM_APPCOMMAND, (WPARAM)hWnd, 379 MAKELPARAM(LOWORD(wParam), FAPPCOMMAND_MOUSE | HIWORD(wParam))); 380 } 381 break; 382 383 case WM_CONTEXTMENU: 384 { 385 if (GetWindowLongPtrW(hWnd, GWL_STYLE) & WS_CHILD) 386 { 387 if (bUnicode) 388 { 389 SendMessageW(GetParent(hWnd), Msg, wParam, lParam); 390 } 391 else 392 { 393 SendMessageA(GetParent(hWnd), WM_CONTEXTMENU, wParam, lParam); 394 } 395 } 396 else 397 { 398 goto GoSS; 399 } 400 break; 401 } 402 403 case WM_CLOSE: 404 DestroyWindow(hWnd); 405 return (0); 406 407 case WM_MOUSEACTIVATE: 408 if (GetWindowLongPtrW(hWnd, GWL_STYLE) & WS_CHILD) 409 { 410 LONG Ret = SendMessageW(GetParent(hWnd), WM_MOUSEACTIVATE, wParam, lParam); 411 if (Ret) return (Ret); 412 } 413 return ( (HIWORD(lParam) == WM_LBUTTONDOWN && LOWORD(lParam) == HTCAPTION) ? MA_NOACTIVATE : MA_ACTIVATE ); 414 415 case WM_ACTIVATE: 416 /* The default action in Windows is to set the keyboard focus to 417 * the window, if it's being activated and not minimized */ 418 if (LOWORD(wParam) != WA_INACTIVE && 419 !(GetWindowLongPtrW(hWnd, GWL_STYLE) & WS_MINIMIZE)) 420 { 421 //ERR("WM_ACTIVATE %p\n",hWnd); 422 SetFocus(hWnd); 423 } 424 break; 425 426 case WM_MOUSEWHEEL: 427 if (GetWindowLongPtrW(hWnd, GWL_STYLE) & WS_CHILD) 428 return SendMessageW( GetParent(hWnd), WM_MOUSEWHEEL, wParam, lParam); 429 break; 430 431 case WM_ERASEBKGND: 432 case WM_ICONERASEBKGND: 433 { 434 RECT Rect; 435 HBRUSH hBrush = (HBRUSH)GetClassLongPtrW(hWnd, GCL_HBRBACKGROUND); 436 437 if (NULL == hBrush) 438 { 439 return 0; 440 } 441 if (GetClassLongPtrW(hWnd, GCL_STYLE) & CS_PARENTDC) 442 { 443 /* can't use GetClipBox with a parent DC or we fill the whole parent */ 444 GetClientRect(hWnd, &Rect); 445 DPtoLP((HDC)wParam, (LPPOINT)&Rect, 2); 446 } 447 else 448 { 449 GetClipBox((HDC)wParam, &Rect); 450 } 451 FillRect((HDC)wParam, &Rect, hBrush); 452 return (1); 453 } 454 455 case WM_CTLCOLORMSGBOX: 456 case WM_CTLCOLOREDIT: 457 case WM_CTLCOLORLISTBOX: 458 case WM_CTLCOLORBTN: 459 case WM_CTLCOLORDLG: 460 case WM_CTLCOLORSTATIC: 461 case WM_CTLCOLORSCROLLBAR: 462 return (LRESULT) DefWndControlColor((HDC)wParam, Msg - WM_CTLCOLORMSGBOX); 463 464 case WM_CTLCOLOR: 465 return (LRESULT) DefWndControlColor((HDC)wParam, HIWORD(lParam)); 466 467 case WM_SYSCOMMAND: 468 return (DefWndHandleSysCommand(hWnd, wParam, lParam)); 469 470 case WM_VKEYTOITEM: 471 case WM_CHARTOITEM: 472 return (-1); 473 /* 474 case WM_DROPOBJECT: 475 return DRAG_FILE; 476 */ 477 case WM_QUERYDROPOBJECT: 478 { 479 if (GetWindowLongPtrW(hWnd, GWL_EXSTYLE) & WS_EX_ACCEPTFILES) 480 { 481 return(1); 482 } 483 break; 484 } 485 486 case WM_QUERYDRAGICON: 487 { 488 UINT Len; 489 HICON hIcon; 490 491 hIcon = (HICON)GetClassLongPtrW(hWnd, GCL_HICON); 492 if (hIcon) 493 { 494 return ((LRESULT)hIcon); 495 } 496 for (Len = 1; Len < 64; Len++) 497 { 498 if ((hIcon = LoadIconW(NULL, MAKEINTRESOURCEW(Len))) != NULL) 499 { 500 return((LRESULT)hIcon); 501 } 502 } 503 return ((LRESULT)LoadIconW(0, IDI_APPLICATION)); 504 } 505 506 case WM_ISACTIVEICON: 507 { 508 BOOL isai; 509 isai = (pWnd->state & WNDS_ACTIVEFRAME) != 0; 510 return isai; 511 } 512 513 case WM_NOTIFYFORMAT: 514 { 515 if (lParam == NF_QUERY) 516 return IsWindowUnicode(hWnd) ? NFR_UNICODE : NFR_ANSI; 517 break; 518 } 519 520 case WM_GETICON: 521 { 522 return DefWndGetIcon(pWnd, wParam, lParam); 523 } 524 525 case WM_HELP: 526 { 527 if (bUnicode) 528 { 529 SendMessageW(GetParent(hWnd), Msg, wParam, lParam); 530 } 531 else 532 { 533 SendMessageA(GetParent(hWnd), Msg, wParam, lParam); 534 } 535 break; 536 } 537 538 case WM_QUERYOPEN: 539 case WM_QUERYENDSESSION: 540 { 541 return (1); 542 } 543 544 case WM_INPUTLANGCHANGEREQUEST: 545 { 546 HKL NewHkl; 547 548 if(wParam & INPUTLANGCHANGE_BACKWARD 549 && wParam & INPUTLANGCHANGE_FORWARD) 550 { 551 return FALSE; 552 } 553 554 //FIXME: What to do with INPUTLANGCHANGE_SYSCHARSET ? 555 556 if(wParam & INPUTLANGCHANGE_BACKWARD) NewHkl = (HKL) HKL_PREV; 557 else if(wParam & INPUTLANGCHANGE_FORWARD) NewHkl = (HKL) HKL_NEXT; 558 else NewHkl = (HKL) lParam; 559 560 NtUserActivateKeyboardLayout(NewHkl, 0); 561 562 return TRUE; 563 } 564 565 case WM_INPUTLANGCHANGE: 566 { 567 int count = 0; 568 HWND *win_array = WIN_ListChildren( hWnd ); 569 570 if (!win_array) 571 break; 572 while (win_array[count]) 573 SendMessageW( win_array[count++], WM_INPUTLANGCHANGE, wParam, lParam); 574 HeapFree(GetProcessHeap(),0,win_array); 575 break; 576 } 577 578 case WM_QUERYUISTATE: 579 { 580 LRESULT Ret = 0; 581 PWND Wnd = ValidateHwnd(hWnd); 582 if (Wnd != NULL) 583 { 584 if (Wnd->HideFocus) 585 Ret |= UISF_HIDEFOCUS; 586 if (Wnd->HideAccel) 587 Ret |= UISF_HIDEACCEL; 588 } 589 return Ret; 590 } 591 592 case WM_CHANGEUISTATE: 593 { 594 BOOL AlwaysShowCues = FALSE; 595 WORD Action = LOWORD(wParam); 596 WORD Flags = HIWORD(wParam); 597 PWND Wnd; 598 599 SystemParametersInfoW(SPI_GETKEYBOARDCUES, 0, &AlwaysShowCues, 0); 600 if (AlwaysShowCues) 601 break; 602 603 Wnd= ValidateHwnd(hWnd); 604 if (!Wnd || lParam != 0) 605 break; 606 607 if (Flags & ~(UISF_HIDEFOCUS | UISF_HIDEACCEL | UISF_ACTIVE)) 608 break; 609 610 if (Flags & UISF_ACTIVE) 611 { 612 WARN("WM_CHANGEUISTATE does not yet support UISF_ACTIVE!\n"); 613 } 614 615 if (Action == UIS_INITIALIZE) 616 { 617 PDESKTOPINFO Desk = GetThreadDesktopInfo(); 618 if (Desk == NULL) 619 break; 620 621 Action = Desk->LastInputWasKbd ? UIS_CLEAR : UIS_SET; 622 Flags = UISF_HIDEFOCUS | UISF_HIDEACCEL; 623 624 /* We need to update wParam in case we need to send out messages */ 625 wParam = MAKEWPARAM(Action, Flags); 626 } 627 628 switch (Action) 629 { 630 case UIS_SET: 631 /* See if we actually need to change something */ 632 if ((Flags & UISF_HIDEFOCUS) && !Wnd->HideFocus) 633 break; 634 if ((Flags & UISF_HIDEACCEL) && !Wnd->HideAccel) 635 break; 636 637 /* Don't need to do anything... */ 638 return 0; 639 640 case UIS_CLEAR: 641 /* See if we actually need to change something */ 642 if ((Flags & UISF_HIDEFOCUS) && Wnd->HideFocus) 643 break; 644 if ((Flags & UISF_HIDEACCEL) && Wnd->HideAccel) 645 break; 646 647 /* Don't need to do anything... */ 648 return 0; 649 650 default: 651 WARN("WM_CHANGEUISTATE: Unsupported Action 0x%x\n", Action); 652 break; 653 } 654 655 if ((Wnd->style & WS_CHILD) && Wnd->spwndParent != NULL) 656 { 657 /* We're a child window and we need to pass this message down until 658 we reach the root */ 659 hWnd = UserHMGetHandle((PWND)DesktopPtrToUser(Wnd->spwndParent)); 660 } 661 else 662 { 663 /* We're a top level window, we need to change the UI state */ 664 Msg = WM_UPDATEUISTATE; 665 } 666 667 if (bUnicode) 668 return SendMessageW(hWnd, Msg, wParam, lParam); 669 else 670 return SendMessageA(hWnd, Msg, wParam, lParam); 671 } 672 673 case WM_UPDATEUISTATE: 674 { 675 BOOL Change = TRUE; 676 BOOL AlwaysShowCues = FALSE; 677 WORD Action = LOWORD(wParam); 678 WORD Flags = HIWORD(wParam); 679 PWND Wnd; 680 681 SystemParametersInfoW(SPI_GETKEYBOARDCUES, 0, &AlwaysShowCues, 0); 682 if (AlwaysShowCues) 683 break; 684 685 Wnd = ValidateHwnd(hWnd); 686 if (!Wnd || lParam != 0) 687 break; 688 689 if (Flags & ~(UISF_HIDEFOCUS | UISF_HIDEACCEL | UISF_ACTIVE)) 690 break; 691 692 if (Flags & UISF_ACTIVE) 693 { 694 WARN("WM_UPDATEUISTATE does not yet support UISF_ACTIVE!\n"); 695 } 696 697 if (Action == UIS_INITIALIZE) 698 { 699 PDESKTOPINFO Desk = GetThreadDesktopInfo(); 700 if (Desk == NULL) 701 break; 702 703 Action = Desk->LastInputWasKbd ? UIS_CLEAR : UIS_SET; 704 Flags = UISF_HIDEFOCUS | UISF_HIDEACCEL; 705 706 /* We need to update wParam for broadcasting the update */ 707 wParam = MAKEWPARAM(Action, Flags); 708 } 709 710 switch (Action) 711 { 712 case UIS_SET: 713 /* See if we actually need to change something */ 714 if ((Flags & UISF_HIDEFOCUS) && !Wnd->HideFocus) 715 break; 716 if ((Flags & UISF_HIDEACCEL) && !Wnd->HideAccel) 717 break; 718 719 /* Don't need to do anything... */ 720 Change = FALSE; 721 break; 722 723 case UIS_CLEAR: 724 /* See if we actually need to change something */ 725 if ((Flags & UISF_HIDEFOCUS) && Wnd->HideFocus) 726 break; 727 if ((Flags & UISF_HIDEACCEL) && Wnd->HideAccel) 728 break; 729 730 /* Don't need to do anything... */ 731 Change = FALSE; 732 break; 733 734 default: 735 WARN("WM_UPDATEUISTATE: Unsupported Action 0x%x\n", Action); 736 return 0; 737 } 738 739 /* Pack the information and call win32k */ 740 if (Change) 741 { 742 if (!NtUserxUpdateUiState(hWnd, Flags | ((DWORD)Action << 3))) 743 break; 744 } 745 746 /* Always broadcast the update to all children */ 747 EnumChildWindows(hWnd, 748 UserSendUiUpdateMsg, 749 (LPARAM)wParam); 750 751 break; 752 } 753 754 case WM_COPYGLOBALDATA: 755 { 756 TRACE("WM_COPYGLOBALDATA hGlobal %p Size %d Flags 0x%x\n",lParam,wParam,GlobalFlags((HGLOBAL)lParam)); 757 return lParam; 758 } 759 760 /* Move to Win32k !*/ 761 case WM_SHOWWINDOW: 762 if (!lParam) break; // Call when it is necessary. 763 case WM_LBUTTONDOWN: 764 case WM_RBUTTONDOWN: 765 case WM_MBUTTONDOWN: 766 case WM_NCLBUTTONDOWN: 767 case WM_NCRBUTTONDOWN: 768 case WM_LBUTTONDBLCLK: 769 case WM_NCLBUTTONDBLCLK: 770 case WM_KEYF1: 771 case WM_KEYUP: 772 case WM_SYSKEYUP: 773 case WM_KEYDOWN: 774 case WM_SYSKEYDOWN: 775 case WM_SYSCHAR: 776 case WM_CANCELMODE: 777 case WM_PAINTICON: 778 case WM_PAINT: 779 case WM_PRINT: 780 case WM_SETICON: 781 case WM_SYSCOLORCHANGE: 782 case WM_NCUAHDRAWCAPTION: 783 case WM_NCUAHDRAWFRAME: 784 case WM_NCPAINT: 785 case WM_NCACTIVATE: 786 case WM_NCCALCSIZE: 787 case WM_NCHITTEST: 788 case WM_SYNCPAINT: 789 case WM_SETREDRAW: 790 case WM_CLIENTSHUTDOWN: 791 case WM_GETHOTKEY: 792 case WM_SETHOTKEY: 793 case WM_WINDOWPOSCHANGING: 794 case WM_WINDOWPOSCHANGED: 795 case WM_APPCOMMAND: 796 case WM_SETCURSOR: 797 GoSS: 798 { 799 LRESULT lResult; 800 NtUserMessageCall( hWnd, Msg, wParam, lParam, (ULONG_PTR)&lResult, FNID_DEFWINDOWPROC, !bUnicode); 801 return lResult; 802 } 803 } 804 return 0; 805 } 806 807 808 LRESULT WINAPI 809 RealDefWindowProcA(HWND hWnd, 810 UINT Msg, 811 WPARAM wParam, 812 LPARAM lParam) 813 { 814 LRESULT Result = 0; 815 PWND Wnd; 816 817 Wnd = ValidateHwnd(hWnd); 818 819 if ( !Wnd && 820 Msg != WM_CTLCOLORMSGBOX && 821 Msg != WM_CTLCOLORBTN && 822 Msg != WM_CTLCOLORDLG && 823 Msg != WM_CTLCOLORSTATIC ) 824 return 0; 825 826 SPY_EnterMessage(SPY_DEFWNDPROC, hWnd, Msg, wParam, lParam); 827 switch (Msg) 828 { 829 case WM_NCCREATE: 830 { 831 if ( Wnd && 832 Wnd->style & (WS_HSCROLL | WS_VSCROLL) ) 833 { 834 if (!Wnd->pSBInfo) 835 { 836 SCROLLINFO si = {sizeof si, SIF_ALL, 0, 100, 0, 0, 0}; 837 SetScrollInfo( hWnd, SB_HORZ, &si, FALSE ); 838 SetScrollInfo( hWnd, SB_VERT, &si, FALSE ); 839 } 840 } 841 842 if (lParam) 843 { 844 LPCREATESTRUCTA cs = (LPCREATESTRUCTA)lParam; 845 /* check for string, as static icons, bitmaps (SS_ICON, SS_BITMAP) 846 * may have child window IDs instead of window name */ 847 if (HIWORD(cs->lpszName)) 848 { 849 DefSetText(hWnd, (PCWSTR)cs->lpszName, TRUE); 850 } 851 Result = 1; 852 } 853 break; 854 } 855 856 case WM_GETTEXTLENGTH: 857 { 858 PWSTR buf; 859 ULONG len; 860 861 if (Wnd != NULL && Wnd->strName.Length != 0) 862 { 863 buf = DesktopPtrToUser(Wnd->strName.Buffer); 864 if (buf != NULL && 865 NT_SUCCESS(RtlUnicodeToMultiByteSize(&len, 866 buf, 867 Wnd->strName.Length))) 868 { 869 Result = (LRESULT) len; 870 } 871 } 872 else Result = 0L; 873 874 break; 875 } 876 877 case WM_GETTEXT: 878 { 879 PWSTR buf = NULL; 880 PSTR outbuf = (PSTR)lParam; 881 SIZE_T copy; 882 883 if (Wnd != NULL && wParam != 0) 884 { 885 if (Wnd->strName.Buffer != NULL) 886 buf = DesktopPtrToUser(Wnd->strName.Buffer); 887 else 888 outbuf[0] = L'\0'; 889 890 if (buf != NULL) 891 { 892 if (Wnd->strName.Length != 0) 893 { 894 copy = min(Wnd->strName.Length / sizeof(WCHAR), wParam - 1); 895 Result = WideCharToMultiByte(CP_ACP, 896 0, 897 buf, 898 copy, 899 outbuf, 900 wParam, 901 NULL, 902 NULL); 903 outbuf[Result] = '\0'; 904 } 905 else 906 outbuf[0] = '\0'; 907 } 908 } 909 break; 910 } 911 912 case WM_SETTEXT: 913 { 914 DefSetText(hWnd, (PCWSTR)lParam, TRUE); 915 916 if ((GetWindowLongPtrW(hWnd, GWL_STYLE) & WS_CAPTION) == WS_CAPTION) 917 { 918 UserPaintCaption(Wnd, DC_TEXT); 919 IntNotifyWinEvent(EVENT_OBJECT_NAMECHANGE, hWnd, OBJID_WINDOW, CHILDID_SELF, 0); 920 } 921 Result = 1; 922 break; 923 } 924 925 case WM_IME_KEYDOWN: 926 { 927 Result = PostMessageA(hWnd, WM_KEYDOWN, wParam, lParam); 928 break; 929 } 930 931 case WM_IME_KEYUP: 932 { 933 Result = PostMessageA(hWnd, WM_KEYUP, wParam, lParam); 934 break; 935 } 936 937 case WM_IME_CHAR: 938 { 939 if (HIBYTE(wParam)) 940 PostMessageA(hWnd, WM_CHAR, HIBYTE(wParam), lParam); 941 PostMessageA(hWnd, WM_CHAR, LOBYTE(wParam), lParam); 942 break; 943 } 944 945 case WM_IME_COMPOSITION: 946 if (lParam & GCS_RESULTSTR) 947 { 948 LONG size, i; 949 unsigned char lead = 0; 950 char *buf = NULL; 951 HIMC himc = ImmGetContext( hWnd ); 952 953 if (himc) 954 { 955 if ((size = ImmGetCompositionStringA( himc, GCS_RESULTSTR, NULL, 0 ))) 956 { 957 if (!(buf = HeapAlloc( GetProcessHeap(), 0, size ))) size = 0; 958 else size = ImmGetCompositionStringA( himc, GCS_RESULTSTR, buf, size ); 959 } 960 ImmReleaseContext( hWnd, himc ); 961 962 for (i = 0; i < size; i++) 963 { 964 unsigned char c = buf[i]; 965 if (!lead) 966 { 967 if (IsDBCSLeadByte( c )) 968 lead = c; 969 else 970 SendMessageA( hWnd, WM_IME_CHAR, c, 1 ); 971 } 972 else 973 { 974 SendMessageA( hWnd, WM_IME_CHAR, MAKEWORD(c, lead), 1 ); 975 lead = 0; 976 } 977 } 978 HeapFree( GetProcessHeap(), 0, buf ); 979 } 980 } 981 /* fall through */ 982 case WM_IME_STARTCOMPOSITION: 983 case WM_IME_ENDCOMPOSITION: 984 case WM_IME_SELECT: 985 case WM_IME_NOTIFY: 986 case WM_IME_CONTROL: 987 { 988 HWND hwndIME; 989 990 hwndIME = ImmGetDefaultIMEWnd(hWnd); 991 if (hwndIME) 992 Result = SendMessageA(hwndIME, Msg, wParam, lParam); 993 break; 994 } 995 996 case WM_IME_SETCONTEXT: 997 { 998 HWND hwndIME; 999 1000 hwndIME = ImmGetDefaultIMEWnd(hWnd); 1001 if (hwndIME) 1002 Result = ImmIsUIMessageA(hwndIME, Msg, wParam, lParam); 1003 break; 1004 } 1005 1006 /* fall through */ 1007 default: 1008 Result = User32DefWindowProc(hWnd, Msg, wParam, lParam, FALSE); 1009 } 1010 1011 SPY_ExitMessage(SPY_RESULT_DEFWND, hWnd, Msg, Result, wParam, lParam); 1012 return Result; 1013 } 1014 1015 1016 LRESULT WINAPI 1017 RealDefWindowProcW(HWND hWnd, 1018 UINT Msg, 1019 WPARAM wParam, 1020 LPARAM lParam) 1021 { 1022 LRESULT Result = 0; 1023 PWND Wnd; 1024 1025 Wnd = ValidateHwnd(hWnd); 1026 1027 if ( !Wnd && 1028 Msg != WM_CTLCOLORMSGBOX && 1029 Msg != WM_CTLCOLORBTN && 1030 Msg != WM_CTLCOLORDLG && 1031 Msg != WM_CTLCOLORSTATIC ) 1032 return 0; 1033 1034 SPY_EnterMessage(SPY_DEFWNDPROC, hWnd, Msg, wParam, lParam); 1035 switch (Msg) 1036 { 1037 case WM_NCCREATE: 1038 { 1039 if ( Wnd && 1040 Wnd->style & (WS_HSCROLL | WS_VSCROLL) ) 1041 { 1042 if (!Wnd->pSBInfo) 1043 { 1044 SCROLLINFO si = {sizeof si, SIF_ALL, 0, 100, 0, 0, 0}; 1045 if (Wnd->style & WS_HSCROLL) 1046 SetScrollInfo( hWnd, SB_HORZ, &si, FALSE ); 1047 if (Wnd->style & WS_VSCROLL) 1048 SetScrollInfo( hWnd, SB_VERT, &si, FALSE ); 1049 } 1050 } 1051 1052 if (lParam) 1053 { 1054 LPCREATESTRUCTW cs = (LPCREATESTRUCTW)lParam; 1055 /* check for string, as static icons, bitmaps (SS_ICON, SS_BITMAP) 1056 * may have child window IDs instead of window name */ 1057 if (HIWORD(cs->lpszName)) 1058 { 1059 DefSetText(hWnd, cs->lpszName, FALSE); 1060 } 1061 Result = 1; 1062 } 1063 break; 1064 } 1065 1066 case WM_GETTEXTLENGTH: 1067 { 1068 PWSTR buf; 1069 ULONG len; 1070 1071 if (Wnd != NULL && Wnd->strName.Length != 0) 1072 { 1073 buf = DesktopPtrToUser(Wnd->strName.Buffer); 1074 if (buf != NULL && 1075 NT_SUCCESS(RtlUnicodeToMultiByteSize(&len, 1076 buf, 1077 Wnd->strName.Length))) 1078 { 1079 Result = (LRESULT) (Wnd->strName.Length / sizeof(WCHAR)); 1080 } 1081 } 1082 else Result = 0L; 1083 1084 break; 1085 } 1086 1087 case WM_GETTEXT: 1088 { 1089 PWSTR buf = NULL; 1090 PWSTR outbuf = (PWSTR)lParam; 1091 1092 if (Wnd != NULL && wParam != 0) 1093 { 1094 if (Wnd->strName.Buffer != NULL) 1095 buf = DesktopPtrToUser(Wnd->strName.Buffer); 1096 else 1097 outbuf[0] = L'\0'; 1098 1099 if (buf != NULL) 1100 { 1101 if (Wnd->strName.Length != 0) 1102 { 1103 Result = min(Wnd->strName.Length / sizeof(WCHAR), wParam - 1); 1104 RtlCopyMemory(outbuf, 1105 buf, 1106 Result * sizeof(WCHAR)); 1107 outbuf[Result] = L'\0'; 1108 } 1109 else 1110 outbuf[0] = L'\0'; 1111 } 1112 } 1113 break; 1114 } 1115 1116 case WM_SETTEXT: 1117 { 1118 DefSetText(hWnd, (PCWSTR)lParam, FALSE); 1119 1120 if ((GetWindowLongPtrW(hWnd, GWL_STYLE) & WS_CAPTION) == WS_CAPTION) 1121 UserPaintCaption(Wnd, DC_TEXT); 1122 Result = 1; 1123 break; 1124 } 1125 1126 case WM_IME_CHAR: 1127 { 1128 PostMessageW(hWnd, WM_CHAR, wParam, lParam); 1129 Result = 0; 1130 break; 1131 } 1132 1133 case WM_IME_KEYDOWN: 1134 { 1135 Result = PostMessageW(hWnd, WM_KEYDOWN, wParam, lParam); 1136 break; 1137 } 1138 1139 case WM_IME_KEYUP: 1140 { 1141 Result = PostMessageW(hWnd, WM_KEYUP, wParam, lParam); 1142 break; 1143 } 1144 1145 case WM_IME_COMPOSITION: 1146 if (lParam & GCS_RESULTSTR) 1147 { 1148 LONG size, i; 1149 WCHAR *buf = NULL; 1150 HIMC himc = ImmGetContext( hWnd ); 1151 1152 if (himc) 1153 { 1154 if ((size = ImmGetCompositionStringW( himc, GCS_RESULTSTR, NULL, 0 ))) 1155 { 1156 if (!(buf = HeapAlloc( GetProcessHeap(), 0, size * sizeof(WCHAR) ))) size = 0; 1157 else size = ImmGetCompositionStringW( himc, GCS_RESULTSTR, buf, size * sizeof(WCHAR) ); 1158 } 1159 ImmReleaseContext( hWnd, himc ); 1160 1161 for (i = 0; i < size / sizeof(WCHAR); i++) 1162 SendMessageW( hWnd, WM_IME_CHAR, buf[i], 1 ); 1163 HeapFree( GetProcessHeap(), 0, buf ); 1164 } 1165 } 1166 /* fall through */ 1167 case WM_IME_STARTCOMPOSITION: 1168 case WM_IME_ENDCOMPOSITION: 1169 case WM_IME_SELECT: 1170 case WM_IME_NOTIFY: 1171 case WM_IME_CONTROL: 1172 { 1173 HWND hwndIME; 1174 1175 hwndIME = ImmGetDefaultIMEWnd(hWnd); 1176 if (hwndIME) 1177 Result = SendMessageW(hwndIME, Msg, wParam, lParam); 1178 break; 1179 } 1180 1181 case WM_IME_SETCONTEXT: 1182 { 1183 HWND hwndIME; 1184 1185 hwndIME = ImmGetDefaultIMEWnd(hWnd); 1186 if (hwndIME) 1187 Result = ImmIsUIMessageW(hwndIME, Msg, wParam, lParam); 1188 break; 1189 } 1190 1191 default: 1192 Result = User32DefWindowProc(hWnd, Msg, wParam, lParam, TRUE); 1193 } 1194 SPY_ExitMessage(SPY_RESULT_DEFWND, hWnd, Msg, Result, wParam, lParam); 1195 1196 return Result; 1197 } 1198 1199 LRESULT WINAPI 1200 DefWindowProcA(HWND hWnd, 1201 UINT Msg, 1202 WPARAM wParam, 1203 LPARAM lParam) 1204 { 1205 BOOL Hook, msgOverride = FALSE; 1206 LRESULT Result = 0; 1207 1208 LoadUserApiHook(); 1209 1210 Hook = BeginIfHookedUserApiHook(); 1211 if (Hook) 1212 { 1213 msgOverride = IsMsgOverride(Msg, &guah.DefWndProcArray); 1214 if(msgOverride == FALSE) 1215 { 1216 EndUserApiHook(); 1217 } 1218 } 1219 1220 /* Bypass SEH and go direct. */ 1221 if (!Hook || !msgOverride) 1222 return RealDefWindowProcA(hWnd, Msg, wParam, lParam); 1223 1224 _SEH2_TRY 1225 { 1226 Result = guah.DefWindowProcA(hWnd, Msg, wParam, lParam); 1227 } 1228 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 1229 { 1230 ERR("Got exception in hooked DefWindowProcA!\n"); 1231 } 1232 _SEH2_END; 1233 1234 EndUserApiHook(); 1235 1236 return Result; 1237 } 1238 1239 LRESULT WINAPI 1240 DefWindowProcW(HWND hWnd, 1241 UINT Msg, 1242 WPARAM wParam, 1243 LPARAM lParam) 1244 { 1245 BOOL Hook, msgOverride = FALSE; 1246 LRESULT Result = 0; 1247 1248 LoadUserApiHook(); 1249 1250 Hook = BeginIfHookedUserApiHook(); 1251 if (Hook) 1252 { 1253 msgOverride = IsMsgOverride(Msg, &guah.DefWndProcArray); 1254 if(msgOverride == FALSE) 1255 { 1256 EndUserApiHook(); 1257 } 1258 } 1259 1260 /* Bypass SEH and go direct. */ 1261 if (!Hook || !msgOverride) 1262 return RealDefWindowProcW(hWnd, Msg, wParam, lParam); 1263 1264 _SEH2_TRY 1265 { 1266 Result = guah.DefWindowProcW(hWnd, Msg, wParam, lParam); 1267 } 1268 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 1269 { 1270 ERR("Got exception in hooked DefWindowProcW!\n"); 1271 } 1272 _SEH2_END; 1273 1274 EndUserApiHook(); 1275 1276 return Result; 1277 } 1278