-include/ndk/rtltypes.h: add MAX_ATOM_LEN define
[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
824 if (lpString == NULL)
825 return 0;
826
827 if (!NtUserGetWindowThreadProcessId(hWnd, &ProcessId))
828 return 0;
829
830 if (ProcessId != GetCurrentProcessId())
831 {
832 /* do not send WM_GETTEXT messages to other processes */
833 LPWSTR Buffer;
834 INT Length;
835
836 Buffer = HeapAlloc(GetProcessHeap(), 0, nMaxCount * sizeof(WCHAR));
837 if (!Buffer)
838 return FALSE;
839 Length = NtUserInternalGetWindowText(hWnd, Buffer, nMaxCount);
840 if (Length > 0 && nMaxCount > 0 &&
841 !WideCharToMultiByte(CP_ACP, 0, Buffer, -1,
842 lpString, nMaxCount, NULL, NULL))
843 {
844 lpString[0] = '\0';
845 }
846 HeapFree(GetProcessHeap(), 0, Buffer);
847
848 return (LRESULT)Length;
849 }
850
851 return SendMessageA(hWnd, WM_GETTEXT, nMaxCount, (LPARAM)lpString);
852 }
853
854
855 /*
856 * @implemented
857 */
858 int STDCALL
859 GetWindowTextLengthA(HWND hWnd)
860 {
861 DWORD ProcessId;
862 if(!NtUserGetWindowThreadProcessId(hWnd, &ProcessId))
863 {
864 return 0;
865 }
866
867 if(ProcessId == GetCurrentProcessId())
868 {
869 return(SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0));
870 }
871
872 /* do not send WM_GETTEXT messages to other processes */
873 return (LRESULT)NtUserInternalGetWindowText(hWnd, NULL, 0);
874 }
875
876
877 /*
878 * @implemented
879 */
880 int STDCALL
881 GetWindowTextLengthW(HWND hWnd)
882 {
883 DWORD ProcessId;
884 if(!NtUserGetWindowThreadProcessId(hWnd, &ProcessId))
885 {
886 return 0;
887 }
888
889 if(ProcessId == GetCurrentProcessId())
890 {
891 return(SendMessageW(hWnd, WM_GETTEXTLENGTH, 0, 0));
892 }
893
894 /* do not send WM_GETTEXT messages to other processes */
895 return (LRESULT)NtUserInternalGetWindowText(hWnd, NULL, 0);
896 }
897
898
899 /*
900 * @implemented
901 */
902 int STDCALL
903 GetWindowTextW(HWND hWnd, LPWSTR lpString, int nMaxCount)
904 {
905 DWORD ProcessId;
906
907 if (lpString == NULL)
908 return 0;
909
910 if (!NtUserGetWindowThreadProcessId(hWnd, &ProcessId))
911 return 0;
912
913 if (ProcessId == GetCurrentProcessId())
914 return SendMessageW(hWnd, WM_GETTEXT, nMaxCount, (LPARAM)lpString);
915
916 return NtUserInternalGetWindowText(hWnd, lpString, nMaxCount);
917 }
918
919 DWORD STDCALL
920 GetWindowThreadProcessId(HWND hWnd,
921 LPDWORD lpdwProcessId)
922 {
923 return NtUserGetWindowThreadProcessId(hWnd, lpdwProcessId);
924 }
925
926
927 /*
928 * @implemented
929 */
930 BOOL STDCALL
931 IsChild(HWND hWndParent,
932 HWND hWnd)
933 {
934 if (! IsWindow(hWndParent) || ! IsWindow(hWnd))
935 {
936 return FALSE;
937 }
938
939 do
940 {
941 hWnd = (HWND)NtUserGetWindowLong(hWnd, GWL_HWNDPARENT, FALSE);
942 }
943 while (hWnd != NULL && hWnd != hWndParent);
944
945 return hWnd == hWndParent;
946 }
947
948
949 /*
950 * @implemented
951 */
952 BOOL STDCALL
953 IsIconic(HWND hWnd)
954 {
955 return (NtUserGetWindowLong( hWnd, GWL_STYLE, FALSE) & WS_MINIMIZE) != 0;
956 }
957
958
959 /*
960 * @implemented
961 */
962 BOOL STDCALL
963 IsWindow(HWND hWnd)
964 {
965 DWORD WndProc = NtUserGetWindowLong(hWnd, GWL_WNDPROC, FALSE);
966 return (0 != WndProc || ERROR_INVALID_WINDOW_HANDLE != GetLastError());
967 }
968
969
970 /*
971 * @implemented
972 */
973 BOOL STDCALL
974 IsWindowUnicode(HWND hWnd)
975 {
976 return NtUserIsWindowUnicode(hWnd);
977 }
978
979
980 /*
981 * @implemented
982 */
983 BOOL STDCALL
984 IsWindowVisible(HWND hWnd)
985 {
986 while (NtUserGetWindowLong(hWnd, GWL_STYLE, FALSE) & WS_CHILD)
987 {
988 if (!(NtUserGetWindowLong(hWnd, GWL_STYLE, FALSE) & WS_VISIBLE))
989 {
990 return(FALSE);
991 }
992 hWnd = GetAncestor(hWnd, GA_PARENT);
993 }
994 return(NtUserGetWindowLong(hWnd, GWL_STYLE, FALSE) & WS_VISIBLE);
995 }
996
997
998 /*
999 * @implemented
1000 */
1001 BOOL
1002 STDCALL
1003 IsWindowEnabled(
1004 HWND hWnd)
1005 {
1006 // AG: I don't know if child windows are affected if the parent is
1007 // disabled. I think they stop processing messages but stay appearing
1008 // as enabled.
1009
1010 return (! (NtUserGetWindowLong(hWnd, GWL_STYLE, FALSE) & WS_DISABLED));
1011 }
1012
1013
1014 /*
1015 * @implemented
1016 */
1017 BOOL STDCALL
1018 IsZoomed(HWND hWnd)
1019 {
1020 return NtUserGetWindowLong(hWnd, GWL_STYLE, FALSE) & WS_MAXIMIZE;
1021 }
1022
1023
1024 /*
1025 * @unimplemented
1026 */
1027 BOOL STDCALL
1028 LockSetForegroundWindow(UINT uLockCode)
1029 {
1030 UNIMPLEMENTED;
1031 return FALSE;
1032 }
1033
1034
1035 /*
1036 * @implemented
1037 */
1038 BOOL STDCALL
1039 MoveWindow(HWND hWnd,
1040 int X,
1041 int Y,
1042 int nWidth,
1043 int nHeight,
1044 BOOL bRepaint)
1045 {
1046 return NtUserMoveWindow(hWnd, X, Y, nWidth, nHeight, bRepaint);
1047 }
1048
1049
1050 /*
1051 * @implemented
1052 */
1053 BOOL STDCALL
1054 AnimateWindow(HWND hwnd,
1055 DWORD dwTime,
1056 DWORD dwFlags)
1057 {
1058 /* FIXME Add animation code */
1059
1060 /* If trying to show/hide and it's already *
1061 * shown/hidden or invalid window, fail with *
1062 * invalid parameter */
1063
1064 BOOL visible;
1065 visible = IsWindowVisible(hwnd);
1066 if(!IsWindow(hwnd) ||
1067 (visible && !(dwFlags & AW_HIDE)) ||
1068 (!visible && (dwFlags & AW_HIDE)))
1069 {
1070 SetLastError(ERROR_INVALID_PARAMETER);
1071 return FALSE;
1072 }
1073
1074 ShowWindow(hwnd, (dwFlags & AW_HIDE) ? SW_HIDE : ((dwFlags & AW_ACTIVATE) ? SW_SHOW : SW_SHOWNA));
1075
1076 return TRUE;
1077 }
1078
1079
1080 /*
1081 * @implemented
1082 */
1083 BOOL STDCALL
1084 OpenIcon(HWND hWnd)
1085 {
1086 if (!(NtUserGetWindowLong(hWnd, GWL_STYLE, FALSE) & WS_MINIMIZE))
1087 {
1088 return FALSE;
1089 }
1090
1091 ShowWindow(hWnd,SW_RESTORE);
1092 return TRUE;
1093 }
1094
1095
1096 /*
1097 * @unimplemented
1098 */
1099 HWND STDCALL
1100 RealChildWindowFromPoint(HWND hwndParent,
1101 POINT ptParentClientCoords)
1102 {
1103 UNIMPLEMENTED;
1104 return (HWND)0;
1105 }
1106
1107 /*
1108 * @unimplemented
1109 */
1110 BOOL STDCALL
1111 SetForegroundWindow(HWND hWnd)
1112 {
1113 return NtUserCallHwndLock(hWnd, HWNDLOCK_ROUTINE_SETFOREGROUNDWINDOW);
1114 }
1115
1116
1117 /*
1118 * @unimplemented
1119 */
1120 BOOL STDCALL
1121 SetLayeredWindowAttributes(HWND hwnd,
1122 COLORREF crKey,
1123 BYTE bAlpha,
1124 DWORD dwFlags)
1125 {
1126 UNIMPLEMENTED;
1127 return FALSE;
1128 }
1129
1130
1131 /*
1132 * @implemented
1133 */
1134 HWND STDCALL
1135 SetParent(HWND hWndChild,
1136 HWND hWndNewParent)
1137 {
1138 return NtUserSetParent(hWndChild, hWndNewParent);
1139 }
1140
1141
1142 /*
1143 * @unimplemented
1144 */
1145 BOOL STDCALL
1146 SetProcessDefaultLayout(DWORD dwDefaultLayout)
1147 {
1148 UNIMPLEMENTED;
1149 return FALSE;
1150 }
1151
1152
1153 /*
1154 * @unimplemented
1155 */
1156 BOOL STDCALL
1157 SetWindowPlacement(HWND hWnd,
1158 CONST WINDOWPLACEMENT *lpwndpl)
1159 {
1160 return (BOOL)NtUserSetWindowPlacement(hWnd, (WINDOWPLACEMENT *)lpwndpl);
1161 }
1162
1163
1164 /*
1165 * @implemented
1166 */
1167 BOOL STDCALL
1168 SetWindowPos(HWND hWnd,
1169 HWND hWndInsertAfter,
1170 int X,
1171 int Y,
1172 int cx,
1173 int cy,
1174 UINT uFlags)
1175 {
1176 return NtUserSetWindowPos(hWnd,hWndInsertAfter, X, Y, cx, cy, uFlags);
1177 }
1178
1179
1180 /*
1181 * @implemented
1182 */
1183 BOOL STDCALL
1184 SetWindowTextA(HWND hWnd,
1185 LPCSTR lpString)
1186 {
1187 DWORD ProcessId;
1188 if(!NtUserGetWindowThreadProcessId(hWnd, &ProcessId))
1189 {
1190 return FALSE;
1191 }
1192
1193 if(ProcessId != GetCurrentProcessId())
1194 {
1195 /* do not send WM_GETTEXT messages to other processes */
1196 ANSI_STRING AnsiString;
1197 UNICODE_STRING UnicodeString;
1198
1199 if(lpString)
1200 {
1201 RtlInitAnsiString(&AnsiString, (LPSTR)lpString);
1202 RtlAnsiStringToUnicodeString(&UnicodeString, &AnsiString, TRUE);
1203 NtUserDefSetText(hWnd, &UnicodeString);
1204 RtlFreeUnicodeString(&UnicodeString);
1205 }
1206 else
1207 NtUserDefSetText(hWnd, NULL);
1208
1209 if ((GetWindowLongW(hWnd, GWL_STYLE) & WS_CAPTION) == WS_CAPTION)
1210 {
1211 DefWndNCPaint(hWnd, (HRGN)1, -1);
1212 }
1213 return TRUE;
1214 }
1215
1216 return SendMessageA(hWnd, WM_SETTEXT, 0, (LPARAM)lpString);
1217 }
1218
1219
1220 /*
1221 * @implemented
1222 */
1223 BOOL STDCALL
1224 SetWindowTextW(HWND hWnd,
1225 LPCWSTR lpString)
1226 {
1227 DWORD ProcessId;
1228 if(!NtUserGetWindowThreadProcessId(hWnd, &ProcessId))
1229 {
1230 return FALSE;
1231 }
1232
1233 if(ProcessId != GetCurrentProcessId())
1234 {
1235 /* do not send WM_GETTEXT messages to other processes */
1236 UNICODE_STRING UnicodeString;
1237
1238 if(lpString)
1239 RtlInitUnicodeString(&UnicodeString, (LPWSTR)lpString);
1240
1241 NtUserDefSetText(hWnd, (lpString ? &UnicodeString : NULL));
1242
1243 if ((GetWindowLongW(hWnd, GWL_STYLE) & WS_CAPTION) == WS_CAPTION)
1244 {
1245 DefWndNCPaint(hWnd, (HRGN)1, -1);
1246 }
1247 return TRUE;
1248 }
1249
1250 return SendMessageW(hWnd, WM_SETTEXT, 0, (LPARAM)lpString);
1251 }
1252
1253
1254 /*
1255 * @implemented
1256 */
1257 BOOL STDCALL
1258 ShowOwnedPopups(HWND hWnd,
1259 BOOL fShow)
1260 {
1261 return (BOOL)NtUserCallTwoParam((DWORD)hWnd, fShow, TWOPARAM_ROUTINE_SHOWOWNEDPOPUPS);
1262 }
1263
1264
1265 /*
1266 * @implemented
1267 */
1268 BOOL STDCALL
1269 ShowWindow(HWND hWnd,
1270 int nCmdShow)
1271 {
1272 return NtUserShowWindow(hWnd, nCmdShow);
1273 }
1274
1275
1276 /*
1277 * @unimplemented
1278 */
1279 BOOL STDCALL
1280 ShowWindowAsync(HWND hWnd,
1281 int nCmdShow)
1282 {
1283 UNIMPLEMENTED;
1284 return FALSE;
1285 }
1286
1287
1288 /*
1289 * @unimplemented
1290 */
1291 /*
1292 WORD STDCALL
1293 TileWindows(HWND hwndParent,
1294 UINT wHow,
1295 CONST RECT *lpRect,
1296 UINT cKids,
1297 const HWND *lpKids)
1298 {
1299 UNIMPLEMENTED;
1300 return 0;
1301 }
1302 */
1303
1304
1305 /*
1306 * @unimplemented
1307 */
1308 BOOL STDCALL
1309 UpdateLayeredWindow(HWND hwnd,
1310 HDC hdcDst,
1311 POINT *pptDst,
1312 SIZE *psize,
1313 HDC hdcSrc,
1314 POINT *pptSrc,
1315 COLORREF crKey,
1316 BLENDFUNCTION *pblend,
1317 DWORD dwFlags)
1318 {
1319 UNIMPLEMENTED;
1320 return FALSE;
1321 }
1322
1323
1324 /*
1325 * @implemented
1326 */
1327 HWND STDCALL
1328 WindowFromPoint(POINT Point)
1329 {
1330 //TODO: Determine what the actual parameters to
1331 // NtUserWindowFromPoint are.
1332 return NtUserWindowFromPoint(Point.x, Point.y);
1333 }
1334
1335
1336 /*
1337 * @implemented
1338 */
1339 int STDCALL
1340 MapWindowPoints(HWND hWndFrom, HWND hWndTo, LPPOINT lpPoints, UINT cPoints)
1341 {
1342 POINT FromOffset, ToOffset;
1343 LONG XMove, YMove;
1344 ULONG i;
1345
1346 if (hWndFrom == NULL)
1347 {
1348 FromOffset.x = FromOffset.y = 0;
1349 } else
1350 if(!NtUserGetClientOrigin(hWndFrom, &FromOffset))
1351 {
1352 return 0;
1353 }
1354
1355 if (hWndTo == NULL)
1356 {
1357 ToOffset.x = ToOffset.y = 0;
1358 } else
1359 if(!NtUserGetClientOrigin(hWndTo, &ToOffset))
1360 {
1361 return 0;
1362 }
1363 XMove = FromOffset.x - ToOffset.x;
1364 YMove = FromOffset.y - ToOffset.y;
1365
1366 for (i = 0; i < cPoints; i++)
1367 {
1368 lpPoints[i].x += XMove;
1369 lpPoints[i].y += YMove;
1370 }
1371 return(MAKELONG(LOWORD(XMove), LOWORD(YMove)));
1372 }
1373
1374
1375 /*
1376 * @implemented
1377 */
1378 BOOL STDCALL
1379 ScreenToClient(HWND hWnd, LPPOINT lpPoint)
1380 {
1381 return(MapWindowPoints(NULL, hWnd, lpPoint, 1) != 0);
1382 }
1383
1384
1385 /*
1386 * @implemented
1387 */
1388 BOOL STDCALL
1389 ClientToScreen(HWND hWnd, LPPOINT lpPoint)
1390 {
1391 return (MapWindowPoints( hWnd, NULL, lpPoint, 1 ) != 0);
1392 }
1393
1394
1395 /*
1396 * @implemented
1397 */
1398 BOOL
1399 STDCALL
1400 SetWindowContextHelpId(HWND hwnd,
1401 DWORD dwContextHelpId)
1402 {
1403 return NtUserSetWindowContextHelpId(hwnd, dwContextHelpId);
1404 }
1405
1406
1407 /*
1408 * @implemented
1409 */
1410 DWORD
1411 STDCALL
1412 GetWindowContextHelpId(HWND hwnd)
1413 {
1414 return NtUserGetWindowContextHelpId(hwnd);
1415 }
1416
1417 /*
1418 * @implemented
1419 */
1420 int
1421 STDCALL
1422 InternalGetWindowText(HWND hWnd, LPWSTR lpString, int nMaxCount)
1423 {
1424 return NtUserInternalGetWindowText(hWnd, lpString, nMaxCount);
1425 }
1426
1427 /*
1428 * @implemented
1429 */
1430 BOOL
1431 STDCALL
1432 IsHungAppWindow(HWND hwnd)
1433 {
1434 return (NtUserQueryWindow(hwnd, QUERY_WINDOW_ISHUNG) != 0);
1435 }
1436
1437 /*
1438 * @implemented
1439 */
1440 VOID
1441 STDCALL
1442 SetLastErrorEx(DWORD dwErrCode, DWORD dwType)
1443 {
1444 SetLastError(dwErrCode);
1445 }
1446
1447 /*
1448 * @implemented
1449 */
1450 HWND
1451 STDCALL
1452 GetFocus(VOID)
1453 {
1454 return (HWND)NtUserGetThreadState(0);
1455 }
1456
1457 /*
1458 * @implemented
1459 */
1460 HWND
1461 STDCALL
1462 SetTaskmanWindow(HWND hWnd)
1463 {
1464 return NtUserCallHwndOpt(hWnd, HWNDOPT_ROUTINE_SETTASKMANWINDOW);
1465 }
1466
1467 /*
1468 * @implemented
1469 */
1470 HWND
1471 STDCALL
1472 SetProgmanWindow(HWND hWnd)
1473 {
1474 return NtUserCallHwndOpt(hWnd, HWNDOPT_ROUTINE_SETTASKMANWINDOW);
1475 }
1476
1477 /*
1478 * @unimplemented
1479 */
1480 HWND
1481 STDCALL
1482 GetProgmanWindow(VOID)
1483 {
1484 UNIMPLEMENTED;
1485 return FALSE;
1486 }
1487
1488 /*
1489 * @unimplemented
1490 */
1491 HWND
1492 STDCALL
1493 GetTaskmanWindow(VOID)
1494 {
1495 UNIMPLEMENTED;
1496 return FALSE;
1497 }
1498
1499 /*
1500 * @implemented
1501 */
1502 BOOL STDCALL
1503 ScrollWindow(HWND hWnd, int dx, int dy, CONST RECT *lpRect,
1504 CONST RECT *prcClip)
1505 {
1506 return NtUserScrollWindowEx(hWnd, dx, dy, lpRect, prcClip, 0, NULL,
1507 (lpRect ? 0 : SW_SCROLLCHILDREN) | SW_INVALIDATE) != ERROR;
1508 }
1509
1510
1511 /*
1512 * @implemented
1513 */
1514 INT STDCALL
1515 ScrollWindowEx(HWND hWnd, int dx, int dy, CONST RECT *prcScroll,
1516 CONST RECT *prcClip, HRGN hrgnUpdate, LPRECT prcUpdate, UINT flags)
1517 {
1518 return NtUserScrollWindowEx(hWnd, dx, dy, prcScroll, prcClip, hrgnUpdate,
1519 prcUpdate, flags);
1520 }
1521
1522 /*
1523 * @implemented
1524 */
1525 BOOL
1526 STDCALL
1527 AnyPopup(VOID)
1528 {
1529 return NtUserAnyPopup();
1530 }
1531
1532 /*
1533 * @implemented
1534 */
1535 BOOL
1536 STDCALL
1537 IsWindowInDestroy(HWND hWnd)
1538 {
1539 return NtUserIsWindowInDestroy(hWnd);
1540 }
1541
1542 /*
1543 * @implemented
1544 */
1545 VOID
1546 STDCALL
1547 DisableProcessWindowsGhosting(VOID)
1548 {
1549 NtUserEnableProcessWindowGhosting(FALSE);
1550 }
1551
1552 /* EOF */
1553