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