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