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 #define CW_USEDEFAULT16 0x00008000
23 /* FUNCTIONS *****************************************************************/
27 User32CallSendAsyncProcForKernel(PVOID Arguments
, ULONG ArgumentLength
)
29 PSENDASYNCPROC_CALLBACK_ARGUMENTS CallbackArgs
;
31 TRACE("User32CallSendAsyncProcKernel()\n");
32 CallbackArgs
= (PSENDASYNCPROC_CALLBACK_ARGUMENTS
)Arguments
;
34 if (ArgumentLength
!= sizeof(WINDOWPROC_CALLBACK_ARGUMENTS
))
36 return(STATUS_INFO_LENGTH_MISMATCH
);
39 CallbackArgs
->Callback(CallbackArgs
->Wnd
,
41 CallbackArgs
->Context
,
42 CallbackArgs
->Result
);
43 return(STATUS_SUCCESS
);
51 AllowSetForegroundWindow(DWORD dwProcessId
)
53 static BOOL show_message
= TRUE
;
67 BeginDeferWindowPos(int nNumWindows
)
71 SetLastError(ERROR_INVALID_PARAMETER
);
87 BringWindowToTop(HWND hWnd
)
89 return NtUserSetWindowPos(hWnd
,
95 SWP_NOSIZE
| SWP_NOMOVE
);
100 SwitchToThisWindow(HWND hwnd
, BOOL fUnknown
)
102 ShowWindow(hwnd
, SW_SHOW
);
111 CascadeChildWindows ( HWND hWndParent
, WORD wFlags
)
113 return CascadeWindows(hWndParent
, wFlags
, NULL
, 0, NULL
);
121 ChildWindowFromPoint(HWND hWndParent
,
124 return (HWND
) NtUserChildWindowFromPointEx(hWndParent
, Point
.x
, Point
.y
, 0);
132 ChildWindowFromPointEx(HWND hwndParent
,
136 return (HWND
) NtUserChildWindowFromPointEx(hwndParent
, pt
.x
, pt
.y
, uFlags
);
144 CloseWindow(HWND hWnd
)
146 SendMessageA(hWnd
, WM_SYSCOMMAND
, SC_CLOSE
, 0);
153 User32CreateWindowEx(DWORD dwExStyle
,
167 UNICODE_STRING WindowName
;
168 UNICODE_STRING ClassName
;
174 DbgPrint("[window] User32CreateWindowEx style %d, exstyle %d, parent %d\n", dwStyle
, dwExStyle
, hWndParent
);
177 if (!RegisterDefaultClasses
)
179 ERR("User32CreateWindowEx RegisterSystemControls\n");
180 RegisterSystemControls();
183 if (IS_ATOM(lpClassName
))
185 RtlInitUnicodeString(&ClassName
, NULL
);
186 ClassName
.Buffer
= (LPWSTR
)lpClassName
;
191 RtlInitUnicodeString(&ClassName
, (PCWSTR
)lpClassName
);
194 if (!RtlCreateUnicodeStringFromAsciiz(&(ClassName
), (PCSZ
)lpClassName
))
196 SetLastError(ERROR_OUTOFMEMORY
);
203 RtlInitUnicodeString(&WindowName
, (PCWSTR
)lpWindowName
);
206 if (!RtlCreateUnicodeStringFromAsciiz(&WindowName
, (PCSZ
)lpWindowName
))
208 if (!IS_ATOM(lpClassName
))
210 RtlFreeUnicodeString(&ClassName
);
212 SetLastError(ERROR_OUTOFMEMORY
);
217 if(!hMenu
&& (dwStyle
& (WS_OVERLAPPEDWINDOW
| WS_POPUP
)))
221 wceW
.cbSize
= sizeof(WNDCLASSEXW
);
222 if(GetClassInfoExW(hInstance
, (LPCWSTR
)lpClassName
, &wceW
) && wceW
.lpszMenuName
)
224 hMenu
= LoadMenuW(hInstance
, wceW
.lpszMenuName
);
229 wceA
.cbSize
= sizeof(WNDCLASSEXA
);
230 if(GetClassInfoExA(hInstance
, lpClassName
, &wceA
) && wceA
.lpszMenuName
)
232 hMenu
= LoadMenuA(hInstance
, wceA
.lpszMenuName
);
237 Handle
= NtUserCreateWindowEx(dwExStyle
,
254 DbgPrint("[window] NtUserCreateWindowEx() == %d\n", Handle
);
259 RtlFreeUnicodeString(&WindowName
);
261 if (!IS_ATOM(lpClassName
))
263 RtlFreeUnicodeString(&ClassName
);
274 CreateWindowExA(DWORD dwExStyle
,
287 MDICREATESTRUCTA mdi
;
290 if (!RegisterDefaultClasses
)
292 ERR("CreateWindowExA RegisterSystemControls\n");
293 RegisterSystemControls();
296 if (dwExStyle
& WS_EX_MDICHILD
)
302 /* lpParams of WM_[NC]CREATE is different for MDI children.
303 * MDICREATESTRUCT members have the originally passed values.
305 mdi
.szClass
= lpClassName
;
306 mdi
.szTitle
= lpWindowName
;
307 mdi
.hOwner
= hInstance
;
313 mdi
.lParam
= (LPARAM
)lpParam
;
315 lpParam
= (LPVOID
)&mdi
;
317 if (GetWindowLongPtrW(hWndParent
, GWL_STYLE
) & MDIS_ALLCHILDSTYLES
)
319 if (dwStyle
& WS_POPUP
)
321 WARN("WS_POPUP with MDIS_ALLCHILDSTYLES is not allowed\n");
324 dwStyle
|= (WS_CHILD
| WS_CLIPSIBLINGS
);
328 dwStyle
&= ~WS_POPUP
;
329 dwStyle
|= (WS_CHILD
| WS_VISIBLE
| WS_CLIPSIBLINGS
| WS_CAPTION
|
330 WS_SYSMENU
| WS_THICKFRAME
| WS_MINIMIZEBOX
| WS_MAXIMIZEBOX
);
333 top_child
= GetWindow(hWndParent
, GW_CHILD
);
337 /* Restore current maximized child */
338 if((dwStyle
& WS_VISIBLE
) && IsZoomed(top_child
))
340 TRACE("Restoring current maximized child %p\n", top_child
);
341 SendMessageW( top_child
, WM_SETREDRAW
, FALSE
, 0 );
342 ShowWindow(top_child
, SW_RESTORE
);
343 SendMessageW( top_child
, WM_SETREDRAW
, TRUE
, 0 );
347 MDI_CalcDefaultChildPos(hWndParent
, -1, mPos
, 0, &id
);
349 if (!(dwStyle
& WS_POPUP
)) hMenu
= (HMENU
)id
;
351 if (dwStyle
& (WS_CHILD
| WS_POPUP
))
353 if (x
== CW_USEDEFAULT
|| x
== CW_USEDEFAULT16
)
358 if (nWidth
== CW_USEDEFAULT
|| nWidth
== CW_USEDEFAULT16
|| !nWidth
)
360 if (nHeight
== CW_USEDEFAULT
|| nHeight
== CW_USEDEFAULT16
|| !nHeight
)
365 hwnd
= User32CreateWindowEx(dwExStyle
,
386 CreateWindowExW(DWORD dwExStyle
,
388 LPCWSTR lpWindowName
,
399 MDICREATESTRUCTW mdi
;
402 if (!RegisterDefaultClasses
)
404 ERR("CreateWindowExW RegisterSystemControls\n");
405 RegisterSystemControls();
408 if (dwExStyle
& WS_EX_MDICHILD
)
414 /* lpParams of WM_[NC]CREATE is different for MDI children.
415 * MDICREATESTRUCT members have the originally passed values.
417 mdi
.szClass
= lpClassName
;
418 mdi
.szTitle
= lpWindowName
;
419 mdi
.hOwner
= hInstance
;
425 mdi
.lParam
= (LPARAM
)lpParam
;
427 lpParam
= (LPVOID
)&mdi
;
429 if (GetWindowLongPtrW(hWndParent
, GWL_STYLE
) & MDIS_ALLCHILDSTYLES
)
431 if (dwStyle
& WS_POPUP
)
433 WARN("WS_POPUP with MDIS_ALLCHILDSTYLES is not allowed\n");
436 dwStyle
|= (WS_CHILD
| WS_CLIPSIBLINGS
);
440 dwStyle
&= ~WS_POPUP
;
441 dwStyle
|= (WS_CHILD
| WS_VISIBLE
| WS_CLIPSIBLINGS
| WS_CAPTION
|
442 WS_SYSMENU
| WS_THICKFRAME
| WS_MINIMIZEBOX
| WS_MAXIMIZEBOX
);
445 top_child
= GetWindow(hWndParent
, GW_CHILD
);
449 /* Restore current maximized child */
450 if((dwStyle
& WS_VISIBLE
) && IsZoomed(top_child
))
452 TRACE("Restoring current maximized child %p\n", top_child
);
453 SendMessageW( top_child
, WM_SETREDRAW
, FALSE
, 0 );
454 ShowWindow(top_child
, SW_RESTORE
);
455 SendMessageW( top_child
, WM_SETREDRAW
, TRUE
, 0 );
459 MDI_CalcDefaultChildPos(hWndParent
, -1, mPos
, 0, &id
);
461 if (!(dwStyle
& WS_POPUP
)) hMenu
= (HMENU
)id
;
463 if (dwStyle
& (WS_CHILD
| WS_POPUP
))
465 if (x
== CW_USEDEFAULT
|| x
== CW_USEDEFAULT16
)
470 if (nWidth
== CW_USEDEFAULT
|| nWidth
== CW_USEDEFAULT16
|| !nWidth
)
472 if (nHeight
== CW_USEDEFAULT
|| nHeight
== CW_USEDEFAULT16
|| !nHeight
)
477 hwnd
= User32CreateWindowEx(dwExStyle
,
478 (LPCSTR
) lpClassName
,
479 (LPCSTR
) lpWindowName
,
497 DeferWindowPos(HDWP hWinPosInfo
,
499 HWND hWndInsertAfter
,
507 return NtUserDeferWindowPos(hWinPosInfo
, hWnd
, hWndInsertAfter
, x
, y
, cx
, cy
, uFlags
);
509 SetWindowPos(hWnd
, hWndInsertAfter
, x
, y
, cx
, cy
, uFlags
);
519 EndDeferWindowPos(HDWP hWinPosInfo
)
534 GetDesktopWindow(VOID
)
541 Wnd
= GetThreadDesktopWnd();
543 Ret
= UserHMGetHandle(Wnd
);
545 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
556 User32EnumWindows(HDESK hDesktop
,
563 DWORD i
, dwCount
= 0;
570 SetLastError ( ERROR_INVALID_PARAMETER
);
574 /* FIXME instead of always making two calls, should we use some
575 sort of persistent buffer and only grow it ( requiring a 2nd
576 call ) when the buffer wasn't already big enough? */
577 /* first get how many window entries there are */
578 Status
= NtUserBuildHwndList(hDesktop
,
585 if (!NT_SUCCESS(Status
))
588 /* allocate buffer to receive HWND handles */
589 hHeap
= GetProcessHeap();
590 pHwnd
= HeapAlloc(hHeap
, 0, sizeof(HWND
)*(dwCount
+1));
593 SetLastError ( ERROR_NOT_ENOUGH_MEMORY
);
597 /* now call kernel again to fill the buffer this time */
598 Status
= NtUserBuildHwndList(hDesktop
,
605 if (!NT_SUCCESS(Status
))
608 HeapFree(hHeap
, 0, pHwnd
);
612 /* call the user's callback function until we're done or
613 they tell us to quit */
614 for ( i
= 0; i
< dwCount
; i
++ )
616 /* FIXME I'm only getting NULLs from Thread Enumeration, and it's
617 * probably because I'm not doing it right in NtUserBuildHwndList.
618 * Once that's fixed, we shouldn't have to check for a NULL HWND
621 if (!(ULONG
)pHwnd
[i
]) /* don't enumerate a NULL HWND */
623 if (!(*lpfn
)(pHwnd
[i
], lParam
))
625 HeapFree ( hHeap
, 0, pHwnd
);
630 HeapFree(hHeap
, 0, pHwnd
);
639 EnumChildWindows(HWND hWndParent
,
640 WNDENUMPROC lpEnumFunc
,
645 return EnumWindows(lpEnumFunc
, lParam
);
647 return User32EnumWindows(NULL
, hWndParent
, lpEnumFunc
, lParam
, 0, TRUE
);
655 EnumThreadWindows(DWORD dwThreadId
,
660 dwThreadId
= GetCurrentThreadId();
661 return User32EnumWindows(NULL
, NULL
, lpfn
, lParam
, dwThreadId
, FALSE
);
669 EnumWindows(WNDENUMPROC lpEnumFunc
,
672 return User32EnumWindows(NULL
, NULL
, lpEnumFunc
, lParam
, 0, FALSE
);
680 EnumDesktopWindows(HDESK hDesktop
,
684 return User32EnumWindows(hDesktop
, NULL
, lpfn
, lParam
, 0, FALSE
);
692 FindWindowExA(HWND hwndParent
,
697 UNICODE_STRING ucClassName
, *pucClassName
= NULL
;
698 UNICODE_STRING ucWindowName
, *pucWindowName
= NULL
;
701 if (IS_ATOM(lpszClass
))
703 ucClassName
.Buffer
= (LPWSTR
)lpszClass
;
704 ucClassName
.Length
= 0;
705 pucClassName
= &ucClassName
;
707 else if (lpszClass
!= NULL
)
709 if (!RtlCreateUnicodeStringFromAsciiz(&ucClassName
,
712 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
715 pucClassName
= &ucClassName
;
718 if (lpszWindow
!= NULL
)
720 if (!RtlCreateUnicodeStringFromAsciiz(&ucWindowName
,
723 if (!IS_ATOM(lpszClass
) && lpszClass
!= NULL
)
724 RtlFreeUnicodeString(&ucWindowName
);
726 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
730 pucWindowName
= &ucWindowName
;
733 Result
= NtUserFindWindowEx(hwndParent
,
739 if (!IS_ATOM(lpszClass
) && lpszClass
!= NULL
)
740 RtlFreeUnicodeString(&ucClassName
);
741 if (lpszWindow
!= NULL
)
742 RtlFreeUnicodeString(&ucWindowName
);
752 FindWindowExW(HWND hwndParent
,
757 UNICODE_STRING ucClassName
, *pucClassName
= NULL
;
758 UNICODE_STRING ucWindowName
, *pucWindowName
= NULL
;
760 if (IS_ATOM(lpszClass
))
762 ucClassName
.Length
= 0;
763 ucClassName
.Buffer
= (LPWSTR
)lpszClass
;
764 pucClassName
= &ucClassName
;
766 else if (lpszClass
!= NULL
)
768 RtlInitUnicodeString(&ucClassName
,
770 pucClassName
= &ucClassName
;
773 if (lpszWindow
!= NULL
)
775 RtlInitUnicodeString(&ucWindowName
,
777 pucWindowName
= &ucWindowName
;
780 return NtUserFindWindowEx(hwndParent
,
792 FindWindowA(LPCSTR lpClassName
, LPCSTR lpWindowName
)
794 //FIXME: FindWindow does not search children, but FindWindowEx does.
795 // what should we do about this?
796 return FindWindowExA (NULL
, NULL
, lpClassName
, lpWindowName
);
804 FindWindowW(LPCWSTR lpClassName
, LPCWSTR lpWindowName
)
808 There was a FIXME here earlier, but I think it is just a documentation unclarity.
810 FindWindow only searches top level windows. What they mean is that child
811 windows of other windows than the desktop can be searched.
812 FindWindowExW never does a recursive search.
817 return FindWindowExW(NULL
, NULL
, lpClassName
, lpWindowName
);
826 GetAltTabInfoA(HWND hwnd
,
841 GetAltTabInfoW(HWND hwnd
,
856 GetAncestor(HWND hwnd
, UINT gaFlags
)
861 Wnd
= ValidateHwnd(hwnd
);
871 if (Wnd
->spwndParent
!= NULL
)
872 Ancestor
= DesktopPtrToUser(Wnd
->spwndParent
);
876 /* FIXME: Call win32k for now */
881 if (Ancestor
!= NULL
)
882 Ret
= UserHMGetHandle(Ancestor
);
884 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
890 if (!Wnd
) /* Fall back */
891 Ret
= NtUserGetAncestor(hwnd
, gaFlags
);
901 GetClientRect(HWND hWnd
, LPRECT lpRect
)
903 PWND Wnd
= ValidateHwnd(hWnd
);
907 lpRect
->left
= lpRect
->top
= 0;
908 lpRect
->right
= Wnd
->rcClient
.right
- Wnd
->rcClient
.left
;
909 lpRect
->bottom
= Wnd
->rcClient
.bottom
- Wnd
->rcClient
.top
;
921 GetLastActivePopup(HWND hWnd
)
926 Wnd
= ValidateHwnd(hWnd
);
931 if (Wnd
->hWndLastActive
)
932 Ret
= Wnd
->hWndLastActive
;
934 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
953 Wnd
= ValidateHwnd(hWnd
);
959 if (Wnd
->style
& WS_CHILD
)
961 if (Wnd
->spwndParent
!= NULL
)
962 WndParent
= DesktopPtrToUser(Wnd
->spwndParent
);
964 else if (Wnd
->style
& WS_POPUP
)
966 if (Wnd
->spwndOwner
!= NULL
)
967 WndParent
= DesktopPtrToUser(Wnd
->spwndOwner
);
970 if (WndParent
!= NULL
)
971 Ret
= UserHMGetHandle(WndParent
);
973 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
988 GetProcessDefaultLayout(DWORD
*pdwDefaultLayout
)
990 if (!pdwDefaultLayout
)
992 SetLastError(ERROR_INVALID_PARAMETER
);
998 *pdwDefaultLayout
= 0;
1007 GetWindow(HWND hWnd
,
1013 Wnd
= ValidateHwnd(hWnd
);
1023 if (Wnd
->spwndOwner
!= NULL
)
1024 FoundWnd
= DesktopPtrToUser(Wnd
->spwndOwner
);
1028 if(Wnd
->spwndParent
!= NULL
)
1030 FoundWnd
= DesktopPtrToUser(Wnd
->spwndParent
);
1031 if (FoundWnd
->spwndChild
!= NULL
)
1032 FoundWnd
= DesktopPtrToUser(FoundWnd
->spwndChild
);
1036 if (Wnd
->spwndNext
!= NULL
)
1037 FoundWnd
= DesktopPtrToUser(Wnd
->spwndNext
);
1041 if (Wnd
->spwndPrev
!= NULL
)
1042 FoundWnd
= DesktopPtrToUser(Wnd
->spwndPrev
);
1046 if (Wnd
->spwndChild
!= NULL
)
1047 FoundWnd
= DesktopPtrToUser(Wnd
->spwndChild
);
1052 while ( FoundWnd
->spwndNext
!= NULL
)
1053 FoundWnd
= DesktopPtrToUser(FoundWnd
->spwndNext
);
1061 if (FoundWnd
!= NULL
)
1062 Ret
= UserHMGetHandle(FoundWnd
);
1064 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
1078 GetTopWindow(HWND hWnd
)
1080 if (!hWnd
) hWnd
= GetDesktopWindow();
1081 return GetWindow(hWnd
, GW_CHILD
);
1089 GetWindowInfo(HWND hWnd
,
1097 if ( !pwi
|| pwi
->cbSize
!= sizeof(WINDOWINFO
))
1098 SetLastError(ERROR_INVALID_PARAMETER
); // Just set the error and go!
1100 pWnd
= ValidateHwnd(hWnd
);
1104 UserGetWindowBorders(pWnd
->style
, pWnd
->ExStyle
, &Size
, FALSE
);
1108 pCls
= DesktopPtrToUser(pWnd
->pcls
);
1109 pwi
->rcWindow
= pWnd
->rcWindow
;
1110 pwi
->rcClient
= pWnd
->rcClient
;
1111 pwi
->dwStyle
= pWnd
->style
;
1112 pwi
->dwExStyle
= pWnd
->ExStyle
;
1113 pwi
->cxWindowBorders
= Size
.cx
;
1114 pwi
->cyWindowBorders
= Size
.cy
;
1115 pwi
->dwWindowStatus
= 0;
1116 if (pWnd
->state
& WNDS_ACTIVEFRAME
)
1117 pwi
->dwWindowStatus
= WS_ACTIVECAPTION
;
1118 pwi
->atomWindowType
= (pCls
? pCls
->atomClassName
: 0 );
1120 if ( pWnd
->state2
& WNDS2_WIN50COMPAT
)
1122 pwi
->wCreatorVersion
= 0x500;
1124 else if ( pWnd
->state2
& WNDS2_WIN40COMPAT
)
1126 pwi
->wCreatorVersion
= 0x400;
1128 else if ( pWnd
->state2
& WNDS2_WIN31COMPAT
)
1130 pwi
->wCreatorVersion
= 0x30A;
1134 pwi
->wCreatorVersion
= 0x300;
1139 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
1153 GetWindowModuleFileNameA(HWND hwnd
,
1155 UINT cchFileNameMax
)
1157 PWND Wnd
= ValidateHwnd(hwnd
);
1162 return GetModuleFileNameA(Wnd
->hModule
, lpszFileName
, cchFileNameMax
);
1170 GetWindowModuleFileNameW(HWND hwnd
,
1171 LPWSTR lpszFileName
,
1172 UINT cchFileNameMax
)
1174 PWND Wnd
= ValidateHwnd(hwnd
);
1179 return GetModuleFileNameW( Wnd
->hModule
, lpszFileName
, cchFileNameMax
);
1187 GetWindowRect(HWND hWnd
,
1190 PWND Wnd
= ValidateHwnd(hWnd
);
1194 *lpRect
= Wnd
->rcWindow
;
1206 GetWindowTextA(HWND hWnd
, LPSTR lpString
, int nMaxCount
)
1212 if (lpString
== NULL
)
1215 Wnd
= ValidateHwnd(hWnd
);
1221 if (!TestWindowProcess( Wnd
))
1225 /* do not send WM_GETTEXT messages to other processes */
1226 Length
= Wnd
->strName
.Length
/ sizeof(WCHAR
);
1229 Buffer
= DesktopPtrToUser(Wnd
->strName
.Buffer
);
1232 if (!WideCharToMultiByte(CP_ACP
,
1241 lpString
[nMaxCount
- 1] = '\0';
1254 Wnd
= NULL
; /* Don't send a message */
1257 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
1261 Wnd
= NULL
; /* Don't send a message */
1266 Length
= SendMessageA(hWnd
, WM_GETTEXT
, nMaxCount
, (LPARAM
)lpString
);
1276 GetWindowTextLengthA(HWND hWnd
)
1278 return(SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0));
1286 GetWindowTextLengthW(HWND hWnd
)
1288 return(SendMessageW(hWnd
, WM_GETTEXTLENGTH
, 0, 0));
1296 GetWindowTextW(HWND hWnd
, LPWSTR lpString
, int nMaxCount
)
1302 if (lpString
== NULL
)
1305 Wnd
= ValidateHwnd(hWnd
);
1311 if (!TestWindowProcess( Wnd
))
1315 /* do not send WM_GETTEXT messages to other processes */
1316 Length
= Wnd
->strName
.Length
/ sizeof(WCHAR
);
1319 Buffer
= DesktopPtrToUser(Wnd
->strName
.Buffer
);
1322 RtlCopyMemory(lpString
,
1324 (Length
+ 1) * sizeof(WCHAR
));
1336 Wnd
= NULL
; /* Don't send a message */
1339 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
1343 Wnd
= NULL
; /* Don't send a message */
1348 Length
= SendMessageW(hWnd
, WM_GETTEXT
, nMaxCount
, (LPARAM
)lpString
);
1354 GetWindowThreadProcessId(HWND hWnd
,
1355 LPDWORD lpdwProcessId
)
1359 PWND pWnd
= ValidateHwnd(hWnd
);
1361 if (!pWnd
) return Ret
;
1363 ti
= pWnd
->head
.pti
;
1367 if (ti
== GetW32ThreadInfo())
1368 { // We are current.
1369 //FIXME("Current!\n");
1371 *lpdwProcessId
= (DWORD
)NtCurrentTeb()->ClientId
.UniqueProcess
;
1372 Ret
= (DWORD
)NtCurrentTeb()->ClientId
.UniqueThread
;
1375 { // Ask kernel for info.
1376 //FIXME("Kernel call!\n");
1378 *lpdwProcessId
= NtUserQueryWindow(hWnd
, QUERY_WINDOW_UNIQUE_PROCESS_ID
);
1379 Ret
= NtUserQueryWindow(hWnd
, QUERY_WINDOW_UNIQUE_THREAD_ID
);
1390 IsChild(HWND hWndParent
,
1393 PWND WndParent
, Wnd
;
1396 WndParent
= ValidateHwnd(hWndParent
);
1399 Wnd
= ValidateHwnd(hWnd
);
1407 if (Wnd
->spwndParent
!= NULL
)
1409 Wnd
= DesktopPtrToUser(Wnd
->spwndParent
);
1410 if (Wnd
== WndParent
)
1420 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
1436 PWND Wnd
= ValidateHwnd(hWnd
);
1439 return (Wnd
->style
& WS_MINIMIZE
) != 0;
1451 PWND Wnd
= ValidateHwndNoErr(hWnd
);
1454 /* FIXME: If window is being destroyed return FALSE! */
1466 IsWindowUnicode(HWND hWnd
)
1468 PWND Wnd
= ValidateHwnd(hWnd
);
1471 return Wnd
->Unicode
;
1481 IsWindowVisible(HWND hWnd
)
1484 PWND Wnd
= ValidateHwnd(hWnd
);
1494 if (!(Wnd
->style
& WS_VISIBLE
))
1500 if (Wnd
->spwndParent
!= NULL
)
1501 Wnd
= DesktopPtrToUser(Wnd
->spwndParent
);
1505 } while (Wnd
!= NULL
);
1507 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
1522 IsWindowEnabled(HWND hWnd
)
1524 // AG: I don't know if child windows are affected if the parent is
1525 // disabled. I think they stop processing messages but stay appearing
1528 return !(GetWindowLongPtrW(hWnd
, GWL_STYLE
) & WS_DISABLED
);
1538 return (GetWindowLongPtrW(hWnd
, GWL_STYLE
) & WS_MAXIMIZE
) != 0;
1546 LockSetForegroundWindow(UINT uLockCode
)
1557 AnimateWindow(HWND hwnd
,
1561 /* FIXME Add animation code */
1563 /* If trying to show/hide and it's already *
1564 * shown/hidden or invalid window, fail with *
1565 * invalid parameter */
1568 visible
= IsWindowVisible(hwnd
);
1569 if(!IsWindow(hwnd
) ||
1570 (visible
&& !(dwFlags
& AW_HIDE
)) ||
1571 (!visible
&& (dwFlags
& AW_HIDE
)))
1573 SetLastError(ERROR_INVALID_PARAMETER
);
1577 ShowWindow(hwnd
, (dwFlags
& AW_HIDE
) ? SW_HIDE
: ((dwFlags
& AW_ACTIVATE
) ? SW_SHOW
: SW_SHOWNA
));
1589 if (!(GetWindowLongPtrW(hWnd
, GWL_STYLE
) & WS_MINIMIZE
))
1592 ShowWindow(hWnd
,SW_RESTORE
);
1601 RealChildWindowFromPoint(HWND hwndParent
,
1602 POINT ptParentClientCoords
)
1604 return ChildWindowFromPointEx(hwndParent
, ptParentClientCoords
, CWP_SKIPTRANSPARENT
);
1611 SetForegroundWindow(HWND hWnd
)
1613 return NtUserCallHwndLock(hWnd
, HWNDLOCK_ROUTINE_SETFOREGROUNDWINDOW
);
1621 SetProcessDefaultLayout(DWORD dwDefaultLayout
)
1623 if (dwDefaultLayout
== 0)
1635 SetWindowTextA(HWND hWnd
,
1639 if(!GetWindowThreadProcessId(hWnd
, &ProcessId
))
1644 if(ProcessId
!= GetCurrentProcessId())
1646 /* do not send WM_GETTEXT messages to other processes */
1648 DefSetText(hWnd
, (PCWSTR
)lpString
, TRUE
);
1650 if ((GetWindowLongPtrW(hWnd
, GWL_STYLE
) & WS_CAPTION
) == WS_CAPTION
)
1652 DefWndNCPaint(hWnd
, (HRGN
)1, -1);
1657 return SendMessageA(hWnd
, WM_SETTEXT
, 0, (LPARAM
)lpString
);
1665 SetWindowTextW(HWND hWnd
,
1669 if(!GetWindowThreadProcessId(hWnd
, &ProcessId
))
1674 if(ProcessId
!= GetCurrentProcessId())
1676 /* do not send WM_GETTEXT messages to other processes */
1678 DefSetText(hWnd
, lpString
, FALSE
);
1680 if ((GetWindowLongPtrW(hWnd
, GWL_STYLE
) & WS_CAPTION
) == WS_CAPTION
)
1682 DefWndNCPaint(hWnd
, (HRGN
)1, -1);
1687 return SendMessageW(hWnd
, WM_SETTEXT
, 0, (LPARAM
)lpString
);
1695 ShowOwnedPopups(HWND hWnd
,
1698 return (BOOL
)NtUserCallTwoParam((DWORD
)hWnd
, fShow
, TWOPARAM_ROUTINE_SHOWOWNEDPOPUPS
);
1706 UpdateLayeredWindow( HWND hwnd
,
1716 if ( dwFlags
& ULW_EX_NORESIZE
)
1717 dwFlags
= ~(ULW_EX_NORESIZE
|ULW_OPAQUE
|ULW_ALPHA
|ULW_COLORKEY
);
1718 return NtUserUpdateLayeredWindow( hwnd
,
1734 UpdateLayeredWindowIndirect(HWND hwnd
,
1735 const UPDATELAYEREDWINDOWINFO
*info
)
1737 if (info
&& info
->cbSize
== sizeof(info
))
1739 return NtUserUpdateLayeredWindow( hwnd
,
1741 (POINT
*)info
->pptDst
,
1742 (SIZE
*)info
->psize
,
1744 (POINT
*)info
->pptSrc
,
1746 (BLENDFUNCTION
*)info
->pblend
,
1748 (RECT
*)info
->prcDirty
);
1750 SetLastError(ERROR_INVALID_PARAMETER
);
1759 WindowFromPoint(POINT Point
)
1761 //TODO: Determine what the actual parameters to
1762 // NtUserWindowFromPoint are.
1763 return NtUserWindowFromPoint(Point
.x
, Point
.y
);
1771 MapWindowPoints(HWND hWndFrom
, HWND hWndTo
, LPPOINT lpPoints
, UINT cPoints
)
1773 PWND FromWnd
, ToWnd
;
1777 FromWnd
= ValidateHwndOrDesk(hWndFrom
);
1781 ToWnd
= ValidateHwndOrDesk(hWndTo
);
1785 Delta
.x
= FromWnd
->rcClient
.left
- ToWnd
->rcClient
.left
;
1786 Delta
.y
= FromWnd
->rcClient
.top
- ToWnd
->rcClient
.top
;
1788 for (i
= 0; i
!= cPoints
; i
++)
1790 lpPoints
[i
].x
+= Delta
.x
;
1791 lpPoints
[i
].y
+= Delta
.y
;
1794 return MAKELONG(LOWORD(Delta
.x
), LOWORD(Delta
.y
));
1802 ScreenToClient(HWND hWnd
, LPPOINT lpPoint
)
1804 PWND Wnd
, DesktopWnd
;
1806 Wnd
= ValidateHwnd(hWnd
);
1810 DesktopWnd
= GetThreadDesktopWnd();
1812 lpPoint
->x
+= DesktopWnd
->rcClient
.left
- Wnd
->rcClient
.left
;
1813 lpPoint
->y
+= DesktopWnd
->rcClient
.top
- Wnd
->rcClient
.top
;
1823 ClientToScreen(HWND hWnd
, LPPOINT lpPoint
)
1825 PWND Wnd
, DesktopWnd
;
1827 Wnd
= ValidateHwnd(hWnd
);
1831 DesktopWnd
= GetThreadDesktopWnd();
1833 lpPoint
->x
+= Wnd
->rcClient
.left
- DesktopWnd
->rcClient
.left
;
1834 lpPoint
->y
+= Wnd
->rcClient
.top
- DesktopWnd
->rcClient
.top
;
1844 SetWindowContextHelpId(HWND hwnd
,
1845 DWORD dwContextHelpId
)
1847 return NtUserSetWindowContextHelpId(hwnd
, dwContextHelpId
);
1855 GetWindowContextHelpId(HWND hwnd
)
1857 return NtUserCallHwnd(hwnd
, HWND_ROUTINE_GETWNDCONTEXTHLPID
);
1864 InternalGetWindowText(HWND hWnd
, LPWSTR lpString
, int nMaxCount
)
1866 INT Ret
= NtUserInternalGetWindowText(hWnd
, lpString
, nMaxCount
);
1876 IsHungAppWindow(HWND hwnd
)
1878 return (NtUserQueryWindow(hwnd
, QUERY_WINDOW_ISHUNG
) != 0);
1885 SetLastErrorEx(DWORD dwErrCode
, DWORD dwType
)
1887 SetLastError(dwErrCode
);
1896 return (HWND
)NtUserGetThreadState(THREADSTATE_FOCUSWINDOW
);
1900 GetRealWindowOwner(HWND hwnd
)
1902 return NtUserQueryWindow(hwnd
, QUERY_WINDOW_REAL_ID
);
1909 SetTaskmanWindow(HWND hWnd
)
1911 return NtUserCallHwndOpt(hWnd
, HWNDOPT_ROUTINE_SETTASKMANWINDOW
);
1918 SetProgmanWindow(HWND hWnd
)
1920 return NtUserCallHwndOpt(hWnd
, HWNDOPT_ROUTINE_SETPROGMANWINDOW
);
1927 GetProgmanWindow(VOID
)
1929 return (HWND
)NtUserGetThreadState(THREADSTATE_PROGMANWINDOW
);
1936 GetTaskmanWindow(VOID
)
1938 return (HWND
)NtUserGetThreadState(THREADSTATE_TASKMANWINDOW
);
1945 ScrollWindow(HWND hWnd
,
1949 CONST RECT
*prcClip
)
1951 return NtUserScrollWindowEx(hWnd
,
1958 (lpRect
? 0 : SW_SCROLLCHILDREN
) | SW_INVALIDATE
) != ERROR
;
1966 ScrollWindowEx(HWND hWnd
,
1969 CONST RECT
*prcScroll
,
1970 CONST RECT
*prcClip
,
1975 return NtUserScrollWindowEx(hWnd
,
1990 TileChildWindows(HWND hWndParent
, WORD wFlags
)
1992 return TileWindows(hWndParent
, wFlags
, NULL
, 0, NULL
);
2001 return NtUserAnyPopup();
2008 IsWindowInDestroy(HWND hWnd
)
2010 return NtUserIsWindowInDestroy(hWnd
);
2017 DisableProcessWindowsGhosting(VOID
)
2019 NtUserEnableProcessWindowGhosting(FALSE
);