Use max tracking size instead of maximized size to limit window size.
[reactos.git] / reactos / lib / user32 / windows / window.c
1 /* $Id$
2 *
3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS user32.dll
5 * FILE: lib/user32/windows/window.c
6 * PURPOSE: Window management
7 * PROGRAMMER: Casper S. Hornstrup (chorns@users.sourceforge.net)
8 * UPDATE HISTORY:
9 * 06-06-2001 CSH Created
10 */
11
12 /* INCLUDES ******************************************************************/
13
14 #include <user32.h>
15 #define NDEBUG
16 #include <debug.h>
17
18 BOOL ControlsInitialized = FALSE;
19
20 LRESULT DefWndNCPaint(HWND hWnd, HRGN hRgn, BOOL Active);
21
22 /* FUNCTIONS *****************************************************************/
23
24
25 NTSTATUS STDCALL
26 User32CallSendAsyncProcForKernel(PVOID Arguments, ULONG ArgumentLength)
27 {
28 PSENDASYNCPROC_CALLBACK_ARGUMENTS CallbackArgs;
29
30 DPRINT("User32CallSendAsyncProcKernel()\n");
31 CallbackArgs = (PSENDASYNCPROC_CALLBACK_ARGUMENTS)Arguments;
32 if (ArgumentLength != sizeof(WINDOWPROC_CALLBACK_ARGUMENTS))
33 {
34 return(STATUS_INFO_LENGTH_MISMATCH);
35 }
36 CallbackArgs->Callback(CallbackArgs->Wnd, CallbackArgs->Msg,
37 CallbackArgs->Context, CallbackArgs->Result);
38 return(STATUS_SUCCESS);
39 }
40
41
42 /*
43 * @unimplemented
44 */
45 BOOL STDCALL
46 AllowSetForegroundWindow(DWORD dwProcessId)
47 {
48 UNIMPLEMENTED;
49 return(FALSE);
50 }
51
52
53 /*
54 * @unimplemented
55 */
56 HDWP STDCALL
57 BeginDeferWindowPos(int nNumWindows)
58 {
59 #if 0
60 UNIMPLEMENTED;
61 return (HDWP)0;
62 #else
63 return (HDWP)1;
64 #endif
65 }
66
67
68 /*
69 * @implemented
70 */
71 BOOL STDCALL
72 BringWindowToTop(HWND hWnd)
73 {
74 return NtUserSetWindowPos( hWnd,
75 HWND_TOP,
76 0,
77 0,
78 0,
79 0,
80 SWP_NOSIZE | SWP_NOMOVE );
81 }
82
83
84 /*
85 * @unimplemented
86 */
87 /*
88 WORD STDCALL
89 CascadeWindows(HWND hwndParent,
90 UINT wHow,
91 CONST RECT *lpRect,
92 UINT cKids,
93 const HWND *lpKids)
94 {
95 UNIMPLEMENTED;
96 return 0;
97 }
98 */
99
100 VOID
101 STDCALL
102 SwitchToThisWindow ( HWND hwnd, BOOL fUnknown )
103 {
104 ShowWindow ( hwnd, SW_SHOW );
105 }
106
107 /*
108 * @implemented
109 */
110 HWND STDCALL
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 STDCALL
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 STDCALL
134 CloseWindow(HWND hWnd)
135 {
136 SendMessageA(hWnd, WM_SYSCOMMAND, SC_CLOSE, 0);
137
138 return (BOOL)(hWnd);
139 }
140
141 /*
142 * @implemented
143 */
144 HWND STDCALL
145 CreateWindowExA(DWORD dwExStyle,
146 LPCSTR lpClassName,
147 LPCSTR lpWindowName,
148 DWORD dwStyle,
149 int x,
150 int y,
151 int nWidth,
152 int nHeight,
153 HWND hWndParent,
154 HMENU hMenu,
155 HINSTANCE hInstance,
156 LPVOID lpParam)
157 {
158 UNICODE_STRING WindowName;
159 UNICODE_STRING ClassName;
160 WNDCLASSEXA wce;
161 HWND Handle;
162
163 #if 0
164 DbgPrint("[window] CreateWindowExA style %d, exstyle %d, parent %d\n", dwStyle, dwExStyle, hWndParent);
165 #endif
166
167 if (IS_ATOM(lpClassName))
168 {
169 RtlInitUnicodeString(&ClassName, NULL);
170 ClassName.Buffer = (LPWSTR)lpClassName;
171 }
172 else
173 {
174 if (!RtlCreateUnicodeStringFromAsciiz(&(ClassName), (PCSZ)lpClassName))
175 {
176 SetLastError(ERROR_OUTOFMEMORY);
177 return (HWND)0;
178 }
179 }
180
181 /* Register built-in controls if not already done */
182 if (! ControlsInitialized)
183 {
184 ControlsInitialized = ControlsInit(ClassName.Buffer);
185 }
186
187 if (dwExStyle & WS_EX_MDICHILD)
188 {
189 if (!IS_ATOM(lpClassName))
190 RtlFreeUnicodeString(&ClassName);
191 return CreateMDIWindowA(lpClassName, lpWindowName, dwStyle, x, y,
192 nWidth, nHeight, hWndParent, hInstance, (LPARAM)lpParam);
193 }
194
195 if (!RtlCreateUnicodeStringFromAsciiz(&WindowName, (PCSZ)lpWindowName))
196 {
197 if (!IS_ATOM(lpClassName))
198 {
199 RtlFreeUnicodeString(&ClassName);
200 }
201 SetLastError(ERROR_OUTOFMEMORY);
202 return (HWND)0;
203 }
204
205 if(!hMenu && (dwStyle & (WS_OVERLAPPEDWINDOW | WS_POPUP)))
206 {
207 wce.cbSize = sizeof(WNDCLASSEXA);
208 if(GetClassInfoExA(hInstance, lpClassName, &wce) && wce.lpszMenuName)
209 {
210 hMenu = LoadMenuA(hInstance, wce.lpszMenuName);
211 }
212 }
213
214 Handle = NtUserCreateWindowEx(dwExStyle,
215 &ClassName,
216 &WindowName,
217 dwStyle,
218 x,
219 y,
220 nWidth,
221 nHeight,
222 hWndParent,
223 hMenu,
224 hInstance,
225 lpParam,
226 SW_SHOW,
227 FALSE);
228
229 #if 0
230 DbgPrint("[window] NtUserCreateWindowEx() == %d\n", Handle);
231 #endif
232
233 RtlFreeUnicodeString(&WindowName);
234
235 if (!IS_ATOM(lpClassName))
236 {
237 RtlFreeUnicodeString(&ClassName);
238 }
239
240 return Handle;
241 }
242
243
244 /*
245 * @implemented
246 */
247 HWND STDCALL
248 CreateWindowExW(DWORD dwExStyle,
249 LPCWSTR lpClassName,
250 LPCWSTR lpWindowName,
251 DWORD dwStyle,
252 int x,
253 int y,
254 int nWidth,
255 int nHeight,
256 HWND hWndParent,
257 HMENU hMenu,
258 HINSTANCE hInstance,
259 LPVOID lpParam)
260 {
261 UNICODE_STRING WindowName;
262 UNICODE_STRING ClassName;
263 WNDCLASSEXW wce;
264 HANDLE Handle;
265
266 /* Register built-in controls if not already done */
267 if (! ControlsInitialized)
268 {
269 ControlsInitialized = ControlsInit(lpClassName);
270 }
271
272 if (dwExStyle & WS_EX_MDICHILD)
273 return CreateMDIWindowW(lpClassName, lpWindowName, dwStyle, x, y,
274 nWidth, nHeight, hWndParent, hInstance, (LPARAM)lpParam);
275
276 if (IS_ATOM(lpClassName))
277 {
278 RtlInitUnicodeString(&ClassName, NULL);
279 ClassName.Buffer = (LPWSTR)lpClassName;
280 }
281 else
282 {
283 RtlInitUnicodeString(&ClassName, lpClassName);
284 }
285
286 RtlInitUnicodeString(&WindowName, lpWindowName);
287
288 if(!hMenu && (dwStyle & (WS_OVERLAPPEDWINDOW | WS_POPUP)))
289 {
290 wce.cbSize = sizeof(WNDCLASSEXW);
291 if(GetClassInfoExW(hInstance, lpClassName, &wce) && wce.lpszMenuName)
292 {
293 hMenu = LoadMenuW(hInstance, wce.lpszMenuName);
294 }
295 }
296
297 Handle = NtUserCreateWindowEx(dwExStyle,
298 &ClassName,
299 &WindowName,
300 dwStyle,
301 x,
302 y,
303 nWidth,
304 nHeight,
305 hWndParent,
306 hMenu,
307 hInstance,
308 lpParam,
309 SW_SHOW,
310 TRUE);
311
312 return (HWND)Handle;
313 }
314
315
316 /*
317 * @unimplemented
318 */
319 HDWP STDCALL
320 DeferWindowPos(HDWP hWinPosInfo,
321 HWND hWnd,
322 HWND hWndInsertAfter,
323 int x,
324 int y,
325 int cx,
326 int cy,
327 UINT uFlags)
328 {
329 #if 0
330 return NtUserDeferWindowPos(hWinPosInfo, hWnd, hWndInsertAfter, x, y, cx, cy, uFlags);
331 #else
332 SetWindowPos(hWnd, hWndInsertAfter, x, y, cx, cy, uFlags);
333 return hWinPosInfo;
334 #endif
335 }
336
337
338 /*
339 * @implemented
340 */
341 BOOL STDCALL
342 DestroyWindow(HWND hWnd)
343 {
344 return NtUserDestroyWindow(hWnd);
345 }
346
347
348 /*
349 * @unimplemented
350 */
351 BOOL STDCALL
352 EndDeferWindowPos(HDWP hWinPosInfo)
353 {
354 #if 0
355 UNIMPLEMENTED;
356 return FALSE;
357 #else
358 return TRUE;
359 #endif
360 }
361
362
363 /*
364 * @implemented
365 */
366 HWND STDCALL
367 GetDesktopWindow(VOID)
368 {
369 return NtUserGetDesktopWindow();
370 }
371
372
373 /*
374 * @unimplemented
375 */
376 HWND STDCALL
377 GetForegroundWindow(VOID)
378 {
379 return NtUserGetForegroundWindow();
380 }
381
382
383 BOOL
384 STATIC
385 User32EnumWindows (
386 HDESK hDesktop,
387 HWND hWndparent,
388 WNDENUMPROC lpfn,
389 LPARAM lParam,
390 DWORD dwThreadId,
391 BOOL bChildren )
392 {
393 DWORD i, dwCount = 0;
394 HWND* pHwnd = NULL;
395 HANDLE hHeap;
396
397 if ( !lpfn )
398 {
399 SetLastError ( ERROR_INVALID_PARAMETER );
400 return FALSE;
401 }
402
403 /* FIXME instead of always making two calls, should we use some
404 sort of persistent buffer and only grow it ( requiring a 2nd
405 call ) when the buffer wasn't already big enough? */
406 /* first get how many window entries there are */
407 SetLastError(0);
408 dwCount = NtUserBuildHwndList (
409 hDesktop, hWndparent, bChildren, dwThreadId, lParam, NULL, 0 );
410 if ( !dwCount || GetLastError() )
411 return FALSE;
412
413 /* allocate buffer to receive HWND handles */
414 hHeap = GetProcessHeap();
415 pHwnd = HeapAlloc ( hHeap, 0, sizeof(HWND)*(dwCount+1) );
416 if ( !pHwnd )
417 {
418 SetLastError ( ERROR_NOT_ENOUGH_MEMORY );
419 return FALSE;
420 }
421
422 /* now call kernel again to fill the buffer this time */
423 dwCount = NtUserBuildHwndList (
424 hDesktop, hWndparent, bChildren, dwThreadId, lParam, pHwnd, dwCount );
425 if ( !dwCount || GetLastError() )
426 {
427 if ( pHwnd )
428 HeapFree ( hHeap, 0, pHwnd );
429 return FALSE;
430 }
431
432 /* call the user's callback function until we're done or
433 they tell us to quit */
434 for ( i = 0; i < dwCount; i++ )
435 {
436 /* FIXME I'm only getting NULLs from Thread Enumeration, and it's
437 * probably because I'm not doing it right in NtUserBuildHwndList.
438 * Once that's fixed, we shouldn't have to check for a NULL HWND
439 * here
440 */
441 if ( !(ULONG)pHwnd[i] ) /* don't enumerate a NULL HWND */
442 continue;
443 if ( !(*lpfn)( pHwnd[i], lParam ) )
444 {
445 HeapFree ( hHeap, 0, pHwnd );
446 return FALSE;
447 }
448 }
449 if ( pHwnd )
450 HeapFree ( hHeap, 0, pHwnd );
451 return TRUE;
452 }
453
454
455 /*
456 * @implemented
457 */
458 BOOL
459 STDCALL
460 EnumChildWindows(
461 HWND hWndParent,
462 WNDENUMPROC lpEnumFunc,
463 LPARAM lParam)
464 {
465 if ( !hWndParent )
466 hWndParent = GetDesktopWindow();
467 return User32EnumWindows ( NULL, hWndParent, lpEnumFunc, lParam, 0, FALSE );
468 }
469
470
471 /*
472 * @implemented
473 */
474 BOOL
475 STDCALL
476 EnumThreadWindows(DWORD dwThreadId,
477 WNDENUMPROC lpfn,
478 LPARAM lParam)
479 {
480 if ( !dwThreadId )
481 dwThreadId = GetCurrentThreadId();
482 return User32EnumWindows ( NULL, NULL, lpfn, lParam, dwThreadId, FALSE );
483 }
484
485
486 /*
487 * @implemented
488 */
489 BOOL STDCALL
490 EnumWindows(WNDENUMPROC lpEnumFunc,
491 LPARAM lParam)
492 {
493 return User32EnumWindows ( NULL, NULL, lpEnumFunc, lParam, 0, FALSE );
494 }
495
496
497 /*
498 * @implemented
499 */
500 BOOL
501 STDCALL
502 EnumDesktopWindows(
503 HDESK hDesktop,
504 WNDENUMPROC lpfn,
505 LPARAM lParam)
506 {
507 return User32EnumWindows ( hDesktop, NULL, lpfn, lParam, 0, FALSE );
508 }
509
510
511 /*
512 * @implemented
513 */
514 HWND STDCALL
515 FindWindowExA(HWND hwndParent,
516 HWND hwndChildAfter,
517 LPCSTR lpszClass,
518 LPCSTR lpszWindow)
519 {
520 UNICODE_STRING ucClassName;
521 UNICODE_STRING ucWindowName;
522 HWND Result;
523
524 if (lpszClass == NULL)
525 {
526 ucClassName.Buffer = NULL;
527 ucClassName.Length = 0;
528 }
529 else if (IS_ATOM(lpszClass))
530 {
531 ucClassName.Buffer = (LPWSTR)lpszClass;
532 ucClassName.Length = 0;
533 }
534 else
535 {
536 RtlCreateUnicodeStringFromAsciiz(&ucClassName, (LPSTR)lpszClass);
537 }
538
539 RtlCreateUnicodeStringFromAsciiz(&ucWindowName, (LPSTR)lpszWindow);
540
541 Result = NtUserFindWindowEx(hwndParent, hwndChildAfter, &ucClassName,
542 &ucWindowName);
543
544 if (!IS_ATOM(lpszClass))
545 RtlFreeUnicodeString(&ucClassName);
546 RtlFreeUnicodeString(&ucWindowName);
547
548 return Result;
549 }
550
551
552 /*
553 * @implemented
554 */
555 HWND STDCALL
556 FindWindowExW(HWND hwndParent,
557 HWND hwndChildAfter,
558 LPCWSTR lpszClass,
559 LPCWSTR lpszWindow)
560 {
561 UNICODE_STRING ucClassName;
562 UNICODE_STRING ucWindowName;
563
564 if (lpszClass == NULL)
565 {
566 ucClassName.Buffer = NULL;
567 ucClassName.Length = 0;
568 }
569 else if (IS_ATOM(lpszClass))
570 {
571 RtlInitUnicodeString(&ucClassName, NULL);
572 ucClassName.Buffer = (LPWSTR)lpszClass;
573 }
574 else
575 {
576 RtlInitUnicodeString(&ucClassName, lpszClass);
577 }
578
579 RtlInitUnicodeString(&ucWindowName, lpszWindow);
580
581 return NtUserFindWindowEx(hwndParent, hwndChildAfter, &ucClassName, &ucWindowName);
582 }
583
584
585 /*
586 * @implemented
587 */
588 HWND STDCALL
589 FindWindowA(LPCSTR lpClassName, LPCSTR lpWindowName)
590 {
591 //FIXME: FindWindow does not search children, but FindWindowEx does.
592 // what should we do about this?
593 return FindWindowExA (NULL, NULL, lpClassName, lpWindowName);
594 }
595
596
597 /*
598 * @implemented
599 */
600 HWND STDCALL
601 FindWindowW(LPCWSTR lpClassName, LPCWSTR lpWindowName)
602 {
603 /*
604
605 There was a FIXME here earlier, but I think it is just a documentation unclarity.
606
607 FindWindow only searches top level windows. What they mean is that child
608 windows of other windows than the desktop can be searched.
609 FindWindowExW never does a recursive search.
610
611 / Joakim
612 */
613
614 return FindWindowExW (NULL, NULL, lpClassName, lpWindowName);
615 }
616
617
618
619 /*
620 * @unimplemented
621 */
622 BOOL STDCALL
623 GetAltTabInfoA(HWND hwnd,
624 int iItem,
625 PALTTABINFO pati,
626 LPSTR pszItemText,
627 UINT cchItemText)
628 {
629 UNIMPLEMENTED;
630 return FALSE;
631 }
632
633
634 /*
635 * @unimplemented
636 */
637 BOOL STDCALL
638 GetAltTabInfoW(HWND hwnd,
639 int iItem,
640 PALTTABINFO pati,
641 LPWSTR pszItemText,
642 UINT cchItemText)
643 {
644 UNIMPLEMENTED;
645 return FALSE;
646 }
647
648
649 /*
650 * @implemented
651 */
652 HWND STDCALL
653 GetAncestor(HWND hwnd, UINT gaFlags)
654 {
655 return(NtUserGetAncestor(hwnd, gaFlags));
656 }
657
658
659 /*
660 * @implemented
661 */
662 BOOL STDCALL
663 GetClientRect(HWND hWnd, LPRECT lpRect)
664 {
665 return(NtUserGetClientRect(hWnd, lpRect));
666 }
667
668
669 /*
670 * @implemented
671 */
672 BOOL STDCALL
673 GetGUIThreadInfo(DWORD idThread,
674 LPGUITHREADINFO lpgui)
675 {
676 return (BOOL)NtUserGetGUIThreadInfo(idThread, lpgui);
677 }
678
679
680 /*
681 * @unimplemented
682 */
683 HWND STDCALL
684 GetLastActivePopup(HWND hWnd)
685 {
686 return NtUserGetLastActivePopup(hWnd);
687 }
688
689
690 /*
691 * @implemented
692 */
693 HWND STDCALL
694 GetParent(HWND hWnd)
695 {
696 return NtUserGetParent(hWnd);
697 }
698
699
700 /*
701 * @unimplemented
702 */
703 BOOL STDCALL
704 GetProcessDefaultLayout(DWORD *pdwDefaultLayout)
705 {
706 UNIMPLEMENTED;
707 return FALSE;
708 }
709
710
711 /*
712 * @unimplemented
713 */
714 BOOL STDCALL
715 GetTitleBarInfo(HWND hwnd,
716 PTITLEBARINFO pti)
717 {
718 UNIMPLEMENTED;
719 return FALSE;
720 }
721
722
723 /*
724 * @implemented
725 */
726 HWND STDCALL
727 GetWindow(HWND hWnd,
728 UINT uCmd)
729 {
730 return NtUserGetWindow(hWnd, uCmd);
731 }
732
733
734 /*
735 * @implemented
736 */
737 HWND STDCALL
738 GetTopWindow(HWND hWnd)
739 {
740 if (!hWnd) hWnd = GetDesktopWindow();
741 return GetWindow( hWnd, GW_CHILD );
742 }
743
744
745 /*
746 * @implemented
747 */
748 BOOL STDCALL
749 GetWindowInfo(HWND hwnd,
750 PWINDOWINFO pwi)
751 {
752 return NtUserGetWindowInfo(hwnd, pwi);
753 }
754
755
756 /*
757 * @implemented
758 */
759 UINT STDCALL
760 GetWindowModuleFileNameA(HWND hwnd,
761 LPSTR lpszFileName,
762 UINT cchFileNameMax)
763 {
764 HINSTANCE hWndInst;
765
766 if(!(hWndInst = NtUserGetWindowInstance(hwnd)))
767 {
768 return 0;
769 }
770
771 return GetModuleFileNameA(hWndInst, lpszFileName, cchFileNameMax);
772 }
773
774
775 /*
776 * @implemented
777 */
778 UINT STDCALL
779 GetWindowModuleFileNameW(HWND hwnd,
780 LPWSTR lpszFileName,
781 UINT cchFileNameMax)
782 {
783 HINSTANCE hWndInst;
784
785 if(!(hWndInst = NtUserGetWindowInstance(hwnd)))
786 {
787 return 0;
788 }
789
790 return GetModuleFileNameW(hWndInst, lpszFileName, cchFileNameMax);
791 }
792
793
794 /*
795 * @implemented
796 */
797 BOOL STDCALL
798 GetWindowPlacement(HWND hWnd,
799 WINDOWPLACEMENT *lpwndpl)
800 {
801 return (BOOL)NtUserGetWindowPlacement(hWnd, lpwndpl);
802 }
803
804
805 /*
806 * @implemented
807 */
808 BOOL STDCALL
809 GetWindowRect(HWND hWnd,
810 LPRECT lpRect)
811 {
812 return(NtUserGetWindowRect(hWnd, lpRect));
813 }
814
815
816 /*
817 * @implemented
818 */
819 int STDCALL
820 GetWindowTextA(HWND hWnd, LPSTR lpString, int nMaxCount)
821 {
822 DWORD ProcessId;
823 if(!NtUserGetWindowThreadProcessId(hWnd, &ProcessId))
824 {
825 return 0;
826 }
827
828 if(ProcessId != GetCurrentProcessId())
829 {
830 /* do not send WM_GETTEXT messages to other processes */
831 LPWSTR Buffer;
832 INT Length;
833
834 if (nMaxCount > 1)
835 {
836 *((PWSTR)lpString) = '\0';
837 }
838 Buffer = HeapAlloc(GetProcessHeap(), 0, nMaxCount * sizeof(WCHAR));
839 if (!Buffer)
840 return FALSE;
841 Length = NtUserInternalGetWindowText(hWnd, Buffer, nMaxCount);
842 if (Length > 0 && nMaxCount > 0 &&
843 !WideCharToMultiByte(CP_ACP, 0, Buffer, -1,
844 lpString, nMaxCount, NULL, NULL))
845 {
846 lpString[0] = '\0';
847 }
848
849 HeapFree(GetProcessHeap(), 0, Buffer);
850
851 return (LRESULT)Length;
852 }
853
854 return(SendMessageA(hWnd, WM_GETTEXT, nMaxCount, (LPARAM)lpString));
855 }
856
857
858 /*
859 * @implemented
860 */
861 int STDCALL
862 GetWindowTextLengthA(HWND hWnd)
863 {
864 DWORD ProcessId;
865 if(!NtUserGetWindowThreadProcessId(hWnd, &ProcessId))
866 {
867 return 0;
868 }
869
870 if(ProcessId == GetCurrentProcessId())
871 {
872 return(SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0));
873 }
874
875 /* do not send WM_GETTEXT messages to other processes */
876 return (LRESULT)NtUserInternalGetWindowText(hWnd, NULL, 0);
877 }
878
879
880 /*
881 * @implemented
882 */
883 int STDCALL
884 GetWindowTextLengthW(HWND hWnd)
885 {
886 DWORD ProcessId;
887 if(!NtUserGetWindowThreadProcessId(hWnd, &ProcessId))
888 {
889 return 0;
890 }
891
892 if(ProcessId == GetCurrentProcessId())
893 {
894 return(SendMessageW(hWnd, WM_GETTEXTLENGTH, 0, 0));
895 }
896
897 /* do not send WM_GETTEXT messages to other processes */
898 return (LRESULT)NtUserInternalGetWindowText(hWnd, NULL, 0);
899 }
900
901
902 /*
903 * @implemented
904 */
905 int STDCALL
906 GetWindowTextW(
907 HWND hWnd,
908 LPWSTR lpString,
909 int nMaxCount)
910 {
911 DWORD ProcessId;
912 if(!NtUserGetWindowThreadProcessId(hWnd, &ProcessId))
913 {
914 return 0;
915 }
916
917 if(ProcessId == GetCurrentProcessId())
918 {
919 return(SendMessageW(hWnd, WM_GETTEXT, nMaxCount, (LPARAM)lpString));
920 }
921
922 /* do not send WM_GETTEXT messages to other processes */
923 if (nMaxCount > 1)
924 {
925 *((PWSTR)lpString) = L'\0';
926 }
927
928 return (LRESULT)NtUserInternalGetWindowText(hWnd, (PWSTR)lpString, nMaxCount);
929 }
930
931 DWORD STDCALL
932 GetWindowThreadProcessId(HWND hWnd,
933 LPDWORD lpdwProcessId)
934 {
935 return NtUserGetWindowThreadProcessId(hWnd, lpdwProcessId);
936 }
937
938
939 /*
940 * @implemented
941 */
942 BOOL STDCALL
943 IsChild(HWND hWndParent,
944 HWND hWnd)
945 {
946 if (! IsWindow(hWndParent) || ! IsWindow(hWnd))
947 {
948 return FALSE;
949 }
950
951 do
952 {
953 hWnd = (HWND)NtUserGetWindowLong(hWnd, GWL_HWNDPARENT, FALSE);
954 }
955 while (hWnd != NULL && hWnd != hWndParent);
956
957 return hWnd == hWndParent;
958 }
959
960
961 /*
962 * @implemented
963 */
964 BOOL STDCALL
965 IsIconic(HWND hWnd)
966 {
967 return (NtUserGetWindowLong( hWnd, GWL_STYLE, FALSE) & WS_MINIMIZE) != 0;
968 }
969
970
971 /*
972 * @implemented
973 */
974 BOOL STDCALL
975 IsWindow(HWND hWnd)
976 {
977 DWORD WndProc = NtUserGetWindowLong(hWnd, GWL_WNDPROC, FALSE);
978 return (0 != WndProc || ERROR_INVALID_WINDOW_HANDLE != GetLastError());
979 }
980
981
982 /*
983 * @implemented
984 */
985 BOOL STDCALL
986 IsWindowUnicode(HWND hWnd)
987 {
988 return NtUserIsWindowUnicode(hWnd);
989 }
990
991
992 /*
993 * @implemented
994 */
995 BOOL STDCALL
996 IsWindowVisible(HWND hWnd)
997 {
998 while (NtUserGetWindowLong(hWnd, GWL_STYLE, FALSE) & WS_CHILD)
999 {
1000 if (!(NtUserGetWindowLong(hWnd, GWL_STYLE, FALSE) & WS_VISIBLE))
1001 {
1002 return(FALSE);
1003 }
1004 hWnd = GetAncestor(hWnd, GA_PARENT);
1005 }
1006 return(NtUserGetWindowLong(hWnd, GWL_STYLE, FALSE) & WS_VISIBLE);
1007 }
1008
1009
1010 /*
1011 * @implemented
1012 */
1013 BOOL
1014 STDCALL
1015 IsWindowEnabled(
1016 HWND hWnd)
1017 {
1018 // AG: I don't know if child windows are affected if the parent is
1019 // disabled. I think they stop processing messages but stay appearing
1020 // as enabled.
1021
1022 return (! (NtUserGetWindowLong(hWnd, GWL_STYLE, FALSE) & WS_DISABLED));
1023 }
1024
1025
1026 /*
1027 * @implemented
1028 */
1029 BOOL STDCALL
1030 IsZoomed(HWND hWnd)
1031 {
1032 return NtUserGetWindowLong(hWnd, GWL_STYLE, FALSE) & WS_MAXIMIZE;
1033 }
1034
1035
1036 /*
1037 * @unimplemented
1038 */
1039 BOOL STDCALL
1040 LockSetForegroundWindow(UINT uLockCode)
1041 {
1042 UNIMPLEMENTED;
1043 return FALSE;
1044 }
1045
1046
1047 /*
1048 * @implemented
1049 */
1050 BOOL STDCALL
1051 MoveWindow(HWND hWnd,
1052 int X,
1053 int Y,
1054 int nWidth,
1055 int nHeight,
1056 BOOL bRepaint)
1057 {
1058 return NtUserMoveWindow(hWnd, X, Y, nWidth, nHeight, bRepaint);
1059 }
1060
1061
1062 /*
1063 * @implemented
1064 */
1065 BOOL STDCALL
1066 AnimateWindow(HWND hwnd,
1067 DWORD dwTime,
1068 DWORD dwFlags)
1069 {
1070 /* FIXME Add animation code */
1071
1072 /* If trying to show/hide and it's already *
1073 * shown/hidden or invalid window, fail with *
1074 * invalid parameter */
1075
1076 BOOL visible;
1077 visible = IsWindowVisible(hwnd);
1078 if(!IsWindow(hwnd) ||
1079 (visible && !(dwFlags & AW_HIDE)) ||
1080 (!visible && (dwFlags & AW_HIDE)))
1081 {
1082 SetLastError(ERROR_INVALID_PARAMETER);
1083 return FALSE;
1084 }
1085
1086 ShowWindow(hwnd, (dwFlags & AW_HIDE) ? SW_HIDE : ((dwFlags & AW_ACTIVATE) ? SW_SHOW : SW_SHOWNA));
1087
1088 return TRUE;
1089 }
1090
1091
1092 /*
1093 * @implemented
1094 */
1095 BOOL STDCALL
1096 OpenIcon(HWND hWnd)
1097 {
1098 if (!(NtUserGetWindowLong(hWnd, GWL_STYLE, FALSE) & WS_MINIMIZE))
1099 {
1100 return FALSE;
1101 }
1102
1103 ShowWindow(hWnd,SW_RESTORE);
1104 return TRUE;
1105 }
1106
1107
1108 /*
1109 * @unimplemented
1110 */
1111 HWND STDCALL
1112 RealChildWindowFromPoint(HWND hwndParent,
1113 POINT ptParentClientCoords)
1114 {
1115 UNIMPLEMENTED;
1116 return (HWND)0;
1117 }
1118
1119 /*
1120 * @unimplemented
1121 */
1122 BOOL STDCALL
1123 SetForegroundWindow(HWND hWnd)
1124 {
1125 return NtUserCallHwndLock(hWnd, HWNDLOCK_ROUTINE_SETFOREGROUNDWINDOW);
1126 }
1127
1128
1129 /*
1130 * @unimplemented
1131 */
1132 BOOL STDCALL
1133 SetLayeredWindowAttributes(HWND hwnd,
1134 COLORREF crKey,
1135 BYTE bAlpha,
1136 DWORD dwFlags)
1137 {
1138 UNIMPLEMENTED;
1139 return FALSE;
1140 }
1141
1142
1143 /*
1144 * @implemented
1145 */
1146 HWND STDCALL
1147 SetParent(HWND hWndChild,
1148 HWND hWndNewParent)
1149 {
1150 return NtUserSetParent(hWndChild, hWndNewParent);
1151 }
1152
1153
1154 /*
1155 * @unimplemented
1156 */
1157 BOOL STDCALL
1158 SetProcessDefaultLayout(DWORD dwDefaultLayout)
1159 {
1160 UNIMPLEMENTED;
1161 return FALSE;
1162 }
1163
1164
1165 /*
1166 * @unimplemented
1167 */
1168 BOOL STDCALL
1169 SetWindowPlacement(HWND hWnd,
1170 CONST WINDOWPLACEMENT *lpwndpl)
1171 {
1172 return (BOOL)NtUserSetWindowPlacement(hWnd, (WINDOWPLACEMENT *)lpwndpl);
1173 }
1174
1175
1176 /*
1177 * @implemented
1178 */
1179 BOOL STDCALL
1180 SetWindowPos(HWND hWnd,
1181 HWND hWndInsertAfter,
1182 int X,
1183 int Y,
1184 int cx,
1185 int cy,
1186 UINT uFlags)
1187 {
1188 return NtUserSetWindowPos(hWnd,hWndInsertAfter, X, Y, cx, cy, uFlags);
1189 }
1190
1191
1192 /*
1193 * @implemented
1194 */
1195 BOOL STDCALL
1196 SetWindowTextA(HWND hWnd,
1197 LPCSTR lpString)
1198 {
1199 DWORD ProcessId;
1200 if(!NtUserGetWindowThreadProcessId(hWnd, &ProcessId))
1201 {
1202 return FALSE;
1203 }
1204
1205 if(ProcessId != GetCurrentProcessId())
1206 {
1207 /* do not send WM_GETTEXT messages to other processes */
1208 ANSI_STRING AnsiString;
1209 UNICODE_STRING UnicodeString;
1210
1211 if(lpString)
1212 {
1213 RtlInitAnsiString(&AnsiString, (LPSTR)lpString);
1214 RtlAnsiStringToUnicodeString(&UnicodeString, &AnsiString, TRUE);
1215 NtUserDefSetText(hWnd, &UnicodeString);
1216 RtlFreeUnicodeString(&UnicodeString);
1217 }
1218 else
1219 NtUserDefSetText(hWnd, NULL);
1220
1221 if ((GetWindowLongW(hWnd, GWL_STYLE) & WS_CAPTION) == WS_CAPTION)
1222 {
1223 DefWndNCPaint(hWnd, (HRGN)1, -1);
1224 }
1225 return TRUE;
1226 }
1227
1228 return SendMessageA(hWnd, WM_SETTEXT, 0, (LPARAM)lpString);
1229 }
1230
1231
1232 /*
1233 * @implemented
1234 */
1235 BOOL STDCALL
1236 SetWindowTextW(HWND hWnd,
1237 LPCWSTR lpString)
1238 {
1239 DWORD ProcessId;
1240 if(!NtUserGetWindowThreadProcessId(hWnd, &ProcessId))
1241 {
1242 return FALSE;
1243 }
1244
1245 if(ProcessId != GetCurrentProcessId())
1246 {
1247 /* do not send WM_GETTEXT messages to other processes */
1248 UNICODE_STRING UnicodeString;
1249
1250 if(lpString)
1251 RtlInitUnicodeString(&UnicodeString, (LPWSTR)lpString);
1252
1253 NtUserDefSetText(hWnd, (lpString ? &UnicodeString : NULL));
1254
1255 if ((GetWindowLongW(hWnd, GWL_STYLE) & WS_CAPTION) == WS_CAPTION)
1256 {
1257 DefWndNCPaint(hWnd, (HRGN)1, -1);
1258 }
1259 return TRUE;
1260 }
1261
1262 return SendMessageW(hWnd, WM_SETTEXT, 0, (LPARAM)lpString);
1263 }
1264
1265
1266 /*
1267 * @implemented
1268 */
1269 BOOL STDCALL
1270 ShowOwnedPopups(HWND hWnd,
1271 BOOL fShow)
1272 {
1273 return (BOOL)NtUserCallTwoParam((DWORD)hWnd, fShow, TWOPARAM_ROUTINE_SHOWOWNEDPOPUPS);
1274 }
1275
1276
1277 /*
1278 * @implemented
1279 */
1280 BOOL STDCALL
1281 ShowWindow(HWND hWnd,
1282 int nCmdShow)
1283 {
1284 return NtUserShowWindow(hWnd, nCmdShow);
1285 }
1286
1287
1288 /*
1289 * @unimplemented
1290 */
1291 BOOL STDCALL
1292 ShowWindowAsync(HWND hWnd,
1293 int nCmdShow)
1294 {
1295 UNIMPLEMENTED;
1296 return FALSE;
1297 }
1298
1299
1300 /*
1301 * @unimplemented
1302 */
1303 /*
1304 WORD STDCALL
1305 TileWindows(HWND hwndParent,
1306 UINT wHow,
1307 CONST RECT *lpRect,
1308 UINT cKids,
1309 const HWND *lpKids)
1310 {
1311 UNIMPLEMENTED;
1312 return 0;
1313 }
1314 */
1315
1316
1317 /*
1318 * @unimplemented
1319 */
1320 BOOL STDCALL
1321 UpdateLayeredWindow(HWND hwnd,
1322 HDC hdcDst,
1323 POINT *pptDst,
1324 SIZE *psize,
1325 HDC hdcSrc,
1326 POINT *pptSrc,
1327 COLORREF crKey,
1328 BLENDFUNCTION *pblend,
1329 DWORD dwFlags)
1330 {
1331 UNIMPLEMENTED;
1332 return FALSE;
1333 }
1334
1335
1336 /*
1337 * @implemented
1338 */
1339 HWND STDCALL
1340 WindowFromPoint(POINT Point)
1341 {
1342 //TODO: Determine what the actual parameters to
1343 // NtUserWindowFromPoint are.
1344 return NtUserWindowFromPoint(Point.x, Point.y);
1345 }
1346
1347
1348 /*
1349 * @implemented
1350 */
1351 int STDCALL
1352 MapWindowPoints(HWND hWndFrom, HWND hWndTo, LPPOINT lpPoints, UINT cPoints)
1353 {
1354 POINT FromOffset, ToOffset;
1355 LONG XMove, YMove;
1356 ULONG i;
1357
1358 if (hWndFrom == NULL)
1359 {
1360 FromOffset.x = FromOffset.y = 0;
1361 } else
1362 if(!NtUserGetClientOrigin(hWndFrom, &FromOffset))
1363 {
1364 return 0;
1365 }
1366
1367 if (hWndTo == NULL)
1368 {
1369 ToOffset.x = ToOffset.y = 0;
1370 } else
1371 if(!NtUserGetClientOrigin(hWndTo, &ToOffset))
1372 {
1373 return 0;
1374 }
1375 XMove = FromOffset.x - ToOffset.x;
1376 YMove = FromOffset.y - ToOffset.y;
1377
1378 for (i = 0; i < cPoints; i++)
1379 {
1380 lpPoints[i].x += XMove;
1381 lpPoints[i].y += YMove;
1382 }
1383 return(MAKELONG(LOWORD(XMove), LOWORD(YMove)));
1384 }
1385
1386
1387 /*
1388 * @implemented
1389 */
1390 BOOL STDCALL
1391 ScreenToClient(HWND hWnd, LPPOINT lpPoint)
1392 {
1393 return(MapWindowPoints(NULL, hWnd, lpPoint, 1) != 0);
1394 }
1395
1396
1397 /*
1398 * @implemented
1399 */
1400 BOOL STDCALL
1401 ClientToScreen(HWND hWnd, LPPOINT lpPoint)
1402 {
1403 return (MapWindowPoints( hWnd, NULL, lpPoint, 1 ) != 0);
1404 }
1405
1406
1407 /*
1408 * @implemented
1409 */
1410 BOOL
1411 STDCALL
1412 SetWindowContextHelpId(HWND hwnd,
1413 DWORD dwContextHelpId)
1414 {
1415 return NtUserSetWindowContextHelpId(hwnd, dwContextHelpId);
1416 }
1417
1418
1419 /*
1420 * @implemented
1421 */
1422 DWORD
1423 STDCALL
1424 GetWindowContextHelpId(HWND hwnd)
1425 {
1426 return NtUserGetWindowContextHelpId(hwnd);
1427 }
1428
1429 /*
1430 * @implemented
1431 */
1432 int
1433 STDCALL
1434 InternalGetWindowText(HWND hWnd, LPWSTR lpString, int nMaxCount)
1435 {
1436 return NtUserInternalGetWindowText(hWnd, lpString, nMaxCount);
1437 }
1438
1439 /*
1440 * @implemented
1441 */
1442 BOOL
1443 STDCALL
1444 IsHungAppWindow(HWND hwnd)
1445 {
1446 return (NtUserQueryWindow(hwnd, QUERY_WINDOW_ISHUNG) != 0);
1447 }
1448
1449 /*
1450 * @implemented
1451 */
1452 VOID
1453 STDCALL
1454 SetLastErrorEx(DWORD dwErrCode, DWORD dwType)
1455 {
1456 SetLastError(dwErrCode);
1457 }
1458
1459 /*
1460 * @implemented
1461 */
1462 HWND
1463 STDCALL
1464 GetFocus(VOID)
1465 {
1466 return (HWND)NtUserGetThreadState(0);
1467 }
1468
1469 /*
1470 * @implemented
1471 */
1472 HWND
1473 STDCALL
1474 SetTaskmanWindow(HWND hWnd)
1475 {
1476 return NtUserCallHwndOpt(hWnd, HWNDOPT_ROUTINE_SETTASKMANWINDOW);
1477 }
1478
1479 /*
1480 * @implemented
1481 */
1482 HWND
1483 STDCALL
1484 SetProgmanWindow(HWND hWnd)
1485 {
1486 return NtUserCallHwndOpt(hWnd, HWNDOPT_ROUTINE_SETTASKMANWINDOW);
1487 }
1488
1489 /*
1490 * @unimplemented
1491 */
1492 HWND
1493 STDCALL
1494 GetProgmanWindow(VOID)
1495 {
1496 UNIMPLEMENTED;
1497 return FALSE;
1498 }
1499
1500 /*
1501 * @unimplemented
1502 */
1503 HWND
1504 STDCALL
1505 GetTaskmanWindow(VOID)
1506 {
1507 UNIMPLEMENTED;
1508 return FALSE;
1509 }
1510
1511 /*
1512 * @implemented
1513 */
1514 BOOL STDCALL
1515 ScrollWindow(HWND hWnd, int dx, int dy, CONST RECT *lpRect,
1516 CONST RECT *prcClip)
1517 {
1518 return NtUserScrollWindowEx(hWnd, dx, dy, lpRect, prcClip, 0, NULL,
1519 (lpRect ? 0 : SW_SCROLLCHILDREN) | SW_INVALIDATE) != ERROR;
1520 }
1521
1522
1523 /*
1524 * @implemented
1525 */
1526 INT STDCALL
1527 ScrollWindowEx(HWND hWnd, int dx, int dy, CONST RECT *prcScroll,
1528 CONST RECT *prcClip, HRGN hrgnUpdate, LPRECT prcUpdate, UINT flags)
1529 {
1530 return NtUserScrollWindowEx(hWnd, dx, dy, prcScroll, prcClip, hrgnUpdate,
1531 prcUpdate, flags);
1532 }
1533
1534 /*
1535 * @implemented
1536 */
1537 BOOL
1538 STDCALL
1539 AnyPopup(VOID)
1540 {
1541 return NtUserAnyPopup();
1542 }
1543
1544 /*
1545 * @implemented
1546 */
1547 BOOL
1548 STDCALL
1549 IsWindowInDestroy(HWND hWnd)
1550 {
1551 return NtUserIsWindowInDestroy(hWnd);
1552 }
1553
1554 /*
1555 * @implemented
1556 */
1557 VOID
1558 STDCALL
1559 DisableProcessWindowsGhosting(VOID)
1560 {
1561 NtUserEnableProcessWindowGhosting(FALSE);
1562 }
1563
1564 /* EOF */
1565