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