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