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