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