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