c95b8dfbcc6f38b6dd4229265aff9a69d7d5e1d6
[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 * 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