implemented GetKeyboardLayoutNameW
[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 static
383 BOOL
384 User32EnumWindows (
385 HDESK hDesktop,
386 HWND hWndparent,
387 WNDENUMPROC lpfn,
388 LPARAM lParam,
389 DWORD dwThreadId,
390 BOOL bChildren )
391 {
392 DWORD i, dwCount = 0;
393 HWND* pHwnd = NULL;
394 HANDLE hHeap;
395
396 if ( !lpfn )
397 {
398 SetLastError ( ERROR_INVALID_PARAMETER );
399 return FALSE;
400 }
401
402 /* FIXME instead of always making two calls, should we use some
403 sort of persistent buffer and only grow it ( requiring a 2nd
404 call ) when the buffer wasn't already big enough? */
405 /* first get how many window entries there are */
406 SetLastError(0);
407 dwCount = NtUserBuildHwndList (
408 hDesktop, hWndparent, bChildren, dwThreadId, lParam, NULL, 0 );
409 if ( !dwCount || GetLastError() )
410 return FALSE;
411
412 /* allocate buffer to receive HWND handles */
413 hHeap = GetProcessHeap();
414 pHwnd = HeapAlloc ( hHeap, 0, sizeof(HWND)*(dwCount+1) );
415 if ( !pHwnd )
416 {
417 SetLastError ( ERROR_NOT_ENOUGH_MEMORY );
418 return FALSE;
419 }
420
421 /* now call kernel again to fill the buffer this time */
422 dwCount = NtUserBuildHwndList (
423 hDesktop, hWndparent, bChildren, dwThreadId, lParam, pHwnd, dwCount );
424 if ( !dwCount || GetLastError() )
425 {
426 if ( pHwnd )
427 HeapFree ( hHeap, 0, pHwnd );
428 return FALSE;
429 }
430
431 /* call the user's callback function until we're done or
432 they tell us to quit */
433 for ( i = 0; i < dwCount; i++ )
434 {
435 /* FIXME I'm only getting NULLs from Thread Enumeration, and it's
436 * probably because I'm not doing it right in NtUserBuildHwndList.
437 * Once that's fixed, we shouldn't have to check for a NULL HWND
438 * here
439 */
440 if ( !(ULONG)pHwnd[i] ) /* don't enumerate a NULL HWND */
441 continue;
442 if ( !(*lpfn)( pHwnd[i], lParam ) )
443 {
444 HeapFree ( hHeap, 0, pHwnd );
445 return FALSE;
446 }
447 }
448 if ( pHwnd )
449 HeapFree ( hHeap, 0, pHwnd );
450 return TRUE;
451 }
452
453
454 /*
455 * @implemented
456 */
457 BOOL
458 STDCALL
459 EnumChildWindows(
460 HWND hWndParent,
461 WNDENUMPROC lpEnumFunc,
462 LPARAM lParam)
463 {
464 if ( !hWndParent )
465 hWndParent = GetDesktopWindow();
466 return User32EnumWindows ( NULL, hWndParent, lpEnumFunc, lParam, 0, FALSE );
467 }
468
469
470 /*
471 * @implemented
472 */
473 BOOL
474 STDCALL
475 EnumThreadWindows(DWORD dwThreadId,
476 WNDENUMPROC lpfn,
477 LPARAM lParam)
478 {
479 if ( !dwThreadId )
480 dwThreadId = GetCurrentThreadId();
481 return User32EnumWindows ( NULL, NULL, lpfn, lParam, dwThreadId, FALSE );
482 }
483
484
485 /*
486 * @implemented
487 */
488 BOOL STDCALL
489 EnumWindows(WNDENUMPROC lpEnumFunc,
490 LPARAM lParam)
491 {
492 return User32EnumWindows ( NULL, NULL, lpEnumFunc, lParam, 0, FALSE );
493 }
494
495
496 /*
497 * @implemented
498 */
499 BOOL
500 STDCALL
501 EnumDesktopWindows(
502 HDESK hDesktop,
503 WNDENUMPROC lpfn,
504 LPARAM lParam)
505 {
506 return User32EnumWindows ( hDesktop, NULL, lpfn, lParam, 0, FALSE );
507 }
508
509
510 /*
511 * @implemented
512 */
513 HWND STDCALL
514 FindWindowExA(HWND hwndParent,
515 HWND hwndChildAfter,
516 LPCSTR lpszClass,
517 LPCSTR lpszWindow)
518 {
519 UNICODE_STRING ucClassName;
520 UNICODE_STRING ucWindowName;
521 HWND Result;
522
523 if (lpszClass == NULL)
524 {
525 ucClassName.Buffer = NULL;
526 ucClassName.Length = 0;
527 }
528 else if (IS_ATOM(lpszClass))
529 {
530 ucClassName.Buffer = (LPWSTR)lpszClass;
531 ucClassName.Length = 0;
532 }
533 else
534 {
535 RtlCreateUnicodeStringFromAsciiz(&ucClassName, (LPSTR)lpszClass);
536 }
537
538 RtlCreateUnicodeStringFromAsciiz(&ucWindowName, (LPSTR)lpszWindow);
539
540 Result = NtUserFindWindowEx(hwndParent, hwndChildAfter, &ucClassName,
541 &ucWindowName);
542
543 if (!IS_ATOM(lpszClass))
544 RtlFreeUnicodeString(&ucClassName);
545 RtlFreeUnicodeString(&ucWindowName);
546
547 return Result;
548 }
549
550
551 /*
552 * @implemented
553 */
554 HWND STDCALL
555 FindWindowExW(HWND hwndParent,
556 HWND hwndChildAfter,
557 LPCWSTR lpszClass,
558 LPCWSTR lpszWindow)
559 {
560 UNICODE_STRING ucClassName;
561 UNICODE_STRING ucWindowName;
562
563 if (lpszClass == NULL)
564 {
565 ucClassName.Buffer = NULL;
566 ucClassName.Length = 0;
567 }
568 else if (IS_ATOM(lpszClass))
569 {
570 RtlInitUnicodeString(&ucClassName, NULL);
571 ucClassName.Buffer = (LPWSTR)lpszClass;
572 }
573 else
574 {
575 RtlInitUnicodeString(&ucClassName, lpszClass);
576 }
577
578 RtlInitUnicodeString(&ucWindowName, lpszWindow);
579
580 return NtUserFindWindowEx(hwndParent, hwndChildAfter, &ucClassName, &ucWindowName);
581 }
582
583
584 /*
585 * @implemented
586 */
587 HWND STDCALL
588 FindWindowA(LPCSTR lpClassName, LPCSTR lpWindowName)
589 {
590 //FIXME: FindWindow does not search children, but FindWindowEx does.
591 // what should we do about this?
592 return FindWindowExA (NULL, NULL, lpClassName, lpWindowName);
593 }
594
595
596 /*
597 * @implemented
598 */
599 HWND STDCALL
600 FindWindowW(LPCWSTR lpClassName, LPCWSTR lpWindowName)
601 {
602 /*
603
604 There was a FIXME here earlier, but I think it is just a documentation unclarity.
605
606 FindWindow only searches top level windows. What they mean is that child
607 windows of other windows than the desktop can be searched.
608 FindWindowExW never does a recursive search.
609
610 / Joakim
611 */
612
613 return FindWindowExW (NULL, NULL, lpClassName, lpWindowName);
614 }
615
616
617
618 /*
619 * @unimplemented
620 */
621 BOOL STDCALL
622 GetAltTabInfoA(HWND hwnd,
623 int iItem,
624 PALTTABINFO pati,
625 LPSTR pszItemText,
626 UINT cchItemText)
627 {
628 UNIMPLEMENTED;
629 return FALSE;
630 }
631
632
633 /*
634 * @unimplemented
635 */
636 BOOL STDCALL
637 GetAltTabInfoW(HWND hwnd,
638 int iItem,
639 PALTTABINFO pati,
640 LPWSTR pszItemText,
641 UINT cchItemText)
642 {
643 UNIMPLEMENTED;
644 return FALSE;
645 }
646
647
648 /*
649 * @implemented
650 */
651 HWND STDCALL
652 GetAncestor(HWND hwnd, UINT gaFlags)
653 {
654 return(NtUserGetAncestor(hwnd, gaFlags));
655 }
656
657
658 /*
659 * @implemented
660 */
661 BOOL STDCALL
662 GetClientRect(HWND hWnd, LPRECT lpRect)
663 {
664 return(NtUserGetClientRect(hWnd, lpRect));
665 }
666
667
668 /*
669 * @implemented
670 */
671 BOOL STDCALL
672 GetGUIThreadInfo(DWORD idThread,
673 LPGUITHREADINFO lpgui)
674 {
675 return (BOOL)NtUserGetGUIThreadInfo(idThread, lpgui);
676 }
677
678
679 /*
680 * @unimplemented
681 */
682 HWND STDCALL
683 GetLastActivePopup(HWND hWnd)
684 {
685 return NtUserGetLastActivePopup(hWnd);
686 }
687
688
689 /*
690 * @implemented
691 */
692 HWND STDCALL
693 GetParent(HWND hWnd)
694 {
695 return NtUserGetParent(hWnd);
696 }
697
698
699 /*
700 * @unimplemented
701 */
702 BOOL STDCALL
703 GetProcessDefaultLayout(DWORD *pdwDefaultLayout)
704 {
705 UNIMPLEMENTED;
706 return FALSE;
707 }
708
709
710 /*
711 * @unimplemented
712 */
713 BOOL STDCALL
714 GetTitleBarInfo(HWND hwnd,
715 PTITLEBARINFO pti)
716 {
717 UNIMPLEMENTED;
718 return FALSE;
719 }
720
721
722 /*
723 * @implemented
724 */
725 HWND STDCALL
726 GetWindow(HWND hWnd,
727 UINT uCmd)
728 {
729 return NtUserGetWindow(hWnd, uCmd);
730 }
731
732
733 /*
734 * @implemented
735 */
736 HWND STDCALL
737 GetTopWindow(HWND hWnd)
738 {
739 if (!hWnd) hWnd = GetDesktopWindow();
740 return GetWindow( hWnd, GW_CHILD );
741 }
742
743
744 /*
745 * @implemented
746 */
747 BOOL STDCALL
748 GetWindowInfo(HWND hwnd,
749 PWINDOWINFO pwi)
750 {
751 return NtUserGetWindowInfo(hwnd, pwi);
752 }
753
754
755 /*
756 * @implemented
757 */
758 UINT STDCALL
759 GetWindowModuleFileNameA(HWND hwnd,
760 LPSTR lpszFileName,
761 UINT cchFileNameMax)
762 {
763 HINSTANCE hWndInst;
764
765 if(!(hWndInst = NtUserGetWindowInstance(hwnd)))
766 {
767 return 0;
768 }
769
770 return GetModuleFileNameA(hWndInst, lpszFileName, cchFileNameMax);
771 }
772
773
774 /*
775 * @implemented
776 */
777 UINT STDCALL
778 GetWindowModuleFileNameW(HWND hwnd,
779 LPWSTR lpszFileName,
780 UINT cchFileNameMax)
781 {
782 HINSTANCE hWndInst;
783
784 if(!(hWndInst = NtUserGetWindowInstance(hwnd)))
785 {
786 return 0;
787 }
788
789 return GetModuleFileNameW(hWndInst, lpszFileName, cchFileNameMax);
790 }
791
792
793 /*
794 * @implemented
795 */
796 BOOL STDCALL
797 GetWindowPlacement(HWND hWnd,
798 WINDOWPLACEMENT *lpwndpl)
799 {
800 return (BOOL)NtUserGetWindowPlacement(hWnd, lpwndpl);
801 }
802
803
804 /*
805 * @implemented
806 */
807 BOOL STDCALL
808 GetWindowRect(HWND hWnd,
809 LPRECT lpRect)
810 {
811 return(NtUserGetWindowRect(hWnd, lpRect));
812 }
813
814
815 /*
816 * @implemented
817 */
818 int STDCALL
819 GetWindowTextA(HWND hWnd, LPSTR lpString, int nMaxCount)
820 {
821 DWORD ProcessId;
822
823 if (lpString == NULL)
824 return 0;
825
826 if (!NtUserGetWindowThreadProcessId(hWnd, &ProcessId))
827 return 0;
828
829 if (ProcessId != GetCurrentProcessId())
830 {
831 /* do not send WM_GETTEXT messages to other processes */
832 LPWSTR Buffer;
833 INT Length;
834
835 Buffer = HeapAlloc(GetProcessHeap(), 0, nMaxCount * sizeof(WCHAR));
836 if (!Buffer)
837 return FALSE;
838 Length = NtUserInternalGetWindowText(hWnd, Buffer, nMaxCount);
839 if (Length > 0 && nMaxCount > 0 &&
840 !WideCharToMultiByte(CP_ACP, 0, Buffer, -1,
841 lpString, nMaxCount, NULL, NULL))
842 {
843 lpString[0] = '\0';
844 }
845 HeapFree(GetProcessHeap(), 0, Buffer);
846
847 return (LRESULT)Length;
848 }
849
850 return SendMessageA(hWnd, WM_GETTEXT, nMaxCount, (LPARAM)lpString);
851 }
852
853
854 /*
855 * @implemented
856 */
857 int STDCALL
858 GetWindowTextLengthA(HWND hWnd)
859 {
860 DWORD ProcessId;
861 if(!NtUserGetWindowThreadProcessId(hWnd, &ProcessId))
862 {
863 return 0;
864 }
865
866 if(ProcessId == GetCurrentProcessId())
867 {
868 return(SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0));
869 }
870
871 /* do not send WM_GETTEXT messages to other processes */
872 return (LRESULT)NtUserInternalGetWindowText(hWnd, NULL, 0);
873 }
874
875
876 /*
877 * @implemented
878 */
879 int STDCALL
880 GetWindowTextLengthW(HWND hWnd)
881 {
882 DWORD ProcessId;
883 if(!NtUserGetWindowThreadProcessId(hWnd, &ProcessId))
884 {
885 return 0;
886 }
887
888 if(ProcessId == GetCurrentProcessId())
889 {
890 return(SendMessageW(hWnd, WM_GETTEXTLENGTH, 0, 0));
891 }
892
893 /* do not send WM_GETTEXT messages to other processes */
894 return (LRESULT)NtUserInternalGetWindowText(hWnd, NULL, 0);
895 }
896
897
898 /*
899 * @implemented
900 */
901 int STDCALL
902 GetWindowTextW(HWND hWnd, LPWSTR lpString, int nMaxCount)
903 {
904 DWORD ProcessId;
905
906 if (lpString == NULL)
907 return 0;
908
909 if (!NtUserGetWindowThreadProcessId(hWnd, &ProcessId))
910 return 0;
911
912 if (ProcessId == GetCurrentProcessId())
913 return SendMessageW(hWnd, WM_GETTEXT, nMaxCount, (LPARAM)lpString);
914
915 return NtUserInternalGetWindowText(hWnd, lpString, nMaxCount);
916 }
917
918 DWORD STDCALL
919 GetWindowThreadProcessId(HWND hWnd,
920 LPDWORD lpdwProcessId)
921 {
922 return NtUserGetWindowThreadProcessId(hWnd, lpdwProcessId);
923 }
924
925
926 /*
927 * @implemented
928 */
929 BOOL STDCALL
930 IsChild(HWND hWndParent,
931 HWND hWnd)
932 {
933 if (! IsWindow(hWndParent) || ! IsWindow(hWnd))
934 {
935 return FALSE;
936 }
937
938 do
939 {
940 hWnd = (HWND)NtUserGetWindowLong(hWnd, GWL_HWNDPARENT, FALSE);
941 }
942 while (hWnd != NULL && hWnd != hWndParent);
943
944 return hWnd == hWndParent;
945 }
946
947
948 /*
949 * @implemented
950 */
951 BOOL STDCALL
952 IsIconic(HWND hWnd)
953 {
954 return (NtUserGetWindowLong( hWnd, GWL_STYLE, FALSE) & WS_MINIMIZE) != 0;
955 }
956
957
958 /*
959 * @implemented
960 */
961 BOOL STDCALL
962 IsWindow(HWND hWnd)
963 {
964 DWORD WndProc = NtUserGetWindowLong(hWnd, GWL_WNDPROC, FALSE);
965 return (0 != WndProc || ERROR_INVALID_WINDOW_HANDLE != GetLastError());
966 }
967
968
969 /*
970 * @implemented
971 */
972 BOOL STDCALL
973 IsWindowUnicode(HWND hWnd)
974 {
975 return NtUserIsWindowUnicode(hWnd);
976 }
977
978
979 /*
980 * @implemented
981 */
982 BOOL STDCALL
983 IsWindowVisible(HWND hWnd)
984 {
985 while (NtUserGetWindowLong(hWnd, GWL_STYLE, FALSE) & WS_CHILD)
986 {
987 if (!(NtUserGetWindowLong(hWnd, GWL_STYLE, FALSE) & WS_VISIBLE))
988 {
989 return(FALSE);
990 }
991 hWnd = GetAncestor(hWnd, GA_PARENT);
992 }
993 return(NtUserGetWindowLong(hWnd, GWL_STYLE, FALSE) & WS_VISIBLE);
994 }
995
996
997 /*
998 * @implemented
999 */
1000 BOOL
1001 STDCALL
1002 IsWindowEnabled(
1003 HWND hWnd)
1004 {
1005 // AG: I don't know if child windows are affected if the parent is
1006 // disabled. I think they stop processing messages but stay appearing
1007 // as enabled.
1008
1009 return (! (NtUserGetWindowLong(hWnd, GWL_STYLE, FALSE) & WS_DISABLED));
1010 }
1011
1012
1013 /*
1014 * @implemented
1015 */
1016 BOOL STDCALL
1017 IsZoomed(HWND hWnd)
1018 {
1019 return NtUserGetWindowLong(hWnd, GWL_STYLE, FALSE) & WS_MAXIMIZE;
1020 }
1021
1022
1023 /*
1024 * @unimplemented
1025 */
1026 BOOL STDCALL
1027 LockSetForegroundWindow(UINT uLockCode)
1028 {
1029 UNIMPLEMENTED;
1030 return FALSE;
1031 }
1032
1033
1034 /*
1035 * @implemented
1036 */
1037 BOOL STDCALL
1038 MoveWindow(HWND hWnd,
1039 int X,
1040 int Y,
1041 int nWidth,
1042 int nHeight,
1043 BOOL bRepaint)
1044 {
1045 return NtUserMoveWindow(hWnd, X, Y, nWidth, nHeight, bRepaint);
1046 }
1047
1048
1049 /*
1050 * @implemented
1051 */
1052 BOOL STDCALL
1053 AnimateWindow(HWND hwnd,
1054 DWORD dwTime,
1055 DWORD dwFlags)
1056 {
1057 /* FIXME Add animation code */
1058
1059 /* If trying to show/hide and it's already *
1060 * shown/hidden or invalid window, fail with *
1061 * invalid parameter */
1062
1063 BOOL visible;
1064 visible = IsWindowVisible(hwnd);
1065 if(!IsWindow(hwnd) ||
1066 (visible && !(dwFlags & AW_HIDE)) ||
1067 (!visible && (dwFlags & AW_HIDE)))
1068 {
1069 SetLastError(ERROR_INVALID_PARAMETER);
1070 return FALSE;
1071 }
1072
1073 ShowWindow(hwnd, (dwFlags & AW_HIDE) ? SW_HIDE : ((dwFlags & AW_ACTIVATE) ? SW_SHOW : SW_SHOWNA));
1074
1075 return TRUE;
1076 }
1077
1078
1079 /*
1080 * @implemented
1081 */
1082 BOOL STDCALL
1083 OpenIcon(HWND hWnd)
1084 {
1085 if (!(NtUserGetWindowLong(hWnd, GWL_STYLE, FALSE) & WS_MINIMIZE))
1086 {
1087 return FALSE;
1088 }
1089
1090 ShowWindow(hWnd,SW_RESTORE);
1091 return TRUE;
1092 }
1093
1094
1095 /*
1096 * @unimplemented
1097 */
1098 HWND STDCALL
1099 RealChildWindowFromPoint(HWND hwndParent,
1100 POINT ptParentClientCoords)
1101 {
1102 UNIMPLEMENTED;
1103 return (HWND)0;
1104 }
1105
1106 /*
1107 * @unimplemented
1108 */
1109 BOOL STDCALL
1110 SetForegroundWindow(HWND hWnd)
1111 {
1112 return NtUserCallHwndLock(hWnd, HWNDLOCK_ROUTINE_SETFOREGROUNDWINDOW);
1113 }
1114
1115
1116 /*
1117 * @unimplemented
1118 */
1119 BOOL STDCALL
1120 SetLayeredWindowAttributes(HWND hwnd,
1121 COLORREF crKey,
1122 BYTE bAlpha,
1123 DWORD dwFlags)
1124 {
1125 UNIMPLEMENTED;
1126 return FALSE;
1127 }
1128
1129
1130 /*
1131 * @implemented
1132 */
1133 HWND STDCALL
1134 SetParent(HWND hWndChild,
1135 HWND hWndNewParent)
1136 {
1137 return NtUserSetParent(hWndChild, hWndNewParent);
1138 }
1139
1140
1141 /*
1142 * @unimplemented
1143 */
1144 BOOL STDCALL
1145 SetProcessDefaultLayout(DWORD dwDefaultLayout)
1146 {
1147 UNIMPLEMENTED;
1148 return FALSE;
1149 }
1150
1151
1152 /*
1153 * @unimplemented
1154 */
1155 BOOL STDCALL
1156 SetWindowPlacement(HWND hWnd,
1157 CONST WINDOWPLACEMENT *lpwndpl)
1158 {
1159 return (BOOL)NtUserSetWindowPlacement(hWnd, (WINDOWPLACEMENT *)lpwndpl);
1160 }
1161
1162
1163 /*
1164 * @implemented
1165 */
1166 BOOL STDCALL
1167 SetWindowPos(HWND hWnd,
1168 HWND hWndInsertAfter,
1169 int X,
1170 int Y,
1171 int cx,
1172 int cy,
1173 UINT uFlags)
1174 {
1175 return NtUserSetWindowPos(hWnd,hWndInsertAfter, X, Y, cx, cy, uFlags);
1176 }
1177
1178
1179 /*
1180 * @implemented
1181 */
1182 BOOL STDCALL
1183 SetWindowTextA(HWND hWnd,
1184 LPCSTR lpString)
1185 {
1186 DWORD ProcessId;
1187 if(!NtUserGetWindowThreadProcessId(hWnd, &ProcessId))
1188 {
1189 return FALSE;
1190 }
1191
1192 if(ProcessId != GetCurrentProcessId())
1193 {
1194 /* do not send WM_GETTEXT messages to other processes */
1195 ANSI_STRING AnsiString;
1196 UNICODE_STRING UnicodeString;
1197
1198 if(lpString)
1199 {
1200 RtlInitAnsiString(&AnsiString, (LPSTR)lpString);
1201 RtlAnsiStringToUnicodeString(&UnicodeString, &AnsiString, TRUE);
1202 NtUserDefSetText(hWnd, &UnicodeString);
1203 RtlFreeUnicodeString(&UnicodeString);
1204 }
1205 else
1206 NtUserDefSetText(hWnd, NULL);
1207
1208 if ((GetWindowLongW(hWnd, GWL_STYLE) & WS_CAPTION) == WS_CAPTION)
1209 {
1210 DefWndNCPaint(hWnd, (HRGN)1, -1);
1211 }
1212 return TRUE;
1213 }
1214
1215 return SendMessageA(hWnd, WM_SETTEXT, 0, (LPARAM)lpString);
1216 }
1217
1218
1219 /*
1220 * @implemented
1221 */
1222 BOOL STDCALL
1223 SetWindowTextW(HWND hWnd,
1224 LPCWSTR lpString)
1225 {
1226 DWORD ProcessId;
1227 if(!NtUserGetWindowThreadProcessId(hWnd, &ProcessId))
1228 {
1229 return FALSE;
1230 }
1231
1232 if(ProcessId != GetCurrentProcessId())
1233 {
1234 /* do not send WM_GETTEXT messages to other processes */
1235 UNICODE_STRING UnicodeString;
1236
1237 if(lpString)
1238 RtlInitUnicodeString(&UnicodeString, (LPWSTR)lpString);
1239
1240 NtUserDefSetText(hWnd, (lpString ? &UnicodeString : NULL));
1241
1242 if ((GetWindowLongW(hWnd, GWL_STYLE) & WS_CAPTION) == WS_CAPTION)
1243 {
1244 DefWndNCPaint(hWnd, (HRGN)1, -1);
1245 }
1246 return TRUE;
1247 }
1248
1249 return SendMessageW(hWnd, WM_SETTEXT, 0, (LPARAM)lpString);
1250 }
1251
1252
1253 /*
1254 * @implemented
1255 */
1256 BOOL STDCALL
1257 ShowOwnedPopups(HWND hWnd,
1258 BOOL fShow)
1259 {
1260 return (BOOL)NtUserCallTwoParam((DWORD)hWnd, fShow, TWOPARAM_ROUTINE_SHOWOWNEDPOPUPS);
1261 }
1262
1263
1264 /*
1265 * @implemented
1266 */
1267 BOOL STDCALL
1268 ShowWindow(HWND hWnd,
1269 int nCmdShow)
1270 {
1271 return NtUserShowWindow(hWnd, nCmdShow);
1272 }
1273
1274
1275 /*
1276 * @unimplemented
1277 */
1278 BOOL STDCALL
1279 ShowWindowAsync(HWND hWnd,
1280 int nCmdShow)
1281 {
1282 return NtUserShowWindowAsync(hWnd, nCmdShow);
1283 }
1284
1285
1286 /*
1287 * @unimplemented
1288 */
1289 /*
1290 WORD STDCALL
1291 TileWindows(HWND hwndParent,
1292 UINT wHow,
1293 CONST RECT *lpRect,
1294 UINT cKids,
1295 const HWND *lpKids)
1296 {
1297 UNIMPLEMENTED;
1298 return 0;
1299 }
1300 */
1301
1302
1303 /*
1304 * @unimplemented
1305 */
1306 BOOL STDCALL
1307 UpdateLayeredWindow(HWND hwnd,
1308 HDC hdcDst,
1309 POINT *pptDst,
1310 SIZE *psize,
1311 HDC hdcSrc,
1312 POINT *pptSrc,
1313 COLORREF crKey,
1314 BLENDFUNCTION *pblend,
1315 DWORD dwFlags)
1316 {
1317 UNIMPLEMENTED;
1318 return FALSE;
1319 }
1320
1321
1322 /*
1323 * @implemented
1324 */
1325 HWND STDCALL
1326 WindowFromPoint(POINT Point)
1327 {
1328 //TODO: Determine what the actual parameters to
1329 // NtUserWindowFromPoint are.
1330 return NtUserWindowFromPoint(Point.x, Point.y);
1331 }
1332
1333
1334 /*
1335 * @implemented
1336 */
1337 int STDCALL
1338 MapWindowPoints(HWND hWndFrom, HWND hWndTo, LPPOINT lpPoints, UINT cPoints)
1339 {
1340 POINT FromOffset, ToOffset;
1341 LONG XMove, YMove;
1342 ULONG i;
1343
1344 if (hWndFrom == NULL)
1345 {
1346 FromOffset.x = FromOffset.y = 0;
1347 } else
1348 if(!NtUserGetClientOrigin(hWndFrom, &FromOffset))
1349 {
1350 return 0;
1351 }
1352
1353 if (hWndTo == NULL)
1354 {
1355 ToOffset.x = ToOffset.y = 0;
1356 } else
1357 if(!NtUserGetClientOrigin(hWndTo, &ToOffset))
1358 {
1359 return 0;
1360 }
1361 XMove = FromOffset.x - ToOffset.x;
1362 YMove = FromOffset.y - ToOffset.y;
1363
1364 for (i = 0; i < cPoints; i++)
1365 {
1366 lpPoints[i].x += XMove;
1367 lpPoints[i].y += YMove;
1368 }
1369 return(MAKELONG(LOWORD(XMove), LOWORD(YMove)));
1370 }
1371
1372
1373 /*
1374 * @implemented
1375 */
1376 BOOL STDCALL
1377 ScreenToClient(HWND hWnd, LPPOINT lpPoint)
1378 {
1379 return(MapWindowPoints(NULL, hWnd, lpPoint, 1) != 0);
1380 }
1381
1382
1383 /*
1384 * @implemented
1385 */
1386 BOOL STDCALL
1387 ClientToScreen(HWND hWnd, LPPOINT lpPoint)
1388 {
1389 return (MapWindowPoints( hWnd, NULL, lpPoint, 1 ) != 0);
1390 }
1391
1392
1393 /*
1394 * @implemented
1395 */
1396 BOOL
1397 STDCALL
1398 SetWindowContextHelpId(HWND hwnd,
1399 DWORD dwContextHelpId)
1400 {
1401 return NtUserSetWindowContextHelpId(hwnd, dwContextHelpId);
1402 }
1403
1404
1405 /*
1406 * @implemented
1407 */
1408 DWORD
1409 STDCALL
1410 GetWindowContextHelpId(HWND hwnd)
1411 {
1412 return NtUserGetWindowContextHelpId(hwnd);
1413 }
1414
1415 /*
1416 * @implemented
1417 */
1418 int
1419 STDCALL
1420 InternalGetWindowText(HWND hWnd, LPWSTR lpString, int nMaxCount)
1421 {
1422 return NtUserInternalGetWindowText(hWnd, lpString, nMaxCount);
1423 }
1424
1425 /*
1426 * @implemented
1427 */
1428 BOOL
1429 STDCALL
1430 IsHungAppWindow(HWND hwnd)
1431 {
1432 return (NtUserQueryWindow(hwnd, QUERY_WINDOW_ISHUNG) != 0);
1433 }
1434
1435 /*
1436 * @implemented
1437 */
1438 VOID
1439 STDCALL
1440 SetLastErrorEx(DWORD dwErrCode, DWORD dwType)
1441 {
1442 SetLastError(dwErrCode);
1443 }
1444
1445 /*
1446 * @implemented
1447 */
1448 HWND
1449 STDCALL
1450 GetFocus(VOID)
1451 {
1452 return (HWND)NtUserGetThreadState(0);
1453 }
1454
1455 /*
1456 * @implemented
1457 */
1458 HWND
1459 STDCALL
1460 SetTaskmanWindow(HWND hWnd)
1461 {
1462 return NtUserCallHwndOpt(hWnd, HWNDOPT_ROUTINE_SETTASKMANWINDOW);
1463 }
1464
1465 /*
1466 * @implemented
1467 */
1468 HWND
1469 STDCALL
1470 SetProgmanWindow(HWND hWnd)
1471 {
1472 return NtUserCallHwndOpt(hWnd, HWNDOPT_ROUTINE_SETTASKMANWINDOW);
1473 }
1474
1475 /*
1476 * @unimplemented
1477 */
1478 HWND
1479 STDCALL
1480 GetProgmanWindow(VOID)
1481 {
1482 UNIMPLEMENTED;
1483 return FALSE;
1484 }
1485
1486 /*
1487 * @unimplemented
1488 */
1489 HWND
1490 STDCALL
1491 GetTaskmanWindow(VOID)
1492 {
1493 UNIMPLEMENTED;
1494 return FALSE;
1495 }
1496
1497 /*
1498 * @implemented
1499 */
1500 BOOL STDCALL
1501 ScrollWindow(HWND hWnd, int dx, int dy, CONST RECT *lpRect,
1502 CONST RECT *prcClip)
1503 {
1504 return NtUserScrollWindowEx(hWnd, dx, dy, lpRect, prcClip, 0, NULL,
1505 (lpRect ? 0 : SW_SCROLLCHILDREN) | SW_INVALIDATE) != ERROR;
1506 }
1507
1508
1509 /*
1510 * @implemented
1511 */
1512 INT STDCALL
1513 ScrollWindowEx(HWND hWnd, int dx, int dy, CONST RECT *prcScroll,
1514 CONST RECT *prcClip, HRGN hrgnUpdate, LPRECT prcUpdate, UINT flags)
1515 {
1516 return NtUserScrollWindowEx(hWnd, dx, dy, prcScroll, prcClip, hrgnUpdate,
1517 prcUpdate, flags);
1518 }
1519
1520 /*
1521 * @implemented
1522 */
1523 BOOL
1524 STDCALL
1525 AnyPopup(VOID)
1526 {
1527 return NtUserAnyPopup();
1528 }
1529
1530 /*
1531 * @implemented
1532 */
1533 BOOL
1534 STDCALL
1535 IsWindowInDestroy(HWND hWnd)
1536 {
1537 return NtUserIsWindowInDestroy(hWnd);
1538 }
1539
1540 /*
1541 * @implemented
1542 */
1543 VOID
1544 STDCALL
1545 DisableProcessWindowsGhosting(VOID)
1546 {
1547 NtUserEnableProcessWindowGhosting(FALSE);
1548 }
1549
1550 /* EOF */
1551