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 /* Move to Win32k !*/ 752 case WM_SHOWWINDOW: 753 if (!lParam) break; // Call when it is necessary. 754 case WM_LBUTTONDOWN: 755 case WM_RBUTTONDOWN: 756 case WM_MBUTTONDOWN: 757 case WM_NCLBUTTONDOWN: 758 case WM_NCRBUTTONDOWN: 759 case WM_LBUTTONDBLCLK: 760 case WM_NCLBUTTONDBLCLK: 761 case WM_KEYF1: 762 case WM_KEYUP: 763 case WM_SYSKEYUP: 764 case WM_KEYDOWN: 765 case WM_SYSKEYDOWN: 766 case WM_SYSCHAR: 767 case WM_CANCELMODE: 768 case WM_PAINTICON: 769 case WM_PAINT: 770 case WM_PRINT: 771 case WM_SETICON: 772 case WM_SYSCOLORCHANGE: 773 case WM_NCUAHDRAWCAPTION: 774 case WM_NCUAHDRAWFRAME: 775 case WM_NCPAINT: 776 case WM_NCACTIVATE: 777 case WM_NCCALCSIZE: 778 case WM_NCHITTEST: 779 case WM_SYNCPAINT: 780 case WM_SETREDRAW: 781 case WM_CLIENTSHUTDOWN: 782 case WM_GETHOTKEY: 783 case WM_SETHOTKEY: 784 case WM_WINDOWPOSCHANGING: 785 case WM_WINDOWPOSCHANGED: 786 case WM_APPCOMMAND: 787 case WM_SETCURSOR: 788 GoSS: 789 { 790 LRESULT lResult; 791 NtUserMessageCall( hWnd, Msg, wParam, lParam, (ULONG_PTR)&lResult, FNID_DEFWINDOWPROC, !bUnicode); 792 return lResult; 793 } 794 } 795 return 0; 796 } 797 798 799 LRESULT WINAPI 800 RealDefWindowProcA(HWND hWnd, 801 UINT Msg, 802 WPARAM wParam, 803 LPARAM lParam) 804 { 805 LRESULT Result = 0; 806 PWND Wnd; 807 808 Wnd = ValidateHwnd(hWnd); 809 810 if ( !Wnd && 811 Msg != WM_CTLCOLORMSGBOX && 812 Msg != WM_CTLCOLORBTN && 813 Msg != WM_CTLCOLORDLG && 814 Msg != WM_CTLCOLORSTATIC ) 815 return 0; 816 817 SPY_EnterMessage(SPY_DEFWNDPROC, hWnd, Msg, wParam, lParam); 818 switch (Msg) 819 { 820 case WM_NCCREATE: 821 { 822 if ( Wnd && 823 Wnd->style & (WS_HSCROLL | WS_VSCROLL) ) 824 { 825 if (!Wnd->pSBInfo) 826 { 827 SCROLLINFO si = {sizeof si, SIF_ALL, 0, 100, 0, 0, 0}; 828 SetScrollInfo( hWnd, SB_HORZ, &si, FALSE ); 829 SetScrollInfo( hWnd, SB_VERT, &si, FALSE ); 830 } 831 } 832 833 if (lParam) 834 { 835 LPCREATESTRUCTA cs = (LPCREATESTRUCTA)lParam; 836 /* check for string, as static icons, bitmaps (SS_ICON, SS_BITMAP) 837 * may have child window IDs instead of window name */ 838 if (HIWORD(cs->lpszName)) 839 { 840 DefSetText(hWnd, (PCWSTR)cs->lpszName, TRUE); 841 } 842 Result = 1; 843 } 844 break; 845 } 846 847 case WM_GETTEXTLENGTH: 848 { 849 PWSTR buf; 850 ULONG len; 851 852 if (Wnd != NULL && Wnd->strName.Length != 0) 853 { 854 buf = DesktopPtrToUser(Wnd->strName.Buffer); 855 if (buf != NULL && 856 NT_SUCCESS(RtlUnicodeToMultiByteSize(&len, 857 buf, 858 Wnd->strName.Length))) 859 { 860 Result = (LRESULT) len; 861 } 862 } 863 else Result = 0L; 864 865 break; 866 } 867 868 case WM_GETTEXT: 869 { 870 PWSTR buf = NULL; 871 PSTR outbuf = (PSTR)lParam; 872 SIZE_T copy; 873 874 if (Wnd != NULL && wParam != 0) 875 { 876 if (Wnd->strName.Buffer != NULL) 877 buf = DesktopPtrToUser(Wnd->strName.Buffer); 878 else 879 outbuf[0] = L'\0'; 880 881 if (buf != NULL) 882 { 883 if (Wnd->strName.Length != 0) 884 { 885 copy = min(Wnd->strName.Length / sizeof(WCHAR), wParam - 1); 886 Result = WideCharToMultiByte(CP_ACP, 887 0, 888 buf, 889 copy, 890 outbuf, 891 wParam, 892 NULL, 893 NULL); 894 outbuf[Result] = '\0'; 895 } 896 else 897 outbuf[0] = '\0'; 898 } 899 } 900 break; 901 } 902 903 case WM_SETTEXT: 904 { 905 DefSetText(hWnd, (PCWSTR)lParam, TRUE); 906 907 if ((GetWindowLongPtrW(hWnd, GWL_STYLE) & WS_CAPTION) == WS_CAPTION) 908 { 909 UserPaintCaption(Wnd, DC_TEXT); 910 IntNotifyWinEvent(EVENT_OBJECT_NAMECHANGE, hWnd, OBJID_WINDOW, CHILDID_SELF, 0); 911 } 912 Result = 1; 913 break; 914 } 915 916 case WM_IME_KEYDOWN: 917 { 918 Result = PostMessageA(hWnd, WM_KEYDOWN, wParam, lParam); 919 break; 920 } 921 922 case WM_IME_KEYUP: 923 { 924 Result = PostMessageA(hWnd, WM_KEYUP, wParam, lParam); 925 break; 926 } 927 928 case WM_IME_CHAR: 929 { 930 if (HIBYTE(wParam)) 931 PostMessageA(hWnd, WM_CHAR, HIBYTE(wParam), lParam); 932 PostMessageA(hWnd, WM_CHAR, LOBYTE(wParam), lParam); 933 break; 934 } 935 936 case WM_IME_COMPOSITION: 937 if (lParam & GCS_RESULTSTR) 938 { 939 LONG size, i; 940 unsigned char lead = 0; 941 char *buf = NULL; 942 HIMC himc = ImmGetContext( hWnd ); 943 944 if (himc) 945 { 946 if ((size = ImmGetCompositionStringA( himc, GCS_RESULTSTR, NULL, 0 ))) 947 { 948 if (!(buf = HeapAlloc( GetProcessHeap(), 0, size ))) size = 0; 949 else size = ImmGetCompositionStringA( himc, GCS_RESULTSTR, buf, size ); 950 } 951 ImmReleaseContext( hWnd, himc ); 952 953 for (i = 0; i < size; i++) 954 { 955 unsigned char c = buf[i]; 956 if (!lead) 957 { 958 if (IsDBCSLeadByte( c )) 959 lead = c; 960 else 961 SendMessageA( hWnd, WM_IME_CHAR, c, 1 ); 962 } 963 else 964 { 965 SendMessageA( hWnd, WM_IME_CHAR, MAKEWORD(c, lead), 1 ); 966 lead = 0; 967 } 968 } 969 HeapFree( GetProcessHeap(), 0, buf ); 970 } 971 } 972 /* fall through */ 973 case WM_IME_STARTCOMPOSITION: 974 case WM_IME_ENDCOMPOSITION: 975 case WM_IME_SELECT: 976 case WM_IME_NOTIFY: 977 case WM_IME_CONTROL: 978 { 979 HWND hwndIME; 980 981 hwndIME = ImmGetDefaultIMEWnd(hWnd); 982 if (hwndIME) 983 Result = SendMessageA(hwndIME, Msg, wParam, lParam); 984 break; 985 } 986 987 case WM_IME_SETCONTEXT: 988 { 989 HWND hwndIME; 990 991 hwndIME = ImmGetDefaultIMEWnd(hWnd); 992 if (hwndIME) 993 Result = ImmIsUIMessageA(hwndIME, Msg, wParam, lParam); 994 break; 995 } 996 997 /* fall through */ 998 default: 999 Result = User32DefWindowProc(hWnd, Msg, wParam, lParam, FALSE); 1000 } 1001 1002 SPY_ExitMessage(SPY_RESULT_DEFWND, hWnd, Msg, Result, wParam, lParam); 1003 return Result; 1004 } 1005 1006 1007 LRESULT WINAPI 1008 RealDefWindowProcW(HWND hWnd, 1009 UINT Msg, 1010 WPARAM wParam, 1011 LPARAM lParam) 1012 { 1013 LRESULT Result = 0; 1014 PWND Wnd; 1015 1016 Wnd = ValidateHwnd(hWnd); 1017 1018 if ( !Wnd && 1019 Msg != WM_CTLCOLORMSGBOX && 1020 Msg != WM_CTLCOLORBTN && 1021 Msg != WM_CTLCOLORDLG && 1022 Msg != WM_CTLCOLORSTATIC ) 1023 return 0; 1024 1025 SPY_EnterMessage(SPY_DEFWNDPROC, hWnd, Msg, wParam, lParam); 1026 switch (Msg) 1027 { 1028 case WM_NCCREATE: 1029 { 1030 if ( Wnd && 1031 Wnd->style & (WS_HSCROLL | WS_VSCROLL) ) 1032 { 1033 if (!Wnd->pSBInfo) 1034 { 1035 SCROLLINFO si = {sizeof si, SIF_ALL, 0, 100, 0, 0, 0}; 1036 SetScrollInfo( hWnd, SB_HORZ, &si, FALSE ); 1037 SetScrollInfo( hWnd, SB_VERT, &si, FALSE ); 1038 } 1039 } 1040 1041 if (lParam) 1042 { 1043 LPCREATESTRUCTW cs = (LPCREATESTRUCTW)lParam; 1044 /* check for string, as static icons, bitmaps (SS_ICON, SS_BITMAP) 1045 * may have child window IDs instead of window name */ 1046 if (HIWORD(cs->lpszName)) 1047 { 1048 DefSetText(hWnd, cs->lpszName, FALSE); 1049 } 1050 Result = 1; 1051 } 1052 break; 1053 } 1054 1055 case WM_GETTEXTLENGTH: 1056 { 1057 PWSTR buf; 1058 ULONG len; 1059 1060 if (Wnd != NULL && Wnd->strName.Length != 0) 1061 { 1062 buf = DesktopPtrToUser(Wnd->strName.Buffer); 1063 if (buf != NULL && 1064 NT_SUCCESS(RtlUnicodeToMultiByteSize(&len, 1065 buf, 1066 Wnd->strName.Length))) 1067 { 1068 Result = (LRESULT) (Wnd->strName.Length / sizeof(WCHAR)); 1069 } 1070 } 1071 else Result = 0L; 1072 1073 break; 1074 } 1075 1076 case WM_GETTEXT: 1077 { 1078 PWSTR buf = NULL; 1079 PWSTR outbuf = (PWSTR)lParam; 1080 1081 if (Wnd != NULL && wParam != 0) 1082 { 1083 if (Wnd->strName.Buffer != NULL) 1084 buf = DesktopPtrToUser(Wnd->strName.Buffer); 1085 else 1086 outbuf[0] = L'\0'; 1087 1088 if (buf != NULL) 1089 { 1090 if (Wnd->strName.Length != 0) 1091 { 1092 Result = min(Wnd->strName.Length / sizeof(WCHAR), wParam - 1); 1093 RtlCopyMemory(outbuf, 1094 buf, 1095 Result * sizeof(WCHAR)); 1096 outbuf[Result] = L'\0'; 1097 } 1098 else 1099 outbuf[0] = L'\0'; 1100 } 1101 } 1102 break; 1103 } 1104 1105 case WM_SETTEXT: 1106 { 1107 DefSetText(hWnd, (PCWSTR)lParam, FALSE); 1108 1109 if ((GetWindowLongPtrW(hWnd, GWL_STYLE) & WS_CAPTION) == WS_CAPTION) 1110 UserPaintCaption(Wnd, DC_TEXT); 1111 Result = 1; 1112 break; 1113 } 1114 1115 case WM_IME_CHAR: 1116 { 1117 PostMessageW(hWnd, WM_CHAR, wParam, lParam); 1118 Result = 0; 1119 break; 1120 } 1121 1122 case WM_IME_KEYDOWN: 1123 { 1124 Result = PostMessageW(hWnd, WM_KEYDOWN, wParam, lParam); 1125 break; 1126 } 1127 1128 case WM_IME_KEYUP: 1129 { 1130 Result = PostMessageW(hWnd, WM_KEYUP, wParam, lParam); 1131 break; 1132 } 1133 1134 case WM_IME_COMPOSITION: 1135 if (lParam & GCS_RESULTSTR) 1136 { 1137 LONG size, i; 1138 WCHAR *buf = NULL; 1139 HIMC himc = ImmGetContext( hWnd ); 1140 1141 if (himc) 1142 { 1143 if ((size = ImmGetCompositionStringW( himc, GCS_RESULTSTR, NULL, 0 ))) 1144 { 1145 if (!(buf = HeapAlloc( GetProcessHeap(), 0, size * sizeof(WCHAR) ))) size = 0; 1146 else size = ImmGetCompositionStringW( himc, GCS_RESULTSTR, buf, size * sizeof(WCHAR) ); 1147 } 1148 ImmReleaseContext( hWnd, himc ); 1149 1150 for (i = 0; i < size / sizeof(WCHAR); i++) 1151 SendMessageW( hWnd, WM_IME_CHAR, buf[i], 1 ); 1152 HeapFree( GetProcessHeap(), 0, buf ); 1153 } 1154 } 1155 /* fall through */ 1156 case WM_IME_STARTCOMPOSITION: 1157 case WM_IME_ENDCOMPOSITION: 1158 case WM_IME_SELECT: 1159 case WM_IME_NOTIFY: 1160 case WM_IME_CONTROL: 1161 { 1162 HWND hwndIME; 1163 1164 hwndIME = ImmGetDefaultIMEWnd(hWnd); 1165 if (hwndIME) 1166 Result = SendMessageW(hwndIME, Msg, wParam, lParam); 1167 break; 1168 } 1169 1170 case WM_IME_SETCONTEXT: 1171 { 1172 HWND hwndIME; 1173 1174 hwndIME = ImmGetDefaultIMEWnd(hWnd); 1175 if (hwndIME) 1176 Result = ImmIsUIMessageW(hwndIME, Msg, wParam, lParam); 1177 break; 1178 } 1179 1180 default: 1181 Result = User32DefWindowProc(hWnd, Msg, wParam, lParam, TRUE); 1182 } 1183 SPY_ExitMessage(SPY_RESULT_DEFWND, hWnd, Msg, Result, wParam, lParam); 1184 1185 return Result; 1186 } 1187 1188 LRESULT WINAPI 1189 DefWindowProcA(HWND hWnd, 1190 UINT Msg, 1191 WPARAM wParam, 1192 LPARAM lParam) 1193 { 1194 BOOL Hook, msgOverride = FALSE; 1195 LRESULT Result = 0; 1196 1197 LoadUserApiHook(); 1198 1199 Hook = BeginIfHookedUserApiHook(); 1200 if (Hook) 1201 { 1202 msgOverride = IsMsgOverride(Msg, &guah.DefWndProcArray); 1203 if(msgOverride == FALSE) 1204 { 1205 EndUserApiHook(); 1206 } 1207 } 1208 1209 /* Bypass SEH and go direct. */ 1210 if (!Hook || !msgOverride) 1211 return RealDefWindowProcA(hWnd, Msg, wParam, lParam); 1212 1213 _SEH2_TRY 1214 { 1215 Result = guah.DefWindowProcA(hWnd, Msg, wParam, lParam); 1216 } 1217 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 1218 { 1219 ERR("Got exception in hooked DefWindowProcA!\n"); 1220 } 1221 _SEH2_END; 1222 1223 EndUserApiHook(); 1224 1225 return Result; 1226 } 1227 1228 LRESULT WINAPI 1229 DefWindowProcW(HWND hWnd, 1230 UINT Msg, 1231 WPARAM wParam, 1232 LPARAM lParam) 1233 { 1234 BOOL Hook, msgOverride = FALSE; 1235 LRESULT Result = 0; 1236 1237 LoadUserApiHook(); 1238 1239 Hook = BeginIfHookedUserApiHook(); 1240 if (Hook) 1241 { 1242 msgOverride = IsMsgOverride(Msg, &guah.DefWndProcArray); 1243 if(msgOverride == FALSE) 1244 { 1245 EndUserApiHook(); 1246 } 1247 } 1248 1249 /* Bypass SEH and go direct. */ 1250 if (!Hook || !msgOverride) 1251 return RealDefWindowProcW(hWnd, Msg, wParam, lParam); 1252 1253 _SEH2_TRY 1254 { 1255 Result = guah.DefWindowProcW(hWnd, Msg, wParam, lParam); 1256 } 1257 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 1258 { 1259 ERR("Got exception in hooked DefWindowProcW!\n"); 1260 } 1261 _SEH2_END; 1262 1263 EndUserApiHook(); 1264 1265 return Result; 1266 } 1267