Sync with trunk r43000
[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 ShowWindow(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 Unicode,
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 (GetWindowLongPtrW(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 ShowWindow(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 (GetWindowLongPtrW(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 ShowWindow(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 SetWindowPos(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 PWND 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 PWND 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->spwndParent != NULL)
854 Ancestor = DesktopPtrToUser(Wnd->spwndParent);
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 PWND Wnd = ValidateHwnd(hWnd);
886
887 if (Wnd != NULL)
888 {
889 lpRect->left = lpRect->top = 0;
890 lpRect->right = Wnd->rcClient.right - Wnd->rcClient.left;
891 lpRect->bottom = Wnd->rcClient.bottom - Wnd->rcClient.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 PWND 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 PWND 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->spwndParent != NULL)
944 WndParent = DesktopPtrToUser(Wnd->spwndParent);
945 }
946 else if (Wnd->style & WS_POPUP)
947 {
948 if (Wnd->spwndOwner != NULL)
949 WndParent = DesktopPtrToUser(Wnd->spwndOwner);
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 PWND 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->spwndOwner != NULL)
1006 FoundWnd = DesktopPtrToUser(Wnd->spwndOwner);
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 PWND pWnd;
1050 PCLS pCls = NULL;
1051 SIZE Size = {0,0};
1052 BOOL Ret = FALSE;
1053
1054 if ( !pwi || pwi->cbSize != sizeof(WINDOWINFO))
1055 SetLastError(ERROR_INVALID_PARAMETER); // Just set the error and go!
1056
1057 pWnd = ValidateHwnd(hWnd);
1058 if (!pWnd)
1059 return Ret;
1060
1061 UserGetWindowBorders(pWnd->style, pWnd->ExStyle, &Size, FALSE);
1062
1063 _SEH2_TRY
1064 {
1065 pCls = DesktopPtrToUser(pWnd->pcls);
1066 pwi->rcWindow = pWnd->rcWindow;
1067 pwi->rcClient = pWnd->rcClient;
1068 pwi->dwStyle = pWnd->style;
1069 pwi->dwExStyle = pWnd->ExStyle;
1070 pwi->cxWindowBorders = Size.cx;
1071 pwi->cyWindowBorders = Size.cy;
1072 pwi->dwWindowStatus = 0;
1073 if (pWnd->state & WNDS_ACTIVEFRAME)
1074 pwi->dwWindowStatus = WS_ACTIVECAPTION;
1075 pwi->atomWindowType = (pCls ? pCls->atomClassName : 0 );
1076
1077 if ( pWnd->state2 & WNDS2_WIN50COMPAT )
1078 {
1079 pwi->wCreatorVersion = 0x500;
1080 }
1081 else if ( pWnd->state2 & WNDS2_WIN40COMPAT )
1082 {
1083 pwi->wCreatorVersion = 0x400;
1084 }
1085 else if ( pWnd->state2 & WNDS2_WIN31COMPAT )
1086 {
1087 pwi->wCreatorVersion = 0x30A;
1088 }
1089 else
1090 {
1091 pwi->wCreatorVersion = 0x300;
1092 }
1093
1094 Ret = TRUE;
1095 }
1096 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
1097 {
1098 /* Do nothing */
1099 }
1100 _SEH2_END;
1101
1102 return Ret;
1103 }
1104
1105
1106 /*
1107 * @implemented
1108 */
1109 UINT WINAPI
1110 GetWindowModuleFileNameA(HWND hwnd,
1111 LPSTR lpszFileName,
1112 UINT cchFileNameMax)
1113 {
1114 HINSTANCE hWndInst;
1115
1116 if(!(hWndInst = NtUserGetWindowInstance(hwnd)))
1117 {
1118 return 0;
1119 }
1120
1121 return GetModuleFileNameA(hWndInst, lpszFileName, cchFileNameMax);
1122 }
1123
1124
1125 /*
1126 * @implemented
1127 */
1128 UINT WINAPI
1129 GetWindowModuleFileNameW(HWND hwnd,
1130 LPWSTR lpszFileName,
1131 UINT cchFileNameMax)
1132 {
1133 HINSTANCE hWndInst;
1134
1135 if(!(hWndInst = NtUserGetWindowInstance(hwnd)))
1136 {
1137 return 0;
1138 }
1139
1140 return GetModuleFileNameW(hWndInst, lpszFileName, cchFileNameMax);
1141 }
1142
1143
1144 /*
1145 * @implemented
1146 */
1147 BOOL WINAPI
1148 GetWindowRect(HWND hWnd,
1149 LPRECT lpRect)
1150 {
1151 PWND Wnd = ValidateHwnd(hWnd);
1152
1153 if (Wnd != NULL)
1154 {
1155 *lpRect = Wnd->rcWindow;
1156 return TRUE;
1157 }
1158
1159 return FALSE;
1160 }
1161
1162
1163 /*
1164 * @implemented
1165 */
1166 int WINAPI
1167 GetWindowTextA(HWND hWnd, LPSTR lpString, int nMaxCount)
1168 {
1169 PWND Wnd;
1170 PCWSTR Buffer;
1171 INT Length = 0;
1172
1173 if (lpString == NULL)
1174 return 0;
1175
1176 Wnd = ValidateHwnd(hWnd);
1177 if (!Wnd)
1178 return 0;
1179
1180 _SEH2_TRY
1181 {
1182 if (!TestWindowProcess( Wnd))
1183 {
1184 if (nMaxCount > 0)
1185 {
1186 /* do not send WM_GETTEXT messages to other processes */
1187 Length = Wnd->strName.Length / sizeof(WCHAR);
1188 if (Length != 0)
1189 {
1190 Buffer = DesktopPtrToUser(Wnd->strName.Buffer);
1191 if (Buffer != NULL)
1192 {
1193 if (!WideCharToMultiByte(CP_ACP,
1194 0,
1195 Buffer,
1196 Length + 1,
1197 lpString,
1198 nMaxCount,
1199 NULL,
1200 NULL))
1201 {
1202 lpString[nMaxCount - 1] = '\0';
1203 }
1204 }
1205 else
1206 {
1207 Length = 0;
1208 lpString[0] = '\0';
1209 }
1210 }
1211 else
1212 lpString[0] = '\0';
1213 }
1214
1215 Wnd = NULL; /* Don't send a message */
1216 }
1217 }
1218 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
1219 {
1220 lpString[0] = '\0';
1221 Length = 0;
1222 Wnd = NULL; /* Don't send a message */
1223 }
1224 _SEH2_END;
1225
1226 if (Wnd != NULL)
1227 Length = SendMessageA(hWnd, WM_GETTEXT, nMaxCount, (LPARAM)lpString);
1228
1229 return Length;
1230 }
1231
1232
1233 /*
1234 * @implemented
1235 */
1236 int WINAPI
1237 GetWindowTextLengthA(HWND hWnd)
1238 {
1239 return(SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0));
1240 }
1241
1242
1243 /*
1244 * @implemented
1245 */
1246 int WINAPI
1247 GetWindowTextLengthW(HWND hWnd)
1248 {
1249 return(SendMessageW(hWnd, WM_GETTEXTLENGTH, 0, 0));
1250 }
1251
1252
1253 /*
1254 * @implemented
1255 */
1256 int WINAPI
1257 GetWindowTextW(HWND hWnd, LPWSTR lpString, int nMaxCount)
1258 {
1259 PWND Wnd;
1260 PCWSTR Buffer;
1261 INT Length = 0;
1262
1263 if (lpString == NULL)
1264 return 0;
1265
1266 Wnd = ValidateHwnd(hWnd);
1267 if (!Wnd)
1268 return 0;
1269
1270 _SEH2_TRY
1271 {
1272 if (!TestWindowProcess( Wnd))
1273 {
1274 if (nMaxCount > 0)
1275 {
1276 /* do not send WM_GETTEXT messages to other processes */
1277 Length = Wnd->strName.Length / sizeof(WCHAR);
1278 if (Length != 0)
1279 {
1280 Buffer = DesktopPtrToUser(Wnd->strName.Buffer);
1281 if (Buffer != NULL)
1282 {
1283 RtlCopyMemory(lpString,
1284 Buffer,
1285 (Length + 1) * sizeof(WCHAR));
1286 }
1287 else
1288 {
1289 Length = 0;
1290 lpString[0] = '\0';
1291 }
1292 }
1293 else
1294 lpString[0] = '\0';
1295 }
1296
1297 Wnd = NULL; /* Don't send a message */
1298 }
1299 }
1300 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
1301 {
1302 lpString[0] = '\0';
1303 Length = 0;
1304 Wnd = NULL; /* Don't send a message */
1305 }
1306 _SEH2_END;
1307
1308 if (Wnd != NULL)
1309 Length = SendMessageW(hWnd, WM_GETTEXT, nMaxCount, (LPARAM)lpString);
1310
1311 return Length;
1312 }
1313
1314 DWORD WINAPI
1315 GetWindowThreadProcessId(HWND hWnd,
1316 LPDWORD lpdwProcessId)
1317 {
1318 DWORD Ret = 0;
1319 PTHREADINFO ti;
1320 PWND pWnd = ValidateHwnd(hWnd);
1321
1322 if (!pWnd) return Ret;
1323
1324 ti = pWnd->head.pti;
1325
1326 if (ti)
1327 {
1328 if (ti == GetW32ThreadInfo())
1329 { // We are current.
1330 //FIXME("Current!\n");
1331 if (lpdwProcessId)
1332 *lpdwProcessId = (DWORD)NtCurrentTeb()->ClientId.UniqueProcess;
1333 Ret = (DWORD)NtCurrentTeb()->ClientId.UniqueThread;
1334 }
1335 else
1336 { // Ask kernel for info.
1337 //FIXME("Kernel call!\n");
1338 if (lpdwProcessId)
1339 *lpdwProcessId = NtUserQueryWindow(hWnd, QUERY_WINDOW_UNIQUE_PROCESS_ID);
1340 Ret = NtUserQueryWindow(hWnd, QUERY_WINDOW_UNIQUE_THREAD_ID);
1341 }
1342 }
1343 return Ret;
1344 }
1345
1346
1347 /*
1348 * @implemented
1349 */
1350 BOOL WINAPI
1351 IsChild(HWND hWndParent,
1352 HWND hWnd)
1353 {
1354 PWND WndParent, Wnd;
1355 BOOL Ret = FALSE;
1356
1357 WndParent = ValidateHwnd(hWndParent);
1358 if (!WndParent)
1359 return FALSE;
1360 Wnd = ValidateHwnd(hWnd);
1361 if (!Wnd)
1362 return FALSE;
1363
1364 _SEH2_TRY
1365 {
1366 while (Wnd != NULL)
1367 {
1368 if (Wnd->spwndParent != NULL)
1369 {
1370 Wnd = DesktopPtrToUser(Wnd->spwndParent);
1371 if (Wnd == WndParent)
1372 {
1373 Ret = TRUE;
1374 break;
1375 }
1376 }
1377 else
1378 break;
1379 }
1380 }
1381 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
1382 {
1383 /* Do nothing */
1384 }
1385 _SEH2_END;
1386
1387 return Ret;
1388 }
1389
1390
1391 /*
1392 * @implemented
1393 */
1394 BOOL WINAPI
1395 IsIconic(HWND hWnd)
1396 {
1397 PWND Wnd = ValidateHwnd(hWnd);
1398
1399 if (Wnd != NULL)
1400 return (Wnd->style & WS_MINIMIZE) != 0;
1401
1402 return FALSE;
1403 }
1404
1405
1406 /*
1407 * @implemented
1408 */
1409 BOOL WINAPI
1410 IsWindow(HWND hWnd)
1411 {
1412 PWND Wnd = ValidateHwndNoErr(hWnd);
1413 if (Wnd != NULL)
1414 {
1415 /* FIXME: If window is being destroyed return FALSE! */
1416 return TRUE;
1417 }
1418
1419 return FALSE;
1420 }
1421
1422
1423 /*
1424 * @implemented
1425 */
1426 BOOL WINAPI
1427 IsWindowUnicode(HWND hWnd)
1428 {
1429 PWND Wnd = ValidateHwnd(hWnd);
1430
1431 if (Wnd != NULL)
1432 return Wnd->Unicode;
1433
1434 return FALSE;
1435 }
1436
1437
1438 /*
1439 * @implemented
1440 */
1441 BOOL WINAPI
1442 IsWindowVisible(HWND hWnd)
1443 {
1444 BOOL Ret = FALSE;
1445 PWND Wnd = ValidateHwnd(hWnd);
1446
1447 if (Wnd != NULL)
1448 {
1449 _SEH2_TRY
1450 {
1451 Ret = TRUE;
1452
1453 do
1454 {
1455 if (!(Wnd->style & WS_VISIBLE))
1456 {
1457 Ret = FALSE;
1458 break;
1459 }
1460
1461 if (Wnd->spwndParent != NULL)
1462 Wnd = DesktopPtrToUser(Wnd->spwndParent);
1463 else
1464 break;
1465
1466 } while (Wnd != NULL);
1467 }
1468 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
1469 {
1470 Ret = FALSE;
1471 }
1472 _SEH2_END;
1473 }
1474
1475 return Ret;
1476 }
1477
1478
1479 /*
1480 * @implemented
1481 */
1482 BOOL WINAPI
1483 IsWindowEnabled(HWND hWnd)
1484 {
1485 // AG: I don't know if child windows are affected if the parent is
1486 // disabled. I think they stop processing messages but stay appearing
1487 // as enabled.
1488
1489 return !(GetWindowLongPtrW(hWnd, GWL_STYLE) & WS_DISABLED);
1490 }
1491
1492
1493 /*
1494 * @implemented
1495 */
1496 BOOL WINAPI
1497 IsZoomed(HWND hWnd)
1498 {
1499 return (GetWindowLongPtrW(hWnd, GWL_STYLE) & WS_MAXIMIZE) != 0;
1500 }
1501
1502
1503 /*
1504 * @unimplemented
1505 */
1506 BOOL WINAPI
1507 LockSetForegroundWindow(UINT uLockCode)
1508 {
1509 UNIMPLEMENTED;
1510 return TRUE;
1511 }
1512
1513
1514 /*
1515 * @implemented
1516 */
1517 BOOL WINAPI
1518 AnimateWindow(HWND hwnd,
1519 DWORD dwTime,
1520 DWORD dwFlags)
1521 {
1522 /* FIXME Add animation code */
1523
1524 /* If trying to show/hide and it's already *
1525 * shown/hidden or invalid window, fail with *
1526 * invalid parameter */
1527
1528 BOOL visible;
1529 visible = IsWindowVisible(hwnd);
1530 if(!IsWindow(hwnd) ||
1531 (visible && !(dwFlags & AW_HIDE)) ||
1532 (!visible && (dwFlags & AW_HIDE)))
1533 {
1534 SetLastError(ERROR_INVALID_PARAMETER);
1535 return FALSE;
1536 }
1537
1538 ShowWindow(hwnd, (dwFlags & AW_HIDE) ? SW_HIDE : ((dwFlags & AW_ACTIVATE) ? SW_SHOW : SW_SHOWNA));
1539
1540 return TRUE;
1541 }
1542
1543
1544 /*
1545 * @implemented
1546 */
1547 BOOL WINAPI
1548 OpenIcon(HWND hWnd)
1549 {
1550 if (!(GetWindowLongPtrW(hWnd, GWL_STYLE) & WS_MINIMIZE))
1551 return FALSE;
1552
1553 ShowWindow(hWnd,SW_RESTORE);
1554 return TRUE;
1555 }
1556
1557
1558 /*
1559 * @implemented
1560 */
1561 HWND WINAPI
1562 RealChildWindowFromPoint(HWND hwndParent,
1563 POINT ptParentClientCoords)
1564 {
1565 return ChildWindowFromPointEx(hwndParent, ptParentClientCoords, CWP_SKIPTRANSPARENT);
1566 }
1567
1568 /*
1569 * @unimplemented
1570 */
1571 BOOL WINAPI
1572 SetForegroundWindow(HWND hWnd)
1573 {
1574 return NtUserCallHwndLock(hWnd, HWNDLOCK_ROUTINE_SETFOREGROUNDWINDOW);
1575 }
1576
1577
1578 /*
1579 * @unimplemented
1580 */
1581 BOOL WINAPI
1582 SetProcessDefaultLayout(DWORD dwDefaultLayout)
1583 {
1584 if (dwDefaultLayout == 0)
1585 return TRUE;
1586
1587 UNIMPLEMENTED;
1588 return FALSE;
1589 }
1590
1591
1592 /*
1593 * @implemented
1594 */
1595 BOOL WINAPI
1596 SetWindowTextA(HWND hWnd,
1597 LPCSTR lpString)
1598 {
1599 DWORD ProcessId;
1600 if(!GetWindowThreadProcessId(hWnd, &ProcessId))
1601 {
1602 return FALSE;
1603 }
1604
1605 if(ProcessId != GetCurrentProcessId())
1606 {
1607 /* do not send WM_GETTEXT messages to other processes */
1608
1609 DefSetText(hWnd, (PCWSTR)lpString, TRUE);
1610
1611 if ((GetWindowLongPtrW(hWnd, GWL_STYLE) & WS_CAPTION) == WS_CAPTION)
1612 {
1613 DefWndNCPaint(hWnd, (HRGN)1, -1);
1614 }
1615 return TRUE;
1616 }
1617
1618 return SendMessageA(hWnd, WM_SETTEXT, 0, (LPARAM)lpString);
1619 }
1620
1621
1622 /*
1623 * @implemented
1624 */
1625 BOOL WINAPI
1626 SetWindowTextW(HWND hWnd,
1627 LPCWSTR lpString)
1628 {
1629 DWORD ProcessId;
1630 if(!GetWindowThreadProcessId(hWnd, &ProcessId))
1631 {
1632 return FALSE;
1633 }
1634
1635 if(ProcessId != GetCurrentProcessId())
1636 {
1637 /* do not send WM_GETTEXT messages to other processes */
1638
1639 DefSetText(hWnd, lpString, FALSE);
1640
1641 if ((GetWindowLongPtrW(hWnd, GWL_STYLE) & WS_CAPTION) == WS_CAPTION)
1642 {
1643 DefWndNCPaint(hWnd, (HRGN)1, -1);
1644 }
1645 return TRUE;
1646 }
1647
1648 return SendMessageW(hWnd, WM_SETTEXT, 0, (LPARAM)lpString);
1649 }
1650
1651
1652 /*
1653 * @implemented
1654 */
1655 BOOL WINAPI
1656 ShowOwnedPopups(HWND hWnd,
1657 BOOL fShow)
1658 {
1659 return (BOOL)NtUserCallTwoParam((DWORD_PTR)hWnd, fShow, TWOPARAM_ROUTINE_SHOWOWNEDPOPUPS);
1660 }
1661
1662
1663 /*
1664 * @implemented
1665 */
1666 BOOL WINAPI
1667 UpdateLayeredWindow( HWND hwnd,
1668 HDC hdcDst,
1669 POINT *pptDst,
1670 SIZE *psize,
1671 HDC hdcSrc,
1672 POINT *pptSrc,
1673 COLORREF crKey,
1674 BLENDFUNCTION *pbl,
1675 DWORD dwFlags)
1676 {
1677 if ( dwFlags & ULW_EX_NORESIZE)
1678 dwFlags = ~(ULW_EX_NORESIZE|ULW_OPAQUE|ULW_ALPHA|ULW_COLORKEY);
1679 return NtUserUpdateLayeredWindow( hwnd,
1680 hdcDst,
1681 pptDst,
1682 psize,
1683 hdcSrc,
1684 pptSrc,
1685 crKey,
1686 pbl,
1687 dwFlags,
1688 NULL);
1689 }
1690
1691 /*
1692 * @implemented
1693 */
1694 BOOL WINAPI
1695 UpdateLayeredWindowIndirect(HWND hwnd,
1696 const UPDATELAYEREDWINDOWINFO *info)
1697 {
1698 if (info && info->cbSize == sizeof(info))
1699 {
1700 return NtUserUpdateLayeredWindow( hwnd,
1701 info->hdcDst,
1702 (POINT *)info->pptDst,
1703 (SIZE *)info->psize,
1704 info->hdcSrc,
1705 (POINT *)info->pptSrc,
1706 info->crKey,
1707 (BLENDFUNCTION *)info->pblend,
1708 info->dwFlags,
1709 (RECT *)info->prcDirty);
1710 }
1711 SetLastError(ERROR_INVALID_PARAMETER);
1712 return FALSE;
1713 }
1714
1715
1716 /*
1717 * @implemented
1718 */
1719 HWND WINAPI
1720 WindowFromPoint(POINT Point)
1721 {
1722 //TODO: Determine what the actual parameters to
1723 // NtUserWindowFromPoint are.
1724 return NtUserWindowFromPoint(Point.x, Point.y);
1725 }
1726
1727
1728 /*
1729 * @implemented
1730 */
1731 int WINAPI
1732 MapWindowPoints(HWND hWndFrom, HWND hWndTo, LPPOINT lpPoints, UINT cPoints)
1733 {
1734 PWND FromWnd, ToWnd;
1735 POINT Delta;
1736 UINT i;
1737
1738 FromWnd = ValidateHwndOrDesk(hWndFrom);
1739 if (!FromWnd)
1740 return 0;
1741
1742 ToWnd = ValidateHwndOrDesk(hWndTo);
1743 if (!ToWnd)
1744 return 0;
1745
1746 Delta.x = FromWnd->rcClient.left - ToWnd->rcClient.left;
1747 Delta.y = FromWnd->rcClient.top - ToWnd->rcClient.top;
1748
1749 for (i = 0; i != cPoints; i++)
1750 {
1751 lpPoints[i].x += Delta.x;
1752 lpPoints[i].y += Delta.y;
1753 }
1754
1755 return MAKELONG(LOWORD(Delta.x), LOWORD(Delta.y));
1756 }
1757
1758
1759 /*
1760 * @implemented
1761 */
1762 BOOL WINAPI
1763 ScreenToClient(HWND hWnd, LPPOINT lpPoint)
1764 {
1765 PWND Wnd, DesktopWnd;
1766
1767 Wnd = ValidateHwnd(hWnd);
1768 if (!Wnd)
1769 return FALSE;
1770
1771 DesktopWnd = GetThreadDesktopWnd();
1772
1773 lpPoint->x += DesktopWnd->rcClient.left - Wnd->rcClient.left;
1774 lpPoint->y += DesktopWnd->rcClient.top - Wnd->rcClient.top;
1775
1776 return TRUE;
1777 }
1778
1779
1780 /*
1781 * @implemented
1782 */
1783 BOOL WINAPI
1784 ClientToScreen(HWND hWnd, LPPOINT lpPoint)
1785 {
1786 PWND Wnd, DesktopWnd;
1787
1788 Wnd = ValidateHwnd(hWnd);
1789 if (!Wnd)
1790 return FALSE;
1791
1792 DesktopWnd = GetThreadDesktopWnd();
1793
1794 lpPoint->x += Wnd->rcClient.left - DesktopWnd->rcClient.left;
1795 lpPoint->y += Wnd->rcClient.top - DesktopWnd->rcClient.top;
1796
1797 return TRUE;
1798 }
1799
1800
1801 /*
1802 * @implemented
1803 */
1804 BOOL WINAPI
1805 SetWindowContextHelpId(HWND hwnd,
1806 DWORD dwContextHelpId)
1807 {
1808 return NtUserSetWindowContextHelpId(hwnd, dwContextHelpId);
1809 }
1810
1811
1812 /*
1813 * @implemented
1814 */
1815 DWORD WINAPI
1816 GetWindowContextHelpId(HWND hwnd)
1817 {
1818 return NtUserCallHwnd(hwnd, HWND_ROUTINE_GETWNDCONTEXTHLPID);
1819 }
1820
1821 /*
1822 * @implemented
1823 */
1824 int WINAPI
1825 InternalGetWindowText(HWND hWnd, LPWSTR lpString, int nMaxCount)
1826 {
1827 INT Ret = NtUserInternalGetWindowText(hWnd, lpString, nMaxCount);
1828 if (Ret == 0)
1829 *lpString = L'\0';
1830 return Ret;
1831 }
1832
1833 /*
1834 * @implemented
1835 */
1836 BOOL WINAPI
1837 IsHungAppWindow(HWND hwnd)
1838 {
1839 return (NtUserQueryWindow(hwnd, QUERY_WINDOW_ISHUNG) != 0);
1840 }
1841
1842 /*
1843 * @implemented
1844 */
1845 VOID WINAPI
1846 SetLastErrorEx(DWORD dwErrCode, DWORD dwType)
1847 {
1848 SetLastError(dwErrCode);
1849 }
1850
1851 /*
1852 * @implemented
1853 */
1854 HWND WINAPI
1855 GetFocus(VOID)
1856 {
1857 return (HWND)NtUserGetThreadState(THREADSTATE_FOCUSWINDOW);
1858 }
1859
1860 /*
1861 * @implemented
1862 */
1863 HWND WINAPI
1864 SetTaskmanWindow(HWND hWnd)
1865 {
1866 return NtUserCallHwndOpt(hWnd, HWNDOPT_ROUTINE_SETTASKMANWINDOW);
1867 }
1868
1869 /*
1870 * @implemented
1871 */
1872 HWND WINAPI
1873 SetProgmanWindow(HWND hWnd)
1874 {
1875 return NtUserCallHwndOpt(hWnd, HWNDOPT_ROUTINE_SETPROGMANWINDOW);
1876 }
1877
1878 /*
1879 * @implemented
1880 */
1881 HWND WINAPI
1882 GetProgmanWindow(VOID)
1883 {
1884 return (HWND)NtUserGetThreadState(THREADSTATE_PROGMANWINDOW);
1885 }
1886
1887 /*
1888 * @implemented
1889 */
1890 HWND WINAPI
1891 GetTaskmanWindow(VOID)
1892 {
1893 return (HWND)NtUserGetThreadState(THREADSTATE_TASKMANWINDOW);
1894 }
1895
1896 /*
1897 * @implemented
1898 */
1899 BOOL WINAPI
1900 ScrollWindow(HWND hWnd,
1901 int dx,
1902 int dy,
1903 CONST RECT *lpRect,
1904 CONST RECT *prcClip)
1905 {
1906 return NtUserScrollWindowEx(hWnd,
1907 dx,
1908 dy,
1909 lpRect,
1910 prcClip,
1911 0,
1912 NULL,
1913 (lpRect ? 0 : SW_SCROLLCHILDREN) | SW_INVALIDATE) != ERROR;
1914 }
1915
1916
1917 /*
1918 * @implemented
1919 */
1920 INT WINAPI
1921 ScrollWindowEx(HWND hWnd,
1922 int dx,
1923 int dy,
1924 CONST RECT *prcScroll,
1925 CONST RECT *prcClip,
1926 HRGN hrgnUpdate,
1927 LPRECT prcUpdate,
1928 UINT flags)
1929 {
1930 return NtUserScrollWindowEx(hWnd,
1931 dx,
1932 dy,
1933 prcScroll,
1934 prcClip,
1935 hrgnUpdate,
1936 prcUpdate,
1937 flags);
1938 }
1939
1940 /*
1941 * @implemented
1942 */
1943 WORD
1944 WINAPI
1945 TileChildWindows(HWND hWndParent, WORD wFlags)
1946 {
1947 return TileWindows(hWndParent, wFlags, NULL, 0, NULL);
1948 }
1949
1950 /*
1951 * @implemented
1952 */
1953 BOOL WINAPI
1954 AnyPopup(VOID)
1955 {
1956 return NtUserAnyPopup();
1957 }
1958
1959 /*
1960 * @implemented
1961 */
1962 BOOL WINAPI
1963 IsWindowInDestroy(HWND hWnd)
1964 {
1965 return NtUserIsWindowInDestroy(hWnd);
1966 }
1967
1968 /*
1969 * @implemented
1970 */
1971 VOID WINAPI
1972 DisableProcessWindowsGhosting(VOID)
1973 {
1974 NtUserEnableProcessWindowGhosting(FALSE);
1975 }
1976
1977 /* EOF */
1978