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