2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS user32.dll
4 * FILE: lib/user32/windows/window.c
5 * PURPOSE: Window management
6 * PROGRAMMER: Casper S. Hornstrup (chorns@users.sourceforge.net)
8 * 06-06-2001 CSH Created
11 /* INCLUDES ******************************************************************/
15 #include <wine/debug.h>
16 WINE_DEFAULT_DEBUG_CHANNEL(user32
);
18 LRESULT
DefWndNCPaint(HWND hWnd
, HRGN hRgn
, BOOL Active
);
19 void MDI_CalcDefaultChildPos( HWND hwndClient
, INT total
, LPPOINT lpPos
, INT delta
, UINT
*id
);
21 /* FUNCTIONS *****************************************************************/
25 User32CallSendAsyncProcForKernel(PVOID Arguments
, ULONG ArgumentLength
)
27 PSENDASYNCPROC_CALLBACK_ARGUMENTS CallbackArgs
;
29 TRACE("User32CallSendAsyncProcKernel()\n");
31 CallbackArgs
= (PSENDASYNCPROC_CALLBACK_ARGUMENTS
)Arguments
;
33 if (ArgumentLength
!= sizeof(SENDASYNCPROC_CALLBACK_ARGUMENTS
))
35 return(STATUS_INFO_LENGTH_MISMATCH
);
38 CallbackArgs
->Callback(CallbackArgs
->Wnd
,
40 CallbackArgs
->Context
,
41 CallbackArgs
->Result
);
42 return(STATUS_SUCCESS
);
50 AllowSetForegroundWindow(DWORD dwProcessId
)
52 return NtUserxAllowSetForegroundWindow(dwProcessId
);
60 BeginDeferWindowPos(int nNumWindows
)
62 return NtUserxBeginDeferWindowPos(nNumWindows
);
70 BringWindowToTop(HWND hWnd
)
72 return NtUserSetWindowPos(hWnd
,
78 SWP_NOSIZE
| SWP_NOMOVE
);
83 SwitchToThisWindow(HWND hwnd
, BOOL fUnknown
)
85 ShowWindow(hwnd
, SW_SHOW
);
93 ChildWindowFromPoint(HWND hWndParent
,
96 return (HWND
) NtUserChildWindowFromPointEx(hWndParent
, Point
.x
, Point
.y
, 0);
104 ChildWindowFromPointEx(HWND hwndParent
,
108 return (HWND
) NtUserChildWindowFromPointEx(hwndParent
, pt
.x
, pt
.y
, uFlags
);
116 CloseWindow(HWND hWnd
)
118 SendMessageA(hWnd
, WM_SYSCOMMAND
, SC_CLOSE
, 0);
120 return HandleToUlong(hWnd
);
126 OUT PLARGE_STRING plstr
,
132 RtlInitLargeUnicodeString((PLARGE_UNICODE_STRING
)plstr
, (PWSTR
)psz
, 0);
136 RtlInitLargeAnsiString((PLARGE_ANSI_STRING
)plstr
, (PSTR
)psz
, 0);
143 IN PLARGE_STRING LargeString
)
145 if (LargeString
->Buffer
)
147 RtlFreeHeap(GetProcessHeap(), 0, LargeString
->Buffer
);
148 RtlZeroMemory(LargeString
, sizeof(LARGE_STRING
));
153 User32CreateWindowEx(DWORD dwExStyle
,
167 LARGE_STRING WindowName
;
168 LARGE_STRING lstrClassName
, *plstrClassName
;
169 UNICODE_STRING ClassName
;
176 DbgPrint("[window] User32CreateWindowEx style %d, exstyle %d, parent %d\n", dwStyle
, dwExStyle
, hWndParent
);
179 if (!RegisterDefaultClasses
)
181 ERR("User32CreateWindowEx RegisterSystemControls\n");
182 RegisterSystemControls();
185 Unicode
= !(dwFlags
& NUCWE_ANSI
);
187 if (IS_ATOM(lpClassName
))
189 plstrClassName
= (PVOID
)lpClassName
;
194 RtlInitUnicodeString(&ClassName
, (PCWSTR
)lpClassName
);
197 if (!RtlCreateUnicodeStringFromAsciiz(&ClassName
, (PCSZ
)lpClassName
))
199 SetLastError(ERROR_OUTOFMEMORY
);
204 /* Copy it to a LARGE_STRING */
205 lstrClassName
.Buffer
= ClassName
.Buffer
;
206 lstrClassName
.Length
= ClassName
.Length
;
207 lstrClassName
.MaximumLength
= ClassName
.MaximumLength
;
208 plstrClassName
= &lstrClassName
;
211 /* Initialize a LARGE_STRING */
212 RtlInitLargeString(&WindowName
, lpWindowName
, Unicode
);
214 // HACK: The current implementation expects the Window name to be UNICODE
218 PSTR AnsiBuffer
= WindowName
.Buffer
;
219 ULONG AnsiLength
= WindowName
.Length
;
221 WindowName
.Length
= 0;
222 WindowName
.MaximumLength
= AnsiLength
* sizeof(WCHAR
);
223 WindowName
.Buffer
= RtlAllocateHeap(RtlGetProcessHeap(),
225 WindowName
.MaximumLength
);
226 if (!WindowName
.Buffer
)
228 SetLastError(ERROR_OUTOFMEMORY
);
232 Status
= RtlMultiByteToUnicodeN(WindowName
.Buffer
,
233 WindowName
.MaximumLength
,
237 if (!NT_SUCCESS(Status
))
243 if(!hMenu
&& (dwStyle
& (WS_OVERLAPPEDWINDOW
| WS_POPUP
)))
247 wceW
.cbSize
= sizeof(WNDCLASSEXW
);
248 if(GetClassInfoExW(hInstance
, (LPCWSTR
)lpClassName
, &wceW
) && wceW
.lpszMenuName
)
250 hMenu
= LoadMenuW(hInstance
, wceW
.lpszMenuName
);
255 wceA
.cbSize
= sizeof(WNDCLASSEXA
);
256 if(GetClassInfoExA(hInstance
, lpClassName
, &wceA
) && wceA
.lpszMenuName
)
258 hMenu
= LoadMenuA(hInstance
, wceA
.lpszMenuName
);
263 if (!Unicode
) dwExStyle
|= WS_EX_SETANSICREATOR
;
265 Handle
= NtUserCreateWindowEx(dwExStyle
,
282 DbgPrint("[window] NtUserCreateWindowEx() == %d\n", Handle
);
287 if (!IS_ATOM(lpClassName
))
289 RtlFreeUnicodeString(&ClassName
);
292 RtlFreeLargeString(&WindowName
);
303 CreateWindowExA(DWORD dwExStyle
,
316 MDICREATESTRUCTA mdi
;
319 if (!RegisterDefaultClasses
)
321 ERR("CreateWindowExA RegisterSystemControls\n");
322 RegisterSystemControls();
325 if (dwExStyle
& WS_EX_MDICHILD
)
332 pWndParent
= ValidateHwnd(hWndParent
);
334 if (!pWndParent
) return NULL
;
336 if (pWndParent
->fnid
!= FNID_MDICLIENT
) // wine uses WIN_ISMDICLIENT
338 WARN("WS_EX_MDICHILD, but parent %p is not MDIClient\n", hWndParent
);
342 /* lpParams of WM_[NC]CREATE is different for MDI children.
343 * MDICREATESTRUCT members have the originally passed values.
345 mdi
.szClass
= lpClassName
;
346 mdi
.szTitle
= lpWindowName
;
347 mdi
.hOwner
= hInstance
;
353 mdi
.lParam
= (LPARAM
)lpParam
;
355 lpParam
= (LPVOID
)&mdi
;
357 if (pWndParent
->style
& MDIS_ALLCHILDSTYLES
)
359 if (dwStyle
& WS_POPUP
)
361 WARN("WS_POPUP with MDIS_ALLCHILDSTYLES is not allowed\n");
364 dwStyle
|= (WS_CHILD
| WS_CLIPSIBLINGS
);
368 dwStyle
&= ~WS_POPUP
;
369 dwStyle
|= (WS_CHILD
| WS_VISIBLE
| WS_CLIPSIBLINGS
| WS_CAPTION
|
370 WS_SYSMENU
| WS_THICKFRAME
| WS_MINIMIZEBOX
| WS_MAXIMIZEBOX
);
373 top_child
= GetWindow(hWndParent
, GW_CHILD
);
377 /* Restore current maximized child */
378 if((dwStyle
& WS_VISIBLE
) && IsZoomed(top_child
))
380 TRACE("Restoring current maximized child %p\n", top_child
);
381 SendMessageW( top_child
, WM_SETREDRAW
, FALSE
, 0 );
382 ShowWindow(top_child
, SW_RESTORE
);
383 SendMessageW( top_child
, WM_SETREDRAW
, TRUE
, 0 );
387 MDI_CalcDefaultChildPos(hWndParent
, -1, mPos
, 0, &id
);
389 if (!(dwStyle
& WS_POPUP
)) hMenu
= UlongToHandle(id
);
391 if (dwStyle
& (WS_CHILD
| WS_POPUP
))
393 if (x
== CW_USEDEFAULT
|| x
== CW_USEDEFAULT16
)
398 if (nWidth
== CW_USEDEFAULT
|| nWidth
== CW_USEDEFAULT16
|| !nWidth
)
400 if (nHeight
== CW_USEDEFAULT
|| nHeight
== CW_USEDEFAULT16
|| !nHeight
)
405 hwnd
= User32CreateWindowEx(dwExStyle
,
426 CreateWindowExW(DWORD dwExStyle
,
428 LPCWSTR lpWindowName
,
439 MDICREATESTRUCTW mdi
;
442 if (!RegisterDefaultClasses
)
444 ERR("CreateWindowExW RegisterSystemControls\n");
445 RegisterSystemControls();
448 if (dwExStyle
& WS_EX_MDICHILD
)
455 pWndParent
= ValidateHwnd(hWndParent
);
457 if (!pWndParent
) return NULL
;
459 if (pWndParent
->fnid
!= FNID_MDICLIENT
)
461 WARN("WS_EX_MDICHILD, but parent %p is not MDIClient\n", hWndParent
);
465 /* lpParams of WM_[NC]CREATE is different for MDI children.
466 * MDICREATESTRUCT members have the originally passed values.
468 mdi
.szClass
= lpClassName
;
469 mdi
.szTitle
= lpWindowName
;
470 mdi
.hOwner
= hInstance
;
476 mdi
.lParam
= (LPARAM
)lpParam
;
478 lpParam
= (LPVOID
)&mdi
;
480 if (pWndParent
->style
& MDIS_ALLCHILDSTYLES
)
482 if (dwStyle
& WS_POPUP
)
484 WARN("WS_POPUP with MDIS_ALLCHILDSTYLES is not allowed\n");
487 dwStyle
|= (WS_CHILD
| WS_CLIPSIBLINGS
);
491 dwStyle
&= ~WS_POPUP
;
492 dwStyle
|= (WS_CHILD
| WS_VISIBLE
| WS_CLIPSIBLINGS
| WS_CAPTION
|
493 WS_SYSMENU
| WS_THICKFRAME
| WS_MINIMIZEBOX
| WS_MAXIMIZEBOX
);
496 top_child
= GetWindow(hWndParent
, GW_CHILD
);
500 /* Restore current maximized child */
501 if((dwStyle
& WS_VISIBLE
) && IsZoomed(top_child
))
503 TRACE("Restoring current maximized child %p\n", top_child
);
504 SendMessageW( top_child
, WM_SETREDRAW
, FALSE
, 0 );
505 ShowWindow(top_child
, SW_RESTORE
);
506 SendMessageW( top_child
, WM_SETREDRAW
, TRUE
, 0 );
510 MDI_CalcDefaultChildPos(hWndParent
, -1, mPos
, 0, &id
);
512 if (!(dwStyle
& WS_POPUP
)) hMenu
= UlongToHandle(id
);
514 if (dwStyle
& (WS_CHILD
| WS_POPUP
))
516 if (x
== CW_USEDEFAULT
|| x
== CW_USEDEFAULT16
)
521 if (nWidth
== CW_USEDEFAULT
|| nWidth
== CW_USEDEFAULT16
|| !nWidth
)
523 if (nHeight
== CW_USEDEFAULT
|| nHeight
== CW_USEDEFAULT16
|| !nHeight
)
528 hwnd
= User32CreateWindowEx(dwExStyle
,
529 (LPCSTR
) lpClassName
,
530 (LPCSTR
) lpWindowName
,
548 DeferWindowPos(HDWP hWinPosInfo
,
550 HWND hWndInsertAfter
,
557 return NtUserDeferWindowPos(hWinPosInfo
, hWnd
, hWndInsertAfter
, x
, y
, cx
, cy
, uFlags
);
565 EndDeferWindowPos(HDWP hWinPosInfo
)
567 return NtUserEndDeferWindowPosEx(hWinPosInfo
, 0);
575 GetDesktopWindow(VOID
)
582 Wnd
= GetThreadDesktopWnd();
584 Ret
= UserHMGetHandle(Wnd
);
586 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
597 User32EnumWindows(HDESK hDesktop
,
604 DWORD i
, dwCount
= 0;
611 SetLastError ( ERROR_INVALID_PARAMETER
);
615 /* FIXME instead of always making two calls, should we use some
616 sort of persistent buffer and only grow it ( requiring a 2nd
617 call ) when the buffer wasn't already big enough? */
618 /* first get how many window entries there are */
619 Status
= NtUserBuildHwndList(hDesktop
,
626 if (!NT_SUCCESS(Status
))
629 /* allocate buffer to receive HWND handles */
630 hHeap
= GetProcessHeap();
631 pHwnd
= HeapAlloc(hHeap
, 0, sizeof(HWND
)*(dwCount
+1));
634 SetLastError ( ERROR_NOT_ENOUGH_MEMORY
);
638 /* now call kernel again to fill the buffer this time */
639 Status
= NtUserBuildHwndList(hDesktop
,
646 if (!NT_SUCCESS(Status
))
649 HeapFree(hHeap
, 0, pHwnd
);
661 /* call the user's callback function until we're done or
662 they tell us to quit */
663 for ( i
= 0; i
< dwCount
; i
++ )
665 /* FIXME I'm only getting NULLs from Thread Enumeration, and it's
666 * probably because I'm not doing it right in NtUserBuildHwndList.
667 * Once that's fixed, we shouldn't have to check for a NULL HWND
669 * This is now fixed in revision 50205. (jt)
671 if (!pHwnd
[i
]) /* don't enumerate a NULL HWND */
673 if (!(*lpfn
)(pHwnd
[i
], lParam
))
675 HeapFree ( hHeap
, 0, pHwnd
);
680 HeapFree(hHeap
, 0, pHwnd
);
689 EnumChildWindows(HWND hWndParent
,
690 WNDENUMPROC lpEnumFunc
,
695 return EnumWindows(lpEnumFunc
, lParam
);
697 return User32EnumWindows(NULL
, hWndParent
, lpEnumFunc
, lParam
, 0, TRUE
);
705 EnumThreadWindows(DWORD dwThreadId
,
710 dwThreadId
= GetCurrentThreadId();
711 return User32EnumWindows(NULL
, NULL
, lpfn
, lParam
, dwThreadId
, FALSE
);
719 EnumWindows(WNDENUMPROC lpEnumFunc
,
722 return User32EnumWindows(NULL
, NULL
, lpEnumFunc
, lParam
, 0, FALSE
);
730 EnumDesktopWindows(HDESK hDesktop
,
734 return User32EnumWindows(hDesktop
, NULL
, lpfn
, lParam
, 0, FALSE
);
742 FindWindowExA(HWND hwndParent
,
747 UNICODE_STRING ucClassName
, *pucClassName
= NULL
;
748 UNICODE_STRING ucWindowName
, *pucWindowName
= NULL
;
751 if (IS_ATOM(lpszClass
))
753 ucClassName
.Buffer
= (LPWSTR
)lpszClass
;
754 ucClassName
.Length
= 0;
755 pucClassName
= &ucClassName
;
757 else if (lpszClass
!= NULL
)
759 if (!RtlCreateUnicodeStringFromAsciiz(&ucClassName
,
762 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
765 pucClassName
= &ucClassName
;
768 if (lpszWindow
!= NULL
)
770 if (!RtlCreateUnicodeStringFromAsciiz(&ucWindowName
,
773 if (!IS_ATOM(lpszClass
) && lpszClass
!= NULL
)
774 RtlFreeUnicodeString(&ucWindowName
);
776 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
780 pucWindowName
= &ucWindowName
;
783 Result
= NtUserFindWindowEx(hwndParent
,
789 if (!IS_ATOM(lpszClass
) && lpszClass
!= NULL
)
790 RtlFreeUnicodeString(&ucClassName
);
791 if (lpszWindow
!= NULL
)
792 RtlFreeUnicodeString(&ucWindowName
);
802 FindWindowExW(HWND hwndParent
,
807 UNICODE_STRING ucClassName
, *pucClassName
= NULL
;
808 UNICODE_STRING ucWindowName
, *pucWindowName
= NULL
;
810 if (IS_ATOM(lpszClass
))
812 ucClassName
.Length
= 0;
813 ucClassName
.Buffer
= (LPWSTR
)lpszClass
;
814 pucClassName
= &ucClassName
;
816 else if (lpszClass
!= NULL
)
818 RtlInitUnicodeString(&ucClassName
,
820 pucClassName
= &ucClassName
;
823 if (lpszWindow
!= NULL
)
825 RtlInitUnicodeString(&ucWindowName
,
827 pucWindowName
= &ucWindowName
;
830 return NtUserFindWindowEx(hwndParent
,
842 FindWindowA(LPCSTR lpClassName
, LPCSTR lpWindowName
)
844 //FIXME: FindWindow does not search children, but FindWindowEx does.
845 // what should we do about this?
846 return FindWindowExA (NULL
, NULL
, lpClassName
, lpWindowName
);
854 FindWindowW(LPCWSTR lpClassName
, LPCWSTR lpWindowName
)
858 There was a FIXME here earlier, but I think it is just a documentation unclarity.
860 FindWindow only searches top level windows. What they mean is that child
861 windows of other windows than the desktop can be searched.
862 FindWindowExW never does a recursive search.
867 return FindWindowExW(NULL
, NULL
, lpClassName
, lpWindowName
);
876 GetAltTabInfoA(HWND hwnd
,
891 GetAltTabInfoW(HWND hwnd
,
906 GetAncestor(HWND hwnd
, UINT gaFlags
)
911 Wnd
= ValidateHwnd(hwnd
);
921 if (Wnd
->spwndParent
!= NULL
)
922 Ancestor
= DesktopPtrToUser(Wnd
->spwndParent
);
926 /* FIXME: Call win32k for now */
931 if (Ancestor
!= NULL
)
932 Ret
= UserHMGetHandle(Ancestor
);
934 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
940 if (!Wnd
) /* Fall back */
941 Ret
= NtUserGetAncestor(hwnd
, gaFlags
);
951 GetClientRect(HWND hWnd
, LPRECT lpRect
)
953 PWND Wnd
= ValidateHwnd(hWnd
);
955 if (!Wnd
) return FALSE
;
956 if (Wnd
->style
& WS_MINIMIZED
)
958 lpRect
->left
= lpRect
->top
= 0;
959 lpRect
->right
= GetSystemMetrics(SM_CXMINIMIZED
);
960 lpRect
->bottom
= GetSystemMetrics(SM_CYMINIMIZED
);
963 if ( hWnd
!= GetDesktopWindow()) // Wnd->fnid != FNID_DESKTOP )
965 /* lpRect->left = lpRect->top = 0;
966 lpRect->right = Wnd->rcClient.right - Wnd->rcClient.left;
967 lpRect->bottom = Wnd->rcClient.bottom - Wnd->rcClient.top;
969 *lpRect
= Wnd
->rcClient
;
970 OffsetRect(lpRect
, -Wnd
->rcClient
.left
, -Wnd
->rcClient
.top
);
974 lpRect
->left
= lpRect
->top
= 0;
975 lpRect
->right
= Wnd
->rcClient
.right
;
976 lpRect
->bottom
= Wnd
->rcClient
.bottom
;
977 /* Do this until Init bug is fixed. This sets 640x480, see InitMetrics.
978 lpRect->right = GetSystemMetrics(SM_CXSCREEN);
979 lpRect->bottom = GetSystemMetrics(SM_CYSCREEN);
989 GetLastActivePopup(HWND hWnd
)
994 Wnd
= ValidateHwnd(hWnd
);
999 if (Wnd
->spwndLastActive
)
1001 PWND LastActive
= DesktopPtrToUser(Wnd
->spwndLastActive
);
1002 Ret
= UserHMGetHandle(LastActive
);
1005 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
1019 GetParent(HWND hWnd
)
1021 PWND Wnd
, WndParent
;
1024 Wnd
= ValidateHwnd(hWnd
);
1030 if (Wnd
->style
& WS_POPUP
)
1032 if (Wnd
->spwndOwner
!= NULL
)
1033 WndParent
= DesktopPtrToUser(Wnd
->spwndOwner
);
1035 else if (Wnd
->style
& WS_CHILD
)
1037 if (Wnd
->spwndParent
!= NULL
)
1038 WndParent
= DesktopPtrToUser(Wnd
->spwndParent
);
1041 if (WndParent
!= NULL
)
1042 Ret
= UserHMGetHandle(WndParent
);
1044 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
1059 GetProcessDefaultLayout(DWORD
*pdwDefaultLayout
)
1061 if (!pdwDefaultLayout
)
1063 SetLastError(ERROR_INVALID_PARAMETER
);
1069 *pdwDefaultLayout
= 0;
1078 GetWindow(HWND hWnd
,
1084 Wnd
= ValidateHwnd(hWnd
);
1094 if (Wnd
->spwndOwner
!= NULL
)
1095 FoundWnd
= DesktopPtrToUser(Wnd
->spwndOwner
);
1099 if(Wnd
->spwndParent
!= NULL
)
1101 FoundWnd
= DesktopPtrToUser(Wnd
->spwndParent
);
1102 if (FoundWnd
->spwndChild
!= NULL
)
1103 FoundWnd
= DesktopPtrToUser(FoundWnd
->spwndChild
);
1107 if (Wnd
->spwndNext
!= NULL
)
1108 FoundWnd
= DesktopPtrToUser(Wnd
->spwndNext
);
1112 if (Wnd
->spwndPrev
!= NULL
)
1113 FoundWnd
= DesktopPtrToUser(Wnd
->spwndPrev
);
1117 if (Wnd
->spwndChild
!= NULL
)
1118 FoundWnd
= DesktopPtrToUser(Wnd
->spwndChild
);
1123 while ( FoundWnd
->spwndNext
!= NULL
)
1124 FoundWnd
= DesktopPtrToUser(FoundWnd
->spwndNext
);
1132 if (FoundWnd
!= NULL
)
1133 Ret
= UserHMGetHandle(FoundWnd
);
1135 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
1149 GetTopWindow(HWND hWnd
)
1151 if (!hWnd
) hWnd
= GetDesktopWindow();
1152 return GetWindow(hWnd
, GW_CHILD
);
1160 GetWindowInfo(HWND hWnd
,
1168 if ( !pwi
|| pwi
->cbSize
!= sizeof(WINDOWINFO
))
1169 SetLastError(ERROR_INVALID_PARAMETER
); // Just set the error and go!
1171 pWnd
= ValidateHwnd(hWnd
);
1175 UserGetWindowBorders(pWnd
->style
, pWnd
->ExStyle
, &Size
, FALSE
);
1179 pCls
= DesktopPtrToUser(pWnd
->pcls
);
1180 pwi
->rcWindow
= pWnd
->rcWindow
;
1181 pwi
->rcClient
= pWnd
->rcClient
;
1182 pwi
->dwStyle
= pWnd
->style
;
1183 pwi
->dwExStyle
= pWnd
->ExStyle
;
1184 pwi
->cxWindowBorders
= Size
.cx
;
1185 pwi
->cyWindowBorders
= Size
.cy
;
1186 pwi
->dwWindowStatus
= 0;
1187 if (pWnd
->state
& WNDS_ACTIVEFRAME
)
1188 pwi
->dwWindowStatus
= WS_ACTIVECAPTION
;
1189 pwi
->atomWindowType
= (pCls
? pCls
->atomClassName
: 0 );
1191 if ( pWnd
->state2
& WNDS2_WIN50COMPAT
)
1193 pwi
->wCreatorVersion
= 0x500;
1195 else if ( pWnd
->state2
& WNDS2_WIN40COMPAT
)
1197 pwi
->wCreatorVersion
= 0x400;
1199 else if ( pWnd
->state2
& WNDS2_WIN31COMPAT
)
1201 pwi
->wCreatorVersion
= 0x30A;
1205 pwi
->wCreatorVersion
= 0x300;
1210 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
1224 GetWindowModuleFileNameA(HWND hwnd
,
1226 UINT cchFileNameMax
)
1228 PWND Wnd
= ValidateHwnd(hwnd
);
1233 return GetModuleFileNameA(Wnd
->hModule
, lpszFileName
, cchFileNameMax
);
1241 GetWindowModuleFileNameW(HWND hwnd
,
1242 LPWSTR lpszFileName
,
1243 UINT cchFileNameMax
)
1245 PWND Wnd
= ValidateHwnd(hwnd
);
1250 return GetModuleFileNameW( Wnd
->hModule
, lpszFileName
, cchFileNameMax
);
1258 GetWindowRect(HWND hWnd
,
1261 PWND Wnd
= ValidateHwnd(hWnd
);
1263 if (!Wnd
) return FALSE
;
1264 if ( hWnd
!= GetDesktopWindow()) // Wnd->fnid != FNID_DESKTOP )
1266 *lpRect
= Wnd
->rcWindow
;
1270 lpRect
->left
= lpRect
->top
= 0;
1271 lpRect
->right
= Wnd
->rcWindow
.right
;
1272 lpRect
->bottom
= Wnd
->rcWindow
.bottom
;
1273 /* Do this until Init bug is fixed. This sets 640x480, see InitMetrics.
1274 lpRect->right = GetSystemMetrics(SM_CXSCREEN);
1275 lpRect->bottom = GetSystemMetrics(SM_CYSCREEN);
1285 GetWindowTextA(HWND hWnd
, LPSTR lpString
, int nMaxCount
)
1291 if (lpString
== NULL
)
1294 Wnd
= ValidateHwnd(hWnd
);
1300 if (!TestWindowProcess( Wnd
))
1304 /* do not send WM_GETTEXT messages to other processes */
1305 Length
= Wnd
->strName
.Length
/ sizeof(WCHAR
);
1308 Buffer
= DesktopPtrToUser(Wnd
->strName
.Buffer
);
1311 if (!WideCharToMultiByte(CP_ACP
,
1320 lpString
[nMaxCount
- 1] = '\0';
1333 Wnd
= NULL
; /* Don't send a message */
1336 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
1340 Wnd
= NULL
; /* Don't send a message */
1345 Length
= SendMessageA(hWnd
, WM_GETTEXT
, nMaxCount
, (LPARAM
)lpString
);
1355 GetWindowTextLengthA(HWND hWnd
)
1357 return(SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0));
1365 GetWindowTextLengthW(HWND hWnd
)
1367 return(SendMessageW(hWnd
, WM_GETTEXTLENGTH
, 0, 0));
1375 GetWindowTextW(HWND hWnd
, LPWSTR lpString
, int nMaxCount
)
1381 if (lpString
== NULL
)
1384 Wnd
= ValidateHwnd(hWnd
);
1390 if (!TestWindowProcess( Wnd
))
1394 /* do not send WM_GETTEXT messages to other processes */
1395 Length
= Wnd
->strName
.Length
/ sizeof(WCHAR
);
1398 Buffer
= DesktopPtrToUser(Wnd
->strName
.Buffer
);
1401 RtlCopyMemory(lpString
,
1403 (Length
+ 1) * sizeof(WCHAR
));
1415 Wnd
= NULL
; /* Don't send a message */
1418 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
1422 Wnd
= NULL
; /* Don't send a message */
1427 Length
= SendMessageW(hWnd
, WM_GETTEXT
, nMaxCount
, (LPARAM
)lpString
);
1433 GetWindowThreadProcessId(HWND hWnd
,
1434 LPDWORD lpdwProcessId
)
1438 PWND pWnd
= ValidateHwnd(hWnd
);
1440 if (!pWnd
) return Ret
;
1442 ti
= pWnd
->head
.pti
;
1446 if (ti
== GetW32ThreadInfo())
1447 { // We are current.
1448 //FIXME("Current!\n");
1450 *lpdwProcessId
= (DWORD_PTR
)NtCurrentTeb()->ClientId
.UniqueProcess
;
1451 Ret
= (DWORD_PTR
)NtCurrentTeb()->ClientId
.UniqueThread
;
1454 { // Ask kernel for info.
1455 //FIXME("Kernel call!\n");
1457 *lpdwProcessId
= NtUserQueryWindow(hWnd
, QUERY_WINDOW_UNIQUE_PROCESS_ID
);
1458 Ret
= NtUserQueryWindow(hWnd
, QUERY_WINDOW_UNIQUE_THREAD_ID
);
1469 IsChild(HWND hWndParent
,
1472 PWND WndParent
, DesktopWnd
, Wnd
;
1475 WndParent
= ValidateHwnd(hWndParent
);
1478 Wnd
= ValidateHwnd(hWnd
);
1482 DesktopWnd
= GetThreadDesktopWnd();
1488 while (Wnd
!= NULL
&& ((Wnd
->style
& (WS_POPUP
|WS_CHILD
)) == WS_CHILD
))
1490 if (Wnd
->spwndParent
!= NULL
)
1492 Wnd
= DesktopPtrToUser(Wnd
->spwndParent
);
1494 if (Wnd
== WndParent
)
1504 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
1520 PWND Wnd
= ValidateHwnd(hWnd
);
1523 return (Wnd
->style
& WS_MINIMIZE
) != 0;
1535 PWND Wnd
= ValidateHwndNoErr(hWnd
);
1538 /* FIXME: If window is being destroyed return FALSE! */
1550 IsWindowUnicode(HWND hWnd
)
1552 PWND Wnd
= ValidateHwnd(hWnd
);
1555 return Wnd
->Unicode
;
1565 IsWindowVisible(HWND hWnd
)
1568 PWND Wnd
= ValidateHwnd(hWnd
);
1578 if (!(Wnd
->style
& WS_VISIBLE
))
1584 if (Wnd
->spwndParent
!= NULL
)
1585 Wnd
= DesktopPtrToUser(Wnd
->spwndParent
);
1589 } while (Wnd
!= NULL
);
1591 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
1606 IsWindowEnabled(HWND hWnd
)
1608 // AG: I don't know if child windows are affected if the parent is
1609 // disabled. I think they stop processing messages but stay appearing
1612 return !(GetWindowLongPtrW(hWnd
, GWL_STYLE
) & WS_DISABLED
);
1622 return (GetWindowLongPtrW(hWnd
, GWL_STYLE
) & WS_MAXIMIZE
) != 0;
1630 LockSetForegroundWindow(UINT uLockCode
)
1632 return NtUserxLockSetForegroundWindow(uLockCode
);
1640 AnimateWindow(HWND hwnd
,
1644 /* FIXME Add animation code */
1646 /* If trying to show/hide and it's already *
1647 * shown/hidden or invalid window, fail with *
1648 * invalid parameter */
1651 visible
= IsWindowVisible(hwnd
);
1652 if(!IsWindow(hwnd
) ||
1653 (visible
&& !(dwFlags
& AW_HIDE
)) ||
1654 (!visible
&& (dwFlags
& AW_HIDE
)))
1656 SetLastError(ERROR_INVALID_PARAMETER
);
1660 ShowWindow(hwnd
, (dwFlags
& AW_HIDE
) ? SW_HIDE
: ((dwFlags
& AW_ACTIVATE
) ? SW_SHOW
: SW_SHOWNA
));
1672 if (!(GetWindowLongPtrW(hWnd
, GWL_STYLE
) & WS_MINIMIZE
))
1675 ShowWindow(hWnd
,SW_RESTORE
);
1684 RealChildWindowFromPoint(HWND hwndParent
,
1685 POINT ptParentClientCoords
)
1687 return ChildWindowFromPointEx(hwndParent
, ptParentClientCoords
, CWP_SKIPTRANSPARENT
| CWP_SKIPINVISIBLE
);
1694 SetForegroundWindow(HWND hWnd
)
1696 return NtUserxSetForegroundWindow(hWnd
);
1704 SetProcessDefaultLayout(DWORD dwDefaultLayout
)
1706 if (dwDefaultLayout
== 0)
1718 SetWindowTextA(HWND hWnd
,
1723 pwnd
= ValidateHwnd(hWnd
);
1726 if (!TestWindowProcess(pwnd
))
1728 /* do not send WM_GETTEXT messages to other processes */
1729 return (DefWindowProcA(hWnd
, WM_SETTEXT
, 0, (LPARAM
)lpString
) >= 0);
1731 return (SendMessageA(hWnd
, WM_SETTEXT
, 0, (LPARAM
)lpString
) >= 0);
1741 SetWindowTextW(HWND hWnd
,
1746 pwnd
= ValidateHwnd(hWnd
);
1749 if (!TestWindowProcess(pwnd
))
1751 /* do not send WM_GETTEXT messages to other processes */
1752 return (DefWindowProcW(hWnd
, WM_SETTEXT
, 0, (LPARAM
)lpString
) >= 0);
1754 return (SendMessageW(hWnd
, WM_SETTEXT
, 0, (LPARAM
)lpString
) >= 0);
1764 ShowOwnedPopups(HWND hWnd
, BOOL fShow
)
1766 return NtUserxShowOwnedPopups(hWnd
, fShow
);
1774 UpdateLayeredWindow( HWND hwnd
,
1784 if ( dwFlags
& ULW_EX_NORESIZE
)
1785 dwFlags
= ~(ULW_EX_NORESIZE
|ULW_OPAQUE
|ULW_ALPHA
|ULW_COLORKEY
);
1786 return NtUserUpdateLayeredWindow( hwnd
,
1802 UpdateLayeredWindowIndirect(HWND hwnd
,
1803 const UPDATELAYEREDWINDOWINFO
*info
)
1805 if (info
&& info
->cbSize
== sizeof(*info
))
1807 return NtUserUpdateLayeredWindow( hwnd
,
1809 (POINT
*)info
->pptDst
,
1810 (SIZE
*)info
->psize
,
1812 (POINT
*)info
->pptSrc
,
1814 (BLENDFUNCTION
*)info
->pblend
,
1816 (RECT
*)info
->prcDirty
);
1818 SetLastError(ERROR_INVALID_PARAMETER
);
1826 SetWindowContextHelpId(HWND hwnd
,
1827 DWORD dwContextHelpId
)
1829 return NtUserxSetWindowContextHelpId(hwnd
, dwContextHelpId
);
1836 GetWindowContextHelpId(HWND hwnd
)
1838 return NtUserxGetWindowContextHelpId(hwnd
);
1845 InternalGetWindowText(HWND hWnd
, LPWSTR lpString
, int nMaxCount
)
1847 INT Ret
= NtUserInternalGetWindowText(hWnd
, lpString
, nMaxCount
);
1857 IsHungAppWindow(HWND hwnd
)
1859 return (NtUserQueryWindow(hwnd
, QUERY_WINDOW_ISHUNG
) != 0);
1866 SetLastErrorEx(DWORD dwErrCode
, DWORD dwType
)
1868 SetLastError(dwErrCode
);
1877 return (HWND
)NtUserGetThreadState(THREADSTATE_FOCUSWINDOW
);
1881 GetRealWindowOwner(HWND hwnd
)
1883 return NtUserQueryWindow(hwnd
, QUERY_WINDOW_REAL_ID
);
1890 SetTaskmanWindow(HWND hWnd
)
1892 return NtUserxSetTaskmanWindow(hWnd
);
1899 SetProgmanWindow(HWND hWnd
)
1901 return NtUserxSetProgmanWindow(hWnd
);
1908 GetProgmanWindow(VOID
)
1910 return (HWND
)NtUserGetThreadState(THREADSTATE_PROGMANWINDOW
);
1917 GetTaskmanWindow(VOID
)
1919 return (HWND
)NtUserGetThreadState(THREADSTATE_TASKMANWINDOW
);
1926 ScrollWindow(HWND hWnd
,
1930 CONST RECT
*prcClip
)
1932 return NtUserScrollWindowEx(hWnd
,
1939 (lpRect
? 0 : SW_SCROLLCHILDREN
) | SW_INVALIDATE
) != ERROR
;
1947 ScrollWindowEx(HWND hWnd
,
1950 CONST RECT
*prcScroll
,
1951 CONST RECT
*prcClip
,
1956 return NtUserScrollWindowEx(hWnd
,
1974 HWND
*list
= WIN_ListChildren( GetDesktopWindow() );
1976 if (!list
) return FALSE
;
1977 for (i
= 0; list
[i
]; i
++)
1979 if (IsWindowVisible( list
[i
] ) && GetWindow( list
[i
], GW_OWNER
)) break;
1981 retvalue
= (list
[i
] != 0);
1982 HeapFree( GetProcessHeap(), 0, list
);
1990 IsWindowInDestroy(HWND hWnd
)
1993 pwnd
= ValidateHwnd(hWnd
);
1996 return ((pwnd
->state2
& WNDS2_INDESTROY
) == WNDS2_INDESTROY
);
2003 DisableProcessWindowsGhosting(VOID
)
2005 NtUserxEnableProcessWindowGhosting(FALSE
);