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)hWnd, lParam); 394 } 395 else 396 { 397 SendMessageA(GetParent(hWnd), Msg, (WPARAM)hWnd, 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 hNewKL; 551 HWND hwndFocus; 552 553 if ((wParam & INPUTLANGCHANGE_BACKWARD) && (wParam & INPUTLANGCHANGE_FORWARD)) 554 return FALSE; 555 556 hwndFocus = GetFocus(); 557 if (hwndFocus && hwndFocus != hWnd && 558 GetClassLongPtrW(hWnd, GCW_ATOM) != (ULONG_PTR)WC_DIALOG) 559 { 560 return SendMessageW(hwndFocus, Msg, wParam, lParam); 561 } 562 563 if (wParam & INPUTLANGCHANGE_FORWARD) 564 hNewKL = (HKL)UlongToHandle(HKL_NEXT); 565 else if (wParam & INPUTLANGCHANGE_BACKWARD) 566 hNewKL = (HKL)UlongToHandle(HKL_PREV); 567 else 568 hNewKL = (HKL)lParam; 569 570 NtUserActivateKeyboardLayout(hNewKL, KLF_SETFORPROCESS); 571 return TRUE; 572 } 573 574 case WM_INPUTLANGCHANGE: 575 { 576 int count = 0; 577 HWND *win_array = WIN_ListChildren( hWnd ); 578 579 if (!win_array) 580 break; 581 while (win_array[count]) 582 SendMessageW( win_array[count++], WM_INPUTLANGCHANGE, wParam, lParam); 583 HeapFree(GetProcessHeap(),0,win_array); 584 break; 585 } 586 587 case WM_QUERYUISTATE: 588 { 589 LRESULT Ret = 0; 590 PWND Wnd = ValidateHwnd(hWnd); 591 if (Wnd != NULL) 592 { 593 if (Wnd->HideFocus) 594 Ret |= UISF_HIDEFOCUS; 595 if (Wnd->HideAccel) 596 Ret |= UISF_HIDEACCEL; 597 } 598 return Ret; 599 } 600 601 case WM_CHANGEUISTATE: 602 { 603 BOOL AlwaysShowCues = FALSE; 604 WORD Action = LOWORD(wParam); 605 WORD Flags = HIWORD(wParam); 606 PWND Wnd; 607 608 SystemParametersInfoW(SPI_GETKEYBOARDCUES, 0, &AlwaysShowCues, 0); 609 if (AlwaysShowCues) 610 break; 611 612 Wnd= ValidateHwnd(hWnd); 613 if (!Wnd || lParam != 0) 614 break; 615 616 if (Flags & ~(UISF_HIDEFOCUS | UISF_HIDEACCEL | UISF_ACTIVE)) 617 break; 618 619 if (Flags & UISF_ACTIVE) 620 { 621 WARN("WM_CHANGEUISTATE does not yet support UISF_ACTIVE!\n"); 622 } 623 624 if (Action == UIS_INITIALIZE) 625 { 626 PDESKTOPINFO Desk = GetThreadDesktopInfo(); 627 if (Desk == NULL) 628 break; 629 630 Action = Desk->LastInputWasKbd ? UIS_CLEAR : UIS_SET; 631 Flags = UISF_HIDEFOCUS | UISF_HIDEACCEL; 632 633 /* We need to update wParam in case we need to send out messages */ 634 wParam = MAKEWPARAM(Action, Flags); 635 } 636 637 switch (Action) 638 { 639 case UIS_SET: 640 /* See if we actually need to change something */ 641 if ((Flags & UISF_HIDEFOCUS) && !Wnd->HideFocus) 642 break; 643 if ((Flags & UISF_HIDEACCEL) && !Wnd->HideAccel) 644 break; 645 646 /* Don't need to do anything... */ 647 return 0; 648 649 case UIS_CLEAR: 650 /* See if we actually need to change something */ 651 if ((Flags & UISF_HIDEFOCUS) && Wnd->HideFocus) 652 break; 653 if ((Flags & UISF_HIDEACCEL) && Wnd->HideAccel) 654 break; 655 656 /* Don't need to do anything... */ 657 return 0; 658 659 default: 660 WARN("WM_CHANGEUISTATE: Unsupported Action 0x%x\n", Action); 661 break; 662 } 663 664 if ((Wnd->style & WS_CHILD) && Wnd->spwndParent != NULL) 665 { 666 /* We're a child window and we need to pass this message down until 667 we reach the root */ 668 hWnd = UserHMGetHandle((PWND)DesktopPtrToUser(Wnd->spwndParent)); 669 } 670 else 671 { 672 /* We're a top level window, we need to change the UI state */ 673 Msg = WM_UPDATEUISTATE; 674 } 675 676 if (bUnicode) 677 return SendMessageW(hWnd, Msg, wParam, lParam); 678 else 679 return SendMessageA(hWnd, Msg, wParam, lParam); 680 } 681 682 case WM_UPDATEUISTATE: 683 { 684 BOOL Change = TRUE; 685 BOOL AlwaysShowCues = FALSE; 686 WORD Action = LOWORD(wParam); 687 WORD Flags = HIWORD(wParam); 688 PWND Wnd; 689 690 SystemParametersInfoW(SPI_GETKEYBOARDCUES, 0, &AlwaysShowCues, 0); 691 if (AlwaysShowCues) 692 break; 693 694 Wnd = ValidateHwnd(hWnd); 695 if (!Wnd || lParam != 0) 696 break; 697 698 if (Flags & ~(UISF_HIDEFOCUS | UISF_HIDEACCEL | UISF_ACTIVE)) 699 break; 700 701 if (Flags & UISF_ACTIVE) 702 { 703 WARN("WM_UPDATEUISTATE does not yet support UISF_ACTIVE!\n"); 704 } 705 706 if (Action == UIS_INITIALIZE) 707 { 708 PDESKTOPINFO Desk = GetThreadDesktopInfo(); 709 if (Desk == NULL) 710 break; 711 712 Action = Desk->LastInputWasKbd ? UIS_CLEAR : UIS_SET; 713 Flags = UISF_HIDEFOCUS | UISF_HIDEACCEL; 714 715 /* We need to update wParam for broadcasting the update */ 716 wParam = MAKEWPARAM(Action, Flags); 717 } 718 719 switch (Action) 720 { 721 case UIS_SET: 722 /* See if we actually need to change something */ 723 if ((Flags & UISF_HIDEFOCUS) && !Wnd->HideFocus) 724 break; 725 if ((Flags & UISF_HIDEACCEL) && !Wnd->HideAccel) 726 break; 727 728 /* Don't need to do anything... */ 729 Change = FALSE; 730 break; 731 732 case UIS_CLEAR: 733 /* See if we actually need to change something */ 734 if ((Flags & UISF_HIDEFOCUS) && Wnd->HideFocus) 735 break; 736 if ((Flags & UISF_HIDEACCEL) && Wnd->HideAccel) 737 break; 738 739 /* Don't need to do anything... */ 740 Change = FALSE; 741 break; 742 743 default: 744 WARN("WM_UPDATEUISTATE: Unsupported Action 0x%x\n", Action); 745 return 0; 746 } 747 748 /* Pack the information and call win32k */ 749 if (Change) 750 { 751 if (!NtUserxUpdateUiState(hWnd, Flags | ((DWORD)Action << 3))) 752 break; 753 } 754 755 /* Always broadcast the update to all children */ 756 EnumChildWindows(hWnd, 757 UserSendUiUpdateMsg, 758 (LPARAM)wParam); 759 760 break; 761 } 762 763 case WM_COPYGLOBALDATA: 764 { 765 TRACE("WM_COPYGLOBALDATA hGlobal %p Size %d Flags 0x%x\n",lParam,wParam,GlobalFlags((HGLOBAL)lParam)); 766 return lParam; 767 } 768 769 /* Move to Win32k !*/ 770 case WM_SHOWWINDOW: 771 if (!lParam) break; // Call when it is necessary. 772 case WM_LBUTTONDOWN: 773 case WM_RBUTTONDOWN: 774 case WM_MBUTTONDOWN: 775 case WM_NCLBUTTONDOWN: 776 case WM_NCRBUTTONDOWN: 777 case WM_LBUTTONDBLCLK: 778 case WM_NCLBUTTONDBLCLK: 779 case WM_KEYF1: 780 case WM_KEYUP: 781 case WM_SYSKEYUP: 782 case WM_KEYDOWN: 783 case WM_SYSKEYDOWN: 784 case WM_SYSCHAR: 785 case WM_CANCELMODE: 786 case WM_PAINTICON: 787 case WM_PAINT: 788 case WM_PRINT: 789 case WM_SETICON: 790 case WM_SYSCOLORCHANGE: 791 case WM_NCUAHDRAWCAPTION: 792 case WM_NCUAHDRAWFRAME: 793 case WM_NCPAINT: 794 case WM_NCACTIVATE: 795 case WM_NCCALCSIZE: 796 case WM_NCHITTEST: 797 case WM_SYNCPAINT: 798 case WM_SETREDRAW: 799 case WM_CLIENTSHUTDOWN: 800 case WM_GETHOTKEY: 801 case WM_SETHOTKEY: 802 case WM_WINDOWPOSCHANGING: 803 case WM_WINDOWPOSCHANGED: 804 case WM_APPCOMMAND: 805 case WM_SETCURSOR: 806 GoSS: 807 { 808 LRESULT lResult; 809 NtUserMessageCall( hWnd, Msg, wParam, lParam, (ULONG_PTR)&lResult, FNID_DEFWINDOWPROC, !bUnicode); 810 return lResult; 811 } 812 } 813 return 0; 814 } 815 816 817 LRESULT WINAPI 818 RealDefWindowProcA(HWND hWnd, 819 UINT Msg, 820 WPARAM wParam, 821 LPARAM lParam) 822 { 823 LRESULT Result = 0; 824 PWND Wnd; 825 826 Wnd = ValidateHwnd(hWnd); 827 828 if ( !Wnd && 829 Msg != WM_CTLCOLORMSGBOX && 830 Msg != WM_CTLCOLORBTN && 831 Msg != WM_CTLCOLORDLG && 832 Msg != WM_CTLCOLORSTATIC ) 833 return 0; 834 835 SPY_EnterMessage(SPY_DEFWNDPROC, hWnd, Msg, wParam, lParam); 836 switch (Msg) 837 { 838 case WM_NCCREATE: 839 { 840 if ( Wnd && 841 Wnd->style & (WS_HSCROLL | WS_VSCROLL) ) 842 { 843 if (!Wnd->pSBInfo) 844 { 845 SCROLLINFO si = {sizeof si, SIF_ALL, 0, 100, 0, 0, 0}; 846 SetScrollInfo( hWnd, SB_HORZ, &si, FALSE ); 847 SetScrollInfo( hWnd, SB_VERT, &si, FALSE ); 848 } 849 } 850 851 if (lParam) 852 { 853 LPCREATESTRUCTA cs = (LPCREATESTRUCTA)lParam; 854 /* check for string, as static icons, bitmaps (SS_ICON, SS_BITMAP) 855 * may have child window IDs instead of window name */ 856 if (HIWORD(cs->lpszName)) 857 { 858 DefSetText(hWnd, (PCWSTR)cs->lpszName, TRUE); 859 } 860 Result = 1; 861 } 862 break; 863 } 864 865 case WM_GETTEXTLENGTH: 866 { 867 PWSTR buf; 868 ULONG len; 869 870 if (Wnd != NULL && Wnd->strName.Length != 0) 871 { 872 buf = DesktopPtrToUser(Wnd->strName.Buffer); 873 if (buf != NULL && 874 NT_SUCCESS(RtlUnicodeToMultiByteSize(&len, 875 buf, 876 Wnd->strName.Length))) 877 { 878 Result = (LRESULT) len; 879 } 880 } 881 else Result = 0L; 882 883 break; 884 } 885 886 case WM_GETTEXT: 887 { 888 PWSTR buf = NULL; 889 PSTR outbuf = (PSTR)lParam; 890 SIZE_T copy; 891 892 if (Wnd != NULL && wParam != 0) 893 { 894 if (Wnd->strName.Buffer != NULL) 895 buf = DesktopPtrToUser(Wnd->strName.Buffer); 896 else 897 outbuf[0] = L'\0'; 898 899 if (buf != NULL) 900 { 901 if (Wnd->strName.Length != 0) 902 { 903 copy = min(Wnd->strName.Length / sizeof(WCHAR), wParam - 1); 904 Result = WideCharToMultiByte(CP_ACP, 905 0, 906 buf, 907 copy, 908 outbuf, 909 wParam, 910 NULL, 911 NULL); 912 outbuf[Result] = '\0'; 913 } 914 else 915 outbuf[0] = '\0'; 916 } 917 } 918 break; 919 } 920 921 case WM_SETTEXT: 922 { 923 DefSetText(hWnd, (PCWSTR)lParam, TRUE); 924 925 if ((GetWindowLongPtrW(hWnd, GWL_STYLE) & WS_CAPTION) == WS_CAPTION) 926 { 927 UserPaintCaption(Wnd, DC_TEXT); 928 IntNotifyWinEvent(EVENT_OBJECT_NAMECHANGE, hWnd, OBJID_WINDOW, CHILDID_SELF, 0); 929 } 930 Result = 1; 931 break; 932 } 933 934 case WM_IME_KEYDOWN: 935 { 936 Result = PostMessageA(hWnd, WM_KEYDOWN, wParam, lParam); 937 break; 938 } 939 940 case WM_IME_KEYUP: 941 { 942 Result = PostMessageA(hWnd, WM_KEYUP, wParam, lParam); 943 break; 944 } 945 946 case WM_IME_CHAR: 947 { 948 if (HIBYTE(wParam)) 949 PostMessageA(hWnd, WM_CHAR, HIBYTE(wParam), lParam); 950 PostMessageA(hWnd, WM_CHAR, LOBYTE(wParam), lParam); 951 break; 952 } 953 954 case WM_IME_COMPOSITION: 955 if (lParam & GCS_RESULTSTR) 956 { 957 LONG size, i; 958 unsigned char lead = 0; 959 char *buf = NULL; 960 HIMC himc = IMM_FN(ImmGetContext)( hWnd ); 961 962 if (himc) 963 { 964 if ((size = IMM_FN(ImmGetCompositionStringA)( himc, GCS_RESULTSTR, NULL, 0 ))) 965 { 966 if (!(buf = HeapAlloc( GetProcessHeap(), 0, size ))) size = 0; 967 else size = IMM_FN(ImmGetCompositionStringA)( himc, GCS_RESULTSTR, buf, size ); 968 } 969 IMM_FN(ImmReleaseContext)( hWnd, himc ); 970 971 for (i = 0; i < size; i++) 972 { 973 unsigned char c = buf[i]; 974 if (!lead) 975 { 976 if (IsDBCSLeadByte( c )) 977 lead = c; 978 else 979 SendMessageA( hWnd, WM_IME_CHAR, c, 1 ); 980 } 981 else 982 { 983 SendMessageA( hWnd, WM_IME_CHAR, MAKEWORD(c, lead), 1 ); 984 lead = 0; 985 } 986 } 987 HeapFree( GetProcessHeap(), 0, buf ); 988 } 989 } 990 /* fall through */ 991 case WM_IME_STARTCOMPOSITION: 992 case WM_IME_ENDCOMPOSITION: 993 case WM_IME_SELECT: 994 case WM_IME_NOTIFY: 995 case WM_IME_CONTROL: 996 case WM_IME_SETCONTEXT: 997 NormalImeMsgHandling: 998 { 999 HWND hwndIME; 1000 1001 if (GetWin32ClientInfo()->dwTIFlags & TIF_DISABLEIME) 1002 { 1003 TRACE("This thread's IME is disabled\n"); 1004 break; 1005 } 1006 1007 hwndIME = IMM_FN(ImmGetDefaultIMEWnd)(hWnd); 1008 if (!hwndIME) 1009 { 1010 ERR("hwndIME was NULL\n"); 1011 break; 1012 } 1013 1014 if (hwndIME == hWnd) 1015 { 1016 ImeWndProc_common(hwndIME, Msg, wParam, lParam, FALSE); 1017 break; 1018 } 1019 1020 Result = SendMessageA(hwndIME, Msg, wParam, lParam); 1021 break; 1022 } 1023 1024 case WM_IME_SYSTEM: 1025 { 1026 if (wParam == 4) 1027 break; 1028 1029 goto NormalImeMsgHandling; 1030 } 1031 1032 default: 1033 Result = User32DefWindowProc(hWnd, Msg, wParam, lParam, FALSE); 1034 } 1035 1036 SPY_ExitMessage(SPY_RESULT_DEFWND, hWnd, Msg, Result, wParam, lParam); 1037 return Result; 1038 } 1039 1040 1041 LRESULT WINAPI 1042 RealDefWindowProcW(HWND hWnd, 1043 UINT Msg, 1044 WPARAM wParam, 1045 LPARAM lParam) 1046 { 1047 LRESULT Result = 0; 1048 PWND Wnd; 1049 1050 Wnd = ValidateHwnd(hWnd); 1051 1052 if ( !Wnd && 1053 Msg != WM_CTLCOLORMSGBOX && 1054 Msg != WM_CTLCOLORBTN && 1055 Msg != WM_CTLCOLORDLG && 1056 Msg != WM_CTLCOLORSTATIC ) 1057 return 0; 1058 1059 SPY_EnterMessage(SPY_DEFWNDPROC, hWnd, Msg, wParam, lParam); 1060 switch (Msg) 1061 { 1062 case WM_NCCREATE: 1063 { 1064 if ( Wnd && 1065 Wnd->style & (WS_HSCROLL | WS_VSCROLL) ) 1066 { 1067 if (!Wnd->pSBInfo) 1068 { 1069 SCROLLINFO si = {sizeof si, SIF_ALL, 0, 100, 0, 0, 0}; 1070 if (Wnd->style & WS_HSCROLL) 1071 SetScrollInfo( hWnd, SB_HORZ, &si, FALSE ); 1072 if (Wnd->style & WS_VSCROLL) 1073 SetScrollInfo( hWnd, SB_VERT, &si, FALSE ); 1074 } 1075 } 1076 1077 if (lParam) 1078 { 1079 LPCREATESTRUCTW cs = (LPCREATESTRUCTW)lParam; 1080 /* check for string, as static icons, bitmaps (SS_ICON, SS_BITMAP) 1081 * may have child window IDs instead of window name */ 1082 if (HIWORD(cs->lpszName)) 1083 { 1084 DefSetText(hWnd, cs->lpszName, FALSE); 1085 } 1086 Result = 1; 1087 } 1088 break; 1089 } 1090 1091 case WM_GETTEXTLENGTH: 1092 { 1093 PWSTR buf; 1094 ULONG len; 1095 1096 if (Wnd != NULL && Wnd->strName.Length != 0) 1097 { 1098 buf = DesktopPtrToUser(Wnd->strName.Buffer); 1099 if (buf != NULL && 1100 NT_SUCCESS(RtlUnicodeToMultiByteSize(&len, 1101 buf, 1102 Wnd->strName.Length))) 1103 { 1104 Result = (LRESULT) (Wnd->strName.Length / sizeof(WCHAR)); 1105 } 1106 } 1107 else Result = 0L; 1108 1109 break; 1110 } 1111 1112 case WM_GETTEXT: 1113 { 1114 PWSTR buf = NULL; 1115 PWSTR outbuf = (PWSTR)lParam; 1116 1117 if (Wnd != NULL && wParam != 0) 1118 { 1119 if (Wnd->strName.Buffer != NULL) 1120 buf = DesktopPtrToUser(Wnd->strName.Buffer); 1121 else 1122 outbuf[0] = L'\0'; 1123 1124 if (buf != NULL) 1125 { 1126 if (Wnd->strName.Length != 0) 1127 { 1128 Result = min(Wnd->strName.Length / sizeof(WCHAR), wParam - 1); 1129 RtlCopyMemory(outbuf, 1130 buf, 1131 Result * sizeof(WCHAR)); 1132 outbuf[Result] = L'\0'; 1133 } 1134 else 1135 outbuf[0] = L'\0'; 1136 } 1137 } 1138 break; 1139 } 1140 1141 case WM_SETTEXT: 1142 { 1143 DefSetText(hWnd, (PCWSTR)lParam, FALSE); 1144 1145 if ((GetWindowLongPtrW(hWnd, GWL_STYLE) & WS_CAPTION) == WS_CAPTION) 1146 UserPaintCaption(Wnd, DC_TEXT); 1147 Result = 1; 1148 break; 1149 } 1150 1151 case WM_IME_CHAR: 1152 { 1153 PostMessageW(hWnd, WM_CHAR, wParam, lParam); 1154 Result = 0; 1155 break; 1156 } 1157 1158 case WM_IME_KEYDOWN: 1159 { 1160 Result = PostMessageW(hWnd, WM_KEYDOWN, wParam, lParam); 1161 break; 1162 } 1163 1164 case WM_IME_KEYUP: 1165 { 1166 Result = PostMessageW(hWnd, WM_KEYUP, wParam, lParam); 1167 break; 1168 } 1169 1170 case WM_IME_COMPOSITION: 1171 if (lParam & GCS_RESULTSTR) 1172 { 1173 LONG size, i; 1174 WCHAR *buf = NULL; 1175 HIMC himc = IMM_FN(ImmGetContext)( hWnd ); 1176 1177 if (himc) 1178 { 1179 if ((size = IMM_FN(ImmGetCompositionStringW)( himc, GCS_RESULTSTR, NULL, 0 ))) 1180 { 1181 if (!(buf = HeapAlloc( GetProcessHeap(), 0, size * sizeof(WCHAR) ))) size = 0; 1182 else size = IMM_FN(ImmGetCompositionStringW)( himc, GCS_RESULTSTR, buf, size * sizeof(WCHAR) ); 1183 } 1184 IMM_FN(ImmReleaseContext)( hWnd, himc ); 1185 1186 for (i = 0; i < size / sizeof(WCHAR); i++) 1187 SendMessageW( hWnd, WM_IME_CHAR, buf[i], 1 ); 1188 HeapFree( GetProcessHeap(), 0, buf ); 1189 } 1190 } 1191 /* fall through */ 1192 case WM_IME_STARTCOMPOSITION: 1193 case WM_IME_ENDCOMPOSITION: 1194 case WM_IME_SELECT: 1195 case WM_IME_NOTIFY: 1196 case WM_IME_CONTROL: 1197 case WM_IME_SETCONTEXT: 1198 NormalImeMsgHandling: 1199 { 1200 HWND hwndIME; 1201 1202 if (GetWin32ClientInfo()->dwTIFlags & TIF_DISABLEIME) 1203 { 1204 TRACE("This thread's IME is disabled\n"); 1205 break; 1206 } 1207 1208 hwndIME = IMM_FN(ImmGetDefaultIMEWnd)(hWnd); 1209 if (!hwndIME) 1210 { 1211 ERR("hwndIME was NULL\n"); 1212 break; 1213 } 1214 1215 if (hwndIME == hWnd) 1216 { 1217 ImeWndProc_common(hwndIME, Msg, wParam, lParam, TRUE); 1218 break; 1219 } 1220 1221 Result = SendMessageW(hwndIME, Msg, wParam, lParam); 1222 break; 1223 } 1224 1225 case WM_IME_SYSTEM: 1226 { 1227 if (wParam == 4) 1228 break; 1229 1230 goto NormalImeMsgHandling; 1231 } 1232 1233 default: 1234 Result = User32DefWindowProc(hWnd, Msg, wParam, lParam, TRUE); 1235 } 1236 SPY_ExitMessage(SPY_RESULT_DEFWND, hWnd, Msg, Result, wParam, lParam); 1237 1238 return Result; 1239 } 1240 1241 LRESULT WINAPI 1242 DefWindowProcA(HWND hWnd, 1243 UINT Msg, 1244 WPARAM wParam, 1245 LPARAM lParam) 1246 { 1247 BOOL Hook, msgOverride = FALSE; 1248 LRESULT Result = 0; 1249 1250 LoadUserApiHook(); 1251 1252 Hook = BeginIfHookedUserApiHook(); 1253 if (Hook) 1254 { 1255 msgOverride = IsMsgOverride(Msg, &guah.DefWndProcArray); 1256 if(msgOverride == FALSE) 1257 { 1258 EndUserApiHook(); 1259 } 1260 } 1261 1262 /* Bypass SEH and go direct. */ 1263 if (!Hook || !msgOverride) 1264 return RealDefWindowProcA(hWnd, Msg, wParam, lParam); 1265 1266 _SEH2_TRY 1267 { 1268 Result = guah.DefWindowProcA(hWnd, Msg, wParam, lParam); 1269 } 1270 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 1271 { 1272 ERR("Got exception in hooked DefWindowProcA!\n"); 1273 } 1274 _SEH2_END; 1275 1276 EndUserApiHook(); 1277 1278 return Result; 1279 } 1280 1281 LRESULT WINAPI 1282 DefWindowProcW(HWND hWnd, 1283 UINT Msg, 1284 WPARAM wParam, 1285 LPARAM lParam) 1286 { 1287 BOOL Hook, msgOverride = FALSE; 1288 LRESULT Result = 0; 1289 1290 LoadUserApiHook(); 1291 1292 Hook = BeginIfHookedUserApiHook(); 1293 if (Hook) 1294 { 1295 msgOverride = IsMsgOverride(Msg, &guah.DefWndProcArray); 1296 if(msgOverride == FALSE) 1297 { 1298 EndUserApiHook(); 1299 } 1300 } 1301 1302 /* Bypass SEH and go direct. */ 1303 if (!Hook || !msgOverride) 1304 return RealDefWindowProcW(hWnd, Msg, wParam, lParam); 1305 1306 _SEH2_TRY 1307 { 1308 Result = guah.DefWindowProcW(hWnd, Msg, wParam, lParam); 1309 } 1310 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 1311 { 1312 ERR("Got exception in hooked DefWindowProcW!\n"); 1313 } 1314 _SEH2_END; 1315 1316 EndUserApiHook(); 1317 1318 return Result; 1319 } 1320