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