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)
8 * 06-06-2001 CSH Created
11 /* INCLUDES ******************************************************************/
15 #include <wine/debug.h>
16 WINE_DEFAULT_DEBUG_CHANNEL(user32
);
18 void MDI_CalcDefaultChildPos( HWND hwndClient
, INT total
, LPPOINT lpPos
, INT delta
, UINT
*id
);
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 fUnknown
)
84 ShowWindow(hwnd
, SW_SHOW
);
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 SendMessageA(hWnd
, WM_SYSCOMMAND
, SC_CLOSE
, 0);
119 return HandleToUlong(hWnd
);
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
));
152 User32CreateWindowEx(DWORD dwExStyle
,
166 LARGE_STRING WindowName
;
167 LARGE_STRING lstrClassName
, *plstrClassName
;
168 UNICODE_STRING ClassName
;
171 HMODULE hLibModule
= NULL
;
173 BOOL Unicode
, ClassFound
= FALSE
;
177 DbgPrint("[window] User32CreateWindowEx style %d, exstyle %d, parent %d\n", dwStyle
, dwExStyle
, hWndParent
);
180 if (!RegisterDefaultClasses
)
182 TRACE("RegisterSystemControls\n");
183 RegisterSystemControls();
186 Unicode
= !(dwFlags
& NUCWE_ANSI
);
188 if (IS_ATOM(lpClassName
))
190 plstrClassName
= (PVOID
)lpClassName
;
195 RtlInitUnicodeString(&ClassName
, (PCWSTR
)lpClassName
);
198 if (!RtlCreateUnicodeStringFromAsciiz(&ClassName
, (PCSZ
)lpClassName
))
200 SetLastError(ERROR_OUTOFMEMORY
);
205 /* Copy it to a LARGE_STRING */
206 lstrClassName
.Buffer
= ClassName
.Buffer
;
207 lstrClassName
.Length
= ClassName
.Length
;
208 lstrClassName
.MaximumLength
= ClassName
.MaximumLength
;
209 plstrClassName
= &lstrClassName
;
212 /* Initialize a LARGE_STRING */
213 RtlInitLargeString(&WindowName
, lpWindowName
, Unicode
);
215 // HACK: The current implementation expects the Window name to be UNICODE
219 PSTR AnsiBuffer
= WindowName
.Buffer
;
220 ULONG AnsiLength
= WindowName
.Length
;
222 WindowName
.Length
= 0;
223 WindowName
.MaximumLength
= AnsiLength
* sizeof(WCHAR
);
224 WindowName
.Buffer
= RtlAllocateHeap(RtlGetProcessHeap(),
226 WindowName
.MaximumLength
);
227 if (!WindowName
.Buffer
)
229 SetLastError(ERROR_OUTOFMEMORY
);
233 Status
= RtlMultiByteToUnicodeN(WindowName
.Buffer
,
234 WindowName
.MaximumLength
,
238 if (!NT_SUCCESS(Status
))
244 if(!hMenu
&& (dwStyle
& (WS_OVERLAPPEDWINDOW
| WS_POPUP
)))
248 wceW
.cbSize
= sizeof(WNDCLASSEXW
);
249 if(GetClassInfoExW(hInstance
, (LPCWSTR
)lpClassName
, &wceW
) && wceW
.lpszMenuName
)
251 hMenu
= LoadMenuW(hInstance
, wceW
.lpszMenuName
);
256 wceA
.cbSize
= sizeof(WNDCLASSEXA
);
257 if(GetClassInfoExA(hInstance
, lpClassName
, &wceA
) && wceA
.lpszMenuName
)
259 hMenu
= LoadMenuA(hInstance
, wceA
.lpszMenuName
);
264 if (!Unicode
) dwExStyle
|= WS_EX_SETANSICREATOR
;
268 Handle
= NtUserCreateWindowEx(dwExStyle
,
286 save_error
= GetLastError();
287 if ( save_error
== ERROR_CANNOT_FIND_WND_CLASS
)
289 ClassFound
= VersionRegisterClass(ClassName
.Buffer
, NULL
, NULL
, &hLibModule
);
290 if (ClassFound
) continue;
295 save_error
= GetLastError();
296 FreeLibrary(hLibModule
);
297 SetLastError(save_error
);
304 DbgPrint("[window] NtUserCreateWindowEx() == %d\n", Handle
);
309 if (!IS_ATOM(lpClassName
))
311 RtlFreeUnicodeString(&ClassName
);
314 RtlFreeLargeString(&WindowName
);
327 CreateWindowExA(DWORD dwExStyle
,
340 MDICREATESTRUCTA mdi
;
343 if (!RegisterDefaultClasses
)
345 TRACE("CreateWindowExA RegisterSystemControls\n");
346 RegisterSystemControls();
349 if (dwExStyle
& WS_EX_MDICHILD
)
356 pWndParent
= ValidateHwnd(hWndParent
);
358 if (!pWndParent
) return NULL
;
360 if (pWndParent
->fnid
!= FNID_MDICLIENT
) // wine uses WIN_ISMDICLIENT
362 WARN("WS_EX_MDICHILD, but parent %p is not MDIClient\n", hWndParent
);
366 /* lpParams of WM_[NC]CREATE is different for MDI children.
367 * MDICREATESTRUCT members have the originally passed values.
369 mdi
.szClass
= lpClassName
;
370 mdi
.szTitle
= lpWindowName
;
371 mdi
.hOwner
= hInstance
;
377 mdi
.lParam
= (LPARAM
)lpParam
;
379 lpParam
= (LPVOID
)&mdi
;
381 if (pWndParent
->style
& MDIS_ALLCHILDSTYLES
)
383 if (dwStyle
& WS_POPUP
)
385 WARN("WS_POPUP with MDIS_ALLCHILDSTYLES is not allowed\n");
388 dwStyle
|= (WS_CHILD
| WS_CLIPSIBLINGS
);
392 dwStyle
&= ~WS_POPUP
;
393 dwStyle
|= (WS_CHILD
| WS_VISIBLE
| WS_CLIPSIBLINGS
| WS_CAPTION
|
394 WS_SYSMENU
| WS_THICKFRAME
| WS_MINIMIZEBOX
| WS_MAXIMIZEBOX
);
397 top_child
= GetWindow(hWndParent
, GW_CHILD
);
401 /* Restore current maximized child */
402 if((dwStyle
& WS_VISIBLE
) && IsZoomed(top_child
))
404 TRACE("Restoring current maximized child %p\n", top_child
);
405 SendMessageW( top_child
, WM_SETREDRAW
, FALSE
, 0 );
406 ShowWindow(top_child
, SW_RESTORE
);
407 SendMessageW( top_child
, WM_SETREDRAW
, TRUE
, 0 );
411 MDI_CalcDefaultChildPos(hWndParent
, -1, mPos
, 0, &id
);
413 if (!(dwStyle
& WS_POPUP
)) hMenu
= UlongToHandle(id
);
415 if (dwStyle
& (WS_CHILD
| WS_POPUP
))
417 if (x
== CW_USEDEFAULT
|| x
== CW_USEDEFAULT16
)
422 if (nWidth
== CW_USEDEFAULT
|| nWidth
== CW_USEDEFAULT16
|| !nWidth
)
424 if (nHeight
== CW_USEDEFAULT
|| nHeight
== CW_USEDEFAULT16
|| !nHeight
)
429 hwnd
= User32CreateWindowEx(dwExStyle
,
452 CreateWindowExW(DWORD dwExStyle
,
454 LPCWSTR lpWindowName
,
465 MDICREATESTRUCTW mdi
;
468 if (!RegisterDefaultClasses
)
470 ERR("CreateWindowExW RegisterSystemControls\n");
471 RegisterSystemControls();
474 if (dwExStyle
& WS_EX_MDICHILD
)
481 pWndParent
= ValidateHwnd(hWndParent
);
483 if (!pWndParent
) return NULL
;
485 if (pWndParent
->fnid
!= FNID_MDICLIENT
)
487 WARN("WS_EX_MDICHILD, but parent %p is not MDIClient\n", hWndParent
);
491 /* lpParams of WM_[NC]CREATE is different for MDI children.
492 * MDICREATESTRUCT members have the originally passed values.
494 mdi
.szClass
= lpClassName
;
495 mdi
.szTitle
= lpWindowName
;
496 mdi
.hOwner
= hInstance
;
502 mdi
.lParam
= (LPARAM
)lpParam
;
504 lpParam
= (LPVOID
)&mdi
;
506 if (pWndParent
->style
& MDIS_ALLCHILDSTYLES
)
508 if (dwStyle
& WS_POPUP
)
510 WARN("WS_POPUP with MDIS_ALLCHILDSTYLES is not allowed\n");
513 dwStyle
|= (WS_CHILD
| WS_CLIPSIBLINGS
);
517 dwStyle
&= ~WS_POPUP
;
518 dwStyle
|= (WS_CHILD
| WS_VISIBLE
| WS_CLIPSIBLINGS
| WS_CAPTION
|
519 WS_SYSMENU
| WS_THICKFRAME
| WS_MINIMIZEBOX
| WS_MAXIMIZEBOX
);
522 top_child
= GetWindow(hWndParent
, GW_CHILD
);
526 /* Restore current maximized child */
527 if((dwStyle
& WS_VISIBLE
) && IsZoomed(top_child
))
529 TRACE("Restoring current maximized child %p\n", top_child
);
530 SendMessageW( top_child
, WM_SETREDRAW
, FALSE
, 0 );
531 ShowWindow(top_child
, SW_RESTORE
);
532 SendMessageW( top_child
, WM_SETREDRAW
, TRUE
, 0 );
536 MDI_CalcDefaultChildPos(hWndParent
, -1, mPos
, 0, &id
);
538 if (!(dwStyle
& WS_POPUP
)) hMenu
= UlongToHandle(id
);
540 if (dwStyle
& (WS_CHILD
| WS_POPUP
))
542 if (x
== CW_USEDEFAULT
|| x
== CW_USEDEFAULT16
)
547 if (nWidth
== CW_USEDEFAULT
|| nWidth
== CW_USEDEFAULT16
|| !nWidth
)
549 if (nHeight
== CW_USEDEFAULT
|| nHeight
== CW_USEDEFAULT16
|| !nHeight
)
554 hwnd
= User32CreateWindowEx(dwExStyle
,
555 (LPCSTR
) lpClassName
,
556 (LPCSTR
) lpWindowName
,
574 DeferWindowPos(HDWP hWinPosInfo
,
576 HWND hWndInsertAfter
,
583 return NtUserDeferWindowPos(hWinPosInfo
, hWnd
, hWndInsertAfter
, x
, y
, cx
, cy
, uFlags
);
591 EndDeferWindowPos(HDWP hWinPosInfo
)
593 return NtUserEndDeferWindowPosEx(hWinPosInfo
, 0);
601 GetDesktopWindow(VOID
)
608 Wnd
= GetThreadDesktopWnd();
610 Ret
= UserHMGetHandle(Wnd
);
612 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
623 User32EnumWindows(HDESK hDesktop
,
630 DWORD i
, dwCount
= 0;
637 SetLastError ( ERROR_INVALID_PARAMETER
);
641 /* FIXME instead of always making two calls, should we use some
642 sort of persistent buffer and only grow it ( requiring a 2nd
643 call ) when the buffer wasn't already big enough? */
644 /* first get how many window entries there are */
645 Status
= NtUserBuildHwndList(hDesktop
,
652 if (!NT_SUCCESS(Status
))
655 /* allocate buffer to receive HWND handles */
656 hHeap
= GetProcessHeap();
657 pHwnd
= HeapAlloc(hHeap
, 0, sizeof(HWND
)*(dwCount
+1));
660 SetLastError ( ERROR_NOT_ENOUGH_MEMORY
);
664 /* now call kernel again to fill the buffer this time */
665 Status
= NtUserBuildHwndList(hDesktop
,
672 if (!NT_SUCCESS(Status
))
675 HeapFree(hHeap
, 0, pHwnd
);
687 /* call the user's callback function until we're done or
688 they tell us to quit */
689 for ( i
= 0; i
< dwCount
; i
++ )
691 /* FIXME I'm only getting NULLs from Thread Enumeration, and it's
692 * probably because I'm not doing it right in NtUserBuildHwndList.
693 * Once that's fixed, we shouldn't have to check for a NULL HWND
695 * This is now fixed in revision 50205. (jt)
697 if (!pHwnd
[i
]) /* don't enumerate a NULL HWND */
699 if (!(*lpfn
)(pHwnd
[i
], lParam
))
701 HeapFree ( hHeap
, 0, pHwnd
);
706 HeapFree(hHeap
, 0, pHwnd
);
715 EnumChildWindows(HWND hWndParent
,
716 WNDENUMPROC lpEnumFunc
,
721 return EnumWindows(lpEnumFunc
, lParam
);
723 return User32EnumWindows(NULL
, hWndParent
, lpEnumFunc
, lParam
, 0, TRUE
);
731 EnumThreadWindows(DWORD dwThreadId
,
736 dwThreadId
= GetCurrentThreadId();
737 return User32EnumWindows(NULL
, NULL
, lpfn
, lParam
, dwThreadId
, FALSE
);
745 EnumWindows(WNDENUMPROC lpEnumFunc
,
748 return User32EnumWindows(NULL
, NULL
, lpEnumFunc
, lParam
, 0, FALSE
);
756 EnumDesktopWindows(HDESK hDesktop
,
760 return User32EnumWindows(hDesktop
, NULL
, lpfn
, lParam
, 0, FALSE
);
768 FindWindowExA(HWND hwndParent
,
773 LPWSTR titleW
= NULL
;
778 DWORD len
= MultiByteToWideChar( CP_ACP
, 0, lpszWindow
, -1, NULL
, 0 );
779 if (!(titleW
= HeapAlloc( GetProcessHeap(), 0, len
* sizeof(WCHAR
) ))) return 0;
780 MultiByteToWideChar( CP_ACP
, 0, lpszWindow
, -1, titleW
, len
);
783 if (!IS_INTRESOURCE(lpszClass
))
786 if (MultiByteToWideChar( CP_ACP
, 0, lpszClass
, -1, classW
, sizeof(classW
)/sizeof(WCHAR
) ))
787 hwnd
= FindWindowExW( hwndParent
, hwndChildAfter
, classW
, titleW
);
791 hwnd
= FindWindowExW( hwndParent
, hwndChildAfter
, (LPCWSTR
)lpszClass
, titleW
);
794 HeapFree( GetProcessHeap(), 0, titleW
);
803 FindWindowExW(HWND hwndParent
,
808 UNICODE_STRING ucClassName
, *pucClassName
= NULL
;
809 UNICODE_STRING ucWindowName
, *pucWindowName
= NULL
;
811 if (IS_ATOM(lpszClass
))
813 ucClassName
.Length
= 0;
814 ucClassName
.Buffer
= (LPWSTR
)lpszClass
;
815 pucClassName
= &ucClassName
;
817 else if (lpszClass
!= NULL
)
819 RtlInitUnicodeString(&ucClassName
,
821 pucClassName
= &ucClassName
;
824 if (lpszWindow
!= NULL
)
826 RtlInitUnicodeString(&ucWindowName
,
828 pucWindowName
= &ucWindowName
;
831 return NtUserFindWindowEx(hwndParent
,
843 FindWindowA(LPCSTR lpClassName
, LPCSTR lpWindowName
)
845 //FIXME: FindWindow does not search children, but FindWindowEx does.
846 // what should we do about this?
847 return FindWindowExA (NULL
, NULL
, lpClassName
, lpWindowName
);
855 FindWindowW(LPCWSTR lpClassName
, LPCWSTR lpWindowName
)
859 There was a FIXME here earlier, but I think it is just a documentation unclarity.
861 FindWindow only searches top level windows. What they mean is that child
862 windows of other windows than the desktop can be searched.
863 FindWindowExW never does a recursive search.
868 return FindWindowExW(NULL
, NULL
, lpClassName
, lpWindowName
);
877 GetAltTabInfoA(HWND hwnd
,
883 return NtUserGetAltTabInfo(hwnd
,iItem
,pati
,(LPWSTR
)pszItemText
,cchItemText
,TRUE
);
891 GetAltTabInfoW(HWND hwnd
,
897 return NtUserGetAltTabInfo(hwnd
,iItem
,pati
,pszItemText
,cchItemText
,FALSE
);
905 GetAncestor(HWND hwnd
, UINT gaFlags
)
910 Wnd
= ValidateHwnd(hwnd
);
920 if (Wnd
->spwndParent
!= NULL
)
921 Ancestor
= DesktopPtrToUser(Wnd
->spwndParent
);
925 /* FIXME: Call win32k for now */
930 if (Ancestor
!= NULL
)
931 Ret
= UserHMGetHandle(Ancestor
);
933 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
939 if (!Wnd
) /* Fall back */
940 Ret
= NtUserGetAncestor(hwnd
, gaFlags
);
950 GetClientRect(HWND hWnd
, LPRECT lpRect
)
952 PWND Wnd
= ValidateHwnd(hWnd
);
954 if (!Wnd
) return FALSE
;
955 if (Wnd
->style
& WS_MINIMIZED
)
957 lpRect
->left
= lpRect
->top
= 0;
958 lpRect
->right
= GetSystemMetrics(SM_CXMINIMIZED
);
959 lpRect
->bottom
= GetSystemMetrics(SM_CYMINIMIZED
);
962 if ( hWnd
!= GetDesktopWindow()) // Wnd->fnid != FNID_DESKTOP )
964 /* lpRect->left = lpRect->top = 0;
965 lpRect->right = Wnd->rcClient.right - Wnd->rcClient.left;
966 lpRect->bottom = Wnd->rcClient.bottom - Wnd->rcClient.top;
968 *lpRect
= Wnd
->rcClient
;
969 OffsetRect(lpRect
, -Wnd
->rcClient
.left
, -Wnd
->rcClient
.top
);
973 lpRect
->left
= lpRect
->top
= 0;
974 lpRect
->right
= Wnd
->rcClient
.right
;
975 lpRect
->bottom
= Wnd
->rcClient
.bottom
;
976 /* Do this until Init bug is fixed. This sets 640x480, see InitMetrics.
977 lpRect->right = GetSystemMetrics(SM_CXSCREEN);
978 lpRect->bottom = GetSystemMetrics(SM_CYSCREEN);
988 GetLastActivePopup(HWND hWnd
)
993 Wnd
= ValidateHwnd(hWnd
);
998 if (Wnd
->spwndLastActive
)
1000 PWND LastActive
= DesktopPtrToUser(Wnd
->spwndLastActive
);
1001 Ret
= UserHMGetHandle(LastActive
);
1004 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
1018 GetParent(HWND hWnd
)
1020 PWND Wnd
, WndParent
;
1023 Wnd
= ValidateHwnd(hWnd
);
1029 if (Wnd
->style
& WS_POPUP
)
1031 if (Wnd
->spwndOwner
!= NULL
)
1032 WndParent
= DesktopPtrToUser(Wnd
->spwndOwner
);
1034 else if (Wnd
->style
& WS_CHILD
)
1036 if (Wnd
->spwndParent
!= NULL
)
1037 WndParent
= DesktopPtrToUser(Wnd
->spwndParent
);
1040 if (WndParent
!= NULL
)
1041 Ret
= UserHMGetHandle(WndParent
);
1043 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
1058 GetProcessDefaultLayout(DWORD
*pdwDefaultLayout
)
1060 return (BOOL
)NtUserCallOneParam( (DWORD_PTR
)pdwDefaultLayout
, ONEPARAM_ROUTINE_GETPROCDEFLAYOUT
);
1068 GetWindow(HWND hWnd
,
1074 Wnd
= ValidateHwnd(hWnd
);
1084 if (Wnd
->spwndOwner
!= NULL
)
1085 FoundWnd
= DesktopPtrToUser(Wnd
->spwndOwner
);
1089 if(Wnd
->spwndParent
!= NULL
)
1091 FoundWnd
= DesktopPtrToUser(Wnd
->spwndParent
);
1092 if (FoundWnd
->spwndChild
!= NULL
)
1093 FoundWnd
= DesktopPtrToUser(FoundWnd
->spwndChild
);
1097 if (Wnd
->spwndNext
!= NULL
)
1098 FoundWnd
= DesktopPtrToUser(Wnd
->spwndNext
);
1102 if (Wnd
->spwndPrev
!= NULL
)
1103 FoundWnd
= DesktopPtrToUser(Wnd
->spwndPrev
);
1107 if (Wnd
->spwndChild
!= NULL
)
1108 FoundWnd
= DesktopPtrToUser(Wnd
->spwndChild
);
1113 while ( FoundWnd
->spwndNext
!= NULL
)
1114 FoundWnd
= DesktopPtrToUser(FoundWnd
->spwndNext
);
1122 if (FoundWnd
!= NULL
)
1123 Ret
= UserHMGetHandle(FoundWnd
);
1125 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
1139 GetTopWindow(HWND hWnd
)
1141 if (!hWnd
) hWnd
= GetDesktopWindow();
1142 return GetWindow(hWnd
, GW_CHILD
);
1152 GetWindowInfo(HWND hWnd
,
1160 if ( !pwi
|| pwi
->cbSize
!= sizeof(WINDOWINFO
))
1161 SetLastError(ERROR_INVALID_PARAMETER
); // Just set the error and go!
1163 pWnd
= ValidateHwnd(hWnd
);
1167 UserGetWindowBorders(pWnd
->style
, pWnd
->ExStyle
, &Size
, FALSE
);
1171 pCls
= DesktopPtrToUser(pWnd
->pcls
);
1172 pwi
->rcWindow
= pWnd
->rcWindow
;
1173 pwi
->rcClient
= pWnd
->rcClient
;
1174 pwi
->dwStyle
= pWnd
->style
;
1175 pwi
->dwExStyle
= pWnd
->ExStyle
;
1176 pwi
->cxWindowBorders
= Size
.cx
;
1177 pwi
->cyWindowBorders
= Size
.cy
;
1178 pwi
->dwWindowStatus
= 0;
1179 if (pWnd
->state
& WNDS_ACTIVEFRAME
|| (GetActiveWindow() == hWnd
))
1180 pwi
->dwWindowStatus
= WS_ACTIVECAPTION
;
1181 pwi
->atomWindowType
= (pCls
? pCls
->atomClassName
: 0 );
1183 if ( pWnd
->state2
& WNDS2_WIN50COMPAT
)
1185 pwi
->wCreatorVersion
= 0x500;
1187 else if ( pWnd
->state2
& WNDS2_WIN40COMPAT
)
1189 pwi
->wCreatorVersion
= 0x400;
1191 else if ( pWnd
->state2
& WNDS2_WIN31COMPAT
)
1193 pwi
->wCreatorVersion
= 0x30A;
1197 pwi
->wCreatorVersion
= 0x300;
1202 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
1216 GetWindowModuleFileNameA(HWND hwnd
,
1218 UINT cchFileNameMax
)
1220 PWND Wnd
= ValidateHwnd(hwnd
);
1225 return GetModuleFileNameA(Wnd
->hModule
, lpszFileName
, cchFileNameMax
);
1233 GetWindowModuleFileNameW(HWND hwnd
,
1234 LPWSTR lpszFileName
,
1235 UINT cchFileNameMax
)
1237 PWND Wnd
= ValidateHwnd(hwnd
);
1242 return GetModuleFileNameW( Wnd
->hModule
, lpszFileName
, cchFileNameMax
);
1249 GetWindowRect(HWND hWnd
,
1252 PWND Wnd
= ValidateHwnd(hWnd
);
1254 if (!Wnd
) return FALSE
;
1255 if ( hWnd
!= GetDesktopWindow()) // Wnd->fnid != FNID_DESKTOP )
1257 *lpRect
= Wnd
->rcWindow
;
1261 lpRect
->left
= lpRect
->top
= 0;
1262 lpRect
->right
= Wnd
->rcWindow
.right
;
1263 lpRect
->bottom
= Wnd
->rcWindow
.bottom
;
1264 /* Do this until Init bug is fixed. This sets 640x480, see InitMetrics.
1265 lpRect->right = GetSystemMetrics(SM_CXSCREEN);
1266 lpRect->bottom = GetSystemMetrics(SM_CYSCREEN);
1275 GetWindowTextA(HWND hWnd
, LPSTR lpString
, int nMaxCount
)
1280 if (lpString
== NULL
|| nMaxCount
== 0)
1283 Wnd
= ValidateHwnd(hWnd
);
1289 if (!TestWindowProcess( Wnd
))
1293 Length
= DefWindowProcA(hWnd
, WM_GETTEXT
, nMaxCount
, (LPARAM
)lpString
);
1295 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
1302 Length
= SendMessageA(hWnd
, WM_GETTEXT
, nMaxCount
, (LPARAM
)lpString
);
1303 //ERR("GWTA Len %d : %s\n",Length,lpString);
1311 GetWindowTextLengthA(HWND hWnd
)
1313 return(SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0));
1320 GetWindowTextLengthW(HWND hWnd
)
1322 return(SendMessageW(hWnd
, WM_GETTEXTLENGTH
, 0, 0));
1329 GetWindowTextW(HWND hWnd
, LPWSTR lpString
, int nMaxCount
)
1334 if (lpString
== NULL
|| nMaxCount
== 0)
1337 Wnd
= ValidateHwnd(hWnd
);
1341 lpString
[0] = L
'\0';
1343 if (!TestWindowProcess( Wnd
))
1347 Length
= DefWindowProcW(hWnd
, WM_GETTEXT
, nMaxCount
, (LPARAM
)lpString
);
1349 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
1356 Length
= SendMessageW(hWnd
, WM_GETTEXT
, nMaxCount
, (LPARAM
)lpString
);
1357 //ERR("GWTW Len %d : %S\n",Length,lpString);
1362 GetWindowThreadProcessId(HWND hWnd
,
1363 LPDWORD lpdwProcessId
)
1367 PWND pWnd
= ValidateHwnd(hWnd
);
1369 if (!pWnd
) return Ret
;
1371 ti
= pWnd
->head
.pti
;
1375 if (ti
== GetW32ThreadInfo())
1376 { // We are current.
1377 //FIXME("Current!\n");
1379 *lpdwProcessId
= (DWORD_PTR
)NtCurrentTeb()->ClientId
.UniqueProcess
;
1380 Ret
= (DWORD_PTR
)NtCurrentTeb()->ClientId
.UniqueThread
;
1383 { // Ask kernel for info.
1384 //FIXME("Kernel call!\n");
1386 *lpdwProcessId
= NtUserQueryWindow(hWnd
, QUERY_WINDOW_UNIQUE_PROCESS_ID
);
1387 Ret
= NtUserQueryWindow(hWnd
, QUERY_WINDOW_UNIQUE_THREAD_ID
);
1398 IsChild(HWND hWndParent
,
1401 PWND WndParent
, DesktopWnd
, Wnd
;
1404 WndParent
= ValidateHwnd(hWndParent
);
1407 Wnd
= ValidateHwnd(hWnd
);
1411 DesktopWnd
= GetThreadDesktopWnd();
1417 while (Wnd
!= NULL
&& ((Wnd
->style
& (WS_POPUP
|WS_CHILD
)) == WS_CHILD
))
1419 if (Wnd
->spwndParent
!= NULL
)
1421 Wnd
= DesktopPtrToUser(Wnd
->spwndParent
);
1423 if (Wnd
== WndParent
)
1433 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
1449 PWND Wnd
= ValidateHwnd(hWnd
);
1452 return (Wnd
->style
& WS_MINIMIZE
) != 0;
1464 PWND Wnd
= ValidateHwndNoErr(hWnd
);
1467 if (Wnd
->state
& WNDS_DESTROYED
||
1468 Wnd
->state2
& WNDS2_INDESTROY
)
1481 IsWindowUnicode(HWND hWnd
)
1483 PWND Wnd
= ValidateHwnd(hWnd
);
1486 return Wnd
->Unicode
;
1496 IsWindowVisible(HWND hWnd
)
1499 PWND Wnd
= ValidateHwnd(hWnd
);
1509 if (!(Wnd
->style
& WS_VISIBLE
))
1515 if (Wnd
->spwndParent
!= NULL
)
1516 Wnd
= DesktopPtrToUser(Wnd
->spwndParent
);
1520 } while (Wnd
!= NULL
);
1522 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
1537 IsWindowEnabled(HWND hWnd
)
1539 // AG: I don't know if child windows are affected if the parent is
1540 // disabled. I think they stop processing messages but stay appearing
1543 return !(GetWindowLongPtrW(hWnd
, GWL_STYLE
) & WS_DISABLED
);
1553 return (GetWindowLongPtrW(hWnd
, GWL_STYLE
) & WS_MAXIMIZE
) != 0;
1561 LockSetForegroundWindow(UINT uLockCode
)
1563 return NtUserxLockSetForegroundWindow(uLockCode
);
1571 AnimateWindow(HWND hwnd
,
1575 /* FIXME Add animation code */
1577 /* If trying to show/hide and it's already *
1578 * shown/hidden or invalid window, fail with *
1579 * invalid parameter */
1582 visible
= IsWindowVisible(hwnd
);
1583 if(!IsWindow(hwnd
) ||
1584 (visible
&& !(dwFlags
& AW_HIDE
)) ||
1585 (!visible
&& (dwFlags
& AW_HIDE
)))
1587 SetLastError(ERROR_INVALID_PARAMETER
);
1591 ShowWindow(hwnd
, (dwFlags
& AW_HIDE
) ? SW_HIDE
: ((dwFlags
& AW_ACTIVATE
) ? SW_SHOW
: SW_SHOWNA
));
1603 if (!(GetWindowLongPtrW(hWnd
, GWL_STYLE
) & WS_MINIMIZE
))
1606 ShowWindow(hWnd
,SW_RESTORE
);
1615 RealChildWindowFromPoint(HWND hwndParent
,
1616 POINT ptParentClientCoords
)
1618 return NtUserRealChildWindowFromPoint(hwndParent
, ptParentClientCoords
.x
, ptParentClientCoords
.y
);
1625 SetForegroundWindow(HWND hWnd
)
1627 return NtUserxSetForegroundWindow(hWnd
);
1635 SetProcessDefaultLayout(DWORD dwDefaultLayout
)
1637 return NtUserCallOneParam( (DWORD_PTR
)dwDefaultLayout
, ONEPARAM_ROUTINE_SETPROCDEFLAYOUT
);
1647 SetWindowTextA(HWND hWnd
,
1652 pwnd
= ValidateHwnd(hWnd
);
1655 if (!TestWindowProcess(pwnd
))
1657 /* do not send WM_GETTEXT messages to other processes */
1658 return (DefWindowProcA(hWnd
, WM_SETTEXT
, 0, (LPARAM
)lpString
) >= 0);
1660 return (SendMessageA(hWnd
, WM_SETTEXT
, 0, (LPARAM
)lpString
) >= 0);
1672 SetWindowTextW(HWND hWnd
,
1677 pwnd
= ValidateHwnd(hWnd
);
1680 if (!TestWindowProcess(pwnd
))
1682 /* do not send WM_GETTEXT messages to other processes */
1683 return (DefWindowProcW(hWnd
, WM_SETTEXT
, 0, (LPARAM
)lpString
) >= 0);
1685 return (SendMessageW(hWnd
, WM_SETTEXT
, 0, (LPARAM
)lpString
) >= 0);
1695 ShowOwnedPopups(HWND hWnd
, BOOL fShow
)
1697 return NtUserxShowOwnedPopups(hWnd
, fShow
);
1705 UpdateLayeredWindow( HWND hwnd
,
1715 if (dwFlags
& ULW_EX_NORESIZE
) /* only valid for UpdateLayeredWindowIndirect */
1717 SetLastError( ERROR_INVALID_PARAMETER
);
1720 return NtUserUpdateLayeredWindow( hwnd
,
1736 UpdateLayeredWindowIndirect(HWND hwnd
,
1737 const UPDATELAYEREDWINDOWINFO
*info
)
1739 if (info
&& info
->cbSize
== sizeof(*info
))
1741 return NtUserUpdateLayeredWindow( hwnd
,
1743 (POINT
*)info
->pptDst
,
1744 (SIZE
*)info
->psize
,
1746 (POINT
*)info
->pptSrc
,
1748 (BLENDFUNCTION
*)info
->pblend
,
1750 (RECT
*)info
->prcDirty
);
1752 SetLastError(ERROR_INVALID_PARAMETER
);
1760 SetWindowContextHelpId(HWND hwnd
,
1761 DWORD dwContextHelpId
)
1763 return NtUserxSetWindowContextHelpId(hwnd
, dwContextHelpId
);
1770 GetWindowContextHelpId(HWND hwnd
)
1772 return NtUserxGetWindowContextHelpId(hwnd
);
1779 InternalGetWindowText(HWND hWnd
, LPWSTR lpString
, int nMaxCount
)
1781 INT Ret
= NtUserInternalGetWindowText(hWnd
, lpString
, nMaxCount
);
1791 IsHungAppWindow(HWND hwnd
)
1793 return (NtUserQueryWindow(hwnd
, QUERY_WINDOW_ISHUNG
) != 0);
1800 SetLastErrorEx(DWORD dwErrCode
, DWORD dwType
)
1802 SetLastError(dwErrCode
);
1811 return (HWND
)NtUserGetThreadState(THREADSTATE_FOCUSWINDOW
);
1815 GetRealWindowOwner(HWND hwnd
)
1817 return NtUserQueryWindow(hwnd
, QUERY_WINDOW_REAL_ID
);
1824 SetTaskmanWindow(HWND hWnd
)
1826 return NtUserxSetTaskmanWindow(hWnd
);
1833 SetProgmanWindow(HWND hWnd
)
1835 return NtUserxSetProgmanWindow(hWnd
);
1842 GetProgmanWindow(VOID
)
1844 return (HWND
)NtUserGetThreadState(THREADSTATE_PROGMANWINDOW
);
1851 GetTaskmanWindow(VOID
)
1853 return (HWND
)NtUserGetThreadState(THREADSTATE_TASKMANWINDOW
);
1860 ScrollWindow(HWND hWnd
,
1864 CONST RECT
*prcClip
)
1866 return NtUserScrollWindowEx(hWnd
,
1873 (lpRect
? 0 : SW_SCROLLCHILDREN
) | (SW_ERASE
|SW_INVALIDATE
|SW_SCROLLWNDDCE
)) != ERROR
;
1876 /* ScrollWindow uses the window DC, ScrollWindowEx doesn't */
1882 ScrollWindowEx(HWND hWnd
,
1885 CONST RECT
*prcScroll
,
1886 CONST RECT
*prcClip
,
1891 if (flags
& SW_SMOOTHSCROLL
)
1893 FIXME("SW_SMOOTHSCROLL not supported.");
1896 return NtUserScrollWindowEx(hWnd
,
1914 HWND
*list
= WIN_ListChildren( GetDesktopWindow() );
1916 if (!list
) return FALSE
;
1917 for (i
= 0; list
[i
]; i
++)
1919 if (IsWindowVisible( list
[i
] ) && GetWindow( list
[i
], GW_OWNER
)) break;
1921 retvalue
= (list
[i
] != 0);
1922 HeapFree( GetProcessHeap(), 0, list
);
1930 IsWindowInDestroy(HWND hWnd
)
1933 pwnd
= ValidateHwnd(hWnd
);
1936 return ((pwnd
->state2
& WNDS2_INDESTROY
) == WNDS2_INDESTROY
);
1943 DisableProcessWindowsGhosting(VOID
)
1945 NtUserxEnableProcessWindowGhosting(FALSE
);