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