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