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