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 * PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
7 * Katayama Hirofumi MZ (katayama.hirofumi.mz@gmail.com)
9 * 06-06-2001 CSH Created
15 WINE_DEFAULT_DEBUG_CHANNEL(user32
);
17 void MDI_CalcDefaultChildPos( HWND hwndClient
, INT total
, LPPOINT lpPos
, INT delta
, UINT
*id
);
18 extern LPCWSTR FASTCALL
ClassNameToVersion(const void *lpszClass
, LPCWSTR lpszMenuName
, LPCWSTR
*plpLibFileName
, HANDLE
*pContext
, BOOL bAnsi
);
20 /* FUNCTIONS *****************************************************************/
24 User32CallSendAsyncProcForKernel(PVOID Arguments
, ULONG ArgumentLength
)
26 PSENDASYNCPROC_CALLBACK_ARGUMENTS CallbackArgs
;
28 TRACE("User32CallSendAsyncProcKernel()\n");
30 CallbackArgs
= (PSENDASYNCPROC_CALLBACK_ARGUMENTS
)Arguments
;
32 if (ArgumentLength
!= sizeof(SENDASYNCPROC_CALLBACK_ARGUMENTS
))
34 return(STATUS_INFO_LENGTH_MISMATCH
);
37 CallbackArgs
->Callback(CallbackArgs
->Wnd
,
39 CallbackArgs
->Context
,
40 CallbackArgs
->Result
);
41 return(STATUS_SUCCESS
);
49 AllowSetForegroundWindow(DWORD dwProcessId
)
51 return NtUserxAllowSetForegroundWindow(dwProcessId
);
59 BeginDeferWindowPos(int nNumWindows
)
61 return NtUserxBeginDeferWindowPos(nNumWindows
);
69 BringWindowToTop(HWND hWnd
)
71 return NtUserSetWindowPos(hWnd
,
77 SWP_NOSIZE
| SWP_NOMOVE
);
82 SwitchToThisWindow(HWND hwnd
, BOOL fAltTab
)
84 NtUserxSwitchToThisWindow(hwnd
, fAltTab
);
92 ChildWindowFromPoint(HWND hWndParent
,
95 return (HWND
) NtUserChildWindowFromPointEx(hWndParent
, Point
.x
, Point
.y
, 0);
103 ChildWindowFromPointEx(HWND hwndParent
,
107 return (HWND
) NtUserChildWindowFromPointEx(hwndParent
, pt
.x
, pt
.y
, uFlags
);
115 CloseWindow(HWND hWnd
)
117 /* NOTE: CloseWindow does minimizes, and doesn't close. */
118 SetActiveWindow(hWnd
);
119 return ShowWindow(hWnd
, SW_SHOWMINIMIZED
);
125 OUT PLARGE_STRING plstr
,
131 RtlInitLargeUnicodeString((PLARGE_UNICODE_STRING
)plstr
, (PWSTR
)psz
, 0);
135 RtlInitLargeAnsiString((PLARGE_ANSI_STRING
)plstr
, (PSTR
)psz
, 0);
142 IN PLARGE_STRING LargeString
)
144 if (LargeString
->Buffer
)
146 RtlFreeHeap(GetProcessHeap(), 0, LargeString
->Buffer
);
147 RtlZeroMemory(LargeString
, sizeof(LARGE_STRING
));
153 RtlGetExpWinVer( HMODULE hModule
)
155 DWORD dwMajorVersion
= 3; // Set default to Windows 3.10.
156 DWORD dwMinorVersion
= 10;
157 PIMAGE_NT_HEADERS pinth
;
159 if ( hModule
&& !((ULONG_PTR
)hModule
>> 16))
161 pinth
= RtlImageNtHeader( hModule
);
163 dwMajorVersion
= pinth
->OptionalHeader
.MajorSubsystemVersion
;
165 if ( dwMajorVersion
== 1 )
171 dwMinorVersion
= pinth
->OptionalHeader
.MinorSubsystemVersion
;
174 return MAKELONG(MAKEWORD(dwMinorVersion
, dwMajorVersion
), 0);
178 User32CreateWindowEx(DWORD dwExStyle
,
192 LARGE_STRING WindowName
;
193 LARGE_STRING lstrClassName
, *plstrClassName
;
194 LARGE_STRING lstrClassVersion
, *plstrClassVersion
;
195 UNICODE_STRING ClassName
;
196 UNICODE_STRING ClassVersion
;
199 HMODULE hLibModule
= NULL
;
201 BOOL Unicode
, ClassFound
= FALSE
;
203 LPCWSTR lpszClsVersion
;
204 LPCWSTR lpLibFileName
= NULL
;
209 DbgPrint("[window] User32CreateWindowEx style %d, exstyle %d, parent %d\n", dwStyle
, dwExStyle
, hWndParent
);
212 dwFlagsVer
= RtlGetExpWinVer( hInstance
? hInstance
: GetModuleHandleW(NULL
) );
213 TRACE("Module Version %x\n",dwFlagsVer
);
215 if (!RegisterDefaultClasses
)
217 TRACE("RegisterSystemControls\n");
218 RegisterSystemControls();
221 Unicode
= !(dwFlags
& NUCWE_ANSI
);
223 if (IS_ATOM(lpClassName
))
225 plstrClassName
= (PVOID
)lpClassName
;
231 RtlInitUnicodeString(&ClassName
, (PCWSTR
)lpClassName
);
235 if (!RtlCreateUnicodeStringFromAsciiz(&ClassName
, (PCSZ
)lpClassName
))
237 SetLastError(ERROR_OUTOFMEMORY
);
242 /* Copy it to a LARGE_STRING */
243 lstrClassName
.Buffer
= ClassName
.Buffer
;
244 lstrClassName
.Length
= ClassName
.Length
;
245 lstrClassName
.MaximumLength
= ClassName
.MaximumLength
;
246 plstrClassName
= &lstrClassName
;
249 /* Initialize a LARGE_STRING */
250 RtlInitLargeString(&WindowName
, lpWindowName
, Unicode
);
252 // HACK: The current implementation expects the Window name to be UNICODE
256 PSTR AnsiBuffer
= WindowName
.Buffer
;
257 ULONG AnsiLength
= WindowName
.Length
;
259 WindowName
.Length
= 0;
260 WindowName
.MaximumLength
= AnsiLength
* sizeof(WCHAR
);
261 WindowName
.Buffer
= RtlAllocateHeap(RtlGetProcessHeap(),
263 WindowName
.MaximumLength
);
264 if (!WindowName
.Buffer
)
266 SetLastError(ERROR_OUTOFMEMORY
);
270 Status
= RtlMultiByteToUnicodeN(WindowName
.Buffer
,
271 WindowName
.MaximumLength
,
275 if (!NT_SUCCESS(Status
))
281 if (!hMenu
&& (dwStyle
& (WS_OVERLAPPEDWINDOW
| WS_POPUP
)))
285 wceW
.cbSize
= sizeof(wceW
);
286 if (GetClassInfoExW(hInstance
, (LPCWSTR
)lpClassName
, &wceW
) && wceW
.lpszMenuName
)
288 hMenu
= LoadMenuW(hInstance
, wceW
.lpszMenuName
);
293 wceA
.cbSize
= sizeof(wceA
);
294 if (GetClassInfoExA(hInstance
, lpClassName
, &wceA
) && wceA
.lpszMenuName
)
296 hMenu
= LoadMenuA(hInstance
, wceA
.lpszMenuName
);
301 if (!Unicode
) dwExStyle
|= WS_EX_SETANSICREATOR
;
303 lpszClsVersion
= ClassNameToVersion(lpClassName
, NULL
, &lpLibFileName
, &pCtx
, !Unicode
);
306 plstrClassVersion
= plstrClassName
;
310 RtlInitUnicodeString(&ClassVersion
, lpszClsVersion
);
311 lstrClassVersion
.Buffer
= ClassVersion
.Buffer
;
312 lstrClassVersion
.Length
= ClassVersion
.Length
;
313 lstrClassVersion
.MaximumLength
= ClassVersion
.MaximumLength
;
314 plstrClassVersion
= &lstrClassVersion
;
319 Handle
= NtUserCreateWindowEx(dwExStyle
,
335 if (!lpLibFileName
) break;
338 dwLastError
= GetLastError();
339 if (dwLastError
== ERROR_CANNOT_FIND_WND_CLASS
)
341 ClassFound
= VersionRegisterClass(ClassName
.Buffer
, lpLibFileName
, pCtx
, &hLibModule
);
342 if (ClassFound
) continue;
347 dwLastError
= GetLastError();
348 FreeLibrary(hLibModule
);
349 SetLastError(dwLastError
);
356 DbgPrint("[window] NtUserCreateWindowEx() == %d\n", Handle
);
362 if (!IS_ATOM(lpClassName
))
363 RtlFreeUnicodeString(&ClassName
);
365 RtlFreeLargeString(&WindowName
);
378 CreateWindowExA(DWORD dwExStyle
,
391 MDICREATESTRUCTA mdi
;
394 if (!RegisterDefaultClasses
)
396 TRACE("CreateWindowExA RegisterSystemControls\n");
397 RegisterSystemControls();
400 if (dwExStyle
& WS_EX_MDICHILD
)
407 pWndParent
= ValidateHwnd(hWndParent
);
409 if (!pWndParent
) return NULL
;
411 if (pWndParent
->fnid
!= FNID_MDICLIENT
) // wine uses WIN_ISMDICLIENT
413 WARN("WS_EX_MDICHILD, but parent %p is not MDIClient\n", hWndParent
);
417 /* lpParams of WM_[NC]CREATE is different for MDI children.
418 * MDICREATESTRUCT members have the originally passed values.
420 mdi
.szClass
= lpClassName
;
421 mdi
.szTitle
= lpWindowName
;
422 mdi
.hOwner
= hInstance
;
428 mdi
.lParam
= (LPARAM
)lpParam
;
430 lpParam
= (LPVOID
)&mdi
;
432 if (pWndParent
->style
& MDIS_ALLCHILDSTYLES
)
434 if (dwStyle
& WS_POPUP
)
436 WARN("WS_POPUP with MDIS_ALLCHILDSTYLES is not allowed\n");
439 dwStyle
|= (WS_CHILD
| WS_CLIPSIBLINGS
);
443 dwStyle
&= ~WS_POPUP
;
444 dwStyle
|= (WS_CHILD
| WS_VISIBLE
| WS_CLIPSIBLINGS
| WS_CAPTION
|
445 WS_SYSMENU
| WS_THICKFRAME
| WS_MINIMIZEBOX
| WS_MAXIMIZEBOX
);
448 top_child
= GetWindow(hWndParent
, GW_CHILD
);
452 /* Restore current maximized child */
453 if((dwStyle
& WS_VISIBLE
) && IsZoomed(top_child
))
455 TRACE("Restoring current maximized child %p\n", top_child
);
456 SendMessageW( top_child
, WM_SETREDRAW
, FALSE
, 0 );
457 ShowWindow(top_child
, SW_RESTORE
);
458 SendMessageW( top_child
, WM_SETREDRAW
, TRUE
, 0 );
462 MDI_CalcDefaultChildPos(hWndParent
, -1, mPos
, 0, &id
);
464 if (!(dwStyle
& WS_POPUP
)) hMenu
= UlongToHandle(id
);
466 if (dwStyle
& (WS_CHILD
| WS_POPUP
))
468 if (x
== CW_USEDEFAULT
|| x
== CW_USEDEFAULT16
)
473 if (nWidth
== CW_USEDEFAULT
|| nWidth
== CW_USEDEFAULT16
|| !nWidth
)
475 if (nHeight
== CW_USEDEFAULT
|| nHeight
== CW_USEDEFAULT16
|| !nHeight
)
480 hwnd
= User32CreateWindowEx(dwExStyle
,
503 CreateWindowExW(DWORD dwExStyle
,
505 LPCWSTR lpWindowName
,
516 MDICREATESTRUCTW mdi
;
519 if (!RegisterDefaultClasses
)
521 ERR("CreateWindowExW RegisterSystemControls\n");
522 RegisterSystemControls();
525 if (dwExStyle
& WS_EX_MDICHILD
)
532 pWndParent
= ValidateHwnd(hWndParent
);
534 if (!pWndParent
) return NULL
;
536 if (pWndParent
->fnid
!= FNID_MDICLIENT
)
538 WARN("WS_EX_MDICHILD, but parent %p is not MDIClient\n", hWndParent
);
542 /* lpParams of WM_[NC]CREATE is different for MDI children.
543 * MDICREATESTRUCT members have the originally passed values.
545 mdi
.szClass
= lpClassName
;
546 mdi
.szTitle
= lpWindowName
;
547 mdi
.hOwner
= hInstance
;
553 mdi
.lParam
= (LPARAM
)lpParam
;
555 lpParam
= (LPVOID
)&mdi
;
557 if (pWndParent
->style
& MDIS_ALLCHILDSTYLES
)
559 if (dwStyle
& WS_POPUP
)
561 WARN("WS_POPUP with MDIS_ALLCHILDSTYLES is not allowed\n");
564 dwStyle
|= (WS_CHILD
| WS_CLIPSIBLINGS
);
568 dwStyle
&= ~WS_POPUP
;
569 dwStyle
|= (WS_CHILD
| WS_VISIBLE
| WS_CLIPSIBLINGS
| WS_CAPTION
|
570 WS_SYSMENU
| WS_THICKFRAME
| WS_MINIMIZEBOX
| WS_MAXIMIZEBOX
);
573 top_child
= GetWindow(hWndParent
, GW_CHILD
);
577 /* Restore current maximized child */
578 if((dwStyle
& WS_VISIBLE
) && IsZoomed(top_child
))
580 TRACE("Restoring current maximized child %p\n", top_child
);
581 SendMessageW( top_child
, WM_SETREDRAW
, FALSE
, 0 );
582 ShowWindow(top_child
, SW_RESTORE
);
583 SendMessageW( top_child
, WM_SETREDRAW
, TRUE
, 0 );
587 MDI_CalcDefaultChildPos(hWndParent
, -1, mPos
, 0, &id
);
589 if (!(dwStyle
& WS_POPUP
)) hMenu
= UlongToHandle(id
);
591 if (dwStyle
& (WS_CHILD
| WS_POPUP
))
593 if (x
== CW_USEDEFAULT
|| x
== CW_USEDEFAULT16
)
598 if (nWidth
== CW_USEDEFAULT
|| nWidth
== CW_USEDEFAULT16
|| !nWidth
)
600 if (nHeight
== CW_USEDEFAULT
|| nHeight
== CW_USEDEFAULT16
|| !nHeight
)
605 hwnd
= User32CreateWindowEx(dwExStyle
,
607 (LPCSTR
)lpWindowName
,
625 DeferWindowPos(HDWP hWinPosInfo
,
627 HWND hWndInsertAfter
,
634 return NtUserDeferWindowPos(hWinPosInfo
, hWnd
, hWndInsertAfter
, x
, y
, cx
, cy
, uFlags
);
642 EndDeferWindowPos(HDWP hWinPosInfo
)
644 return NtUserEndDeferWindowPosEx(hWinPosInfo
, 0);
652 GetDesktopWindow(VOID
)
659 Wnd
= GetThreadDesktopWnd();
661 Ret
= UserHMGetHandle(Wnd
);
663 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
674 User32EnumWindows(HDESK hDesktop
,
681 DWORD i
, dwCount
= 0;
688 SetLastError ( ERROR_INVALID_PARAMETER
);
692 /* FIXME instead of always making two calls, should we use some
693 sort of persistent buffer and only grow it ( requiring a 2nd
694 call ) when the buffer wasn't already big enough? */
695 /* first get how many window entries there are */
696 Status
= NtUserBuildHwndList(hDesktop
,
703 if (!NT_SUCCESS(Status
))
714 /* allocate buffer to receive HWND handles */
715 hHeap
= GetProcessHeap();
716 pHwnd
= HeapAlloc(hHeap
, 0, sizeof(HWND
)*(dwCount
+1));
719 SetLastError ( ERROR_NOT_ENOUGH_MEMORY
);
723 /* now call kernel again to fill the buffer this time */
724 Status
= NtUserBuildHwndList(hDesktop
,
731 if (!NT_SUCCESS(Status
))
734 HeapFree(hHeap
, 0, pHwnd
);
738 /* call the user's callback function until we're done or
739 they tell us to quit */
740 for ( i
= 0; i
< dwCount
; i
++ )
742 /* FIXME I'm only getting NULLs from Thread Enumeration, and it's
743 * probably because I'm not doing it right in NtUserBuildHwndList.
744 * Once that's fixed, we shouldn't have to check for a NULL HWND
746 * This is now fixed in revision 50205. (jt)
748 if (!pHwnd
[i
]) /* don't enumerate a NULL HWND */
750 if (!(*lpfn
)(pHwnd
[i
], lParam
))
752 HeapFree ( hHeap
, 0, pHwnd
);
757 HeapFree(hHeap
, 0, pHwnd
);
766 EnumChildWindows(HWND hWndParent
,
767 WNDENUMPROC lpEnumFunc
,
772 return EnumWindows(lpEnumFunc
, lParam
);
774 return User32EnumWindows(NULL
, hWndParent
, lpEnumFunc
, lParam
, 0, TRUE
);
782 EnumThreadWindows(DWORD dwThreadId
,
787 dwThreadId
= GetCurrentThreadId();
788 return User32EnumWindows(NULL
, NULL
, lpfn
, lParam
, dwThreadId
, FALSE
);
796 EnumWindows(WNDENUMPROC lpEnumFunc
,
799 return User32EnumWindows(NULL
, NULL
, lpEnumFunc
, lParam
, 0, FALSE
);
807 EnumDesktopWindows(HDESK hDesktop
,
811 return User32EnumWindows(hDesktop
, NULL
, lpfn
, lParam
, 0, FALSE
);
819 FindWindowExA(HWND hwndParent
,
824 LPWSTR titleW
= NULL
;
829 DWORD len
= MultiByteToWideChar( CP_ACP
, 0, lpszWindow
, -1, NULL
, 0 );
830 if (!(titleW
= HeapAlloc( GetProcessHeap(), 0, len
* sizeof(WCHAR
) ))) return 0;
831 MultiByteToWideChar( CP_ACP
, 0, lpszWindow
, -1, titleW
, len
);
834 if (!IS_INTRESOURCE(lpszClass
))
837 if (MultiByteToWideChar( CP_ACP
, 0, lpszClass
, -1, classW
, sizeof(classW
)/sizeof(WCHAR
) ))
838 hwnd
= FindWindowExW( hwndParent
, hwndChildAfter
, classW
, titleW
);
842 hwnd
= FindWindowExW( hwndParent
, hwndChildAfter
, (LPCWSTR
)lpszClass
, titleW
);
845 HeapFree( GetProcessHeap(), 0, titleW
);
854 FindWindowExW(HWND hwndParent
,
859 UNICODE_STRING ucClassName
, *pucClassName
= NULL
;
860 UNICODE_STRING ucWindowName
, *pucWindowName
= NULL
;
862 if (IS_ATOM(lpszClass
))
864 ucClassName
.Length
= 0;
865 ucClassName
.Buffer
= (LPWSTR
)lpszClass
;
866 pucClassName
= &ucClassName
;
868 else if (lpszClass
!= NULL
)
870 RtlInitUnicodeString(&ucClassName
,
872 pucClassName
= &ucClassName
;
875 if (lpszWindow
!= NULL
)
877 RtlInitUnicodeString(&ucWindowName
,
879 pucWindowName
= &ucWindowName
;
882 return NtUserFindWindowEx(hwndParent
,
894 FindWindowA(LPCSTR lpClassName
, LPCSTR lpWindowName
)
896 //FIXME: FindWindow does not search children, but FindWindowEx does.
897 // what should we do about this?
898 return FindWindowExA (NULL
, NULL
, lpClassName
, lpWindowName
);
906 FindWindowW(LPCWSTR lpClassName
, LPCWSTR lpWindowName
)
910 There was a FIXME here earlier, but I think it is just a documentation unclarity.
912 FindWindow only searches top level windows. What they mean is that child
913 windows of other windows than the desktop can be searched.
914 FindWindowExW never does a recursive search.
919 return FindWindowExW(NULL
, NULL
, lpClassName
, lpWindowName
);
928 GetAltTabInfoA(HWND hwnd
,
934 return NtUserGetAltTabInfo(hwnd
,iItem
,pati
,(LPWSTR
)pszItemText
,cchItemText
,TRUE
);
942 GetAltTabInfoW(HWND hwnd
,
948 return NtUserGetAltTabInfo(hwnd
,iItem
,pati
,pszItemText
,cchItemText
,FALSE
);
956 GetAncestor(HWND hwnd
, UINT gaFlags
)
961 Wnd
= ValidateHwnd(hwnd
);
971 if (Wnd
->spwndParent
!= NULL
)
972 Ancestor
= DesktopPtrToUser(Wnd
->spwndParent
);
976 /* FIXME: Call win32k for now */
981 if (Ancestor
!= NULL
)
982 Ret
= UserHMGetHandle(Ancestor
);
984 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
990 if (!Wnd
) /* Fall back */
991 Ret
= NtUserGetAncestor(hwnd
, gaFlags
);
1001 GetClientRect(HWND hWnd
, LPRECT lpRect
)
1003 PWND Wnd
= ValidateHwnd(hWnd
);
1005 if (!Wnd
) return FALSE
;
1006 if (Wnd
->style
& WS_MINIMIZED
)
1008 lpRect
->left
= lpRect
->top
= 0;
1009 lpRect
->right
= GetSystemMetrics(SM_CXMINIMIZED
);
1010 lpRect
->bottom
= GetSystemMetrics(SM_CYMINIMIZED
);
1013 if ( hWnd
!= GetDesktopWindow()) // Wnd->fnid != FNID_DESKTOP )
1015 /* lpRect->left = lpRect->top = 0;
1016 lpRect->right = Wnd->rcClient.right - Wnd->rcClient.left;
1017 lpRect->bottom = Wnd->rcClient.bottom - Wnd->rcClient.top;
1019 *lpRect
= Wnd
->rcClient
;
1020 OffsetRect(lpRect
, -Wnd
->rcClient
.left
, -Wnd
->rcClient
.top
);
1024 lpRect
->left
= lpRect
->top
= 0;
1025 lpRect
->right
= Wnd
->rcClient
.right
;
1026 lpRect
->bottom
= Wnd
->rcClient
.bottom
;
1027 /* Do this until Init bug is fixed. This sets 640x480, see InitMetrics.
1028 lpRect->right = GetSystemMetrics(SM_CXSCREEN);
1029 lpRect->bottom = GetSystemMetrics(SM_CYSCREEN);
1039 GetLastActivePopup(HWND hWnd
)
1044 Wnd
= ValidateHwnd(hWnd
);
1049 if (Wnd
->spwndLastActive
)
1051 PWND LastActive
= DesktopPtrToUser(Wnd
->spwndLastActive
);
1052 Ret
= UserHMGetHandle(LastActive
);
1055 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
1069 GetParent(HWND hWnd
)
1071 PWND Wnd
, WndParent
;
1074 Wnd
= ValidateHwnd(hWnd
);
1080 if (Wnd
->style
& WS_POPUP
)
1082 if (Wnd
->spwndOwner
!= NULL
)
1083 WndParent
= DesktopPtrToUser(Wnd
->spwndOwner
);
1085 else if (Wnd
->style
& WS_CHILD
)
1087 if (Wnd
->spwndParent
!= NULL
)
1088 WndParent
= DesktopPtrToUser(Wnd
->spwndParent
);
1091 if (WndParent
!= NULL
)
1092 Ret
= UserHMGetHandle(WndParent
);
1094 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
1109 GetProcessDefaultLayout(DWORD
*pdwDefaultLayout
)
1111 return (BOOL
)NtUserCallOneParam( (DWORD_PTR
)pdwDefaultLayout
, ONEPARAM_ROUTINE_GETPROCDEFLAYOUT
);
1119 GetWindow(HWND hWnd
,
1125 Wnd
= ValidateHwnd(hWnd
);
1135 if (Wnd
->spwndOwner
!= NULL
)
1136 FoundWnd
= DesktopPtrToUser(Wnd
->spwndOwner
);
1140 if(Wnd
->spwndParent
!= NULL
)
1142 FoundWnd
= DesktopPtrToUser(Wnd
->spwndParent
);
1143 if (FoundWnd
->spwndChild
!= NULL
)
1144 FoundWnd
= DesktopPtrToUser(FoundWnd
->spwndChild
);
1148 if (Wnd
->spwndNext
!= NULL
)
1149 FoundWnd
= DesktopPtrToUser(Wnd
->spwndNext
);
1153 if (Wnd
->spwndPrev
!= NULL
)
1154 FoundWnd
= DesktopPtrToUser(Wnd
->spwndPrev
);
1158 if (Wnd
->spwndChild
!= NULL
)
1159 FoundWnd
= DesktopPtrToUser(Wnd
->spwndChild
);
1164 while ( FoundWnd
->spwndNext
!= NULL
)
1165 FoundWnd
= DesktopPtrToUser(FoundWnd
->spwndNext
);
1173 if (FoundWnd
!= NULL
)
1174 Ret
= UserHMGetHandle(FoundWnd
);
1176 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
1190 GetTopWindow(HWND hWnd
)
1192 if (!hWnd
) hWnd
= GetDesktopWindow();
1193 return GetWindow(hWnd
, GW_CHILD
);
1203 GetWindowInfo(HWND hWnd
,
1211 if ( !pwi
|| pwi
->cbSize
!= sizeof(WINDOWINFO
))
1212 SetLastError(ERROR_INVALID_PARAMETER
); // Just set the error and go!
1214 pWnd
= ValidateHwnd(hWnd
);
1218 UserGetWindowBorders(pWnd
->style
, pWnd
->ExStyle
, &Size
, FALSE
);
1222 pCls
= DesktopPtrToUser(pWnd
->pcls
);
1223 pwi
->rcWindow
= pWnd
->rcWindow
;
1224 pwi
->rcClient
= pWnd
->rcClient
;
1225 pwi
->dwStyle
= pWnd
->style
;
1226 pwi
->dwExStyle
= pWnd
->ExStyle
;
1227 pwi
->cxWindowBorders
= Size
.cx
;
1228 pwi
->cyWindowBorders
= Size
.cy
;
1229 pwi
->dwWindowStatus
= 0;
1230 if (pWnd
->state
& WNDS_ACTIVEFRAME
|| (GetActiveWindow() == hWnd
))
1231 pwi
->dwWindowStatus
= WS_ACTIVECAPTION
;
1232 pwi
->atomWindowType
= (pCls
? pCls
->atomClassName
: 0 );
1234 if ( pWnd
->state2
& WNDS2_WIN50COMPAT
)
1236 pwi
->wCreatorVersion
= 0x500;
1238 else if ( pWnd
->state2
& WNDS2_WIN40COMPAT
)
1240 pwi
->wCreatorVersion
= 0x400;
1242 else if ( pWnd
->state2
& WNDS2_WIN31COMPAT
)
1244 pwi
->wCreatorVersion
= 0x30A;
1248 pwi
->wCreatorVersion
= 0x300;
1253 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
1267 GetWindowModuleFileNameA(HWND hwnd
,
1269 UINT cchFileNameMax
)
1271 PWND Wnd
= ValidateHwnd(hwnd
);
1276 return GetModuleFileNameA(Wnd
->hModule
, lpszFileName
, cchFileNameMax
);
1284 GetWindowModuleFileNameW(HWND hwnd
,
1285 LPWSTR lpszFileName
,
1286 UINT cchFileNameMax
)
1288 PWND Wnd
= ValidateHwnd(hwnd
);
1293 return GetModuleFileNameW( Wnd
->hModule
, lpszFileName
, cchFileNameMax
);
1300 GetWindowRect(HWND hWnd
,
1303 PWND Wnd
= ValidateHwnd(hWnd
);
1305 if (!Wnd
) return FALSE
;
1306 if ( hWnd
!= GetDesktopWindow()) // Wnd->fnid != FNID_DESKTOP )
1308 *lpRect
= Wnd
->rcWindow
;
1312 lpRect
->left
= lpRect
->top
= 0;
1313 lpRect
->right
= Wnd
->rcWindow
.right
;
1314 lpRect
->bottom
= Wnd
->rcWindow
.bottom
;
1315 /* Do this until Init bug is fixed. This sets 640x480, see InitMetrics.
1316 lpRect->right = GetSystemMetrics(SM_CXSCREEN);
1317 lpRect->bottom = GetSystemMetrics(SM_CYSCREEN);
1326 GetWindowTextA(HWND hWnd
, LPSTR lpString
, int nMaxCount
)
1331 if (lpString
== NULL
|| nMaxCount
== 0)
1334 Wnd
= ValidateHwnd(hWnd
);
1340 if (!TestWindowProcess(Wnd
))
1344 Length
= DefWindowProcA(hWnd
, WM_GETTEXT
, nMaxCount
, (LPARAM
)lpString
);
1346 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
1354 Length
= SendMessageA(hWnd
, WM_GETTEXT
, nMaxCount
, (LPARAM
)lpString
);
1356 //ERR("GWTA Len %d : %s\n",Length,lpString);
1364 GetWindowTextLengthA(HWND hWnd
)
1368 Wnd
= ValidateHwnd(hWnd
);
1372 if (!TestWindowProcess(Wnd
))
1374 return DefWindowProcA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
1378 return SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
1386 GetWindowTextLengthW(HWND hWnd
)
1390 Wnd
= ValidateHwnd(hWnd
);
1394 if (!TestWindowProcess(Wnd
))
1396 return DefWindowProcW(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
1400 return SendMessageW(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
1408 GetWindowTextW(HWND hWnd
, LPWSTR lpString
, int nMaxCount
)
1413 if (lpString
== NULL
|| nMaxCount
== 0)
1416 Wnd
= ValidateHwnd(hWnd
);
1420 lpString
[0] = L
'\0';
1422 if (!TestWindowProcess(Wnd
))
1426 Length
= DefWindowProcW(hWnd
, WM_GETTEXT
, nMaxCount
, (LPARAM
)lpString
);
1428 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
1436 Length
= SendMessageW(hWnd
, WM_GETTEXT
, nMaxCount
, (LPARAM
)lpString
);
1438 //ERR("GWTW Len %d : %S\n",Length,lpString);
1443 GetWindowThreadProcessId(HWND hWnd
,
1444 LPDWORD lpdwProcessId
)
1448 PWND pWnd
= ValidateHwnd(hWnd
);
1450 if (!pWnd
) return Ret
;
1452 ti
= pWnd
->head
.pti
;
1456 if (ti
== GetW32ThreadInfo())
1457 { // We are current.
1458 //FIXME("Current!\n");
1460 *lpdwProcessId
= (DWORD_PTR
)NtCurrentTeb()->ClientId
.UniqueProcess
;
1461 Ret
= (DWORD_PTR
)NtCurrentTeb()->ClientId
.UniqueThread
;
1464 { // Ask kernel for info.
1465 //FIXME("Kernel call!\n");
1467 *lpdwProcessId
= NtUserQueryWindow(hWnd
, QUERY_WINDOW_UNIQUE_PROCESS_ID
);
1468 Ret
= NtUserQueryWindow(hWnd
, QUERY_WINDOW_UNIQUE_THREAD_ID
);
1479 IsChild(HWND hWndParent
,
1482 PWND WndParent
, DesktopWnd
, Wnd
;
1485 WndParent
= ValidateHwnd(hWndParent
);
1488 Wnd
= ValidateHwnd(hWnd
);
1492 DesktopWnd
= GetThreadDesktopWnd();
1498 while (Wnd
!= NULL
&& ((Wnd
->style
& (WS_POPUP
|WS_CHILD
)) == WS_CHILD
))
1500 if (Wnd
->spwndParent
!= NULL
)
1502 Wnd
= DesktopPtrToUser(Wnd
->spwndParent
);
1504 if (Wnd
== WndParent
)
1514 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
1530 PWND Wnd
= ValidateHwnd(hWnd
);
1533 return (Wnd
->style
& WS_MINIMIZE
) != 0;
1545 PWND Wnd
= ValidateHwndNoErr(hWnd
);
1548 if (Wnd
->state
& WNDS_DESTROYED
||
1549 Wnd
->state2
& WNDS2_INDESTROY
)
1562 IsWindowUnicode(HWND hWnd
)
1564 PWND Wnd
= ValidateHwnd(hWnd
);
1567 return Wnd
->Unicode
;
1577 IsWindowVisible(HWND hWnd
)
1580 PWND Wnd
= ValidateHwnd(hWnd
);
1590 if (!(Wnd
->style
& WS_VISIBLE
))
1596 if (Wnd
->spwndParent
!= NULL
)
1597 Wnd
= DesktopPtrToUser(Wnd
->spwndParent
);
1601 } while (Wnd
!= NULL
);
1603 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
1618 IsWindowEnabled(HWND hWnd
)
1620 // AG: I don't know if child windows are affected if the parent is
1621 // disabled. I think they stop processing messages but stay appearing
1624 return !(GetWindowLongPtrW(hWnd
, GWL_STYLE
) & WS_DISABLED
);
1634 return (GetWindowLongPtrW(hWnd
, GWL_STYLE
) & WS_MAXIMIZE
) != 0;
1642 LockSetForegroundWindow(UINT uLockCode
)
1644 return NtUserxLockSetForegroundWindow(uLockCode
);
1652 AnimateWindow(HWND hwnd
,
1656 /* FIXME Add animation code */
1658 /* If trying to show/hide and it's already *
1659 * shown/hidden or invalid window, fail with *
1660 * invalid parameter */
1663 visible
= IsWindowVisible(hwnd
);
1664 if(!IsWindow(hwnd
) ||
1665 (visible
&& !(dwFlags
& AW_HIDE
)) ||
1666 (!visible
&& (dwFlags
& AW_HIDE
)))
1668 SetLastError(ERROR_INVALID_PARAMETER
);
1672 ShowWindow(hwnd
, (dwFlags
& AW_HIDE
) ? SW_HIDE
: ((dwFlags
& AW_ACTIVATE
) ? SW_SHOW
: SW_SHOWNA
));
1684 if (!(GetWindowLongPtrW(hWnd
, GWL_STYLE
) & WS_MINIMIZE
))
1687 ShowWindow(hWnd
,SW_RESTORE
);
1696 RealChildWindowFromPoint(HWND hwndParent
,
1697 POINT ptParentClientCoords
)
1699 return NtUserRealChildWindowFromPoint(hwndParent
, ptParentClientCoords
.x
, ptParentClientCoords
.y
);
1706 SetForegroundWindow(HWND hWnd
)
1708 return NtUserxSetForegroundWindow(hWnd
);
1716 SetProcessDefaultLayout(DWORD dwDefaultLayout
)
1718 return NtUserCallOneParam( (DWORD_PTR
)dwDefaultLayout
, ONEPARAM_ROUTINE_SETPROCDEFLAYOUT
);
1728 SetWindowTextA(HWND hWnd
,
1733 pwnd
= ValidateHwnd(hWnd
);
1736 if (!TestWindowProcess(pwnd
))
1738 /* do not send WM_GETTEXT messages to other processes */
1739 return (DefWindowProcA(hWnd
, WM_SETTEXT
, 0, (LPARAM
)lpString
) >= 0);
1741 return (SendMessageA(hWnd
, WM_SETTEXT
, 0, (LPARAM
)lpString
) >= 0);
1753 SetWindowTextW(HWND hWnd
,
1758 pwnd
= ValidateHwnd(hWnd
);
1761 if (!TestWindowProcess(pwnd
))
1763 /* do not send WM_GETTEXT messages to other processes */
1764 return (DefWindowProcW(hWnd
, WM_SETTEXT
, 0, (LPARAM
)lpString
) >= 0);
1766 return (SendMessageW(hWnd
, WM_SETTEXT
, 0, (LPARAM
)lpString
) >= 0);
1776 ShowOwnedPopups(HWND hWnd
, BOOL fShow
)
1778 return NtUserxShowOwnedPopups(hWnd
, fShow
);
1786 UpdateLayeredWindow( HWND hwnd
,
1796 if (dwFlags
& ULW_EX_NORESIZE
) /* only valid for UpdateLayeredWindowIndirect */
1798 SetLastError( ERROR_INVALID_PARAMETER
);
1801 return NtUserUpdateLayeredWindow( hwnd
,
1817 UpdateLayeredWindowIndirect(HWND hwnd
,
1818 const UPDATELAYEREDWINDOWINFO
*info
)
1820 if (info
&& info
->cbSize
== sizeof(*info
))
1822 return NtUserUpdateLayeredWindow( hwnd
,
1824 (POINT
*)info
->pptDst
,
1825 (SIZE
*)info
->psize
,
1827 (POINT
*)info
->pptSrc
,
1829 (BLENDFUNCTION
*)info
->pblend
,
1831 (RECT
*)info
->prcDirty
);
1833 SetLastError(ERROR_INVALID_PARAMETER
);
1841 SetWindowContextHelpId(HWND hwnd
,
1842 DWORD dwContextHelpId
)
1844 return NtUserxSetWindowContextHelpId(hwnd
, dwContextHelpId
);
1851 GetWindowContextHelpId(HWND hwnd
)
1853 return NtUserxGetWindowContextHelpId(hwnd
);
1860 InternalGetWindowText(HWND hWnd
, LPWSTR lpString
, int nMaxCount
)
1862 INT Ret
= NtUserInternalGetWindowText(hWnd
, lpString
, nMaxCount
);
1863 if (Ret
== 0 && lpString
)
1872 IsHungAppWindow(HWND hwnd
)
1875 UNICODE_STRING ClassName
;
1877 static const UNICODE_STRING GhostClass
= RTL_CONSTANT_STRING(L
"Ghost");
1879 /* Ghost is a hung window */
1880 RtlInitEmptyUnicodeString(&ClassName
, szClass
, sizeof(szClass
));
1881 Window
= ValidateHwnd(hwnd
);
1882 if (Window
&& Window
->fnid
== FNID_GHOST
&&
1883 NtUserGetClassName(hwnd
, FALSE
, &ClassName
) &&
1884 RtlEqualUnicodeString(&ClassName
, &GhostClass
, TRUE
))
1889 return (NtUserQueryWindow(hwnd
, QUERY_WINDOW_ISHUNG
) != 0);
1896 SetLastErrorEx(DWORD dwErrCode
, DWORD dwType
)
1898 SetLastError(dwErrCode
);
1907 return (HWND
)NtUserGetThreadState(THREADSTATE_FOCUSWINDOW
);
1911 GetRealWindowOwner(HWND hwnd
)
1913 return NtUserQueryWindow(hwnd
, QUERY_WINDOW_REAL_ID
);
1920 SetTaskmanWindow(HWND hWnd
)
1922 return NtUserxSetTaskmanWindow(hWnd
);
1929 SetProgmanWindow(HWND hWnd
)
1931 return NtUserxSetProgmanWindow(hWnd
);
1938 GetProgmanWindow(VOID
)
1940 return (HWND
)NtUserGetThreadState(THREADSTATE_PROGMANWINDOW
);
1947 GetTaskmanWindow(VOID
)
1949 return (HWND
)NtUserGetThreadState(THREADSTATE_TASKMANWINDOW
);
1956 ScrollWindow(HWND hWnd
,
1960 CONST RECT
*prcClip
)
1962 return NtUserScrollWindowEx(hWnd
,
1969 (lpRect
? 0 : SW_SCROLLCHILDREN
) | (SW_ERASE
|SW_INVALIDATE
|SW_SCROLLWNDDCE
)) != ERROR
;
1972 /* ScrollWindow uses the window DC, ScrollWindowEx doesn't */
1978 ScrollWindowEx(HWND hWnd
,
1981 CONST RECT
*prcScroll
,
1982 CONST RECT
*prcClip
,
1987 if (flags
& SW_SMOOTHSCROLL
)
1989 FIXME("SW_SMOOTHSCROLL not supported.");
1992 return NtUserScrollWindowEx(hWnd
,
2010 HWND
*list
= WIN_ListChildren( GetDesktopWindow() );
2012 if (!list
) return FALSE
;
2013 for (i
= 0; list
[i
]; i
++)
2015 if (IsWindowVisible( list
[i
] ) && GetWindow( list
[i
], GW_OWNER
)) break;
2017 retvalue
= (list
[i
] != 0);
2018 HeapFree( GetProcessHeap(), 0, list
);
2026 IsWindowInDestroy(HWND hWnd
)
2029 pwnd
= ValidateHwnd(hWnd
);
2032 return ((pwnd
->state2
& WNDS2_INDESTROY
) == WNDS2_INDESTROY
);
2039 DisableProcessWindowsGhosting(VOID
)
2041 NtUserxEnableProcessWindowGhosting(FALSE
);