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