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