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
14 WINE_DEFAULT_DEBUG_CHANNEL(user32
);
16 void MDI_CalcDefaultChildPos( HWND hwndClient
, INT total
, LPPOINT lpPos
, INT delta
, UINT
*id
);
17 extern LPCWSTR FASTCALL
ClassNameToVersion(const void *lpszClass
, LPCWSTR lpszMenuName
, LPCWSTR
*plpLibFileName
, HANDLE
*pContext
, BOOL bAnsi
);
19 /* FUNCTIONS *****************************************************************/
23 User32CallSendAsyncProcForKernel(PVOID Arguments
, ULONG ArgumentLength
)
25 PSENDASYNCPROC_CALLBACK_ARGUMENTS CallbackArgs
;
27 TRACE("User32CallSendAsyncProcKernel()\n");
29 CallbackArgs
= (PSENDASYNCPROC_CALLBACK_ARGUMENTS
)Arguments
;
31 if (ArgumentLength
!= sizeof(SENDASYNCPROC_CALLBACK_ARGUMENTS
))
33 return(STATUS_INFO_LENGTH_MISMATCH
);
36 CallbackArgs
->Callback(CallbackArgs
->Wnd
,
38 CallbackArgs
->Context
,
39 CallbackArgs
->Result
);
40 return(STATUS_SUCCESS
);
48 AllowSetForegroundWindow(DWORD dwProcessId
)
50 return NtUserxAllowSetForegroundWindow(dwProcessId
);
58 BeginDeferWindowPos(int nNumWindows
)
60 return NtUserxBeginDeferWindowPos(nNumWindows
);
68 BringWindowToTop(HWND hWnd
)
70 return NtUserSetWindowPos(hWnd
,
76 SWP_NOSIZE
| SWP_NOMOVE
);
81 SwitchToThisWindow(HWND hwnd
, BOOL fUnknown
)
83 ShowWindow(hwnd
, SW_SHOW
);
91 ChildWindowFromPoint(HWND hWndParent
,
94 return (HWND
) NtUserChildWindowFromPointEx(hWndParent
, Point
.x
, Point
.y
, 0);
102 ChildWindowFromPointEx(HWND hwndParent
,
106 return (HWND
) NtUserChildWindowFromPointEx(hwndParent
, pt
.x
, pt
.y
, uFlags
);
114 CloseWindow(HWND hWnd
)
116 SendMessageA(hWnd
, WM_SYSCOMMAND
, SC_CLOSE
, 0);
118 return HandleToUlong(hWnd
);
124 OUT PLARGE_STRING plstr
,
130 RtlInitLargeUnicodeString((PLARGE_UNICODE_STRING
)plstr
, (PWSTR
)psz
, 0);
134 RtlInitLargeAnsiString((PLARGE_ANSI_STRING
)plstr
, (PSTR
)psz
, 0);
141 IN PLARGE_STRING LargeString
)
143 if (LargeString
->Buffer
)
145 RtlFreeHeap(GetProcessHeap(), 0, LargeString
->Buffer
);
146 RtlZeroMemory(LargeString
, sizeof(LARGE_STRING
));
151 User32CreateWindowEx(DWORD dwExStyle
,
165 LARGE_STRING WindowName
;
166 LARGE_STRING lstrClassName
, *plstrClassName
;
167 LARGE_STRING lstrClassVersion
, *plstrClassVersion
;
168 UNICODE_STRING ClassName
;
169 UNICODE_STRING ClassVersion
;
172 HMODULE hLibModule
= NULL
;
174 BOOL Unicode
, ClassFound
= FALSE
;
176 LPCWSTR lpszClsVersion
;
177 LPCWSTR lpLibFileName
= NULL
;
181 DbgPrint("[window] User32CreateWindowEx style %d, exstyle %d, parent %d\n", dwStyle
, dwExStyle
, hWndParent
);
184 if (!RegisterDefaultClasses
)
186 TRACE("RegisterSystemControls\n");
187 RegisterSystemControls();
190 Unicode
= !(dwFlags
& NUCWE_ANSI
);
192 if (IS_ATOM(lpClassName
))
194 plstrClassName
= (PVOID
)lpClassName
;
200 RtlInitUnicodeString(&ClassName
, (PCWSTR
)lpClassName
);
204 if (!RtlCreateUnicodeStringFromAsciiz(&ClassName
, (PCSZ
)lpClassName
))
206 SetLastError(ERROR_OUTOFMEMORY
);
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
;
218 /* Initialize a LARGE_STRING */
219 RtlInitLargeString(&WindowName
, lpWindowName
, Unicode
);
221 // HACK: The current implementation expects the Window name to be UNICODE
225 PSTR AnsiBuffer
= WindowName
.Buffer
;
226 ULONG AnsiLength
= WindowName
.Length
;
228 WindowName
.Length
= 0;
229 WindowName
.MaximumLength
= AnsiLength
* sizeof(WCHAR
);
230 WindowName
.Buffer
= RtlAllocateHeap(RtlGetProcessHeap(),
232 WindowName
.MaximumLength
);
233 if (!WindowName
.Buffer
)
235 SetLastError(ERROR_OUTOFMEMORY
);
239 Status
= RtlMultiByteToUnicodeN(WindowName
.Buffer
,
240 WindowName
.MaximumLength
,
244 if (!NT_SUCCESS(Status
))
250 if (!hMenu
&& (dwStyle
& (WS_OVERLAPPEDWINDOW
| WS_POPUP
)))
254 wceW
.cbSize
= sizeof(wceW
);
255 if (GetClassInfoExW(hInstance
, (LPCWSTR
)lpClassName
, &wceW
) && wceW
.lpszMenuName
)
257 hMenu
= LoadMenuW(hInstance
, wceW
.lpszMenuName
);
262 wceA
.cbSize
= sizeof(wceA
);
263 if (GetClassInfoExA(hInstance
, lpClassName
, &wceA
) && wceA
.lpszMenuName
)
265 hMenu
= LoadMenuA(hInstance
, wceA
.lpszMenuName
);
270 if (!Unicode
) dwExStyle
|= WS_EX_SETANSICREATOR
;
272 lpszClsVersion
= ClassNameToVersion(lpClassName
, NULL
, &lpLibFileName
, &pCtx
, !Unicode
);
275 plstrClassVersion
= plstrClassName
;
279 RtlInitUnicodeString(&ClassVersion
, lpszClsVersion
);
280 lstrClassVersion
.Buffer
= ClassVersion
.Buffer
;
281 lstrClassVersion
.Length
= ClassVersion
.Length
;
282 lstrClassVersion
.MaximumLength
= ClassVersion
.MaximumLength
;
283 plstrClassVersion
= &lstrClassVersion
;
288 Handle
= NtUserCreateWindowEx(dwExStyle
,
304 if (!lpLibFileName
) break;
307 dwLastError
= GetLastError();
308 if (dwLastError
== ERROR_CANNOT_FIND_WND_CLASS
)
310 ClassFound
= VersionRegisterClass(ClassName
.Buffer
, lpLibFileName
, pCtx
, &hLibModule
);
311 if (ClassFound
) continue;
316 dwLastError
= GetLastError();
317 FreeLibrary(hLibModule
);
318 SetLastError(dwLastError
);
325 DbgPrint("[window] NtUserCreateWindowEx() == %d\n", Handle
);
331 if (!IS_ATOM(lpClassName
))
332 RtlFreeUnicodeString(&ClassName
);
334 RtlFreeLargeString(&WindowName
);
347 CreateWindowExA(DWORD dwExStyle
,
360 MDICREATESTRUCTA mdi
;
363 if (!RegisterDefaultClasses
)
365 TRACE("CreateWindowExA RegisterSystemControls\n");
366 RegisterSystemControls();
369 if (dwExStyle
& WS_EX_MDICHILD
)
376 pWndParent
= ValidateHwnd(hWndParent
);
378 if (!pWndParent
) return NULL
;
380 if (pWndParent
->fnid
!= FNID_MDICLIENT
) // wine uses WIN_ISMDICLIENT
382 WARN("WS_EX_MDICHILD, but parent %p is not MDIClient\n", hWndParent
);
386 /* lpParams of WM_[NC]CREATE is different for MDI children.
387 * MDICREATESTRUCT members have the originally passed values.
389 mdi
.szClass
= lpClassName
;
390 mdi
.szTitle
= lpWindowName
;
391 mdi
.hOwner
= hInstance
;
397 mdi
.lParam
= (LPARAM
)lpParam
;
399 lpParam
= (LPVOID
)&mdi
;
401 if (pWndParent
->style
& MDIS_ALLCHILDSTYLES
)
403 if (dwStyle
& WS_POPUP
)
405 WARN("WS_POPUP with MDIS_ALLCHILDSTYLES is not allowed\n");
408 dwStyle
|= (WS_CHILD
| WS_CLIPSIBLINGS
);
412 dwStyle
&= ~WS_POPUP
;
413 dwStyle
|= (WS_CHILD
| WS_VISIBLE
| WS_CLIPSIBLINGS
| WS_CAPTION
|
414 WS_SYSMENU
| WS_THICKFRAME
| WS_MINIMIZEBOX
| WS_MAXIMIZEBOX
);
417 top_child
= GetWindow(hWndParent
, GW_CHILD
);
421 /* Restore current maximized child */
422 if((dwStyle
& WS_VISIBLE
) && IsZoomed(top_child
))
424 TRACE("Restoring current maximized child %p\n", top_child
);
425 SendMessageW( top_child
, WM_SETREDRAW
, FALSE
, 0 );
426 ShowWindow(top_child
, SW_RESTORE
);
427 SendMessageW( top_child
, WM_SETREDRAW
, TRUE
, 0 );
431 MDI_CalcDefaultChildPos(hWndParent
, -1, mPos
, 0, &id
);
433 if (!(dwStyle
& WS_POPUP
)) hMenu
= UlongToHandle(id
);
435 if (dwStyle
& (WS_CHILD
| WS_POPUP
))
437 if (x
== CW_USEDEFAULT
|| x
== CW_USEDEFAULT16
)
442 if (nWidth
== CW_USEDEFAULT
|| nWidth
== CW_USEDEFAULT16
|| !nWidth
)
444 if (nHeight
== CW_USEDEFAULT
|| nHeight
== CW_USEDEFAULT16
|| !nHeight
)
449 hwnd
= User32CreateWindowEx(dwExStyle
,
472 CreateWindowExW(DWORD dwExStyle
,
474 LPCWSTR lpWindowName
,
485 MDICREATESTRUCTW mdi
;
488 if (!RegisterDefaultClasses
)
490 ERR("CreateWindowExW RegisterSystemControls\n");
491 RegisterSystemControls();
494 if (dwExStyle
& WS_EX_MDICHILD
)
501 pWndParent
= ValidateHwnd(hWndParent
);
503 if (!pWndParent
) return NULL
;
505 if (pWndParent
->fnid
!= FNID_MDICLIENT
)
507 WARN("WS_EX_MDICHILD, but parent %p is not MDIClient\n", hWndParent
);
511 /* lpParams of WM_[NC]CREATE is different for MDI children.
512 * MDICREATESTRUCT members have the originally passed values.
514 mdi
.szClass
= lpClassName
;
515 mdi
.szTitle
= lpWindowName
;
516 mdi
.hOwner
= hInstance
;
522 mdi
.lParam
= (LPARAM
)lpParam
;
524 lpParam
= (LPVOID
)&mdi
;
526 if (pWndParent
->style
& MDIS_ALLCHILDSTYLES
)
528 if (dwStyle
& WS_POPUP
)
530 WARN("WS_POPUP with MDIS_ALLCHILDSTYLES is not allowed\n");
533 dwStyle
|= (WS_CHILD
| WS_CLIPSIBLINGS
);
537 dwStyle
&= ~WS_POPUP
;
538 dwStyle
|= (WS_CHILD
| WS_VISIBLE
| WS_CLIPSIBLINGS
| WS_CAPTION
|
539 WS_SYSMENU
| WS_THICKFRAME
| WS_MINIMIZEBOX
| WS_MAXIMIZEBOX
);
542 top_child
= GetWindow(hWndParent
, GW_CHILD
);
546 /* Restore current maximized child */
547 if((dwStyle
& WS_VISIBLE
) && IsZoomed(top_child
))
549 TRACE("Restoring current maximized child %p\n", top_child
);
550 SendMessageW( top_child
, WM_SETREDRAW
, FALSE
, 0 );
551 ShowWindow(top_child
, SW_RESTORE
);
552 SendMessageW( top_child
, WM_SETREDRAW
, TRUE
, 0 );
556 MDI_CalcDefaultChildPos(hWndParent
, -1, mPos
, 0, &id
);
558 if (!(dwStyle
& WS_POPUP
)) hMenu
= UlongToHandle(id
);
560 if (dwStyle
& (WS_CHILD
| WS_POPUP
))
562 if (x
== CW_USEDEFAULT
|| x
== CW_USEDEFAULT16
)
567 if (nWidth
== CW_USEDEFAULT
|| nWidth
== CW_USEDEFAULT16
|| !nWidth
)
569 if (nHeight
== CW_USEDEFAULT
|| nHeight
== CW_USEDEFAULT16
|| !nHeight
)
574 hwnd
= User32CreateWindowEx(dwExStyle
,
576 (LPCSTR
)lpWindowName
,
594 DeferWindowPos(HDWP hWinPosInfo
,
596 HWND hWndInsertAfter
,
603 return NtUserDeferWindowPos(hWinPosInfo
, hWnd
, hWndInsertAfter
, x
, y
, cx
, cy
, uFlags
);
611 EndDeferWindowPos(HDWP hWinPosInfo
)
613 return NtUserEndDeferWindowPosEx(hWinPosInfo
, 0);
621 GetDesktopWindow(VOID
)
628 Wnd
= GetThreadDesktopWnd();
630 Ret
= UserHMGetHandle(Wnd
);
632 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
643 User32EnumWindows(HDESK hDesktop
,
650 DWORD i
, dwCount
= 0;
657 SetLastError ( ERROR_INVALID_PARAMETER
);
661 /* FIXME instead of always making two calls, should we use some
662 sort of persistent buffer and only grow it ( requiring a 2nd
663 call ) when the buffer wasn't already big enough? */
664 /* first get how many window entries there are */
665 Status
= NtUserBuildHwndList(hDesktop
,
672 if (!NT_SUCCESS(Status
))
683 /* allocate buffer to receive HWND handles */
684 hHeap
= GetProcessHeap();
685 pHwnd
= HeapAlloc(hHeap
, 0, sizeof(HWND
)*(dwCount
+1));
688 SetLastError ( ERROR_NOT_ENOUGH_MEMORY
);
692 /* now call kernel again to fill the buffer this time */
693 Status
= NtUserBuildHwndList(hDesktop
,
700 if (!NT_SUCCESS(Status
))
703 HeapFree(hHeap
, 0, pHwnd
);
707 /* call the user's callback function until we're done or
708 they tell us to quit */
709 for ( i
= 0; i
< dwCount
; i
++ )
711 /* FIXME I'm only getting NULLs from Thread Enumeration, and it's
712 * probably because I'm not doing it right in NtUserBuildHwndList.
713 * Once that's fixed, we shouldn't have to check for a NULL HWND
715 * This is now fixed in revision 50205. (jt)
717 if (!pHwnd
[i
]) /* don't enumerate a NULL HWND */
719 if (!(*lpfn
)(pHwnd
[i
], lParam
))
721 HeapFree ( hHeap
, 0, pHwnd
);
726 HeapFree(hHeap
, 0, pHwnd
);
735 EnumChildWindows(HWND hWndParent
,
736 WNDENUMPROC lpEnumFunc
,
741 return EnumWindows(lpEnumFunc
, lParam
);
743 return User32EnumWindows(NULL
, hWndParent
, lpEnumFunc
, lParam
, 0, TRUE
);
751 EnumThreadWindows(DWORD dwThreadId
,
756 dwThreadId
= GetCurrentThreadId();
757 return User32EnumWindows(NULL
, NULL
, lpfn
, lParam
, dwThreadId
, FALSE
);
765 EnumWindows(WNDENUMPROC lpEnumFunc
,
768 return User32EnumWindows(NULL
, NULL
, lpEnumFunc
, lParam
, 0, FALSE
);
776 EnumDesktopWindows(HDESK hDesktop
,
780 return User32EnumWindows(hDesktop
, NULL
, lpfn
, lParam
, 0, FALSE
);
788 FindWindowExA(HWND hwndParent
,
793 LPWSTR titleW
= NULL
;
798 DWORD len
= MultiByteToWideChar( CP_ACP
, 0, lpszWindow
, -1, NULL
, 0 );
799 if (!(titleW
= HeapAlloc( GetProcessHeap(), 0, len
* sizeof(WCHAR
) ))) return 0;
800 MultiByteToWideChar( CP_ACP
, 0, lpszWindow
, -1, titleW
, len
);
803 if (!IS_INTRESOURCE(lpszClass
))
806 if (MultiByteToWideChar( CP_ACP
, 0, lpszClass
, -1, classW
, sizeof(classW
)/sizeof(WCHAR
) ))
807 hwnd
= FindWindowExW( hwndParent
, hwndChildAfter
, classW
, titleW
);
811 hwnd
= FindWindowExW( hwndParent
, hwndChildAfter
, (LPCWSTR
)lpszClass
, titleW
);
814 HeapFree( GetProcessHeap(), 0, titleW
);
823 FindWindowExW(HWND hwndParent
,
828 UNICODE_STRING ucClassName
, *pucClassName
= NULL
;
829 UNICODE_STRING ucWindowName
, *pucWindowName
= NULL
;
831 if (IS_ATOM(lpszClass
))
833 ucClassName
.Length
= 0;
834 ucClassName
.Buffer
= (LPWSTR
)lpszClass
;
835 pucClassName
= &ucClassName
;
837 else if (lpszClass
!= NULL
)
839 RtlInitUnicodeString(&ucClassName
,
841 pucClassName
= &ucClassName
;
844 if (lpszWindow
!= NULL
)
846 RtlInitUnicodeString(&ucWindowName
,
848 pucWindowName
= &ucWindowName
;
851 return NtUserFindWindowEx(hwndParent
,
863 FindWindowA(LPCSTR lpClassName
, LPCSTR lpWindowName
)
865 //FIXME: FindWindow does not search children, but FindWindowEx does.
866 // what should we do about this?
867 return FindWindowExA (NULL
, NULL
, lpClassName
, lpWindowName
);
875 FindWindowW(LPCWSTR lpClassName
, LPCWSTR lpWindowName
)
879 There was a FIXME here earlier, but I think it is just a documentation unclarity.
881 FindWindow only searches top level windows. What they mean is that child
882 windows of other windows than the desktop can be searched.
883 FindWindowExW never does a recursive search.
888 return FindWindowExW(NULL
, NULL
, lpClassName
, lpWindowName
);
897 GetAltTabInfoA(HWND hwnd
,
903 return NtUserGetAltTabInfo(hwnd
,iItem
,pati
,(LPWSTR
)pszItemText
,cchItemText
,TRUE
);
911 GetAltTabInfoW(HWND hwnd
,
917 return NtUserGetAltTabInfo(hwnd
,iItem
,pati
,pszItemText
,cchItemText
,FALSE
);
925 GetAncestor(HWND hwnd
, UINT gaFlags
)
930 Wnd
= ValidateHwnd(hwnd
);
940 if (Wnd
->spwndParent
!= NULL
)
941 Ancestor
= DesktopPtrToUser(Wnd
->spwndParent
);
945 /* FIXME: Call win32k for now */
950 if (Ancestor
!= NULL
)
951 Ret
= UserHMGetHandle(Ancestor
);
953 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
959 if (!Wnd
) /* Fall back */
960 Ret
= NtUserGetAncestor(hwnd
, gaFlags
);
970 GetClientRect(HWND hWnd
, LPRECT lpRect
)
972 PWND Wnd
= ValidateHwnd(hWnd
);
974 if (!Wnd
) return FALSE
;
975 if (Wnd
->style
& WS_MINIMIZED
)
977 lpRect
->left
= lpRect
->top
= 0;
978 lpRect
->right
= GetSystemMetrics(SM_CXMINIMIZED
);
979 lpRect
->bottom
= GetSystemMetrics(SM_CYMINIMIZED
);
982 if ( hWnd
!= GetDesktopWindow()) // Wnd->fnid != FNID_DESKTOP )
984 /* lpRect->left = lpRect->top = 0;
985 lpRect->right = Wnd->rcClient.right - Wnd->rcClient.left;
986 lpRect->bottom = Wnd->rcClient.bottom - Wnd->rcClient.top;
988 *lpRect
= Wnd
->rcClient
;
989 OffsetRect(lpRect
, -Wnd
->rcClient
.left
, -Wnd
->rcClient
.top
);
993 lpRect
->left
= lpRect
->top
= 0;
994 lpRect
->right
= Wnd
->rcClient
.right
;
995 lpRect
->bottom
= Wnd
->rcClient
.bottom
;
996 /* Do this until Init bug is fixed. This sets 640x480, see InitMetrics.
997 lpRect->right = GetSystemMetrics(SM_CXSCREEN);
998 lpRect->bottom = GetSystemMetrics(SM_CYSCREEN);
1008 GetLastActivePopup(HWND hWnd
)
1013 Wnd
= ValidateHwnd(hWnd
);
1018 if (Wnd
->spwndLastActive
)
1020 PWND LastActive
= DesktopPtrToUser(Wnd
->spwndLastActive
);
1021 Ret
= UserHMGetHandle(LastActive
);
1024 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
1038 GetParent(HWND hWnd
)
1040 PWND Wnd
, WndParent
;
1043 Wnd
= ValidateHwnd(hWnd
);
1049 if (Wnd
->style
& WS_POPUP
)
1051 if (Wnd
->spwndOwner
!= NULL
)
1052 WndParent
= DesktopPtrToUser(Wnd
->spwndOwner
);
1054 else if (Wnd
->style
& WS_CHILD
)
1056 if (Wnd
->spwndParent
!= NULL
)
1057 WndParent
= DesktopPtrToUser(Wnd
->spwndParent
);
1060 if (WndParent
!= NULL
)
1061 Ret
= UserHMGetHandle(WndParent
);
1063 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
1078 GetProcessDefaultLayout(DWORD
*pdwDefaultLayout
)
1080 return (BOOL
)NtUserCallOneParam( (DWORD_PTR
)pdwDefaultLayout
, ONEPARAM_ROUTINE_GETPROCDEFLAYOUT
);
1088 GetWindow(HWND hWnd
,
1094 Wnd
= ValidateHwnd(hWnd
);
1104 if (Wnd
->spwndOwner
!= NULL
)
1105 FoundWnd
= DesktopPtrToUser(Wnd
->spwndOwner
);
1109 if(Wnd
->spwndParent
!= NULL
)
1111 FoundWnd
= DesktopPtrToUser(Wnd
->spwndParent
);
1112 if (FoundWnd
->spwndChild
!= NULL
)
1113 FoundWnd
= DesktopPtrToUser(FoundWnd
->spwndChild
);
1117 if (Wnd
->spwndNext
!= NULL
)
1118 FoundWnd
= DesktopPtrToUser(Wnd
->spwndNext
);
1122 if (Wnd
->spwndPrev
!= NULL
)
1123 FoundWnd
= DesktopPtrToUser(Wnd
->spwndPrev
);
1127 if (Wnd
->spwndChild
!= NULL
)
1128 FoundWnd
= DesktopPtrToUser(Wnd
->spwndChild
);
1133 while ( FoundWnd
->spwndNext
!= NULL
)
1134 FoundWnd
= DesktopPtrToUser(FoundWnd
->spwndNext
);
1142 if (FoundWnd
!= NULL
)
1143 Ret
= UserHMGetHandle(FoundWnd
);
1145 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
1159 GetTopWindow(HWND hWnd
)
1161 if (!hWnd
) hWnd
= GetDesktopWindow();
1162 return GetWindow(hWnd
, GW_CHILD
);
1172 GetWindowInfo(HWND hWnd
,
1180 if ( !pwi
|| pwi
->cbSize
!= sizeof(WINDOWINFO
))
1181 SetLastError(ERROR_INVALID_PARAMETER
); // Just set the error and go!
1183 pWnd
= ValidateHwnd(hWnd
);
1187 UserGetWindowBorders(pWnd
->style
, pWnd
->ExStyle
, &Size
, FALSE
);
1191 pCls
= DesktopPtrToUser(pWnd
->pcls
);
1192 pwi
->rcWindow
= pWnd
->rcWindow
;
1193 pwi
->rcClient
= pWnd
->rcClient
;
1194 pwi
->dwStyle
= pWnd
->style
;
1195 pwi
->dwExStyle
= pWnd
->ExStyle
;
1196 pwi
->cxWindowBorders
= Size
.cx
;
1197 pwi
->cyWindowBorders
= Size
.cy
;
1198 pwi
->dwWindowStatus
= 0;
1199 if (pWnd
->state
& WNDS_ACTIVEFRAME
|| (GetActiveWindow() == hWnd
))
1200 pwi
->dwWindowStatus
= WS_ACTIVECAPTION
;
1201 pwi
->atomWindowType
= (pCls
? pCls
->atomClassName
: 0 );
1203 if ( pWnd
->state2
& WNDS2_WIN50COMPAT
)
1205 pwi
->wCreatorVersion
= 0x500;
1207 else if ( pWnd
->state2
& WNDS2_WIN40COMPAT
)
1209 pwi
->wCreatorVersion
= 0x400;
1211 else if ( pWnd
->state2
& WNDS2_WIN31COMPAT
)
1213 pwi
->wCreatorVersion
= 0x30A;
1217 pwi
->wCreatorVersion
= 0x300;
1222 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
1236 GetWindowModuleFileNameA(HWND hwnd
,
1238 UINT cchFileNameMax
)
1240 PWND Wnd
= ValidateHwnd(hwnd
);
1245 return GetModuleFileNameA(Wnd
->hModule
, lpszFileName
, cchFileNameMax
);
1253 GetWindowModuleFileNameW(HWND hwnd
,
1254 LPWSTR lpszFileName
,
1255 UINT cchFileNameMax
)
1257 PWND Wnd
= ValidateHwnd(hwnd
);
1262 return GetModuleFileNameW( Wnd
->hModule
, lpszFileName
, cchFileNameMax
);
1269 GetWindowRect(HWND hWnd
,
1272 PWND Wnd
= ValidateHwnd(hWnd
);
1274 if (!Wnd
) return FALSE
;
1275 if ( hWnd
!= GetDesktopWindow()) // Wnd->fnid != FNID_DESKTOP )
1277 *lpRect
= Wnd
->rcWindow
;
1281 lpRect
->left
= lpRect
->top
= 0;
1282 lpRect
->right
= Wnd
->rcWindow
.right
;
1283 lpRect
->bottom
= Wnd
->rcWindow
.bottom
;
1284 /* Do this until Init bug is fixed. This sets 640x480, see InitMetrics.
1285 lpRect->right = GetSystemMetrics(SM_CXSCREEN);
1286 lpRect->bottom = GetSystemMetrics(SM_CYSCREEN);
1295 GetWindowTextA(HWND hWnd
, LPSTR lpString
, int nMaxCount
)
1300 if (lpString
== NULL
|| nMaxCount
== 0)
1303 Wnd
= ValidateHwnd(hWnd
);
1309 if (!TestWindowProcess( Wnd
))
1313 Length
= DefWindowProcA(hWnd
, WM_GETTEXT
, nMaxCount
, (LPARAM
)lpString
);
1315 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
1322 Length
= SendMessageA(hWnd
, WM_GETTEXT
, nMaxCount
, (LPARAM
)lpString
);
1323 //ERR("GWTA Len %d : %s\n",Length,lpString);
1331 GetWindowTextLengthA(HWND hWnd
)
1333 return(SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0));
1340 GetWindowTextLengthW(HWND hWnd
)
1342 return(SendMessageW(hWnd
, WM_GETTEXTLENGTH
, 0, 0));
1349 GetWindowTextW(HWND hWnd
, LPWSTR lpString
, int nMaxCount
)
1354 if (lpString
== NULL
|| nMaxCount
== 0)
1357 Wnd
= ValidateHwnd(hWnd
);
1361 lpString
[0] = L
'\0';
1363 if (!TestWindowProcess( Wnd
))
1367 Length
= DefWindowProcW(hWnd
, WM_GETTEXT
, nMaxCount
, (LPARAM
)lpString
);
1369 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
1376 Length
= SendMessageW(hWnd
, WM_GETTEXT
, nMaxCount
, (LPARAM
)lpString
);
1377 //ERR("GWTW Len %d : %S\n",Length,lpString);
1382 GetWindowThreadProcessId(HWND hWnd
,
1383 LPDWORD lpdwProcessId
)
1387 PWND pWnd
= ValidateHwnd(hWnd
);
1389 if (!pWnd
) return Ret
;
1391 ti
= pWnd
->head
.pti
;
1395 if (ti
== GetW32ThreadInfo())
1396 { // We are current.
1397 //FIXME("Current!\n");
1399 *lpdwProcessId
= (DWORD_PTR
)NtCurrentTeb()->ClientId
.UniqueProcess
;
1400 Ret
= (DWORD_PTR
)NtCurrentTeb()->ClientId
.UniqueThread
;
1403 { // Ask kernel for info.
1404 //FIXME("Kernel call!\n");
1406 *lpdwProcessId
= NtUserQueryWindow(hWnd
, QUERY_WINDOW_UNIQUE_PROCESS_ID
);
1407 Ret
= NtUserQueryWindow(hWnd
, QUERY_WINDOW_UNIQUE_THREAD_ID
);
1418 IsChild(HWND hWndParent
,
1421 PWND WndParent
, DesktopWnd
, Wnd
;
1424 WndParent
= ValidateHwnd(hWndParent
);
1427 Wnd
= ValidateHwnd(hWnd
);
1431 DesktopWnd
= GetThreadDesktopWnd();
1437 while (Wnd
!= NULL
&& ((Wnd
->style
& (WS_POPUP
|WS_CHILD
)) == WS_CHILD
))
1439 if (Wnd
->spwndParent
!= NULL
)
1441 Wnd
= DesktopPtrToUser(Wnd
->spwndParent
);
1443 if (Wnd
== WndParent
)
1453 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
1469 PWND Wnd
= ValidateHwnd(hWnd
);
1472 return (Wnd
->style
& WS_MINIMIZE
) != 0;
1484 PWND Wnd
= ValidateHwndNoErr(hWnd
);
1487 if (Wnd
->state
& WNDS_DESTROYED
||
1488 Wnd
->state2
& WNDS2_INDESTROY
)
1501 IsWindowUnicode(HWND hWnd
)
1503 PWND Wnd
= ValidateHwnd(hWnd
);
1506 return Wnd
->Unicode
;
1516 IsWindowVisible(HWND hWnd
)
1519 PWND Wnd
= ValidateHwnd(hWnd
);
1529 if (!(Wnd
->style
& WS_VISIBLE
))
1535 if (Wnd
->spwndParent
!= NULL
)
1536 Wnd
= DesktopPtrToUser(Wnd
->spwndParent
);
1540 } while (Wnd
!= NULL
);
1542 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
1557 IsWindowEnabled(HWND hWnd
)
1559 // AG: I don't know if child windows are affected if the parent is
1560 // disabled. I think they stop processing messages but stay appearing
1563 return !(GetWindowLongPtrW(hWnd
, GWL_STYLE
) & WS_DISABLED
);
1573 return (GetWindowLongPtrW(hWnd
, GWL_STYLE
) & WS_MAXIMIZE
) != 0;
1581 LockSetForegroundWindow(UINT uLockCode
)
1583 return NtUserxLockSetForegroundWindow(uLockCode
);
1591 AnimateWindow(HWND hwnd
,
1595 /* FIXME Add animation code */
1597 /* If trying to show/hide and it's already *
1598 * shown/hidden or invalid window, fail with *
1599 * invalid parameter */
1602 visible
= IsWindowVisible(hwnd
);
1603 if(!IsWindow(hwnd
) ||
1604 (visible
&& !(dwFlags
& AW_HIDE
)) ||
1605 (!visible
&& (dwFlags
& AW_HIDE
)))
1607 SetLastError(ERROR_INVALID_PARAMETER
);
1611 ShowWindow(hwnd
, (dwFlags
& AW_HIDE
) ? SW_HIDE
: ((dwFlags
& AW_ACTIVATE
) ? SW_SHOW
: SW_SHOWNA
));
1623 if (!(GetWindowLongPtrW(hWnd
, GWL_STYLE
) & WS_MINIMIZE
))
1626 ShowWindow(hWnd
,SW_RESTORE
);
1635 RealChildWindowFromPoint(HWND hwndParent
,
1636 POINT ptParentClientCoords
)
1638 return NtUserRealChildWindowFromPoint(hwndParent
, ptParentClientCoords
.x
, ptParentClientCoords
.y
);
1645 SetForegroundWindow(HWND hWnd
)
1647 return NtUserxSetForegroundWindow(hWnd
);
1655 SetProcessDefaultLayout(DWORD dwDefaultLayout
)
1657 return NtUserCallOneParam( (DWORD_PTR
)dwDefaultLayout
, ONEPARAM_ROUTINE_SETPROCDEFLAYOUT
);
1667 SetWindowTextA(HWND hWnd
,
1672 pwnd
= ValidateHwnd(hWnd
);
1675 if (!TestWindowProcess(pwnd
))
1677 /* do not send WM_GETTEXT messages to other processes */
1678 return (DefWindowProcA(hWnd
, WM_SETTEXT
, 0, (LPARAM
)lpString
) >= 0);
1680 return (SendMessageA(hWnd
, WM_SETTEXT
, 0, (LPARAM
)lpString
) >= 0);
1692 SetWindowTextW(HWND hWnd
,
1697 pwnd
= ValidateHwnd(hWnd
);
1700 if (!TestWindowProcess(pwnd
))
1702 /* do not send WM_GETTEXT messages to other processes */
1703 return (DefWindowProcW(hWnd
, WM_SETTEXT
, 0, (LPARAM
)lpString
) >= 0);
1705 return (SendMessageW(hWnd
, WM_SETTEXT
, 0, (LPARAM
)lpString
) >= 0);
1715 ShowOwnedPopups(HWND hWnd
, BOOL fShow
)
1717 return NtUserxShowOwnedPopups(hWnd
, fShow
);
1725 UpdateLayeredWindow( HWND hwnd
,
1735 if (dwFlags
& ULW_EX_NORESIZE
) /* only valid for UpdateLayeredWindowIndirect */
1737 SetLastError( ERROR_INVALID_PARAMETER
);
1740 return NtUserUpdateLayeredWindow( hwnd
,
1756 UpdateLayeredWindowIndirect(HWND hwnd
,
1757 const UPDATELAYEREDWINDOWINFO
*info
)
1759 if (info
&& info
->cbSize
== sizeof(*info
))
1761 return NtUserUpdateLayeredWindow( hwnd
,
1763 (POINT
*)info
->pptDst
,
1764 (SIZE
*)info
->psize
,
1766 (POINT
*)info
->pptSrc
,
1768 (BLENDFUNCTION
*)info
->pblend
,
1770 (RECT
*)info
->prcDirty
);
1772 SetLastError(ERROR_INVALID_PARAMETER
);
1780 SetWindowContextHelpId(HWND hwnd
,
1781 DWORD dwContextHelpId
)
1783 return NtUserxSetWindowContextHelpId(hwnd
, dwContextHelpId
);
1790 GetWindowContextHelpId(HWND hwnd
)
1792 return NtUserxGetWindowContextHelpId(hwnd
);
1799 InternalGetWindowText(HWND hWnd
, LPWSTR lpString
, int nMaxCount
)
1801 INT Ret
= NtUserInternalGetWindowText(hWnd
, lpString
, nMaxCount
);
1811 IsHungAppWindow(HWND hwnd
)
1813 return (NtUserQueryWindow(hwnd
, QUERY_WINDOW_ISHUNG
) != 0);
1820 SetLastErrorEx(DWORD dwErrCode
, DWORD dwType
)
1822 SetLastError(dwErrCode
);
1831 return (HWND
)NtUserGetThreadState(THREADSTATE_FOCUSWINDOW
);
1835 GetRealWindowOwner(HWND hwnd
)
1837 return NtUserQueryWindow(hwnd
, QUERY_WINDOW_REAL_ID
);
1844 SetTaskmanWindow(HWND hWnd
)
1846 return NtUserxSetTaskmanWindow(hWnd
);
1853 SetProgmanWindow(HWND hWnd
)
1855 return NtUserxSetProgmanWindow(hWnd
);
1862 GetProgmanWindow(VOID
)
1864 return (HWND
)NtUserGetThreadState(THREADSTATE_PROGMANWINDOW
);
1871 GetTaskmanWindow(VOID
)
1873 return (HWND
)NtUserGetThreadState(THREADSTATE_TASKMANWINDOW
);
1880 ScrollWindow(HWND hWnd
,
1884 CONST RECT
*prcClip
)
1886 return NtUserScrollWindowEx(hWnd
,
1893 (lpRect
? 0 : SW_SCROLLCHILDREN
) | (SW_ERASE
|SW_INVALIDATE
|SW_SCROLLWNDDCE
)) != ERROR
;
1896 /* ScrollWindow uses the window DC, ScrollWindowEx doesn't */
1902 ScrollWindowEx(HWND hWnd
,
1905 CONST RECT
*prcScroll
,
1906 CONST RECT
*prcClip
,
1911 if (flags
& SW_SMOOTHSCROLL
)
1913 FIXME("SW_SMOOTHSCROLL not supported.");
1916 return NtUserScrollWindowEx(hWnd
,
1934 HWND
*list
= WIN_ListChildren( GetDesktopWindow() );
1936 if (!list
) return FALSE
;
1937 for (i
= 0; list
[i
]; i
++)
1939 if (IsWindowVisible( list
[i
] ) && GetWindow( list
[i
], GW_OWNER
)) break;
1941 retvalue
= (list
[i
] != 0);
1942 HeapFree( GetProcessHeap(), 0, list
);
1950 IsWindowInDestroy(HWND hWnd
)
1953 pwnd
= ValidateHwnd(hWnd
);
1956 return ((pwnd
->state2
& WNDS2_INDESTROY
) == WNDS2_INDESTROY
);
1963 DisableProcessWindowsGhosting(VOID
)
1965 NtUserxEnableProcessWindowGhosting(FALSE
);