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