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