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 (IS_ATOM(lpClassName
))
179 RtlInitUnicodeString(&ClassName
, NULL
);
180 ClassName
.Buffer
= (LPWSTR
)lpClassName
;
185 RtlInitUnicodeString(&ClassName
, (PCWSTR
)lpClassName
);
188 if (!RtlCreateUnicodeStringFromAsciiz(&(ClassName
), (PCSZ
)lpClassName
))
190 SetLastError(ERROR_OUTOFMEMORY
);
197 RtlInitUnicodeString(&WindowName
, (PCWSTR
)lpWindowName
);
200 if (!RtlCreateUnicodeStringFromAsciiz(&WindowName
, (PCSZ
)lpWindowName
))
202 if (!IS_ATOM(lpClassName
))
204 RtlFreeUnicodeString(&ClassName
);
206 SetLastError(ERROR_OUTOFMEMORY
);
211 if(!hMenu
&& (dwStyle
& (WS_OVERLAPPEDWINDOW
| WS_POPUP
)))
215 wceW
.cbSize
= sizeof(WNDCLASSEXW
);
216 if(GetClassInfoExW(hInstance
, (LPCWSTR
)lpClassName
, &wceW
) && wceW
.lpszMenuName
)
218 hMenu
= LoadMenuW(hInstance
, wceW
.lpszMenuName
);
223 wceA
.cbSize
= sizeof(WNDCLASSEXA
);
224 if(GetClassInfoExA(hInstance
, lpClassName
, &wceA
) && wceA
.lpszMenuName
)
226 hMenu
= LoadMenuA(hInstance
, wceA
.lpszMenuName
);
231 Handle
= NtUserCreateWindowEx(dwExStyle
,
248 DbgPrint("[window] NtUserCreateWindowEx() == %d\n", Handle
);
253 RtlFreeUnicodeString(&WindowName
);
255 if (!IS_ATOM(lpClassName
))
257 RtlFreeUnicodeString(&ClassName
);
268 CreateWindowExA(DWORD dwExStyle
,
281 MDICREATESTRUCTA mdi
;
284 if (dwExStyle
& WS_EX_MDICHILD
)
290 /* lpParams of WM_[NC]CREATE is different for MDI children.
291 * MDICREATESTRUCT members have the originally passed values.
293 mdi
.szClass
= lpClassName
;
294 mdi
.szTitle
= lpWindowName
;
295 mdi
.hOwner
= hInstance
;
301 mdi
.lParam
= (LPARAM
)lpParam
;
303 lpParam
= (LPVOID
)&mdi
;
305 if (GetWindowLongPtrW(hWndParent
, GWL_STYLE
) & MDIS_ALLCHILDSTYLES
)
307 if (dwStyle
& WS_POPUP
)
309 WARN("WS_POPUP with MDIS_ALLCHILDSTYLES is not allowed\n");
312 dwStyle
|= (WS_CHILD
| WS_CLIPSIBLINGS
);
316 dwStyle
&= ~WS_POPUP
;
317 dwStyle
|= (WS_CHILD
| WS_VISIBLE
| WS_CLIPSIBLINGS
| WS_CAPTION
|
318 WS_SYSMENU
| WS_THICKFRAME
| WS_MINIMIZEBOX
| WS_MAXIMIZEBOX
);
321 top_child
= GetWindow(hWndParent
, GW_CHILD
);
325 /* Restore current maximized child */
326 if((dwStyle
& WS_VISIBLE
) && IsZoomed(top_child
))
328 TRACE("Restoring current maximized child %p\n", top_child
);
329 SendMessageW( top_child
, WM_SETREDRAW
, FALSE
, 0 );
330 ShowWindow(top_child
, SW_RESTORE
);
331 SendMessageW( top_child
, WM_SETREDRAW
, TRUE
, 0 );
335 MDI_CalcDefaultChildPos(hWndParent
, -1, mPos
, 0, &id
);
337 if (!(dwStyle
& WS_POPUP
)) hMenu
= (HMENU
)id
;
339 if (dwStyle
& (WS_CHILD
| WS_POPUP
))
341 if (x
== CW_USEDEFAULT
|| x
== CW_USEDEFAULT16
)
346 if (nWidth
== CW_USEDEFAULT
|| nWidth
== CW_USEDEFAULT16
|| !nWidth
)
348 if (nHeight
== CW_USEDEFAULT
|| nHeight
== CW_USEDEFAULT16
|| !nHeight
)
353 hwnd
= User32CreateWindowEx(dwExStyle
,
374 CreateWindowExW(DWORD dwExStyle
,
376 LPCWSTR lpWindowName
,
387 MDICREATESTRUCTW mdi
;
390 if (dwExStyle
& WS_EX_MDICHILD
)
396 /* lpParams of WM_[NC]CREATE is different for MDI children.
397 * MDICREATESTRUCT members have the originally passed values.
399 mdi
.szClass
= lpClassName
;
400 mdi
.szTitle
= lpWindowName
;
401 mdi
.hOwner
= hInstance
;
407 mdi
.lParam
= (LPARAM
)lpParam
;
409 lpParam
= (LPVOID
)&mdi
;
411 if (GetWindowLongPtrW(hWndParent
, GWL_STYLE
) & MDIS_ALLCHILDSTYLES
)
413 if (dwStyle
& WS_POPUP
)
415 WARN("WS_POPUP with MDIS_ALLCHILDSTYLES is not allowed\n");
418 dwStyle
|= (WS_CHILD
| WS_CLIPSIBLINGS
);
422 dwStyle
&= ~WS_POPUP
;
423 dwStyle
|= (WS_CHILD
| WS_VISIBLE
| WS_CLIPSIBLINGS
| WS_CAPTION
|
424 WS_SYSMENU
| WS_THICKFRAME
| WS_MINIMIZEBOX
| WS_MAXIMIZEBOX
);
427 top_child
= GetWindow(hWndParent
, GW_CHILD
);
431 /* Restore current maximized child */
432 if((dwStyle
& WS_VISIBLE
) && IsZoomed(top_child
))
434 TRACE("Restoring current maximized child %p\n", top_child
);
435 SendMessageW( top_child
, WM_SETREDRAW
, FALSE
, 0 );
436 ShowWindow(top_child
, SW_RESTORE
);
437 SendMessageW( top_child
, WM_SETREDRAW
, TRUE
, 0 );
441 MDI_CalcDefaultChildPos(hWndParent
, -1, mPos
, 0, &id
);
443 if (!(dwStyle
& WS_POPUP
)) hMenu
= (HMENU
)id
;
445 if (dwStyle
& (WS_CHILD
| WS_POPUP
))
447 if (x
== CW_USEDEFAULT
|| x
== CW_USEDEFAULT16
)
452 if (nWidth
== CW_USEDEFAULT
|| nWidth
== CW_USEDEFAULT16
|| !nWidth
)
454 if (nHeight
== CW_USEDEFAULT
|| nHeight
== CW_USEDEFAULT16
|| !nHeight
)
459 hwnd
= User32CreateWindowEx(dwExStyle
,
460 (LPCSTR
) lpClassName
,
461 (LPCSTR
) lpWindowName
,
479 DeferWindowPos(HDWP hWinPosInfo
,
481 HWND hWndInsertAfter
,
489 return NtUserDeferWindowPos(hWinPosInfo
, hWnd
, hWndInsertAfter
, x
, y
, cx
, cy
, uFlags
);
491 SetWindowPos(hWnd
, hWndInsertAfter
, x
, y
, cx
, cy
, uFlags
);
501 EndDeferWindowPos(HDWP hWinPosInfo
)
516 GetDesktopWindow(VOID
)
523 Wnd
= GetThreadDesktopWnd();
525 Ret
= UserHMGetHandle(Wnd
);
527 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
538 User32EnumWindows(HDESK hDesktop
,
545 DWORD i
, dwCount
= 0;
552 SetLastError ( ERROR_INVALID_PARAMETER
);
556 /* FIXME instead of always making two calls, should we use some
557 sort of persistent buffer and only grow it ( requiring a 2nd
558 call ) when the buffer wasn't already big enough? */
559 /* first get how many window entries there are */
560 Status
= NtUserBuildHwndList(hDesktop
,
567 if (!NT_SUCCESS(Status
))
570 /* allocate buffer to receive HWND handles */
571 hHeap
= GetProcessHeap();
572 pHwnd
= HeapAlloc(hHeap
, 0, sizeof(HWND
)*(dwCount
+1));
575 SetLastError ( ERROR_NOT_ENOUGH_MEMORY
);
579 /* now call kernel again to fill the buffer this time */
580 Status
= NtUserBuildHwndList(hDesktop
,
587 if (!NT_SUCCESS(Status
))
590 HeapFree(hHeap
, 0, pHwnd
);
594 /* call the user's callback function until we're done or
595 they tell us to quit */
596 for ( i
= 0; i
< dwCount
; i
++ )
598 /* FIXME I'm only getting NULLs from Thread Enumeration, and it's
599 * probably because I'm not doing it right in NtUserBuildHwndList.
600 * Once that's fixed, we shouldn't have to check for a NULL HWND
603 if (!(ULONG
)pHwnd
[i
]) /* don't enumerate a NULL HWND */
605 if (!(*lpfn
)(pHwnd
[i
], lParam
))
607 HeapFree ( hHeap
, 0, pHwnd
);
612 HeapFree(hHeap
, 0, pHwnd
);
621 EnumChildWindows(HWND hWndParent
,
622 WNDENUMPROC lpEnumFunc
,
627 return EnumWindows(lpEnumFunc
, lParam
);
629 return User32EnumWindows(NULL
, hWndParent
, lpEnumFunc
, lParam
, 0, TRUE
);
637 EnumThreadWindows(DWORD dwThreadId
,
642 dwThreadId
= GetCurrentThreadId();
643 return User32EnumWindows(NULL
, NULL
, lpfn
, lParam
, dwThreadId
, FALSE
);
651 EnumWindows(WNDENUMPROC lpEnumFunc
,
654 return User32EnumWindows(NULL
, NULL
, lpEnumFunc
, lParam
, 0, FALSE
);
662 EnumDesktopWindows(HDESK hDesktop
,
666 return User32EnumWindows(hDesktop
, NULL
, lpfn
, lParam
, 0, FALSE
);
674 FindWindowExA(HWND hwndParent
,
679 UNICODE_STRING ucClassName
, *pucClassName
= NULL
;
680 UNICODE_STRING ucWindowName
, *pucWindowName
= NULL
;
683 if (IS_ATOM(lpszClass
))
685 ucClassName
.Buffer
= (LPWSTR
)lpszClass
;
686 ucClassName
.Length
= 0;
687 pucClassName
= &ucClassName
;
689 else if (lpszClass
!= NULL
)
691 if (!RtlCreateUnicodeStringFromAsciiz(&ucClassName
,
694 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
697 pucClassName
= &ucClassName
;
700 if (lpszWindow
!= NULL
)
702 if (!RtlCreateUnicodeStringFromAsciiz(&ucWindowName
,
705 if (!IS_ATOM(lpszClass
) && lpszClass
!= NULL
)
706 RtlFreeUnicodeString(&ucWindowName
);
708 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
712 pucWindowName
= &ucWindowName
;
715 Result
= NtUserFindWindowEx(hwndParent
,
721 if (!IS_ATOM(lpszClass
) && lpszClass
!= NULL
)
722 RtlFreeUnicodeString(&ucClassName
);
723 if (lpszWindow
!= NULL
)
724 RtlFreeUnicodeString(&ucWindowName
);
734 FindWindowExW(HWND hwndParent
,
739 UNICODE_STRING ucClassName
, *pucClassName
= NULL
;
740 UNICODE_STRING ucWindowName
, *pucWindowName
= NULL
;
742 if (IS_ATOM(lpszClass
))
744 ucClassName
.Length
= 0;
745 ucClassName
.Buffer
= (LPWSTR
)lpszClass
;
746 pucClassName
= &ucClassName
;
748 else if (lpszClass
!= NULL
)
750 RtlInitUnicodeString(&ucClassName
,
752 pucClassName
= &ucClassName
;
755 if (lpszWindow
!= NULL
)
757 RtlInitUnicodeString(&ucWindowName
,
759 pucWindowName
= &ucWindowName
;
762 return NtUserFindWindowEx(hwndParent
,
774 FindWindowA(LPCSTR lpClassName
, LPCSTR lpWindowName
)
776 //FIXME: FindWindow does not search children, but FindWindowEx does.
777 // what should we do about this?
778 return FindWindowExA (NULL
, NULL
, lpClassName
, lpWindowName
);
786 FindWindowW(LPCWSTR lpClassName
, LPCWSTR lpWindowName
)
790 There was a FIXME here earlier, but I think it is just a documentation unclarity.
792 FindWindow only searches top level windows. What they mean is that child
793 windows of other windows than the desktop can be searched.
794 FindWindowExW never does a recursive search.
799 return FindWindowExW(NULL
, NULL
, lpClassName
, lpWindowName
);
808 GetAltTabInfoA(HWND hwnd
,
823 GetAltTabInfoW(HWND hwnd
,
838 GetAncestor(HWND hwnd
, UINT gaFlags
)
843 Wnd
= ValidateHwnd(hwnd
);
853 if (Wnd
->spwndParent
!= NULL
)
854 Ancestor
= DesktopPtrToUser(Wnd
->spwndParent
);
858 /* FIXME: Call win32k for now */
863 if (Ancestor
!= NULL
)
864 Ret
= UserHMGetHandle(Ancestor
);
866 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
872 if (!Wnd
) /* Fall back */
873 Ret
= NtUserGetAncestor(hwnd
, gaFlags
);
883 GetClientRect(HWND hWnd
, LPRECT lpRect
)
885 PWND Wnd
= ValidateHwnd(hWnd
);
889 lpRect
->left
= lpRect
->top
= 0;
890 lpRect
->right
= Wnd
->rcClient
.right
- Wnd
->rcClient
.left
;
891 lpRect
->bottom
= Wnd
->rcClient
.bottom
- Wnd
->rcClient
.top
;
903 GetLastActivePopup(HWND hWnd
)
908 Wnd
= ValidateHwnd(hWnd
);
913 if (Wnd
->hWndLastActive
)
914 Ret
= Wnd
->hWndLastActive
;
916 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
935 Wnd
= ValidateHwnd(hWnd
);
941 if (Wnd
->style
& WS_CHILD
)
943 if (Wnd
->spwndParent
!= NULL
)
944 WndParent
= DesktopPtrToUser(Wnd
->spwndParent
);
946 else if (Wnd
->style
& WS_POPUP
)
948 if (Wnd
->spwndOwner
!= NULL
)
949 WndParent
= DesktopPtrToUser(Wnd
->spwndOwner
);
952 if (WndParent
!= NULL
)
953 Ret
= UserHMGetHandle(WndParent
);
955 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
970 GetProcessDefaultLayout(DWORD
*pdwDefaultLayout
)
972 if (!pdwDefaultLayout
)
974 SetLastError(ERROR_INVALID_PARAMETER
);
980 *pdwDefaultLayout
= 0;
995 Wnd
= ValidateHwnd(hWnd
);
1005 if (Wnd
->spwndOwner
!= NULL
)
1006 FoundWnd
= DesktopPtrToUser(Wnd
->spwndOwner
);
1010 /* FIXME: Optimize! Fall back to NtUserGetWindow for now... */
1015 if (FoundWnd
!= NULL
)
1016 Ret
= UserHMGetHandle(FoundWnd
);
1018 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
1024 if (!Wnd
) /* Fall back to win32k... */
1025 Ret
= NtUserGetWindow(hWnd
, uCmd
);
1035 GetTopWindow(HWND hWnd
)
1037 if (!hWnd
) hWnd
= GetDesktopWindow();
1038 return GetWindow(hWnd
, GW_CHILD
);
1046 GetWindowInfo(HWND hWnd
,
1054 if ( !pwi
|| pwi
->cbSize
!= sizeof(WINDOWINFO
))
1055 SetLastError(ERROR_INVALID_PARAMETER
); // Just set the error and go!
1057 pWnd
= ValidateHwnd(hWnd
);
1061 UserGetWindowBorders(pWnd
->style
, pWnd
->ExStyle
, &Size
, FALSE
);
1065 pCls
= DesktopPtrToUser(pWnd
->pcls
);
1066 pwi
->rcWindow
= pWnd
->rcWindow
;
1067 pwi
->rcClient
= pWnd
->rcClient
;
1068 pwi
->dwStyle
= pWnd
->style
;
1069 pwi
->dwExStyle
= pWnd
->ExStyle
;
1070 pwi
->cxWindowBorders
= Size
.cx
;
1071 pwi
->cyWindowBorders
= Size
.cy
;
1072 pwi
->dwWindowStatus
= 0;
1073 if (pWnd
->state
& WNDS_ACTIVEFRAME
)
1074 pwi
->dwWindowStatus
= WS_ACTIVECAPTION
;
1075 pwi
->atomWindowType
= (pCls
? pCls
->atomClassName
: 0 );
1077 if ( pWnd
->state2
& WNDS2_WIN50COMPAT
)
1079 pwi
->wCreatorVersion
= 0x500;
1081 else if ( pWnd
->state2
& WNDS2_WIN40COMPAT
)
1083 pwi
->wCreatorVersion
= 0x400;
1085 else if ( pWnd
->state2
& WNDS2_WIN31COMPAT
)
1087 pwi
->wCreatorVersion
= 0x30A;
1091 pwi
->wCreatorVersion
= 0x300;
1096 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
1110 GetWindowModuleFileNameA(HWND hwnd
,
1112 UINT cchFileNameMax
)
1116 if(!(hWndInst
= NtUserGetWindowInstance(hwnd
)))
1121 return GetModuleFileNameA(hWndInst
, lpszFileName
, cchFileNameMax
);
1129 GetWindowModuleFileNameW(HWND hwnd
,
1130 LPWSTR lpszFileName
,
1131 UINT cchFileNameMax
)
1135 if(!(hWndInst
= NtUserGetWindowInstance(hwnd
)))
1140 return GetModuleFileNameW(hWndInst
, lpszFileName
, cchFileNameMax
);
1148 GetWindowRect(HWND hWnd
,
1151 PWND Wnd
= ValidateHwnd(hWnd
);
1155 *lpRect
= Wnd
->rcWindow
;
1167 GetWindowTextA(HWND hWnd
, LPSTR lpString
, int nMaxCount
)
1173 if (lpString
== NULL
)
1176 Wnd
= ValidateHwnd(hWnd
);
1182 if (!TestWindowProcess( Wnd
))
1186 /* do not send WM_GETTEXT messages to other processes */
1187 Length
= Wnd
->strName
.Length
/ sizeof(WCHAR
);
1190 Buffer
= DesktopPtrToUser(Wnd
->strName
.Buffer
);
1193 if (!WideCharToMultiByte(CP_ACP
,
1202 lpString
[nMaxCount
- 1] = '\0';
1215 Wnd
= NULL
; /* Don't send a message */
1218 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
1222 Wnd
= NULL
; /* Don't send a message */
1227 Length
= SendMessageA(hWnd
, WM_GETTEXT
, nMaxCount
, (LPARAM
)lpString
);
1237 GetWindowTextLengthA(HWND hWnd
)
1239 return(SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0));
1247 GetWindowTextLengthW(HWND hWnd
)
1249 return(SendMessageW(hWnd
, WM_GETTEXTLENGTH
, 0, 0));
1257 GetWindowTextW(HWND hWnd
, LPWSTR lpString
, int nMaxCount
)
1263 if (lpString
== NULL
)
1266 Wnd
= ValidateHwnd(hWnd
);
1272 if (!TestWindowProcess( Wnd
))
1276 /* do not send WM_GETTEXT messages to other processes */
1277 Length
= Wnd
->strName
.Length
/ sizeof(WCHAR
);
1280 Buffer
= DesktopPtrToUser(Wnd
->strName
.Buffer
);
1283 RtlCopyMemory(lpString
,
1285 (Length
+ 1) * sizeof(WCHAR
));
1297 Wnd
= NULL
; /* Don't send a message */
1300 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
1304 Wnd
= NULL
; /* Don't send a message */
1309 Length
= SendMessageW(hWnd
, WM_GETTEXT
, nMaxCount
, (LPARAM
)lpString
);
1315 GetWindowThreadProcessId(HWND hWnd
,
1316 LPDWORD lpdwProcessId
)
1320 PWND pWnd
= ValidateHwnd(hWnd
);
1322 if (!pWnd
) return Ret
;
1324 ti
= pWnd
->head
.pti
;
1328 if (ti
== GetW32ThreadInfo())
1329 { // We are current.
1330 //FIXME("Current!\n");
1332 *lpdwProcessId
= (DWORD
)NtCurrentTeb()->ClientId
.UniqueProcess
;
1333 Ret
= (DWORD
)NtCurrentTeb()->ClientId
.UniqueThread
;
1336 { // Ask kernel for info.
1337 //FIXME("Kernel call!\n");
1339 *lpdwProcessId
= NtUserQueryWindow(hWnd
, QUERY_WINDOW_UNIQUE_PROCESS_ID
);
1340 Ret
= NtUserQueryWindow(hWnd
, QUERY_WINDOW_UNIQUE_THREAD_ID
);
1351 IsChild(HWND hWndParent
,
1354 PWND WndParent
, Wnd
;
1357 WndParent
= ValidateHwnd(hWndParent
);
1360 Wnd
= ValidateHwnd(hWnd
);
1368 if (Wnd
->spwndParent
!= NULL
)
1370 Wnd
= DesktopPtrToUser(Wnd
->spwndParent
);
1371 if (Wnd
== WndParent
)
1381 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
1397 PWND Wnd
= ValidateHwnd(hWnd
);
1400 return (Wnd
->style
& WS_MINIMIZE
) != 0;
1412 PWND Wnd
= ValidateHwndNoErr(hWnd
);
1415 /* FIXME: If window is being destroyed return FALSE! */
1427 IsWindowUnicode(HWND hWnd
)
1429 PWND Wnd
= ValidateHwnd(hWnd
);
1432 return Wnd
->Unicode
;
1442 IsWindowVisible(HWND hWnd
)
1445 PWND Wnd
= ValidateHwnd(hWnd
);
1455 if (!(Wnd
->style
& WS_VISIBLE
))
1461 if (Wnd
->spwndParent
!= NULL
)
1462 Wnd
= DesktopPtrToUser(Wnd
->spwndParent
);
1466 } while (Wnd
!= NULL
);
1468 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
1483 IsWindowEnabled(HWND hWnd
)
1485 // AG: I don't know if child windows are affected if the parent is
1486 // disabled. I think they stop processing messages but stay appearing
1489 return !(GetWindowLongPtrW(hWnd
, GWL_STYLE
) & WS_DISABLED
);
1499 return (GetWindowLongPtrW(hWnd
, GWL_STYLE
) & WS_MAXIMIZE
) != 0;
1507 LockSetForegroundWindow(UINT uLockCode
)
1518 AnimateWindow(HWND hwnd
,
1522 /* FIXME Add animation code */
1524 /* If trying to show/hide and it's already *
1525 * shown/hidden or invalid window, fail with *
1526 * invalid parameter */
1529 visible
= IsWindowVisible(hwnd
);
1530 if(!IsWindow(hwnd
) ||
1531 (visible
&& !(dwFlags
& AW_HIDE
)) ||
1532 (!visible
&& (dwFlags
& AW_HIDE
)))
1534 SetLastError(ERROR_INVALID_PARAMETER
);
1538 ShowWindow(hwnd
, (dwFlags
& AW_HIDE
) ? SW_HIDE
: ((dwFlags
& AW_ACTIVATE
) ? SW_SHOW
: SW_SHOWNA
));
1550 if (!(GetWindowLongPtrW(hWnd
, GWL_STYLE
) & WS_MINIMIZE
))
1553 ShowWindow(hWnd
,SW_RESTORE
);
1562 RealChildWindowFromPoint(HWND hwndParent
,
1563 POINT ptParentClientCoords
)
1565 return ChildWindowFromPointEx(hwndParent
, ptParentClientCoords
, CWP_SKIPTRANSPARENT
);
1572 SetForegroundWindow(HWND hWnd
)
1574 return NtUserCallHwndLock(hWnd
, HWNDLOCK_ROUTINE_SETFOREGROUNDWINDOW
);
1582 SetProcessDefaultLayout(DWORD dwDefaultLayout
)
1584 if (dwDefaultLayout
== 0)
1596 SetWindowTextA(HWND hWnd
,
1600 if(!GetWindowThreadProcessId(hWnd
, &ProcessId
))
1605 if(ProcessId
!= GetCurrentProcessId())
1607 /* do not send WM_GETTEXT messages to other processes */
1609 DefSetText(hWnd
, (PCWSTR
)lpString
, TRUE
);
1611 if ((GetWindowLongPtrW(hWnd
, GWL_STYLE
) & WS_CAPTION
) == WS_CAPTION
)
1613 DefWndNCPaint(hWnd
, (HRGN
)1, -1);
1618 return SendMessageA(hWnd
, WM_SETTEXT
, 0, (LPARAM
)lpString
);
1626 SetWindowTextW(HWND hWnd
,
1630 if(!GetWindowThreadProcessId(hWnd
, &ProcessId
))
1635 if(ProcessId
!= GetCurrentProcessId())
1637 /* do not send WM_GETTEXT messages to other processes */
1639 DefSetText(hWnd
, lpString
, FALSE
);
1641 if ((GetWindowLongPtrW(hWnd
, GWL_STYLE
) & WS_CAPTION
) == WS_CAPTION
)
1643 DefWndNCPaint(hWnd
, (HRGN
)1, -1);
1648 return SendMessageW(hWnd
, WM_SETTEXT
, 0, (LPARAM
)lpString
);
1656 ShowOwnedPopups(HWND hWnd
,
1659 return (BOOL
)NtUserCallTwoParam((DWORD_PTR
)hWnd
, fShow
, TWOPARAM_ROUTINE_SHOWOWNEDPOPUPS
);
1667 UpdateLayeredWindow( HWND hwnd
,
1677 if ( dwFlags
& ULW_EX_NORESIZE
)
1678 dwFlags
= ~(ULW_EX_NORESIZE
|ULW_OPAQUE
|ULW_ALPHA
|ULW_COLORKEY
);
1679 return NtUserUpdateLayeredWindow( hwnd
,
1695 UpdateLayeredWindowIndirect(HWND hwnd
,
1696 const UPDATELAYEREDWINDOWINFO
*info
)
1698 if (info
&& info
->cbSize
== sizeof(info
))
1700 return NtUserUpdateLayeredWindow( hwnd
,
1702 (POINT
*)info
->pptDst
,
1703 (SIZE
*)info
->psize
,
1705 (POINT
*)info
->pptSrc
,
1707 (BLENDFUNCTION
*)info
->pblend
,
1709 (RECT
*)info
->prcDirty
);
1711 SetLastError(ERROR_INVALID_PARAMETER
);
1720 WindowFromPoint(POINT Point
)
1722 //TODO: Determine what the actual parameters to
1723 // NtUserWindowFromPoint are.
1724 return NtUserWindowFromPoint(Point
.x
, Point
.y
);
1732 MapWindowPoints(HWND hWndFrom
, HWND hWndTo
, LPPOINT lpPoints
, UINT cPoints
)
1734 PWND FromWnd
, ToWnd
;
1738 FromWnd
= ValidateHwndOrDesk(hWndFrom
);
1742 ToWnd
= ValidateHwndOrDesk(hWndTo
);
1746 Delta
.x
= FromWnd
->rcClient
.left
- ToWnd
->rcClient
.left
;
1747 Delta
.y
= FromWnd
->rcClient
.top
- ToWnd
->rcClient
.top
;
1749 for (i
= 0; i
!= cPoints
; i
++)
1751 lpPoints
[i
].x
+= Delta
.x
;
1752 lpPoints
[i
].y
+= Delta
.y
;
1755 return MAKELONG(LOWORD(Delta
.x
), LOWORD(Delta
.y
));
1763 ScreenToClient(HWND hWnd
, LPPOINT lpPoint
)
1765 PWND Wnd
, DesktopWnd
;
1767 Wnd
= ValidateHwnd(hWnd
);
1771 DesktopWnd
= GetThreadDesktopWnd();
1773 lpPoint
->x
+= DesktopWnd
->rcClient
.left
- Wnd
->rcClient
.left
;
1774 lpPoint
->y
+= DesktopWnd
->rcClient
.top
- Wnd
->rcClient
.top
;
1784 ClientToScreen(HWND hWnd
, LPPOINT lpPoint
)
1786 PWND Wnd
, DesktopWnd
;
1788 Wnd
= ValidateHwnd(hWnd
);
1792 DesktopWnd
= GetThreadDesktopWnd();
1794 lpPoint
->x
+= Wnd
->rcClient
.left
- DesktopWnd
->rcClient
.left
;
1795 lpPoint
->y
+= Wnd
->rcClient
.top
- DesktopWnd
->rcClient
.top
;
1805 SetWindowContextHelpId(HWND hwnd
,
1806 DWORD dwContextHelpId
)
1808 return NtUserSetWindowContextHelpId(hwnd
, dwContextHelpId
);
1816 GetWindowContextHelpId(HWND hwnd
)
1818 return NtUserCallHwnd(hwnd
, HWND_ROUTINE_GETWNDCONTEXTHLPID
);
1825 InternalGetWindowText(HWND hWnd
, LPWSTR lpString
, int nMaxCount
)
1827 INT Ret
= NtUserInternalGetWindowText(hWnd
, lpString
, nMaxCount
);
1837 IsHungAppWindow(HWND hwnd
)
1839 return (NtUserQueryWindow(hwnd
, QUERY_WINDOW_ISHUNG
) != 0);
1846 SetLastErrorEx(DWORD dwErrCode
, DWORD dwType
)
1848 SetLastError(dwErrCode
);
1857 return (HWND
)NtUserGetThreadState(THREADSTATE_FOCUSWINDOW
);
1864 SetTaskmanWindow(HWND hWnd
)
1866 return NtUserCallHwndOpt(hWnd
, HWNDOPT_ROUTINE_SETTASKMANWINDOW
);
1873 SetProgmanWindow(HWND hWnd
)
1875 return NtUserCallHwndOpt(hWnd
, HWNDOPT_ROUTINE_SETPROGMANWINDOW
);
1882 GetProgmanWindow(VOID
)
1884 return (HWND
)NtUserGetThreadState(THREADSTATE_PROGMANWINDOW
);
1891 GetTaskmanWindow(VOID
)
1893 return (HWND
)NtUserGetThreadState(THREADSTATE_TASKMANWINDOW
);
1900 ScrollWindow(HWND hWnd
,
1904 CONST RECT
*prcClip
)
1906 return NtUserScrollWindowEx(hWnd
,
1913 (lpRect
? 0 : SW_SCROLLCHILDREN
) | SW_INVALIDATE
) != ERROR
;
1921 ScrollWindowEx(HWND hWnd
,
1924 CONST RECT
*prcScroll
,
1925 CONST RECT
*prcClip
,
1930 return NtUserScrollWindowEx(hWnd
,
1945 TileChildWindows(HWND hWndParent
, WORD wFlags
)
1947 return TileWindows(hWndParent
, wFlags
, NULL
, 0, NULL
);
1956 return NtUserAnyPopup();
1963 IsWindowInDestroy(HWND hWnd
)
1965 return NtUserIsWindowInDestroy(hWnd
);
1972 DisableProcessWindowsGhosting(VOID
)
1974 NtUserEnableProcessWindowGhosting(FALSE
);