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 Length = SendMessageA(hWnd, WM_GETTEXT, nMaxCount, (LPARAM)lpString); 1323 //ERR("GWTA Len %d : %s\n",Length,lpString); 1324 return Length; 1325 } 1326 1327 /* 1328 * @implemented 1329 */ 1330 int WINAPI 1331 GetWindowTextLengthA(HWND hWnd) 1332 { 1333 return(SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0)); 1334 } 1335 1336 /* 1337 * @implemented 1338 */ 1339 int WINAPI 1340 GetWindowTextLengthW(HWND hWnd) 1341 { 1342 return(SendMessageW(hWnd, WM_GETTEXTLENGTH, 0, 0)); 1343 } 1344 1345 /* 1346 * @implemented 1347 */ 1348 int WINAPI 1349 GetWindowTextW(HWND hWnd, LPWSTR lpString, int nMaxCount) 1350 { 1351 PWND Wnd; 1352 INT Length = 0; 1353 1354 if (lpString == NULL || nMaxCount == 0) 1355 return 0; 1356 1357 Wnd = ValidateHwnd(hWnd); 1358 if (!Wnd) 1359 return 0; 1360 1361 lpString[0] = L'\0'; 1362 1363 if (!TestWindowProcess( Wnd)) 1364 { 1365 _SEH2_TRY 1366 { 1367 Length = DefWindowProcW(hWnd, WM_GETTEXT, nMaxCount, (LPARAM)lpString); 1368 } 1369 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 1370 { 1371 Length = 0; 1372 } 1373 _SEH2_END; 1374 } 1375 else 1376 Length = SendMessageW(hWnd, WM_GETTEXT, nMaxCount, (LPARAM)lpString); 1377 //ERR("GWTW Len %d : %S\n",Length,lpString); 1378 return Length; 1379 } 1380 1381 DWORD WINAPI 1382 GetWindowThreadProcessId(HWND hWnd, 1383 LPDWORD lpdwProcessId) 1384 { 1385 DWORD Ret = 0; 1386 PTHREADINFO ti; 1387 PWND pWnd = ValidateHwnd(hWnd); 1388 1389 if (!pWnd) return Ret; 1390 1391 ti = pWnd->head.pti; 1392 1393 if (ti) 1394 { 1395 if (ti == GetW32ThreadInfo()) 1396 { // We are current. 1397 //FIXME("Current!\n"); 1398 if (lpdwProcessId) 1399 *lpdwProcessId = (DWORD_PTR)NtCurrentTeb()->ClientId.UniqueProcess; 1400 Ret = (DWORD_PTR)NtCurrentTeb()->ClientId.UniqueThread; 1401 } 1402 else 1403 { // Ask kernel for info. 1404 //FIXME("Kernel call!\n"); 1405 if (lpdwProcessId) 1406 *lpdwProcessId = NtUserQueryWindow(hWnd, QUERY_WINDOW_UNIQUE_PROCESS_ID); 1407 Ret = NtUserQueryWindow(hWnd, QUERY_WINDOW_UNIQUE_THREAD_ID); 1408 } 1409 } 1410 return Ret; 1411 } 1412 1413 1414 /* 1415 * @implemented 1416 */ 1417 BOOL WINAPI 1418 IsChild(HWND hWndParent, 1419 HWND hWnd) 1420 { 1421 PWND WndParent, DesktopWnd, Wnd; 1422 BOOL Ret = FALSE; 1423 1424 WndParent = ValidateHwnd(hWndParent); 1425 if (!WndParent) 1426 return FALSE; 1427 Wnd = ValidateHwnd(hWnd); 1428 if (!Wnd) 1429 return FALSE; 1430 1431 DesktopWnd = GetThreadDesktopWnd(); 1432 if (!DesktopWnd) 1433 return FALSE; 1434 1435 _SEH2_TRY 1436 { 1437 while (Wnd != NULL && ((Wnd->style & (WS_POPUP|WS_CHILD)) == WS_CHILD)) 1438 { 1439 if (Wnd->spwndParent != NULL) 1440 { 1441 Wnd = DesktopPtrToUser(Wnd->spwndParent); 1442 1443 if (Wnd == WndParent) 1444 { 1445 Ret = TRUE; 1446 break; 1447 } 1448 } 1449 else 1450 break; 1451 } 1452 } 1453 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 1454 { 1455 /* Do nothing */ 1456 } 1457 _SEH2_END; 1458 1459 return Ret; 1460 } 1461 1462 1463 /* 1464 * @implemented 1465 */ 1466 BOOL WINAPI 1467 IsIconic(HWND hWnd) 1468 { 1469 PWND Wnd = ValidateHwnd(hWnd); 1470 1471 if (Wnd != NULL) 1472 return (Wnd->style & WS_MINIMIZE) != 0; 1473 1474 return FALSE; 1475 } 1476 1477 1478 /* 1479 * @implemented 1480 */ 1481 BOOL WINAPI 1482 IsWindow(HWND hWnd) 1483 { 1484 PWND Wnd = ValidateHwndNoErr(hWnd); 1485 if (Wnd != NULL) 1486 { 1487 if (Wnd->state & WNDS_DESTROYED || 1488 Wnd->state2 & WNDS2_INDESTROY) 1489 return FALSE; 1490 return TRUE; 1491 } 1492 1493 return FALSE; 1494 } 1495 1496 1497 /* 1498 * @implemented 1499 */ 1500 BOOL WINAPI 1501 IsWindowUnicode(HWND hWnd) 1502 { 1503 PWND Wnd = ValidateHwnd(hWnd); 1504 1505 if (Wnd != NULL) 1506 return Wnd->Unicode; 1507 1508 return FALSE; 1509 } 1510 1511 1512 /* 1513 * @implemented 1514 */ 1515 BOOL WINAPI 1516 IsWindowVisible(HWND hWnd) 1517 { 1518 BOOL Ret = FALSE; 1519 PWND Wnd = ValidateHwnd(hWnd); 1520 1521 if (Wnd != NULL) 1522 { 1523 _SEH2_TRY 1524 { 1525 Ret = TRUE; 1526 1527 do 1528 { 1529 if (!(Wnd->style & WS_VISIBLE)) 1530 { 1531 Ret = FALSE; 1532 break; 1533 } 1534 1535 if (Wnd->spwndParent != NULL) 1536 Wnd = DesktopPtrToUser(Wnd->spwndParent); 1537 else 1538 break; 1539 1540 } while (Wnd != NULL); 1541 } 1542 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 1543 { 1544 Ret = FALSE; 1545 } 1546 _SEH2_END; 1547 } 1548 1549 return Ret; 1550 } 1551 1552 1553 /* 1554 * @implemented 1555 */ 1556 BOOL WINAPI 1557 IsWindowEnabled(HWND hWnd) 1558 { 1559 // AG: I don't know if child windows are affected if the parent is 1560 // disabled. I think they stop processing messages but stay appearing 1561 // as enabled. 1562 1563 return !(GetWindowLongPtrW(hWnd, GWL_STYLE) & WS_DISABLED); 1564 } 1565 1566 1567 /* 1568 * @implemented 1569 */ 1570 BOOL WINAPI 1571 IsZoomed(HWND hWnd) 1572 { 1573 return (GetWindowLongPtrW(hWnd, GWL_STYLE) & WS_MAXIMIZE) != 0; 1574 } 1575 1576 1577 /* 1578 * @implemented 1579 */ 1580 BOOL WINAPI 1581 LockSetForegroundWindow(UINT uLockCode) 1582 { 1583 return NtUserxLockSetForegroundWindow(uLockCode); 1584 } 1585 1586 1587 /* 1588 * @implemented 1589 */ 1590 BOOL WINAPI 1591 AnimateWindow(HWND hwnd, 1592 DWORD dwTime, 1593 DWORD dwFlags) 1594 { 1595 /* FIXME Add animation code */ 1596 1597 /* If trying to show/hide and it's already * 1598 * shown/hidden or invalid window, fail with * 1599 * invalid parameter */ 1600 1601 BOOL visible; 1602 visible = IsWindowVisible(hwnd); 1603 if(!IsWindow(hwnd) || 1604 (visible && !(dwFlags & AW_HIDE)) || 1605 (!visible && (dwFlags & AW_HIDE))) 1606 { 1607 SetLastError(ERROR_INVALID_PARAMETER); 1608 return FALSE; 1609 } 1610 1611 ShowWindow(hwnd, (dwFlags & AW_HIDE) ? SW_HIDE : ((dwFlags & AW_ACTIVATE) ? SW_SHOW : SW_SHOWNA)); 1612 1613 return TRUE; 1614 } 1615 1616 1617 /* 1618 * @implemented 1619 */ 1620 BOOL WINAPI 1621 OpenIcon(HWND hWnd) 1622 { 1623 if (!(GetWindowLongPtrW(hWnd, GWL_STYLE) & WS_MINIMIZE)) 1624 return FALSE; 1625 1626 ShowWindow(hWnd,SW_RESTORE); 1627 return TRUE; 1628 } 1629 1630 1631 /* 1632 * @implemented 1633 */ 1634 HWND WINAPI 1635 RealChildWindowFromPoint(HWND hwndParent, 1636 POINT ptParentClientCoords) 1637 { 1638 return NtUserRealChildWindowFromPoint(hwndParent, ptParentClientCoords.x, ptParentClientCoords.y); 1639 } 1640 1641 /* 1642 * @unimplemented 1643 */ 1644 BOOL WINAPI 1645 SetForegroundWindow(HWND hWnd) 1646 { 1647 return NtUserxSetForegroundWindow(hWnd); 1648 } 1649 1650 1651 /* 1652 * @implemented 1653 */ 1654 BOOL WINAPI 1655 SetProcessDefaultLayout(DWORD dwDefaultLayout) 1656 { 1657 return NtUserCallOneParam( (DWORD_PTR)dwDefaultLayout, ONEPARAM_ROUTINE_SETPROCDEFLAYOUT); 1658 } 1659 1660 1661 /* 1662 * @implemented 1663 */ 1664 BOOL 1665 WINAPI 1666 DECLSPEC_HOTPATCH 1667 SetWindowTextA(HWND hWnd, 1668 LPCSTR lpString) 1669 { 1670 PWND pwnd; 1671 1672 pwnd = ValidateHwnd(hWnd); 1673 if (pwnd) 1674 { 1675 if (!TestWindowProcess(pwnd)) 1676 { 1677 /* do not send WM_GETTEXT messages to other processes */ 1678 return (DefWindowProcA(hWnd, WM_SETTEXT, 0, (LPARAM)lpString) >= 0); 1679 } 1680 return (SendMessageA(hWnd, WM_SETTEXT, 0, (LPARAM)lpString) >= 0); 1681 } 1682 return FALSE; 1683 } 1684 1685 1686 /* 1687 * @implemented 1688 */ 1689 BOOL 1690 WINAPI 1691 DECLSPEC_HOTPATCH 1692 SetWindowTextW(HWND hWnd, 1693 LPCWSTR lpString) 1694 { 1695 PWND pwnd; 1696 1697 pwnd = ValidateHwnd(hWnd); 1698 if (pwnd) 1699 { 1700 if (!TestWindowProcess(pwnd)) 1701 { 1702 /* do not send WM_GETTEXT messages to other processes */ 1703 return (DefWindowProcW(hWnd, WM_SETTEXT, 0, (LPARAM)lpString) >= 0); 1704 } 1705 return (SendMessageW(hWnd, WM_SETTEXT, 0, (LPARAM)lpString) >= 0); 1706 } 1707 return FALSE; 1708 } 1709 1710 1711 /* 1712 * @implemented 1713 */ 1714 BOOL WINAPI 1715 ShowOwnedPopups(HWND hWnd, BOOL fShow) 1716 { 1717 return NtUserxShowOwnedPopups(hWnd, fShow); 1718 } 1719 1720 1721 /* 1722 * @implemented 1723 */ 1724 BOOL WINAPI 1725 UpdateLayeredWindow( HWND hwnd, 1726 HDC hdcDst, 1727 POINT *pptDst, 1728 SIZE *psize, 1729 HDC hdcSrc, 1730 POINT *pptSrc, 1731 COLORREF crKey, 1732 BLENDFUNCTION *pbl, 1733 DWORD dwFlags) 1734 { 1735 if (dwFlags & ULW_EX_NORESIZE) /* only valid for UpdateLayeredWindowIndirect */ 1736 { 1737 SetLastError( ERROR_INVALID_PARAMETER ); 1738 return FALSE; 1739 } 1740 return NtUserUpdateLayeredWindow( hwnd, 1741 hdcDst, 1742 pptDst, 1743 psize, 1744 hdcSrc, 1745 pptSrc, 1746 crKey, 1747 pbl, 1748 dwFlags, 1749 NULL); 1750 } 1751 1752 /* 1753 * @implemented 1754 */ 1755 BOOL WINAPI 1756 UpdateLayeredWindowIndirect(HWND hwnd, 1757 const UPDATELAYEREDWINDOWINFO *info) 1758 { 1759 if (info && info->cbSize == sizeof(*info)) 1760 { 1761 return NtUserUpdateLayeredWindow( hwnd, 1762 info->hdcDst, 1763 (POINT *)info->pptDst, 1764 (SIZE *)info->psize, 1765 info->hdcSrc, 1766 (POINT *)info->pptSrc, 1767 info->crKey, 1768 (BLENDFUNCTION *)info->pblend, 1769 info->dwFlags, 1770 (RECT *)info->prcDirty); 1771 } 1772 SetLastError(ERROR_INVALID_PARAMETER); 1773 return FALSE; 1774 } 1775 1776 /* 1777 * @implemented 1778 */ 1779 BOOL WINAPI 1780 SetWindowContextHelpId(HWND hwnd, 1781 DWORD dwContextHelpId) 1782 { 1783 return NtUserxSetWindowContextHelpId(hwnd, dwContextHelpId); 1784 } 1785 1786 /* 1787 * @implemented 1788 */ 1789 DWORD WINAPI 1790 GetWindowContextHelpId(HWND hwnd) 1791 { 1792 return NtUserxGetWindowContextHelpId(hwnd); 1793 } 1794 1795 /* 1796 * @implemented 1797 */ 1798 int WINAPI 1799 InternalGetWindowText(HWND hWnd, LPWSTR lpString, int nMaxCount) 1800 { 1801 INT Ret = NtUserInternalGetWindowText(hWnd, lpString, nMaxCount); 1802 if (Ret == 0) 1803 *lpString = L'\0'; 1804 return Ret; 1805 } 1806 1807 /* 1808 * @implemented 1809 */ 1810 BOOL WINAPI 1811 IsHungAppWindow(HWND hwnd) 1812 { 1813 return (NtUserQueryWindow(hwnd, QUERY_WINDOW_ISHUNG) != 0); 1814 } 1815 1816 /* 1817 * @implemented 1818 */ 1819 VOID WINAPI 1820 SetLastErrorEx(DWORD dwErrCode, DWORD dwType) 1821 { 1822 SetLastError(dwErrCode); 1823 } 1824 1825 /* 1826 * @implemented 1827 */ 1828 HWND WINAPI 1829 GetFocus(VOID) 1830 { 1831 return (HWND)NtUserGetThreadState(THREADSTATE_FOCUSWINDOW); 1832 } 1833 1834 DWORD WINAPI 1835 GetRealWindowOwner(HWND hwnd) 1836 { 1837 return NtUserQueryWindow(hwnd, QUERY_WINDOW_REAL_ID); 1838 } 1839 1840 /* 1841 * @implemented 1842 */ 1843 HWND WINAPI 1844 SetTaskmanWindow(HWND hWnd) 1845 { 1846 return NtUserxSetTaskmanWindow(hWnd); 1847 } 1848 1849 /* 1850 * @implemented 1851 */ 1852 HWND WINAPI 1853 SetProgmanWindow(HWND hWnd) 1854 { 1855 return NtUserxSetProgmanWindow(hWnd); 1856 } 1857 1858 /* 1859 * @implemented 1860 */ 1861 HWND WINAPI 1862 GetProgmanWindow(VOID) 1863 { 1864 return (HWND)NtUserGetThreadState(THREADSTATE_PROGMANWINDOW); 1865 } 1866 1867 /* 1868 * @implemented 1869 */ 1870 HWND WINAPI 1871 GetTaskmanWindow(VOID) 1872 { 1873 return (HWND)NtUserGetThreadState(THREADSTATE_TASKMANWINDOW); 1874 } 1875 1876 /* 1877 * @implemented 1878 */ 1879 BOOL WINAPI 1880 ScrollWindow(HWND hWnd, 1881 int dx, 1882 int dy, 1883 CONST RECT *lpRect, 1884 CONST RECT *prcClip) 1885 { 1886 return NtUserScrollWindowEx(hWnd, 1887 dx, 1888 dy, 1889 lpRect, 1890 prcClip, 1891 0, 1892 NULL, 1893 (lpRect ? 0 : SW_SCROLLCHILDREN) | (SW_ERASE|SW_INVALIDATE|SW_SCROLLWNDDCE)) != ERROR; 1894 } 1895 1896 /* ScrollWindow uses the window DC, ScrollWindowEx doesn't */ 1897 1898 /* 1899 * @implemented 1900 */ 1901 INT WINAPI 1902 ScrollWindowEx(HWND hWnd, 1903 int dx, 1904 int dy, 1905 CONST RECT *prcScroll, 1906 CONST RECT *prcClip, 1907 HRGN hrgnUpdate, 1908 LPRECT prcUpdate, 1909 UINT flags) 1910 { 1911 if (flags & SW_SMOOTHSCROLL) 1912 { 1913 FIXME("SW_SMOOTHSCROLL not supported."); 1914 // Fall through.... 1915 } 1916 return NtUserScrollWindowEx(hWnd, 1917 dx, 1918 dy, 1919 prcScroll, 1920 prcClip, 1921 hrgnUpdate, 1922 prcUpdate, 1923 flags); 1924 } 1925 1926 /* 1927 * @implemented 1928 */ 1929 BOOL WINAPI 1930 AnyPopup(VOID) 1931 { 1932 int i; 1933 BOOL retvalue; 1934 HWND *list = WIN_ListChildren( GetDesktopWindow() ); 1935 1936 if (!list) return FALSE; 1937 for (i = 0; list[i]; i++) 1938 { 1939 if (IsWindowVisible( list[i] ) && GetWindow( list[i], GW_OWNER )) break; 1940 } 1941 retvalue = (list[i] != 0); 1942 HeapFree( GetProcessHeap(), 0, list ); 1943 return retvalue; 1944 } 1945 1946 /* 1947 * @implemented 1948 */ 1949 BOOL WINAPI 1950 IsWindowInDestroy(HWND hWnd) 1951 { 1952 PWND pwnd; 1953 pwnd = ValidateHwnd(hWnd); 1954 if (!pwnd) 1955 return FALSE; 1956 return ((pwnd->state2 & WNDS2_INDESTROY) == WNDS2_INDESTROY); 1957 } 1958 1959 /* 1960 * @implemented 1961 */ 1962 VOID WINAPI 1963 DisableProcessWindowsGhosting(VOID) 1964 { 1965 NtUserxEnableProcessWindowGhosting(FALSE); 1966 } 1967 1968 /* EOF */ 1969 1970