1 /* 2 * COPYRIGHT: See COPYING in the top level directory 3 * PROJECT: ReactOS user32.dll 4 * FILE: win32ss/user/user32/windows/window.c 5 * PURPOSE: Window management 6 * PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net) 7 * Katayama Hirofumi MZ (katayama.hirofumi.mz@gmail.com) 8 * UPDATE HISTORY: 9 * 06-06-2001 CSH Created 10 */ 11 12 #define DEBUG 13 #include <user32.h> 14 15 WINE_DEFAULT_DEBUG_CHANNEL(user32); 16 17 void MDI_CalcDefaultChildPos( HWND hwndClient, INT total, LPPOINT lpPos, INT delta, UINT *id ); 18 extern LPCWSTR FASTCALL ClassNameToVersion(const void *lpszClass, LPCWSTR lpszMenuName, LPCWSTR *plpLibFileName, HANDLE *pContext, BOOL bAnsi); 19 20 /* FUNCTIONS *****************************************************************/ 21 22 23 NTSTATUS WINAPI 24 User32CallSendAsyncProcForKernel(PVOID Arguments, ULONG ArgumentLength) 25 { 26 PSENDASYNCPROC_CALLBACK_ARGUMENTS CallbackArgs; 27 28 TRACE("User32CallSendAsyncProcKernel()\n"); 29 30 CallbackArgs = (PSENDASYNCPROC_CALLBACK_ARGUMENTS)Arguments; 31 32 if (ArgumentLength != sizeof(SENDASYNCPROC_CALLBACK_ARGUMENTS)) 33 { 34 return(STATUS_INFO_LENGTH_MISMATCH); 35 } 36 37 CallbackArgs->Callback(CallbackArgs->Wnd, 38 CallbackArgs->Msg, 39 CallbackArgs->Context, 40 CallbackArgs->Result); 41 return(STATUS_SUCCESS); 42 } 43 44 45 /* 46 * @implemented 47 */ 48 BOOL WINAPI 49 AllowSetForegroundWindow(DWORD dwProcessId) 50 { 51 return NtUserxAllowSetForegroundWindow(dwProcessId); 52 } 53 54 55 /* 56 * @unimplemented 57 */ 58 HDWP WINAPI 59 BeginDeferWindowPos(int nNumWindows) 60 { 61 return NtUserxBeginDeferWindowPos(nNumWindows); 62 } 63 64 65 /* 66 * @implemented 67 */ 68 BOOL WINAPI 69 BringWindowToTop(HWND hWnd) 70 { 71 return NtUserSetWindowPos(hWnd, 72 HWND_TOP, 73 0, 74 0, 75 0, 76 0, 77 SWP_NOSIZE | SWP_NOMOVE); 78 } 79 80 81 VOID WINAPI 82 SwitchToThisWindow(HWND hwnd, BOOL fAltTab) 83 { 84 NtUserxSwitchToThisWindow(hwnd, fAltTab); 85 } 86 87 88 /* 89 * @implemented 90 */ 91 HWND WINAPI 92 ChildWindowFromPoint(HWND hWndParent, 93 POINT Point) 94 { 95 return (HWND) NtUserChildWindowFromPointEx(hWndParent, Point.x, Point.y, 0); 96 } 97 98 99 /* 100 * @implemented 101 */ 102 HWND WINAPI 103 ChildWindowFromPointEx(HWND hwndParent, 104 POINT pt, 105 UINT uFlags) 106 { 107 return (HWND) NtUserChildWindowFromPointEx(hwndParent, pt.x, pt.y, uFlags); 108 } 109 110 111 /* 112 * @implemented 113 */ 114 BOOL WINAPI 115 CloseWindow(HWND hWnd) 116 { 117 /* NOTE: CloseWindow does minimizes, and doesn't close. */ 118 SetActiveWindow(hWnd); 119 return ShowWindow(hWnd, SW_SHOWMINIMIZED); 120 } 121 122 FORCEINLINE 123 VOID 124 RtlInitLargeString( 125 OUT PLARGE_STRING plstr, 126 LPCVOID psz, 127 BOOL bUnicode) 128 { 129 if(bUnicode) 130 { 131 RtlInitLargeUnicodeString((PLARGE_UNICODE_STRING)plstr, (PWSTR)psz, 0); 132 } 133 else 134 { 135 RtlInitLargeAnsiString((PLARGE_ANSI_STRING)plstr, (PSTR)psz, 0); 136 } 137 } 138 139 VOID 140 NTAPI 141 RtlFreeLargeString( 142 IN PLARGE_STRING LargeString) 143 { 144 if (LargeString->Buffer) 145 { 146 RtlFreeHeap(GetProcessHeap(), 0, LargeString->Buffer); 147 RtlZeroMemory(LargeString, sizeof(LARGE_STRING)); 148 } 149 } 150 151 HWND WINAPI 152 User32CreateWindowEx(DWORD dwExStyle, 153 LPCSTR lpClassName, 154 LPCSTR lpWindowName, 155 DWORD dwStyle, 156 int x, 157 int y, 158 int nWidth, 159 int nHeight, 160 HWND hWndParent, 161 HMENU hMenu, 162 HINSTANCE hInstance, 163 LPVOID lpParam, 164 DWORD dwFlags) 165 { 166 LARGE_STRING WindowName; 167 LARGE_STRING lstrClassName, *plstrClassName; 168 LARGE_STRING lstrClassVersion, *plstrClassVersion; 169 UNICODE_STRING ClassName; 170 UNICODE_STRING ClassVersion; 171 WNDCLASSEXA wceA; 172 WNDCLASSEXW wceW; 173 HMODULE hLibModule = NULL; 174 DWORD dwLastError; 175 BOOL Unicode, ClassFound = FALSE; 176 HWND Handle = NULL; 177 LPCWSTR lpszClsVersion; 178 LPCWSTR lpLibFileName = NULL; 179 HANDLE pCtx = NULL; 180 181 #if 0 182 DbgPrint("[window] User32CreateWindowEx style %d, exstyle %d, parent %d\n", dwStyle, dwExStyle, hWndParent); 183 #endif 184 185 if (!RegisterDefaultClasses) 186 { 187 TRACE("RegisterSystemControls\n"); 188 RegisterSystemControls(); 189 } 190 191 Unicode = !(dwFlags & NUCWE_ANSI); 192 193 if (IS_ATOM(lpClassName)) 194 { 195 plstrClassName = (PVOID)lpClassName; 196 } 197 else 198 { 199 if (Unicode) 200 { 201 RtlInitUnicodeString(&ClassName, (PCWSTR)lpClassName); 202 } 203 else 204 { 205 if (!RtlCreateUnicodeStringFromAsciiz(&ClassName, (PCSZ)lpClassName)) 206 { 207 SetLastError(ERROR_OUTOFMEMORY); 208 return NULL; 209 } 210 } 211 212 /* Copy it to a LARGE_STRING */ 213 lstrClassName.Buffer = ClassName.Buffer; 214 lstrClassName.Length = ClassName.Length; 215 lstrClassName.MaximumLength = ClassName.MaximumLength; 216 plstrClassName = &lstrClassName; 217 } 218 219 /* Initialize a LARGE_STRING */ 220 RtlInitLargeString(&WindowName, lpWindowName, Unicode); 221 222 // HACK: The current implementation expects the Window name to be UNICODE 223 if (!Unicode) 224 { 225 NTSTATUS Status; 226 PSTR AnsiBuffer = WindowName.Buffer; 227 ULONG AnsiLength = WindowName.Length; 228 229 WindowName.Length = 0; 230 WindowName.MaximumLength = AnsiLength * sizeof(WCHAR); 231 WindowName.Buffer = RtlAllocateHeap(RtlGetProcessHeap(), 232 0, 233 WindowName.MaximumLength); 234 if (!WindowName.Buffer) 235 { 236 SetLastError(ERROR_OUTOFMEMORY); 237 goto cleanup; 238 } 239 240 Status = RtlMultiByteToUnicodeN(WindowName.Buffer, 241 WindowName.MaximumLength, 242 &WindowName.Length, 243 AnsiBuffer, 244 AnsiLength); 245 if (!NT_SUCCESS(Status)) 246 { 247 goto cleanup; 248 } 249 } 250 251 if (!hMenu && (dwStyle & (WS_OVERLAPPEDWINDOW | WS_POPUP))) 252 { 253 if (Unicode) 254 { 255 wceW.cbSize = sizeof(wceW); 256 if (GetClassInfoExW(hInstance, (LPCWSTR)lpClassName, &wceW) && wceW.lpszMenuName) 257 { 258 hMenu = LoadMenuW(hInstance, wceW.lpszMenuName); 259 } 260 } 261 else 262 { 263 wceA.cbSize = sizeof(wceA); 264 if (GetClassInfoExA(hInstance, lpClassName, &wceA) && wceA.lpszMenuName) 265 { 266 hMenu = LoadMenuA(hInstance, wceA.lpszMenuName); 267 } 268 } 269 } 270 271 if (!Unicode) dwExStyle |= WS_EX_SETANSICREATOR; 272 273 lpszClsVersion = ClassNameToVersion(lpClassName, NULL, &lpLibFileName, &pCtx, !Unicode); 274 if (!lpszClsVersion) 275 { 276 plstrClassVersion = plstrClassName; 277 } 278 else 279 { 280 RtlInitUnicodeString(&ClassVersion, lpszClsVersion); 281 lstrClassVersion.Buffer = ClassVersion.Buffer; 282 lstrClassVersion.Length = ClassVersion.Length; 283 lstrClassVersion.MaximumLength = ClassVersion.MaximumLength; 284 plstrClassVersion = &lstrClassVersion; 285 } 286 287 for (;;) 288 { 289 Handle = NtUserCreateWindowEx(dwExStyle, 290 plstrClassName, 291 plstrClassVersion, 292 &WindowName, 293 dwStyle, 294 x, 295 y, 296 nWidth, 297 nHeight, 298 hWndParent, 299 hMenu, 300 hInstance, 301 lpParam, 302 dwFlags, 303 NULL); 304 if (Handle) break; 305 if (!lpLibFileName) break; 306 if (!ClassFound) 307 { 308 dwLastError = GetLastError(); 309 if (dwLastError == ERROR_CANNOT_FIND_WND_CLASS) 310 { 311 ClassFound = VersionRegisterClass(ClassName.Buffer, lpLibFileName, pCtx, &hLibModule); 312 if (ClassFound) continue; 313 } 314 } 315 if (hLibModule) 316 { 317 dwLastError = GetLastError(); 318 FreeLibrary(hLibModule); 319 SetLastError(dwLastError); 320 hLibModule = NULL; 321 } 322 break; 323 } 324 325 #if 0 326 DbgPrint("[window] NtUserCreateWindowEx() == %d\n", Handle); 327 #endif 328 329 cleanup: 330 if (!Unicode) 331 { 332 if (!IS_ATOM(lpClassName)) 333 RtlFreeUnicodeString(&ClassName); 334 335 RtlFreeLargeString(&WindowName); 336 } 337 338 return Handle; 339 } 340 341 342 /* 343 * @implemented 344 */ 345 HWND 346 WINAPI 347 DECLSPEC_HOTPATCH 348 CreateWindowExA(DWORD dwExStyle, 349 LPCSTR lpClassName, 350 LPCSTR lpWindowName, 351 DWORD dwStyle, 352 int x, 353 int y, 354 int nWidth, 355 int nHeight, 356 HWND hWndParent, 357 HMENU hMenu, 358 HINSTANCE hInstance, 359 LPVOID lpParam) 360 { 361 MDICREATESTRUCTA mdi; 362 HWND hwnd; 363 364 if (!RegisterDefaultClasses) 365 { 366 TRACE("CreateWindowExA RegisterSystemControls\n"); 367 RegisterSystemControls(); 368 } 369 370 if (dwExStyle & WS_EX_MDICHILD) 371 { 372 POINT mPos[2]; 373 UINT id = 0; 374 HWND top_child; 375 PWND pWndParent; 376 377 pWndParent = ValidateHwnd(hWndParent); 378 379 if (!pWndParent) return NULL; 380 381 if (pWndParent->fnid != FNID_MDICLIENT) // wine uses WIN_ISMDICLIENT 382 { 383 WARN("WS_EX_MDICHILD, but parent %p is not MDIClient\n", hWndParent); 384 return NULL; 385 } 386 387 /* lpParams of WM_[NC]CREATE is different for MDI children. 388 * MDICREATESTRUCT members have the originally passed values. 389 */ 390 mdi.szClass = lpClassName; 391 mdi.szTitle = lpWindowName; 392 mdi.hOwner = hInstance; 393 mdi.x = x; 394 mdi.y = y; 395 mdi.cx = nWidth; 396 mdi.cy = nHeight; 397 mdi.style = dwStyle; 398 mdi.lParam = (LPARAM)lpParam; 399 400 lpParam = (LPVOID)&mdi; 401 402 if (pWndParent->style & MDIS_ALLCHILDSTYLES) 403 { 404 if (dwStyle & WS_POPUP) 405 { 406 WARN("WS_POPUP with MDIS_ALLCHILDSTYLES is not allowed\n"); 407 return(0); 408 } 409 dwStyle |= (WS_CHILD | WS_CLIPSIBLINGS); 410 } 411 else 412 { 413 dwStyle &= ~WS_POPUP; 414 dwStyle |= (WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CAPTION | 415 WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX); 416 } 417 418 top_child = GetWindow(hWndParent, GW_CHILD); 419 420 if (top_child) 421 { 422 /* Restore current maximized child */ 423 if((dwStyle & WS_VISIBLE) && IsZoomed(top_child)) 424 { 425 TRACE("Restoring current maximized child %p\n", top_child); 426 SendMessageW( top_child, WM_SETREDRAW, FALSE, 0 ); 427 ShowWindow(top_child, SW_RESTORE); 428 SendMessageW( top_child, WM_SETREDRAW, TRUE, 0 ); 429 } 430 } 431 432 MDI_CalcDefaultChildPos(hWndParent, -1, mPos, 0, &id); 433 434 if (!(dwStyle & WS_POPUP)) hMenu = UlongToHandle(id); 435 436 if (dwStyle & (WS_CHILD | WS_POPUP)) 437 { 438 if (x == CW_USEDEFAULT || x == CW_USEDEFAULT16) 439 { 440 x = mPos[0].x; 441 y = mPos[0].y; 442 } 443 if (nWidth == CW_USEDEFAULT || nWidth == CW_USEDEFAULT16 || !nWidth) 444 nWidth = mPos[1].x; 445 if (nHeight == CW_USEDEFAULT || nHeight == CW_USEDEFAULT16 || !nHeight) 446 nHeight = mPos[1].y; 447 } 448 } 449 450 hwnd = User32CreateWindowEx(dwExStyle, 451 lpClassName, 452 lpWindowName, 453 dwStyle, 454 x, 455 y, 456 nWidth, 457 nHeight, 458 hWndParent, 459 hMenu, 460 hInstance, 461 lpParam, 462 NUCWE_ANSI); 463 return hwnd; 464 } 465 466 467 /* 468 * @implemented 469 */ 470 HWND 471 WINAPI 472 DECLSPEC_HOTPATCH 473 CreateWindowExW(DWORD dwExStyle, 474 LPCWSTR lpClassName, 475 LPCWSTR lpWindowName, 476 DWORD dwStyle, 477 int x, 478 int y, 479 int nWidth, 480 int nHeight, 481 HWND hWndParent, 482 HMENU hMenu, 483 HINSTANCE hInstance, 484 LPVOID lpParam) 485 { 486 MDICREATESTRUCTW mdi; 487 HWND hwnd; 488 489 if (!RegisterDefaultClasses) 490 { 491 ERR("CreateWindowExW RegisterSystemControls\n"); 492 RegisterSystemControls(); 493 } 494 495 if (dwExStyle & WS_EX_MDICHILD) 496 { 497 POINT mPos[2]; 498 UINT id = 0; 499 HWND top_child; 500 PWND pWndParent; 501 502 pWndParent = ValidateHwnd(hWndParent); 503 504 if (!pWndParent) return NULL; 505 506 if (pWndParent->fnid != FNID_MDICLIENT) 507 { 508 WARN("WS_EX_MDICHILD, but parent %p is not MDIClient\n", hWndParent); 509 return NULL; 510 } 511 512 /* lpParams of WM_[NC]CREATE is different for MDI children. 513 * MDICREATESTRUCT members have the originally passed values. 514 */ 515 mdi.szClass = lpClassName; 516 mdi.szTitle = lpWindowName; 517 mdi.hOwner = hInstance; 518 mdi.x = x; 519 mdi.y = y; 520 mdi.cx = nWidth; 521 mdi.cy = nHeight; 522 mdi.style = dwStyle; 523 mdi.lParam = (LPARAM)lpParam; 524 525 lpParam = (LPVOID)&mdi; 526 527 if (pWndParent->style & MDIS_ALLCHILDSTYLES) 528 { 529 if (dwStyle & WS_POPUP) 530 { 531 WARN("WS_POPUP with MDIS_ALLCHILDSTYLES is not allowed\n"); 532 return(0); 533 } 534 dwStyle |= (WS_CHILD | WS_CLIPSIBLINGS); 535 } 536 else 537 { 538 dwStyle &= ~WS_POPUP; 539 dwStyle |= (WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CAPTION | 540 WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX); 541 } 542 543 top_child = GetWindow(hWndParent, GW_CHILD); 544 545 if (top_child) 546 { 547 /* Restore current maximized child */ 548 if((dwStyle & WS_VISIBLE) && IsZoomed(top_child)) 549 { 550 TRACE("Restoring current maximized child %p\n", top_child); 551 SendMessageW( top_child, WM_SETREDRAW, FALSE, 0 ); 552 ShowWindow(top_child, SW_RESTORE); 553 SendMessageW( top_child, WM_SETREDRAW, TRUE, 0 ); 554 } 555 } 556 557 MDI_CalcDefaultChildPos(hWndParent, -1, mPos, 0, &id); 558 559 if (!(dwStyle & WS_POPUP)) hMenu = UlongToHandle(id); 560 561 if (dwStyle & (WS_CHILD | WS_POPUP)) 562 { 563 if (x == CW_USEDEFAULT || x == CW_USEDEFAULT16) 564 { 565 x = mPos[0].x; 566 y = mPos[0].y; 567 } 568 if (nWidth == CW_USEDEFAULT || nWidth == CW_USEDEFAULT16 || !nWidth) 569 nWidth = mPos[1].x; 570 if (nHeight == CW_USEDEFAULT || nHeight == CW_USEDEFAULT16 || !nHeight) 571 nHeight = mPos[1].y; 572 } 573 } 574 575 hwnd = User32CreateWindowEx(dwExStyle, 576 (LPCSTR)lpClassName, 577 (LPCSTR)lpWindowName, 578 dwStyle, 579 x, 580 y, 581 nWidth, 582 nHeight, 583 hWndParent, 584 hMenu, 585 hInstance, 586 lpParam, 587 0); 588 return hwnd; 589 } 590 591 /* 592 * @unimplemented 593 */ 594 HDWP WINAPI 595 DeferWindowPos(HDWP hWinPosInfo, 596 HWND hWnd, 597 HWND hWndInsertAfter, 598 int x, 599 int y, 600 int cx, 601 int cy, 602 UINT uFlags) 603 { 604 return NtUserDeferWindowPos(hWinPosInfo, hWnd, hWndInsertAfter, x, y, cx, cy, uFlags); 605 } 606 607 608 /* 609 * @unimplemented 610 */ 611 BOOL WINAPI 612 EndDeferWindowPos(HDWP hWinPosInfo) 613 { 614 return NtUserEndDeferWindowPosEx(hWinPosInfo, 0); 615 } 616 617 618 /* 619 * @implemented 620 */ 621 HWND WINAPI 622 GetDesktopWindow(VOID) 623 { 624 PWND Wnd; 625 HWND Ret = NULL; 626 627 _SEH2_TRY 628 { 629 Wnd = GetThreadDesktopWnd(); 630 if (Wnd != NULL) 631 Ret = UserHMGetHandle(Wnd); 632 } 633 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 634 { 635 /* Do nothing */ 636 } 637 _SEH2_END; 638 639 return Ret; 640 } 641 642 643 static BOOL 644 User32EnumWindows(HDESK hDesktop, 645 HWND hWndparent, 646 WNDENUMPROC lpfn, 647 LPARAM lParam, 648 DWORD dwThreadId, 649 BOOL bChildren) 650 { 651 DWORD i, dwCount = 0; 652 HWND* pHwnd = NULL; 653 HANDLE hHeap; 654 NTSTATUS Status; 655 656 if (!lpfn) 657 { 658 SetLastError ( ERROR_INVALID_PARAMETER ); 659 return FALSE; 660 } 661 662 /* FIXME instead of always making two calls, should we use some 663 sort of persistent buffer and only grow it ( requiring a 2nd 664 call ) when the buffer wasn't already big enough? */ 665 /* first get how many window entries there are */ 666 Status = NtUserBuildHwndList(hDesktop, 667 hWndparent, 668 bChildren, 669 dwThreadId, 670 lParam, 671 NULL, 672 &dwCount); 673 if (!NT_SUCCESS(Status)) 674 return FALSE; 675 676 if (!dwCount) 677 { 678 if (!dwThreadId) 679 return FALSE; 680 else 681 return TRUE; 682 } 683 684 /* allocate buffer to receive HWND handles */ 685 hHeap = GetProcessHeap(); 686 pHwnd = HeapAlloc(hHeap, 0, sizeof(HWND)*(dwCount+1)); 687 if (!pHwnd) 688 { 689 SetLastError ( ERROR_NOT_ENOUGH_MEMORY ); 690 return FALSE; 691 } 692 693 /* now call kernel again to fill the buffer this time */ 694 Status = NtUserBuildHwndList(hDesktop, 695 hWndparent, 696 bChildren, 697 dwThreadId, 698 lParam, 699 pHwnd, 700 &dwCount); 701 if (!NT_SUCCESS(Status)) 702 { 703 if (pHwnd) 704 HeapFree(hHeap, 0, pHwnd); 705 return FALSE; 706 } 707 708 /* call the user's callback function until we're done or 709 they tell us to quit */ 710 for ( i = 0; i < dwCount; i++ ) 711 { 712 /* FIXME I'm only getting NULLs from Thread Enumeration, and it's 713 * probably because I'm not doing it right in NtUserBuildHwndList. 714 * Once that's fixed, we shouldn't have to check for a NULL HWND 715 * here 716 * This is now fixed in revision 50205. (jt) 717 */ 718 if (!pHwnd[i]) /* don't enumerate a NULL HWND */ 719 continue; 720 if (!(*lpfn)(pHwnd[i], lParam)) 721 { 722 HeapFree ( hHeap, 0, pHwnd ); 723 return FALSE; 724 } 725 } 726 if (pHwnd) 727 HeapFree(hHeap, 0, pHwnd); 728 return TRUE; 729 } 730 731 732 /* 733 * @implemented 734 */ 735 BOOL WINAPI 736 EnumChildWindows(HWND hWndParent, 737 WNDENUMPROC lpEnumFunc, 738 LPARAM lParam) 739 { 740 if (!hWndParent) 741 { 742 return EnumWindows(lpEnumFunc, lParam); 743 } 744 return User32EnumWindows(NULL, hWndParent, lpEnumFunc, lParam, 0, TRUE); 745 } 746 747 748 /* 749 * @implemented 750 */ 751 BOOL WINAPI 752 EnumThreadWindows(DWORD dwThreadId, 753 WNDENUMPROC lpfn, 754 LPARAM lParam) 755 { 756 if (!dwThreadId) 757 dwThreadId = GetCurrentThreadId(); 758 return User32EnumWindows(NULL, NULL, lpfn, lParam, dwThreadId, FALSE); 759 } 760 761 762 /* 763 * @implemented 764 */ 765 BOOL WINAPI 766 EnumWindows(WNDENUMPROC lpEnumFunc, 767 LPARAM lParam) 768 { 769 return User32EnumWindows(NULL, NULL, lpEnumFunc, lParam, 0, FALSE); 770 } 771 772 773 /* 774 * @implemented 775 */ 776 BOOL WINAPI 777 EnumDesktopWindows(HDESK hDesktop, 778 WNDENUMPROC lpfn, 779 LPARAM lParam) 780 { 781 return User32EnumWindows(hDesktop, NULL, lpfn, lParam, 0, FALSE); 782 } 783 784 785 /* 786 * @implemented 787 */ 788 HWND WINAPI 789 FindWindowExA(HWND hwndParent, 790 HWND hwndChildAfter, 791 LPCSTR lpszClass, 792 LPCSTR lpszWindow) 793 { 794 LPWSTR titleW = NULL; 795 HWND hwnd = 0; 796 797 if (lpszWindow) 798 { 799 DWORD len = MultiByteToWideChar( CP_ACP, 0, lpszWindow, -1, NULL, 0 ); 800 if (!(titleW = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) ))) return 0; 801 MultiByteToWideChar( CP_ACP, 0, lpszWindow, -1, titleW, len ); 802 } 803 804 if (!IS_INTRESOURCE(lpszClass)) 805 { 806 WCHAR classW[256]; 807 if (MultiByteToWideChar( CP_ACP, 0, lpszClass, -1, classW, sizeof(classW)/sizeof(WCHAR) )) 808 hwnd = FindWindowExW( hwndParent, hwndChildAfter, classW, titleW ); 809 } 810 else 811 { 812 hwnd = FindWindowExW( hwndParent, hwndChildAfter, (LPCWSTR)lpszClass, titleW ); 813 } 814 815 HeapFree( GetProcessHeap(), 0, titleW ); 816 return hwnd; 817 } 818 819 820 /* 821 * @implemented 822 */ 823 HWND WINAPI 824 FindWindowExW(HWND hwndParent, 825 HWND hwndChildAfter, 826 LPCWSTR lpszClass, 827 LPCWSTR lpszWindow) 828 { 829 UNICODE_STRING ucClassName, *pucClassName = NULL; 830 UNICODE_STRING ucWindowName, *pucWindowName = NULL; 831 832 if (IS_ATOM(lpszClass)) 833 { 834 ucClassName.Length = 0; 835 ucClassName.Buffer = (LPWSTR)lpszClass; 836 pucClassName = &ucClassName; 837 } 838 else if (lpszClass != NULL) 839 { 840 RtlInitUnicodeString(&ucClassName, 841 lpszClass); 842 pucClassName = &ucClassName; 843 } 844 845 if (lpszWindow != NULL) 846 { 847 RtlInitUnicodeString(&ucWindowName, 848 lpszWindow); 849 pucWindowName = &ucWindowName; 850 } 851 852 return NtUserFindWindowEx(hwndParent, 853 hwndChildAfter, 854 pucClassName, 855 pucWindowName, 856 0); 857 } 858 859 860 /* 861 * @implemented 862 */ 863 HWND WINAPI 864 FindWindowA(LPCSTR lpClassName, LPCSTR lpWindowName) 865 { 866 //FIXME: FindWindow does not search children, but FindWindowEx does. 867 // what should we do about this? 868 return FindWindowExA (NULL, NULL, lpClassName, lpWindowName); 869 } 870 871 872 /* 873 * @implemented 874 */ 875 HWND WINAPI 876 FindWindowW(LPCWSTR lpClassName, LPCWSTR lpWindowName) 877 { 878 /* 879 880 There was a FIXME here earlier, but I think it is just a documentation unclarity. 881 882 FindWindow only searches top level windows. What they mean is that child 883 windows of other windows than the desktop can be searched. 884 FindWindowExW never does a recursive search. 885 886 / Joakim 887 */ 888 889 return FindWindowExW(NULL, NULL, lpClassName, lpWindowName); 890 } 891 892 893 894 /* 895 * @implemented 896 */ 897 BOOL WINAPI 898 GetAltTabInfoA(HWND hwnd, 899 int iItem, 900 PALTTABINFO pati, 901 LPSTR pszItemText, 902 UINT cchItemText) 903 { 904 return NtUserGetAltTabInfo(hwnd,iItem,pati,(LPWSTR)pszItemText,cchItemText,TRUE); 905 } 906 907 908 /* 909 * @implemented 910 */ 911 BOOL WINAPI 912 GetAltTabInfoW(HWND hwnd, 913 int iItem, 914 PALTTABINFO pati, 915 LPWSTR pszItemText, 916 UINT cchItemText) 917 { 918 return NtUserGetAltTabInfo(hwnd,iItem,pati,pszItemText,cchItemText,FALSE); 919 } 920 921 922 /* 923 * @implemented 924 */ 925 HWND WINAPI 926 GetAncestor(HWND hwnd, UINT gaFlags) 927 { 928 HWND Ret = NULL; 929 PWND Ancestor, Wnd; 930 931 Wnd = ValidateHwnd(hwnd); 932 if (!Wnd) 933 return NULL; 934 935 _SEH2_TRY 936 { 937 Ancestor = NULL; 938 switch (gaFlags) 939 { 940 case GA_PARENT: 941 if (Wnd->spwndParent != NULL) 942 Ancestor = DesktopPtrToUser(Wnd->spwndParent); 943 break; 944 945 default: 946 /* FIXME: Call win32k for now */ 947 Wnd = NULL; 948 break; 949 } 950 951 if (Ancestor != NULL) 952 Ret = UserHMGetHandle(Ancestor); 953 } 954 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 955 { 956 /* Do nothing */ 957 } 958 _SEH2_END; 959 960 if (!Wnd) /* Fall back */ 961 Ret = NtUserGetAncestor(hwnd, gaFlags); 962 963 return Ret; 964 } 965 966 967 /* 968 * @implemented 969 */ 970 BOOL WINAPI 971 GetClientRect(HWND hWnd, LPRECT lpRect) 972 { 973 PWND Wnd = ValidateHwnd(hWnd); 974 975 if (!Wnd) return FALSE; 976 if (Wnd->style & WS_MINIMIZED) 977 { 978 lpRect->left = lpRect->top = 0; 979 lpRect->right = GetSystemMetrics(SM_CXMINIMIZED); 980 lpRect->bottom = GetSystemMetrics(SM_CYMINIMIZED); 981 return TRUE; 982 } 983 if ( hWnd != GetDesktopWindow()) // Wnd->fnid != FNID_DESKTOP ) 984 { 985 /* lpRect->left = lpRect->top = 0; 986 lpRect->right = Wnd->rcClient.right - Wnd->rcClient.left; 987 lpRect->bottom = Wnd->rcClient.bottom - Wnd->rcClient.top; 988 */ 989 *lpRect = Wnd->rcClient; 990 OffsetRect(lpRect, -Wnd->rcClient.left, -Wnd->rcClient.top); 991 } 992 else 993 { 994 lpRect->left = lpRect->top = 0; 995 lpRect->right = Wnd->rcClient.right; 996 lpRect->bottom = Wnd->rcClient.bottom; 997 /* Do this until Init bug is fixed. This sets 640x480, see InitMetrics. 998 lpRect->right = GetSystemMetrics(SM_CXSCREEN); 999 lpRect->bottom = GetSystemMetrics(SM_CYSCREEN); 1000 */ } 1001 return TRUE; 1002 } 1003 1004 1005 /* 1006 * @implemented 1007 */ 1008 HWND WINAPI 1009 GetLastActivePopup(HWND hWnd) 1010 { 1011 PWND Wnd; 1012 HWND Ret = hWnd; 1013 1014 Wnd = ValidateHwnd(hWnd); 1015 if (Wnd != NULL) 1016 { 1017 _SEH2_TRY 1018 { 1019 if (Wnd->spwndLastActive) 1020 { 1021 PWND LastActive = DesktopPtrToUser(Wnd->spwndLastActive); 1022 Ret = UserHMGetHandle(LastActive); 1023 } 1024 } 1025 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 1026 { 1027 /* Do nothing */ 1028 } 1029 _SEH2_END; 1030 } 1031 return Ret; 1032 } 1033 1034 1035 /* 1036 * @implemented 1037 */ 1038 HWND WINAPI 1039 GetParent(HWND hWnd) 1040 { 1041 PWND Wnd, WndParent; 1042 HWND Ret = NULL; 1043 1044 Wnd = ValidateHwnd(hWnd); 1045 if (Wnd != NULL) 1046 { 1047 _SEH2_TRY 1048 { 1049 WndParent = NULL; 1050 if (Wnd->style & WS_POPUP) 1051 { 1052 if (Wnd->spwndOwner != NULL) 1053 WndParent = DesktopPtrToUser(Wnd->spwndOwner); 1054 } 1055 else if (Wnd->style & WS_CHILD) 1056 { 1057 if (Wnd->spwndParent != NULL) 1058 WndParent = DesktopPtrToUser(Wnd->spwndParent); 1059 } 1060 1061 if (WndParent != NULL) 1062 Ret = UserHMGetHandle(WndParent); 1063 } 1064 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 1065 { 1066 /* Do nothing */ 1067 } 1068 _SEH2_END; 1069 } 1070 1071 return Ret; 1072 } 1073 1074 1075 /* 1076 * @implemented 1077 */ 1078 BOOL WINAPI 1079 GetProcessDefaultLayout(DWORD *pdwDefaultLayout) 1080 { 1081 return (BOOL)NtUserCallOneParam( (DWORD_PTR)pdwDefaultLayout, ONEPARAM_ROUTINE_GETPROCDEFLAYOUT); 1082 } 1083 1084 1085 /* 1086 * @implemented 1087 */ 1088 HWND WINAPI 1089 GetWindow(HWND hWnd, 1090 UINT uCmd) 1091 { 1092 PWND Wnd, FoundWnd; 1093 HWND Ret = NULL; 1094 1095 Wnd = ValidateHwnd(hWnd); 1096 if (!Wnd) 1097 return NULL; 1098 1099 _SEH2_TRY 1100 { 1101 FoundWnd = NULL; 1102 switch (uCmd) 1103 { 1104 case GW_OWNER: 1105 if (Wnd->spwndOwner != NULL) 1106 FoundWnd = DesktopPtrToUser(Wnd->spwndOwner); 1107 break; 1108 1109 case GW_HWNDFIRST: 1110 if(Wnd->spwndParent != NULL) 1111 { 1112 FoundWnd = DesktopPtrToUser(Wnd->spwndParent); 1113 if (FoundWnd->spwndChild != NULL) 1114 FoundWnd = DesktopPtrToUser(FoundWnd->spwndChild); 1115 } 1116 break; 1117 case GW_HWNDNEXT: 1118 if (Wnd->spwndNext != NULL) 1119 FoundWnd = DesktopPtrToUser(Wnd->spwndNext); 1120 break; 1121 1122 case GW_HWNDPREV: 1123 if (Wnd->spwndPrev != NULL) 1124 FoundWnd = DesktopPtrToUser(Wnd->spwndPrev); 1125 break; 1126 1127 case GW_CHILD: 1128 if (Wnd->spwndChild != NULL) 1129 FoundWnd = DesktopPtrToUser(Wnd->spwndChild); 1130 break; 1131 1132 case GW_HWNDLAST: 1133 FoundWnd = Wnd; 1134 while ( FoundWnd->spwndNext != NULL) 1135 FoundWnd = DesktopPtrToUser(FoundWnd->spwndNext); 1136 break; 1137 1138 default: 1139 Wnd = NULL; 1140 break; 1141 } 1142 1143 if (FoundWnd != NULL) 1144 Ret = UserHMGetHandle(FoundWnd); 1145 } 1146 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 1147 { 1148 /* Do nothing */ 1149 } 1150 _SEH2_END; 1151 1152 return Ret; 1153 } 1154 1155 1156 /* 1157 * @implemented 1158 */ 1159 HWND WINAPI 1160 GetTopWindow(HWND hWnd) 1161 { 1162 if (!hWnd) hWnd = GetDesktopWindow(); 1163 return GetWindow(hWnd, GW_CHILD); 1164 } 1165 1166 1167 /* 1168 * @implemented 1169 */ 1170 BOOL 1171 WINAPI 1172 DECLSPEC_HOTPATCH 1173 GetWindowInfo(HWND hWnd, 1174 PWINDOWINFO pwi) 1175 { 1176 PWND pWnd; 1177 PCLS pCls = NULL; 1178 SIZE Size = {0,0}; 1179 BOOL Ret = FALSE; 1180 1181 if ( !pwi || pwi->cbSize != sizeof(WINDOWINFO)) 1182 SetLastError(ERROR_INVALID_PARAMETER); // Just set the error and go! 1183 1184 pWnd = ValidateHwnd(hWnd); 1185 if (!pWnd) 1186 return Ret; 1187 1188 UserGetWindowBorders(pWnd->style, pWnd->ExStyle, &Size, FALSE); 1189 1190 _SEH2_TRY 1191 { 1192 pCls = DesktopPtrToUser(pWnd->pcls); 1193 pwi->rcWindow = pWnd->rcWindow; 1194 pwi->rcClient = pWnd->rcClient; 1195 pwi->dwStyle = pWnd->style; 1196 pwi->dwExStyle = pWnd->ExStyle; 1197 pwi->cxWindowBorders = Size.cx; 1198 pwi->cyWindowBorders = Size.cy; 1199 pwi->dwWindowStatus = 0; 1200 if (pWnd->state & WNDS_ACTIVEFRAME || (GetActiveWindow() == hWnd)) 1201 pwi->dwWindowStatus = WS_ACTIVECAPTION; 1202 pwi->atomWindowType = (pCls ? pCls->atomClassName : 0 ); 1203 1204 if ( pWnd->state2 & WNDS2_WIN50COMPAT ) 1205 { 1206 pwi->wCreatorVersion = 0x500; 1207 } 1208 else if ( pWnd->state2 & WNDS2_WIN40COMPAT ) 1209 { 1210 pwi->wCreatorVersion = 0x400; 1211 } 1212 else if ( pWnd->state2 & WNDS2_WIN31COMPAT ) 1213 { 1214 pwi->wCreatorVersion = 0x30A; 1215 } 1216 else 1217 { 1218 pwi->wCreatorVersion = 0x300; 1219 } 1220 1221 Ret = TRUE; 1222 } 1223 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 1224 { 1225 /* Do nothing */ 1226 } 1227 _SEH2_END; 1228 1229 return Ret; 1230 } 1231 1232 1233 /* 1234 * @implemented 1235 */ 1236 UINT WINAPI 1237 GetWindowModuleFileNameA(HWND hwnd, 1238 LPSTR lpszFileName, 1239 UINT cchFileNameMax) 1240 { 1241 PWND Wnd = ValidateHwnd(hwnd); 1242 1243 if (!Wnd) 1244 return 0; 1245 1246 return GetModuleFileNameA(Wnd->hModule, lpszFileName, cchFileNameMax); 1247 } 1248 1249 1250 /* 1251 * @implemented 1252 */ 1253 UINT WINAPI 1254 GetWindowModuleFileNameW(HWND hwnd, 1255 LPWSTR lpszFileName, 1256 UINT cchFileNameMax) 1257 { 1258 PWND Wnd = ValidateHwnd(hwnd); 1259 1260 if (!Wnd) 1261 return 0; 1262 1263 return GetModuleFileNameW( Wnd->hModule, lpszFileName, cchFileNameMax ); 1264 } 1265 1266 /* 1267 * @implemented 1268 */ 1269 BOOL WINAPI 1270 GetWindowRect(HWND hWnd, 1271 LPRECT lpRect) 1272 { 1273 PWND Wnd = ValidateHwnd(hWnd); 1274 1275 if (!Wnd) return FALSE; 1276 if ( hWnd != GetDesktopWindow()) // Wnd->fnid != FNID_DESKTOP ) 1277 { 1278 *lpRect = Wnd->rcWindow; 1279 } 1280 else 1281 { 1282 lpRect->left = lpRect->top = 0; 1283 lpRect->right = Wnd->rcWindow.right; 1284 lpRect->bottom = Wnd->rcWindow.bottom; 1285 /* Do this until Init bug is fixed. This sets 640x480, see InitMetrics. 1286 lpRect->right = GetSystemMetrics(SM_CXSCREEN); 1287 lpRect->bottom = GetSystemMetrics(SM_CYSCREEN); 1288 */ } 1289 return TRUE; 1290 } 1291 1292 /* 1293 * @implemented 1294 */ 1295 int WINAPI 1296 GetWindowTextA(HWND hWnd, LPSTR lpString, int nMaxCount) 1297 { 1298 PWND Wnd; 1299 INT Length = 0; 1300 1301 if (lpString == NULL || nMaxCount == 0) 1302 return 0; 1303 1304 Wnd = ValidateHwnd(hWnd); 1305 if (!Wnd) 1306 return 0; 1307 1308 lpString[0] = '\0'; 1309 1310 if (!TestWindowProcess(Wnd)) 1311 { 1312 _SEH2_TRY 1313 { 1314 Length = DefWindowProcA(hWnd, WM_GETTEXT, nMaxCount, (LPARAM)lpString); 1315 } 1316 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 1317 { 1318 Length = 0; 1319 } 1320 _SEH2_END; 1321 } 1322 else 1323 { 1324 Length = SendMessageA(hWnd, WM_GETTEXT, nMaxCount, (LPARAM)lpString); 1325 } 1326 //ERR("GWTA Len %d : %s\n",Length,lpString); 1327 return Length; 1328 } 1329 1330 /* 1331 * @implemented 1332 */ 1333 int WINAPI 1334 GetWindowTextLengthA(HWND hWnd) 1335 { 1336 PWND Wnd; 1337 1338 Wnd = ValidateHwnd(hWnd); 1339 if (!Wnd) 1340 return 0; 1341 1342 if (!TestWindowProcess(Wnd)) 1343 { 1344 return DefWindowProcA(hWnd, WM_GETTEXTLENGTH, 0, 0); 1345 } 1346 else 1347 { 1348 return SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0); 1349 } 1350 } 1351 1352 /* 1353 * @implemented 1354 */ 1355 int WINAPI 1356 GetWindowTextLengthW(HWND hWnd) 1357 { 1358 PWND Wnd; 1359 1360 Wnd = ValidateHwnd(hWnd); 1361 if (!Wnd) 1362 return 0; 1363 1364 if (!TestWindowProcess(Wnd)) 1365 { 1366 return DefWindowProcW(hWnd, WM_GETTEXTLENGTH, 0, 0); 1367 } 1368 else 1369 { 1370 return SendMessageW(hWnd, WM_GETTEXTLENGTH, 0, 0); 1371 } 1372 } 1373 1374 /* 1375 * @implemented 1376 */ 1377 int WINAPI 1378 GetWindowTextW(HWND hWnd, LPWSTR lpString, int nMaxCount) 1379 { 1380 PWND Wnd; 1381 INT Length = 0; 1382 1383 if (lpString == NULL || nMaxCount == 0) 1384 return 0; 1385 1386 Wnd = ValidateHwnd(hWnd); 1387 if (!Wnd) 1388 return 0; 1389 1390 lpString[0] = L'\0'; 1391 1392 if (!TestWindowProcess(Wnd)) 1393 { 1394 _SEH2_TRY 1395 { 1396 Length = DefWindowProcW(hWnd, WM_GETTEXT, nMaxCount, (LPARAM)lpString); 1397 } 1398 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 1399 { 1400 Length = 0; 1401 } 1402 _SEH2_END; 1403 } 1404 else 1405 { 1406 Length = SendMessageW(hWnd, WM_GETTEXT, nMaxCount, (LPARAM)lpString); 1407 } 1408 //ERR("GWTW Len %d : %S\n",Length,lpString); 1409 return Length; 1410 } 1411 1412 DWORD WINAPI 1413 GetWindowThreadProcessId(HWND hWnd, 1414 LPDWORD lpdwProcessId) 1415 { 1416 DWORD Ret = 0; 1417 PTHREADINFO ti; 1418 PWND pWnd = ValidateHwnd(hWnd); 1419 1420 if (!pWnd) return Ret; 1421 1422 ti = pWnd->head.pti; 1423 1424 if (ti) 1425 { 1426 if (ti == GetW32ThreadInfo()) 1427 { // We are current. 1428 //FIXME("Current!\n"); 1429 if (lpdwProcessId) 1430 *lpdwProcessId = (DWORD_PTR)NtCurrentTeb()->ClientId.UniqueProcess; 1431 Ret = (DWORD_PTR)NtCurrentTeb()->ClientId.UniqueThread; 1432 } 1433 else 1434 { // Ask kernel for info. 1435 //FIXME("Kernel call!\n"); 1436 if (lpdwProcessId) 1437 *lpdwProcessId = NtUserQueryWindow(hWnd, QUERY_WINDOW_UNIQUE_PROCESS_ID); 1438 Ret = NtUserQueryWindow(hWnd, QUERY_WINDOW_UNIQUE_THREAD_ID); 1439 } 1440 } 1441 return Ret; 1442 } 1443 1444 1445 /* 1446 * @implemented 1447 */ 1448 BOOL WINAPI 1449 IsChild(HWND hWndParent, 1450 HWND hWnd) 1451 { 1452 PWND WndParent, DesktopWnd, Wnd; 1453 BOOL Ret = FALSE; 1454 1455 WndParent = ValidateHwnd(hWndParent); 1456 if (!WndParent) 1457 return FALSE; 1458 Wnd = ValidateHwnd(hWnd); 1459 if (!Wnd) 1460 return FALSE; 1461 1462 DesktopWnd = GetThreadDesktopWnd(); 1463 if (!DesktopWnd) 1464 return FALSE; 1465 1466 _SEH2_TRY 1467 { 1468 while (Wnd != NULL && ((Wnd->style & (WS_POPUP|WS_CHILD)) == WS_CHILD)) 1469 { 1470 if (Wnd->spwndParent != NULL) 1471 { 1472 Wnd = DesktopPtrToUser(Wnd->spwndParent); 1473 1474 if (Wnd == WndParent) 1475 { 1476 Ret = TRUE; 1477 break; 1478 } 1479 } 1480 else 1481 break; 1482 } 1483 } 1484 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 1485 { 1486 /* Do nothing */ 1487 } 1488 _SEH2_END; 1489 1490 return Ret; 1491 } 1492 1493 1494 /* 1495 * @implemented 1496 */ 1497 BOOL WINAPI 1498 IsIconic(HWND hWnd) 1499 { 1500 PWND Wnd = ValidateHwnd(hWnd); 1501 1502 if (Wnd != NULL) 1503 return (Wnd->style & WS_MINIMIZE) != 0; 1504 1505 return FALSE; 1506 } 1507 1508 1509 /* 1510 * @implemented 1511 */ 1512 BOOL WINAPI 1513 IsWindow(HWND hWnd) 1514 { 1515 PWND Wnd = ValidateHwndNoErr(hWnd); 1516 if (Wnd != NULL) 1517 { 1518 if (Wnd->state & WNDS_DESTROYED || 1519 Wnd->state2 & WNDS2_INDESTROY) 1520 return FALSE; 1521 return TRUE; 1522 } 1523 1524 return FALSE; 1525 } 1526 1527 1528 /* 1529 * @implemented 1530 */ 1531 BOOL WINAPI 1532 IsWindowUnicode(HWND hWnd) 1533 { 1534 PWND Wnd = ValidateHwnd(hWnd); 1535 1536 if (Wnd != NULL) 1537 return Wnd->Unicode; 1538 1539 return FALSE; 1540 } 1541 1542 1543 /* 1544 * @implemented 1545 */ 1546 BOOL WINAPI 1547 IsWindowVisible(HWND hWnd) 1548 { 1549 BOOL Ret = FALSE; 1550 PWND Wnd = ValidateHwnd(hWnd); 1551 1552 if (Wnd != NULL) 1553 { 1554 _SEH2_TRY 1555 { 1556 Ret = TRUE; 1557 1558 do 1559 { 1560 if (!(Wnd->style & WS_VISIBLE)) 1561 { 1562 Ret = FALSE; 1563 break; 1564 } 1565 1566 if (Wnd->spwndParent != NULL) 1567 Wnd = DesktopPtrToUser(Wnd->spwndParent); 1568 else 1569 break; 1570 1571 } while (Wnd != NULL); 1572 } 1573 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 1574 { 1575 Ret = FALSE; 1576 } 1577 _SEH2_END; 1578 } 1579 1580 return Ret; 1581 } 1582 1583 1584 /* 1585 * @implemented 1586 */ 1587 BOOL WINAPI 1588 IsWindowEnabled(HWND hWnd) 1589 { 1590 // AG: I don't know if child windows are affected if the parent is 1591 // disabled. I think they stop processing messages but stay appearing 1592 // as enabled. 1593 1594 return !(GetWindowLongPtrW(hWnd, GWL_STYLE) & WS_DISABLED); 1595 } 1596 1597 1598 /* 1599 * @implemented 1600 */ 1601 BOOL WINAPI 1602 IsZoomed(HWND hWnd) 1603 { 1604 return (GetWindowLongPtrW(hWnd, GWL_STYLE) & WS_MAXIMIZE) != 0; 1605 } 1606 1607 1608 /* 1609 * @implemented 1610 */ 1611 BOOL WINAPI 1612 LockSetForegroundWindow(UINT uLockCode) 1613 { 1614 return NtUserxLockSetForegroundWindow(uLockCode); 1615 } 1616 1617 1618 /* 1619 * @implemented 1620 */ 1621 BOOL WINAPI 1622 AnimateWindow(HWND hwnd, 1623 DWORD dwTime, 1624 DWORD dwFlags) 1625 { 1626 /* FIXME Add animation code */ 1627 1628 /* If trying to show/hide and it's already * 1629 * shown/hidden or invalid window, fail with * 1630 * invalid parameter */ 1631 1632 BOOL visible; 1633 visible = IsWindowVisible(hwnd); 1634 if(!IsWindow(hwnd) || 1635 (visible && !(dwFlags & AW_HIDE)) || 1636 (!visible && (dwFlags & AW_HIDE))) 1637 { 1638 SetLastError(ERROR_INVALID_PARAMETER); 1639 return FALSE; 1640 } 1641 1642 ShowWindow(hwnd, (dwFlags & AW_HIDE) ? SW_HIDE : ((dwFlags & AW_ACTIVATE) ? SW_SHOW : SW_SHOWNA)); 1643 1644 return TRUE; 1645 } 1646 1647 1648 /* 1649 * @implemented 1650 */ 1651 BOOL WINAPI 1652 OpenIcon(HWND hWnd) 1653 { 1654 if (!(GetWindowLongPtrW(hWnd, GWL_STYLE) & WS_MINIMIZE)) 1655 return FALSE; 1656 1657 ShowWindow(hWnd,SW_RESTORE); 1658 return TRUE; 1659 } 1660 1661 1662 /* 1663 * @implemented 1664 */ 1665 HWND WINAPI 1666 RealChildWindowFromPoint(HWND hwndParent, 1667 POINT ptParentClientCoords) 1668 { 1669 return NtUserRealChildWindowFromPoint(hwndParent, ptParentClientCoords.x, ptParentClientCoords.y); 1670 } 1671 1672 /* 1673 * @unimplemented 1674 */ 1675 BOOL WINAPI 1676 SetForegroundWindow(HWND hWnd) 1677 { 1678 return NtUserxSetForegroundWindow(hWnd); 1679 } 1680 1681 1682 /* 1683 * @implemented 1684 */ 1685 BOOL WINAPI 1686 SetProcessDefaultLayout(DWORD dwDefaultLayout) 1687 { 1688 return NtUserCallOneParam( (DWORD_PTR)dwDefaultLayout, ONEPARAM_ROUTINE_SETPROCDEFLAYOUT); 1689 } 1690 1691 1692 /* 1693 * @implemented 1694 */ 1695 BOOL 1696 WINAPI 1697 DECLSPEC_HOTPATCH 1698 SetWindowTextA(HWND hWnd, 1699 LPCSTR lpString) 1700 { 1701 PWND pwnd; 1702 1703 pwnd = ValidateHwnd(hWnd); 1704 if (pwnd) 1705 { 1706 if (!TestWindowProcess(pwnd)) 1707 { 1708 /* do not send WM_GETTEXT messages to other processes */ 1709 return (DefWindowProcA(hWnd, WM_SETTEXT, 0, (LPARAM)lpString) >= 0); 1710 } 1711 return (SendMessageA(hWnd, WM_SETTEXT, 0, (LPARAM)lpString) >= 0); 1712 } 1713 return FALSE; 1714 } 1715 1716 1717 /* 1718 * @implemented 1719 */ 1720 BOOL 1721 WINAPI 1722 DECLSPEC_HOTPATCH 1723 SetWindowTextW(HWND hWnd, 1724 LPCWSTR lpString) 1725 { 1726 PWND pwnd; 1727 1728 pwnd = ValidateHwnd(hWnd); 1729 if (pwnd) 1730 { 1731 if (!TestWindowProcess(pwnd)) 1732 { 1733 /* do not send WM_GETTEXT messages to other processes */ 1734 return (DefWindowProcW(hWnd, WM_SETTEXT, 0, (LPARAM)lpString) >= 0); 1735 } 1736 return (SendMessageW(hWnd, WM_SETTEXT, 0, (LPARAM)lpString) >= 0); 1737 } 1738 return FALSE; 1739 } 1740 1741 1742 /* 1743 * @implemented 1744 */ 1745 BOOL WINAPI 1746 ShowOwnedPopups(HWND hWnd, BOOL fShow) 1747 { 1748 return NtUserxShowOwnedPopups(hWnd, fShow); 1749 } 1750 1751 1752 /* 1753 * @implemented 1754 */ 1755 BOOL WINAPI 1756 UpdateLayeredWindow( HWND hwnd, 1757 HDC hdcDst, 1758 POINT *pptDst, 1759 SIZE *psize, 1760 HDC hdcSrc, 1761 POINT *pptSrc, 1762 COLORREF crKey, 1763 BLENDFUNCTION *pbl, 1764 DWORD dwFlags) 1765 { 1766 if (dwFlags & ULW_EX_NORESIZE) /* only valid for UpdateLayeredWindowIndirect */ 1767 { 1768 SetLastError( ERROR_INVALID_PARAMETER ); 1769 return FALSE; 1770 } 1771 return NtUserUpdateLayeredWindow( hwnd, 1772 hdcDst, 1773 pptDst, 1774 psize, 1775 hdcSrc, 1776 pptSrc, 1777 crKey, 1778 pbl, 1779 dwFlags, 1780 NULL); 1781 } 1782 1783 /* 1784 * @implemented 1785 */ 1786 BOOL WINAPI 1787 UpdateLayeredWindowIndirect(HWND hwnd, 1788 const UPDATELAYEREDWINDOWINFO *info) 1789 { 1790 if (info && info->cbSize == sizeof(*info)) 1791 { 1792 return NtUserUpdateLayeredWindow( hwnd, 1793 info->hdcDst, 1794 (POINT *)info->pptDst, 1795 (SIZE *)info->psize, 1796 info->hdcSrc, 1797 (POINT *)info->pptSrc, 1798 info->crKey, 1799 (BLENDFUNCTION *)info->pblend, 1800 info->dwFlags, 1801 (RECT *)info->prcDirty); 1802 } 1803 SetLastError(ERROR_INVALID_PARAMETER); 1804 return FALSE; 1805 } 1806 1807 /* 1808 * @implemented 1809 */ 1810 BOOL WINAPI 1811 SetWindowContextHelpId(HWND hwnd, 1812 DWORD dwContextHelpId) 1813 { 1814 return NtUserxSetWindowContextHelpId(hwnd, dwContextHelpId); 1815 } 1816 1817 /* 1818 * @implemented 1819 */ 1820 DWORD WINAPI 1821 GetWindowContextHelpId(HWND hwnd) 1822 { 1823 return NtUserxGetWindowContextHelpId(hwnd); 1824 } 1825 1826 /* 1827 * @implemented 1828 */ 1829 int WINAPI 1830 InternalGetWindowText(HWND hWnd, LPWSTR lpString, int nMaxCount) 1831 { 1832 INT Ret = NtUserInternalGetWindowText(hWnd, lpString, nMaxCount); 1833 if (Ret == 0 && lpString) 1834 *lpString = L'\0'; 1835 return Ret; 1836 } 1837 1838 /* 1839 * @implemented 1840 */ 1841 BOOL WINAPI 1842 IsHungAppWindow(HWND hwnd) 1843 { 1844 return (NtUserQueryWindow(hwnd, QUERY_WINDOW_ISHUNG) != 0); 1845 } 1846 1847 /* 1848 * @implemented 1849 */ 1850 VOID WINAPI 1851 SetLastErrorEx(DWORD dwErrCode, DWORD dwType) 1852 { 1853 SetLastError(dwErrCode); 1854 } 1855 1856 /* 1857 * @implemented 1858 */ 1859 HWND WINAPI 1860 GetFocus(VOID) 1861 { 1862 return (HWND)NtUserGetThreadState(THREADSTATE_FOCUSWINDOW); 1863 } 1864 1865 DWORD WINAPI 1866 GetRealWindowOwner(HWND hwnd) 1867 { 1868 return NtUserQueryWindow(hwnd, QUERY_WINDOW_REAL_ID); 1869 } 1870 1871 /* 1872 * @implemented 1873 */ 1874 HWND WINAPI 1875 SetTaskmanWindow(HWND hWnd) 1876 { 1877 return NtUserxSetTaskmanWindow(hWnd); 1878 } 1879 1880 /* 1881 * @implemented 1882 */ 1883 HWND WINAPI 1884 SetProgmanWindow(HWND hWnd) 1885 { 1886 return NtUserxSetProgmanWindow(hWnd); 1887 } 1888 1889 /* 1890 * @implemented 1891 */ 1892 HWND WINAPI 1893 GetProgmanWindow(VOID) 1894 { 1895 return (HWND)NtUserGetThreadState(THREADSTATE_PROGMANWINDOW); 1896 } 1897 1898 /* 1899 * @implemented 1900 */ 1901 HWND WINAPI 1902 GetTaskmanWindow(VOID) 1903 { 1904 return (HWND)NtUserGetThreadState(THREADSTATE_TASKMANWINDOW); 1905 } 1906 1907 /* 1908 * @implemented 1909 */ 1910 BOOL WINAPI 1911 ScrollWindow(HWND hWnd, 1912 int dx, 1913 int dy, 1914 CONST RECT *lpRect, 1915 CONST RECT *prcClip) 1916 { 1917 return NtUserScrollWindowEx(hWnd, 1918 dx, 1919 dy, 1920 lpRect, 1921 prcClip, 1922 0, 1923 NULL, 1924 (lpRect ? 0 : SW_SCROLLCHILDREN) | (SW_ERASE|SW_INVALIDATE|SW_SCROLLWNDDCE)) != ERROR; 1925 } 1926 1927 /* ScrollWindow uses the window DC, ScrollWindowEx doesn't */ 1928 1929 /* 1930 * @implemented 1931 */ 1932 INT WINAPI 1933 ScrollWindowEx(HWND hWnd, 1934 int dx, 1935 int dy, 1936 CONST RECT *prcScroll, 1937 CONST RECT *prcClip, 1938 HRGN hrgnUpdate, 1939 LPRECT prcUpdate, 1940 UINT flags) 1941 { 1942 if (flags & SW_SMOOTHSCROLL) 1943 { 1944 FIXME("SW_SMOOTHSCROLL not supported."); 1945 // Fall through.... 1946 } 1947 return NtUserScrollWindowEx(hWnd, 1948 dx, 1949 dy, 1950 prcScroll, 1951 prcClip, 1952 hrgnUpdate, 1953 prcUpdate, 1954 flags); 1955 } 1956 1957 /* 1958 * @implemented 1959 */ 1960 BOOL WINAPI 1961 AnyPopup(VOID) 1962 { 1963 int i; 1964 BOOL retvalue; 1965 HWND *list = WIN_ListChildren( GetDesktopWindow() ); 1966 1967 if (!list) return FALSE; 1968 for (i = 0; list[i]; i++) 1969 { 1970 if (IsWindowVisible( list[i] ) && GetWindow( list[i], GW_OWNER )) break; 1971 } 1972 retvalue = (list[i] != 0); 1973 HeapFree( GetProcessHeap(), 0, list ); 1974 return retvalue; 1975 } 1976 1977 /* 1978 * @implemented 1979 */ 1980 BOOL WINAPI 1981 IsWindowInDestroy(HWND hWnd) 1982 { 1983 PWND pwnd; 1984 pwnd = ValidateHwnd(hWnd); 1985 if (!pwnd) 1986 return FALSE; 1987 return ((pwnd->state2 & WNDS2_INDESTROY) == WNDS2_INDESTROY); 1988 } 1989 1990 /* 1991 * @implemented 1992 */ 1993 VOID WINAPI 1994 DisableProcessWindowsGhosting(VOID) 1995 { 1996 NtUserxEnableProcessWindowGhosting(FALSE); 1997 } 1998 1999 /* EOF */ 2000 2001