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");
33 CallbackArgs
= (PSENDASYNCPROC_CALLBACK_ARGUMENTS
)Arguments
;
35 if (ArgumentLength
!= sizeof(SENDASYNCPROC_CALLBACK_ARGUMENTS
))
37 return(STATUS_INFO_LENGTH_MISMATCH
);
40 CallbackArgs
->Callback(CallbackArgs
->Wnd
,
42 CallbackArgs
->Context
,
43 CallbackArgs
->Result
);
44 return(STATUS_SUCCESS
);
52 AllowSetForegroundWindow(DWORD dwProcessId
)
54 static BOOL show_message
= TRUE
;
68 BeginDeferWindowPos(int nNumWindows
)
72 SetLastError(ERROR_INVALID_PARAMETER
);
88 BringWindowToTop(HWND hWnd
)
90 return NtUserSetWindowPos(hWnd
,
96 SWP_NOSIZE
| SWP_NOMOVE
);
101 SwitchToThisWindow(HWND hwnd
, BOOL fUnknown
)
103 ShowWindow(hwnd
, SW_SHOW
);
111 ChildWindowFromPoint(HWND hWndParent
,
114 return (HWND
) NtUserChildWindowFromPointEx(hWndParent
, Point
.x
, Point
.y
, 0);
122 ChildWindowFromPointEx(HWND hwndParent
,
126 return (HWND
) NtUserChildWindowFromPointEx(hwndParent
, pt
.x
, pt
.y
, uFlags
);
134 CloseWindow(HWND hWnd
)
136 SendMessageA(hWnd
, WM_SYSCOMMAND
, SC_CLOSE
, 0);
144 OUT PLARGE_STRING plstr
,
150 RtlInitLargeUnicodeString((PLARGE_UNICODE_STRING
)plstr
, (PWSTR
)psz
, 0);
154 RtlInitLargeAnsiString((PLARGE_ANSI_STRING
)plstr
, (PSTR
)psz
, 0);
161 IN PLARGE_STRING LargeString
)
163 if (LargeString
->Buffer
)
165 RtlFreeHeap(GetProcessHeap(), 0, LargeString
->Buffer
);
166 RtlZeroMemory(LargeString
, sizeof(LARGE_STRING
));
171 User32CreateWindowEx(DWORD dwExStyle
,
185 LARGE_STRING WindowName
;
186 LARGE_STRING lstrClassName
, *plstrClassName
;
187 UNICODE_STRING ClassName
;
193 DbgPrint("[window] User32CreateWindowEx style %d, exstyle %d, parent %d\n", dwStyle
, dwExStyle
, hWndParent
);
196 if (!RegisterDefaultClasses
)
198 ERR("User32CreateWindowEx RegisterSystemControls\n");
199 RegisterSystemControls();
202 if (IS_ATOM(lpClassName
))
204 plstrClassName
= (PVOID
)lpClassName
;
209 RtlInitUnicodeString(&ClassName
, (PCWSTR
)lpClassName
);
212 if (!RtlCreateUnicodeStringFromAsciiz(&ClassName
, (PCSZ
)lpClassName
))
214 SetLastError(ERROR_OUTOFMEMORY
);
219 /* Copy it to a LARGE_STRING */
220 lstrClassName
.Buffer
= ClassName
.Buffer
;
221 lstrClassName
.Length
= ClassName
.Length
;
222 lstrClassName
.MaximumLength
= ClassName
.MaximumLength
;
223 plstrClassName
= &lstrClassName
;
226 /* Initialize a LARGE_STRING */
227 RtlInitLargeString(&WindowName
, lpWindowName
, Unicode
);
229 // HACK: The current implementation expects the Window name to be UNICODE
233 PSTR AnsiBuffer
= WindowName
.Buffer
;
234 ULONG AnsiLength
= WindowName
.Length
;
236 WindowName
.Length
= 0;
237 WindowName
.MaximumLength
= AnsiLength
* sizeof(WCHAR
);
238 WindowName
.Buffer
= RtlAllocateHeap(RtlGetProcessHeap(),
240 WindowName
.MaximumLength
);
241 if (!WindowName
.Buffer
)
243 SetLastError(ERROR_OUTOFMEMORY
);
247 Status
= RtlMultiByteToUnicodeN(WindowName
.Buffer
,
248 WindowName
.MaximumLength
,
252 if (!NT_SUCCESS(Status
))
258 if(!hMenu
&& (dwStyle
& (WS_OVERLAPPEDWINDOW
| WS_POPUP
)))
262 wceW
.cbSize
= sizeof(WNDCLASSEXW
);
263 if(GetClassInfoExW(hInstance
, (LPCWSTR
)lpClassName
, &wceW
) && wceW
.lpszMenuName
)
265 hMenu
= LoadMenuW(hInstance
, wceW
.lpszMenuName
);
270 wceA
.cbSize
= sizeof(WNDCLASSEXA
);
271 if(GetClassInfoExA(hInstance
, lpClassName
, &wceA
) && wceA
.lpszMenuName
)
273 hMenu
= LoadMenuA(hInstance
, wceA
.lpszMenuName
);
278 if (!Unicode
) dwExStyle
|= WS_EX_SETANSICREATOR
;
280 Handle
= NtUserCreateWindowEx(dwExStyle
,
297 DbgPrint("[window] NtUserCreateWindowEx() == %d\n", Handle
);
302 if (!IS_ATOM(lpClassName
))
304 RtlFreeUnicodeString(&ClassName
);
307 RtlFreeLargeString(&WindowName
);
318 CreateWindowExA(DWORD dwExStyle
,
331 MDICREATESTRUCTA mdi
;
334 if (!RegisterDefaultClasses
)
336 ERR("CreateWindowExA RegisterSystemControls\n");
337 RegisterSystemControls();
340 if (dwExStyle
& WS_EX_MDICHILD
)
348 if(!(WndParent
= ValidateHwnd(hWndParent
)) ||
349 !(pcls
= DesktopPtrToUser(WndParent
->pcls
)))
352 if (pcls
->fnid
!= FNID_MDICLIENT
)
354 ERR("WS_EX_MDICHILD, but parent %p is not MDIClient\n", hWndParent
);
358 /* lpParams of WM_[NC]CREATE is different for MDI children.
359 * MDICREATESTRUCT members have the originally passed values.
361 mdi
.szClass
= lpClassName
;
362 mdi
.szTitle
= lpWindowName
;
363 mdi
.hOwner
= hInstance
;
369 mdi
.lParam
= (LPARAM
)lpParam
;
371 lpParam
= (LPVOID
)&mdi
;
373 if (GetWindowLongPtrW(hWndParent
, GWL_STYLE
) & MDIS_ALLCHILDSTYLES
)
375 if (dwStyle
& WS_POPUP
)
377 WARN("WS_POPUP with MDIS_ALLCHILDSTYLES is not allowed\n");
380 dwStyle
|= (WS_CHILD
| WS_CLIPSIBLINGS
);
384 dwStyle
&= ~WS_POPUP
;
385 dwStyle
|= (WS_CHILD
| WS_VISIBLE
| WS_CLIPSIBLINGS
| WS_CAPTION
|
386 WS_SYSMENU
| WS_THICKFRAME
| WS_MINIMIZEBOX
| WS_MAXIMIZEBOX
);
389 top_child
= GetWindow(hWndParent
, GW_CHILD
);
393 /* Restore current maximized child */
394 if((dwStyle
& WS_VISIBLE
) && IsZoomed(top_child
))
396 TRACE("Restoring current maximized child %p\n", top_child
);
397 SendMessageW( top_child
, WM_SETREDRAW
, FALSE
, 0 );
398 ShowWindow(top_child
, SW_RESTORE
);
399 SendMessageW( top_child
, WM_SETREDRAW
, TRUE
, 0 );
403 MDI_CalcDefaultChildPos(hWndParent
, -1, mPos
, 0, &id
);
405 if (!(dwStyle
& WS_POPUP
)) hMenu
= (HMENU
)id
;
407 if (dwStyle
& (WS_CHILD
| WS_POPUP
))
409 if (x
== CW_USEDEFAULT
|| x
== CW_USEDEFAULT16
)
414 if (nWidth
== CW_USEDEFAULT
|| nWidth
== CW_USEDEFAULT16
|| !nWidth
)
416 if (nHeight
== CW_USEDEFAULT
|| nHeight
== CW_USEDEFAULT16
|| !nHeight
)
421 hwnd
= User32CreateWindowEx(dwExStyle
,
442 CreateWindowExW(DWORD dwExStyle
,
444 LPCWSTR lpWindowName
,
455 MDICREATESTRUCTW mdi
;
458 if (!RegisterDefaultClasses
)
460 ERR("CreateWindowExW RegisterSystemControls\n");
461 RegisterSystemControls();
464 if (dwExStyle
& WS_EX_MDICHILD
)
472 WndParent
= ValidateHwnd(hWndParent
);
477 pcls
= DesktopPtrToUser(WndParent
->pcls
);
482 if (pcls
->fnid
!= FNID_MDICLIENT
)
484 ERR("WS_EX_MDICHILD, but parent %p is not MDIClient\n", hWndParent
);
488 /* lpParams of WM_[NC]CREATE is different for MDI children.
489 * MDICREATESTRUCT members have the originally passed values.
491 mdi
.szClass
= lpClassName
;
492 mdi
.szTitle
= lpWindowName
;
493 mdi
.hOwner
= hInstance
;
499 mdi
.lParam
= (LPARAM
)lpParam
;
501 lpParam
= (LPVOID
)&mdi
;
503 if (GetWindowLongPtrW(hWndParent
, GWL_STYLE
) & MDIS_ALLCHILDSTYLES
)
505 if (dwStyle
& WS_POPUP
)
507 WARN("WS_POPUP with MDIS_ALLCHILDSTYLES is not allowed\n");
510 dwStyle
|= (WS_CHILD
| WS_CLIPSIBLINGS
);
514 dwStyle
&= ~WS_POPUP
;
515 dwStyle
|= (WS_CHILD
| WS_VISIBLE
| WS_CLIPSIBLINGS
| WS_CAPTION
|
516 WS_SYSMENU
| WS_THICKFRAME
| WS_MINIMIZEBOX
| WS_MAXIMIZEBOX
);
519 top_child
= GetWindow(hWndParent
, GW_CHILD
);
523 /* Restore current maximized child */
524 if((dwStyle
& WS_VISIBLE
) && IsZoomed(top_child
))
526 TRACE("Restoring current maximized child %p\n", top_child
);
527 SendMessageW( top_child
, WM_SETREDRAW
, FALSE
, 0 );
528 ShowWindow(top_child
, SW_RESTORE
);
529 SendMessageW( top_child
, WM_SETREDRAW
, TRUE
, 0 );
533 MDI_CalcDefaultChildPos(hWndParent
, -1, mPos
, 0, &id
);
535 if (!(dwStyle
& WS_POPUP
)) hMenu
= (HMENU
)id
;
537 if (dwStyle
& (WS_CHILD
| WS_POPUP
))
539 if (x
== CW_USEDEFAULT
|| x
== CW_USEDEFAULT16
)
544 if (nWidth
== CW_USEDEFAULT
|| nWidth
== CW_USEDEFAULT16
|| !nWidth
)
546 if (nHeight
== CW_USEDEFAULT
|| nHeight
== CW_USEDEFAULT16
|| !nHeight
)
551 hwnd
= User32CreateWindowEx(dwExStyle
,
552 (LPCSTR
) lpClassName
,
553 (LPCSTR
) lpWindowName
,
571 DeferWindowPos(HDWP hWinPosInfo
,
573 HWND hWndInsertAfter
,
581 return NtUserDeferWindowPos(hWinPosInfo
, hWnd
, hWndInsertAfter
, x
, y
, cx
, cy
, uFlags
);
583 SetWindowPos(hWnd
, hWndInsertAfter
, x
, y
, cx
, cy
, uFlags
);
593 EndDeferWindowPos(HDWP hWinPosInfo
)
608 GetDesktopWindow(VOID
)
615 Wnd
= GetThreadDesktopWnd();
617 Ret
= UserHMGetHandle(Wnd
);
619 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
630 User32EnumWindows(HDESK hDesktop
,
637 DWORD i
, dwCount
= 0;
644 SetLastError ( ERROR_INVALID_PARAMETER
);
648 /* FIXME instead of always making two calls, should we use some
649 sort of persistent buffer and only grow it ( requiring a 2nd
650 call ) when the buffer wasn't already big enough? */
651 /* first get how many window entries there are */
652 Status
= NtUserBuildHwndList(hDesktop
,
659 if (!NT_SUCCESS(Status
))
662 /* allocate buffer to receive HWND handles */
663 hHeap
= GetProcessHeap();
664 pHwnd
= HeapAlloc(hHeap
, 0, sizeof(HWND
)*(dwCount
+1));
667 SetLastError ( ERROR_NOT_ENOUGH_MEMORY
);
671 /* now call kernel again to fill the buffer this time */
672 Status
= NtUserBuildHwndList(hDesktop
,
679 if (!NT_SUCCESS(Status
))
682 HeapFree(hHeap
, 0, pHwnd
);
686 /* call the user's callback function until we're done or
687 they tell us to quit */
688 for ( i
= 0; i
< dwCount
; i
++ )
690 /* FIXME I'm only getting NULLs from Thread Enumeration, and it's
691 * probably because I'm not doing it right in NtUserBuildHwndList.
692 * Once that's fixed, we shouldn't have to check for a NULL HWND
695 if (!(ULONG
)pHwnd
[i
]) /* don't enumerate a NULL HWND */
697 if (!(*lpfn
)(pHwnd
[i
], lParam
))
699 HeapFree ( hHeap
, 0, pHwnd
);
704 HeapFree(hHeap
, 0, pHwnd
);
713 EnumChildWindows(HWND hWndParent
,
714 WNDENUMPROC lpEnumFunc
,
719 return EnumWindows(lpEnumFunc
, lParam
);
721 return User32EnumWindows(NULL
, hWndParent
, lpEnumFunc
, lParam
, 0, TRUE
);
729 EnumThreadWindows(DWORD dwThreadId
,
734 dwThreadId
= GetCurrentThreadId();
735 return User32EnumWindows(NULL
, NULL
, lpfn
, lParam
, dwThreadId
, FALSE
);
743 EnumWindows(WNDENUMPROC lpEnumFunc
,
746 return User32EnumWindows(NULL
, NULL
, lpEnumFunc
, lParam
, 0, FALSE
);
754 EnumDesktopWindows(HDESK hDesktop
,
758 return User32EnumWindows(hDesktop
, NULL
, lpfn
, lParam
, 0, FALSE
);
766 FindWindowExA(HWND hwndParent
,
771 UNICODE_STRING ucClassName
, *pucClassName
= NULL
;
772 UNICODE_STRING ucWindowName
, *pucWindowName
= NULL
;
775 if (IS_ATOM(lpszClass
))
777 ucClassName
.Buffer
= (LPWSTR
)lpszClass
;
778 ucClassName
.Length
= 0;
779 pucClassName
= &ucClassName
;
781 else if (lpszClass
!= NULL
)
783 if (!RtlCreateUnicodeStringFromAsciiz(&ucClassName
,
786 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
789 pucClassName
= &ucClassName
;
792 if (lpszWindow
!= NULL
)
794 if (!RtlCreateUnicodeStringFromAsciiz(&ucWindowName
,
797 if (!IS_ATOM(lpszClass
) && lpszClass
!= NULL
)
798 RtlFreeUnicodeString(&ucWindowName
);
800 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
804 pucWindowName
= &ucWindowName
;
807 Result
= NtUserFindWindowEx(hwndParent
,
813 if (!IS_ATOM(lpszClass
) && lpszClass
!= NULL
)
814 RtlFreeUnicodeString(&ucClassName
);
815 if (lpszWindow
!= NULL
)
816 RtlFreeUnicodeString(&ucWindowName
);
826 FindWindowExW(HWND hwndParent
,
831 UNICODE_STRING ucClassName
, *pucClassName
= NULL
;
832 UNICODE_STRING ucWindowName
, *pucWindowName
= NULL
;
834 if (IS_ATOM(lpszClass
))
836 ucClassName
.Length
= 0;
837 ucClassName
.Buffer
= (LPWSTR
)lpszClass
;
838 pucClassName
= &ucClassName
;
840 else if (lpszClass
!= NULL
)
842 RtlInitUnicodeString(&ucClassName
,
844 pucClassName
= &ucClassName
;
847 if (lpszWindow
!= NULL
)
849 RtlInitUnicodeString(&ucWindowName
,
851 pucWindowName
= &ucWindowName
;
854 return NtUserFindWindowEx(hwndParent
,
866 FindWindowA(LPCSTR lpClassName
, LPCSTR lpWindowName
)
868 //FIXME: FindWindow does not search children, but FindWindowEx does.
869 // what should we do about this?
870 return FindWindowExA (NULL
, NULL
, lpClassName
, lpWindowName
);
878 FindWindowW(LPCWSTR lpClassName
, LPCWSTR lpWindowName
)
882 There was a FIXME here earlier, but I think it is just a documentation unclarity.
884 FindWindow only searches top level windows. What they mean is that child
885 windows of other windows than the desktop can be searched.
886 FindWindowExW never does a recursive search.
891 return FindWindowExW(NULL
, NULL
, lpClassName
, lpWindowName
);
900 GetAltTabInfoA(HWND hwnd
,
915 GetAltTabInfoW(HWND hwnd
,
930 GetAncestor(HWND hwnd
, UINT gaFlags
)
935 Wnd
= ValidateHwnd(hwnd
);
945 if (Wnd
->spwndParent
!= NULL
)
946 Ancestor
= DesktopPtrToUser(Wnd
->spwndParent
);
950 /* FIXME: Call win32k for now */
955 if (Ancestor
!= NULL
)
956 Ret
= UserHMGetHandle(Ancestor
);
958 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
964 if (!Wnd
) /* Fall back */
965 Ret
= NtUserGetAncestor(hwnd
, gaFlags
);
975 GetClientRect(HWND hWnd
, LPRECT lpRect
)
977 PWND Wnd
= ValidateHwnd(hWnd
);
981 lpRect
->left
= lpRect
->top
= 0;
982 lpRect
->right
= Wnd
->rcClient
.right
- Wnd
->rcClient
.left
;
983 lpRect
->bottom
= Wnd
->rcClient
.bottom
- Wnd
->rcClient
.top
;
995 GetLastActivePopup(HWND hWnd
)
1000 Wnd
= ValidateHwnd(hWnd
);
1005 if (Wnd
->hWndLastActive
)
1006 Ret
= Wnd
->hWndLastActive
;
1008 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
1022 GetParent(HWND hWnd
)
1024 PWND Wnd
, WndParent
;
1027 Wnd
= ValidateHwnd(hWnd
);
1033 if (Wnd
->style
& WS_POPUP
)
1035 if (Wnd
->spwndOwner
!= NULL
)
1036 WndParent
= DesktopPtrToUser(Wnd
->spwndOwner
);
1038 else if (Wnd
->style
& WS_CHILD
)
1040 if (Wnd
->spwndParent
!= NULL
)
1041 WndParent
= DesktopPtrToUser(Wnd
->spwndParent
);
1044 if (WndParent
!= NULL
)
1045 Ret
= UserHMGetHandle(WndParent
);
1047 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
1062 GetProcessDefaultLayout(DWORD
*pdwDefaultLayout
)
1064 if (!pdwDefaultLayout
)
1066 SetLastError(ERROR_INVALID_PARAMETER
);
1072 *pdwDefaultLayout
= 0;
1081 GetWindow(HWND hWnd
,
1087 Wnd
= ValidateHwnd(hWnd
);
1097 if (Wnd
->spwndOwner
!= NULL
)
1098 FoundWnd
= DesktopPtrToUser(Wnd
->spwndOwner
);
1102 if(Wnd
->spwndParent
!= NULL
)
1104 FoundWnd
= DesktopPtrToUser(Wnd
->spwndParent
);
1105 if (FoundWnd
->spwndChild
!= NULL
)
1106 FoundWnd
= DesktopPtrToUser(FoundWnd
->spwndChild
);
1110 if (Wnd
->spwndNext
!= NULL
)
1111 FoundWnd
= DesktopPtrToUser(Wnd
->spwndNext
);
1115 if (Wnd
->spwndPrev
!= NULL
)
1116 FoundWnd
= DesktopPtrToUser(Wnd
->spwndPrev
);
1120 if (Wnd
->spwndChild
!= NULL
)
1121 FoundWnd
= DesktopPtrToUser(Wnd
->spwndChild
);
1126 while ( FoundWnd
->spwndNext
!= NULL
)
1127 FoundWnd
= DesktopPtrToUser(FoundWnd
->spwndNext
);
1135 if (FoundWnd
!= NULL
)
1136 Ret
= UserHMGetHandle(FoundWnd
);
1138 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
1152 GetTopWindow(HWND hWnd
)
1154 if (!hWnd
) hWnd
= GetDesktopWindow();
1155 return GetWindow(hWnd
, GW_CHILD
);
1163 GetWindowInfo(HWND hWnd
,
1171 if ( !pwi
|| pwi
->cbSize
!= sizeof(WINDOWINFO
))
1172 SetLastError(ERROR_INVALID_PARAMETER
); // Just set the error and go!
1174 pWnd
= ValidateHwnd(hWnd
);
1178 UserGetWindowBorders(pWnd
->style
, pWnd
->ExStyle
, &Size
, FALSE
);
1182 pCls
= DesktopPtrToUser(pWnd
->pcls
);
1183 pwi
->rcWindow
= pWnd
->rcWindow
;
1184 pwi
->rcClient
= pWnd
->rcClient
;
1185 pwi
->dwStyle
= pWnd
->style
;
1186 pwi
->dwExStyle
= pWnd
->ExStyle
;
1187 pwi
->cxWindowBorders
= Size
.cx
;
1188 pwi
->cyWindowBorders
= Size
.cy
;
1189 pwi
->dwWindowStatus
= 0;
1190 if (pWnd
->state
& WNDS_ACTIVEFRAME
)
1191 pwi
->dwWindowStatus
= WS_ACTIVECAPTION
;
1192 pwi
->atomWindowType
= (pCls
? pCls
->atomClassName
: 0 );
1194 if ( pWnd
->state2
& WNDS2_WIN50COMPAT
)
1196 pwi
->wCreatorVersion
= 0x500;
1198 else if ( pWnd
->state2
& WNDS2_WIN40COMPAT
)
1200 pwi
->wCreatorVersion
= 0x400;
1202 else if ( pWnd
->state2
& WNDS2_WIN31COMPAT
)
1204 pwi
->wCreatorVersion
= 0x30A;
1208 pwi
->wCreatorVersion
= 0x300;
1213 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
1227 GetWindowModuleFileNameA(HWND hwnd
,
1229 UINT cchFileNameMax
)
1231 PWND Wnd
= ValidateHwnd(hwnd
);
1236 return GetModuleFileNameA(Wnd
->hModule
, lpszFileName
, cchFileNameMax
);
1244 GetWindowModuleFileNameW(HWND hwnd
,
1245 LPWSTR lpszFileName
,
1246 UINT cchFileNameMax
)
1248 PWND Wnd
= ValidateHwnd(hwnd
);
1253 return GetModuleFileNameW( Wnd
->hModule
, lpszFileName
, cchFileNameMax
);
1261 GetWindowRect(HWND hWnd
,
1264 PWND Wnd
= ValidateHwnd(hWnd
);
1268 *lpRect
= Wnd
->rcWindow
;
1280 GetWindowTextA(HWND hWnd
, LPSTR lpString
, int nMaxCount
)
1286 if (lpString
== NULL
)
1289 Wnd
= ValidateHwnd(hWnd
);
1295 if (!TestWindowProcess( Wnd
))
1299 /* do not send WM_GETTEXT messages to other processes */
1300 Length
= Wnd
->strName
.Length
/ sizeof(WCHAR
);
1303 Buffer
= DesktopPtrToUser(Wnd
->strName
.Buffer
);
1306 if (!WideCharToMultiByte(CP_ACP
,
1315 lpString
[nMaxCount
- 1] = '\0';
1328 Wnd
= NULL
; /* Don't send a message */
1331 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
1335 Wnd
= NULL
; /* Don't send a message */
1340 Length
= SendMessageA(hWnd
, WM_GETTEXT
, nMaxCount
, (LPARAM
)lpString
);
1350 GetWindowTextLengthA(HWND hWnd
)
1352 return(SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0));
1360 GetWindowTextLengthW(HWND hWnd
)
1362 return(SendMessageW(hWnd
, WM_GETTEXTLENGTH
, 0, 0));
1370 GetWindowTextW(HWND hWnd
, LPWSTR lpString
, int nMaxCount
)
1376 if (lpString
== NULL
)
1379 Wnd
= ValidateHwnd(hWnd
);
1385 if (!TestWindowProcess( Wnd
))
1389 /* do not send WM_GETTEXT messages to other processes */
1390 Length
= Wnd
->strName
.Length
/ sizeof(WCHAR
);
1393 Buffer
= DesktopPtrToUser(Wnd
->strName
.Buffer
);
1396 RtlCopyMemory(lpString
,
1398 (Length
+ 1) * sizeof(WCHAR
));
1410 Wnd
= NULL
; /* Don't send a message */
1413 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
1417 Wnd
= NULL
; /* Don't send a message */
1422 Length
= SendMessageW(hWnd
, WM_GETTEXT
, nMaxCount
, (LPARAM
)lpString
);
1428 GetWindowThreadProcessId(HWND hWnd
,
1429 LPDWORD lpdwProcessId
)
1433 PWND pWnd
= ValidateHwnd(hWnd
);
1435 if (!pWnd
) return Ret
;
1437 ti
= pWnd
->head
.pti
;
1441 if (ti
== GetW32ThreadInfo())
1442 { // We are current.
1443 //FIXME("Current!\n");
1445 *lpdwProcessId
= (DWORD
)NtCurrentTeb()->ClientId
.UniqueProcess
;
1446 Ret
= (DWORD
)NtCurrentTeb()->ClientId
.UniqueThread
;
1449 { // Ask kernel for info.
1450 //FIXME("Kernel call!\n");
1452 *lpdwProcessId
= NtUserQueryWindow(hWnd
, QUERY_WINDOW_UNIQUE_PROCESS_ID
);
1453 Ret
= NtUserQueryWindow(hWnd
, QUERY_WINDOW_UNIQUE_THREAD_ID
);
1464 IsChild(HWND hWndParent
,
1467 PWND WndParent
, DesktopWnd
, Wnd
;
1470 WndParent
= ValidateHwnd(hWndParent
);
1473 Wnd
= ValidateHwnd(hWnd
);
1477 DesktopWnd
= GetThreadDesktopWnd();
1485 if (Wnd
->spwndParent
!= NULL
)
1487 Wnd
= DesktopPtrToUser(Wnd
->spwndParent
);
1489 if(Wnd
== DesktopWnd
)
1492 if (Wnd
== WndParent
)
1502 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
1518 PWND Wnd
= ValidateHwnd(hWnd
);
1521 return (Wnd
->style
& WS_MINIMIZE
) != 0;
1533 PWND Wnd
= ValidateHwndNoErr(hWnd
);
1536 /* FIXME: If window is being destroyed return FALSE! */
1548 IsWindowUnicode(HWND hWnd
)
1550 PWND Wnd
= ValidateHwnd(hWnd
);
1553 return Wnd
->Unicode
;
1563 IsWindowVisible(HWND hWnd
)
1566 PWND Wnd
= ValidateHwnd(hWnd
);
1576 if (!(Wnd
->style
& WS_VISIBLE
))
1582 if (Wnd
->spwndParent
!= NULL
)
1583 Wnd
= DesktopPtrToUser(Wnd
->spwndParent
);
1587 } while (Wnd
!= NULL
);
1589 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
1604 IsWindowEnabled(HWND hWnd
)
1606 // AG: I don't know if child windows are affected if the parent is
1607 // disabled. I think they stop processing messages but stay appearing
1610 return !(GetWindowLongPtrW(hWnd
, GWL_STYLE
) & WS_DISABLED
);
1620 return (GetWindowLongPtrW(hWnd
, GWL_STYLE
) & WS_MAXIMIZE
) != 0;
1628 LockSetForegroundWindow(UINT uLockCode
)
1639 AnimateWindow(HWND hwnd
,
1643 /* FIXME Add animation code */
1645 /* If trying to show/hide and it's already *
1646 * shown/hidden or invalid window, fail with *
1647 * invalid parameter */
1650 visible
= IsWindowVisible(hwnd
);
1651 if(!IsWindow(hwnd
) ||
1652 (visible
&& !(dwFlags
& AW_HIDE
)) ||
1653 (!visible
&& (dwFlags
& AW_HIDE
)))
1655 SetLastError(ERROR_INVALID_PARAMETER
);
1659 ShowWindow(hwnd
, (dwFlags
& AW_HIDE
) ? SW_HIDE
: ((dwFlags
& AW_ACTIVATE
) ? SW_SHOW
: SW_SHOWNA
));
1671 if (!(GetWindowLongPtrW(hWnd
, GWL_STYLE
) & WS_MINIMIZE
))
1674 ShowWindow(hWnd
,SW_RESTORE
);
1683 RealChildWindowFromPoint(HWND hwndParent
,
1684 POINT ptParentClientCoords
)
1686 return ChildWindowFromPointEx(hwndParent
, ptParentClientCoords
, CWP_SKIPTRANSPARENT
);
1693 SetForegroundWindow(HWND hWnd
)
1695 return NtUserCallHwndLock(hWnd
, HWNDLOCK_ROUTINE_SETFOREGROUNDWINDOW
);
1703 SetProcessDefaultLayout(DWORD dwDefaultLayout
)
1705 if (dwDefaultLayout
== 0)
1717 SetWindowTextA(HWND hWnd
,
1721 if(!GetWindowThreadProcessId(hWnd
, &ProcessId
))
1726 if(ProcessId
!= GetCurrentProcessId())
1728 /* do not send WM_GETTEXT messages to other processes */
1730 DefSetText(hWnd
, (PCWSTR
)lpString
, TRUE
);
1732 if ((GetWindowLongPtrW(hWnd
, GWL_STYLE
) & WS_CAPTION
) == WS_CAPTION
)
1734 DefWndNCPaint(hWnd
, (HRGN
)1, -1);
1739 return SendMessageA(hWnd
, WM_SETTEXT
, 0, (LPARAM
)lpString
);
1747 SetWindowTextW(HWND hWnd
,
1751 if(!GetWindowThreadProcessId(hWnd
, &ProcessId
))
1756 if(ProcessId
!= GetCurrentProcessId())
1758 /* do not send WM_GETTEXT messages to other processes */
1760 DefSetText(hWnd
, lpString
, FALSE
);
1762 if ((GetWindowLongPtrW(hWnd
, GWL_STYLE
) & WS_CAPTION
) == WS_CAPTION
)
1764 DefWndNCPaint(hWnd
, (HRGN
)1, -1);
1769 return SendMessageW(hWnd
, WM_SETTEXT
, 0, (LPARAM
)lpString
);
1777 ShowOwnedPopups(HWND hWnd
,
1780 return (BOOL
)NtUserCallTwoParam((DWORD_PTR
)hWnd
, fShow
, TWOPARAM_ROUTINE_SHOWOWNEDPOPUPS
);
1788 UpdateLayeredWindow( HWND hwnd
,
1798 if ( dwFlags
& ULW_EX_NORESIZE
)
1799 dwFlags
= ~(ULW_EX_NORESIZE
|ULW_OPAQUE
|ULW_ALPHA
|ULW_COLORKEY
);
1800 return NtUserUpdateLayeredWindow( hwnd
,
1816 UpdateLayeredWindowIndirect(HWND hwnd
,
1817 const UPDATELAYEREDWINDOWINFO
*info
)
1819 if (info
&& info
->cbSize
== sizeof(info
))
1821 return NtUserUpdateLayeredWindow( hwnd
,
1823 (POINT
*)info
->pptDst
,
1824 (SIZE
*)info
->psize
,
1826 (POINT
*)info
->pptSrc
,
1828 (BLENDFUNCTION
*)info
->pblend
,
1830 (RECT
*)info
->prcDirty
);
1832 SetLastError(ERROR_INVALID_PARAMETER
);
1841 WindowFromPoint(POINT Point
)
1843 //TODO: Determine what the actual parameters to
1844 // NtUserWindowFromPoint are.
1845 return NtUserWindowFromPoint(Point
.x
, Point
.y
);
1853 MapWindowPoints(HWND hWndFrom
, HWND hWndTo
, LPPOINT lpPoints
, UINT cPoints
)
1855 PWND FromWnd
, ToWnd
;
1859 FromWnd
= ValidateHwndOrDesk(hWndFrom
);
1863 ToWnd
= ValidateHwndOrDesk(hWndTo
);
1867 Delta
.x
= FromWnd
->rcClient
.left
- ToWnd
->rcClient
.left
;
1868 Delta
.y
= FromWnd
->rcClient
.top
- ToWnd
->rcClient
.top
;
1870 for (i
= 0; i
!= cPoints
; i
++)
1872 lpPoints
[i
].x
+= Delta
.x
;
1873 lpPoints
[i
].y
+= Delta
.y
;
1876 return MAKELONG(LOWORD(Delta
.x
), LOWORD(Delta
.y
));
1884 ScreenToClient(HWND hWnd
, LPPOINT lpPoint
)
1886 PWND Wnd
, DesktopWnd
;
1888 Wnd
= ValidateHwnd(hWnd
);
1892 DesktopWnd
= GetThreadDesktopWnd();
1894 lpPoint
->x
+= DesktopWnd
->rcClient
.left
- Wnd
->rcClient
.left
;
1895 lpPoint
->y
+= DesktopWnd
->rcClient
.top
- Wnd
->rcClient
.top
;
1905 ClientToScreen(HWND hWnd
, LPPOINT lpPoint
)
1907 PWND Wnd
, DesktopWnd
;
1909 Wnd
= ValidateHwnd(hWnd
);
1913 DesktopWnd
= GetThreadDesktopWnd();
1915 lpPoint
->x
+= Wnd
->rcClient
.left
- DesktopWnd
->rcClient
.left
;
1916 lpPoint
->y
+= Wnd
->rcClient
.top
- DesktopWnd
->rcClient
.top
;
1926 SetWindowContextHelpId(HWND hwnd
,
1927 DWORD dwContextHelpId
)
1929 return NtUserSetWindowContextHelpId(hwnd
, dwContextHelpId
);
1937 GetWindowContextHelpId(HWND hwnd
)
1939 return NtUserCallHwnd(hwnd
, HWND_ROUTINE_GETWNDCONTEXTHLPID
);
1946 InternalGetWindowText(HWND hWnd
, LPWSTR lpString
, int nMaxCount
)
1948 INT Ret
= NtUserInternalGetWindowText(hWnd
, lpString
, nMaxCount
);
1958 IsHungAppWindow(HWND hwnd
)
1960 return (NtUserQueryWindow(hwnd
, QUERY_WINDOW_ISHUNG
) != 0);
1967 SetLastErrorEx(DWORD dwErrCode
, DWORD dwType
)
1969 SetLastError(dwErrCode
);
1978 return (HWND
)NtUserGetThreadState(THREADSTATE_FOCUSWINDOW
);
1982 GetRealWindowOwner(HWND hwnd
)
1984 return NtUserQueryWindow(hwnd
, QUERY_WINDOW_REAL_ID
);
1991 SetTaskmanWindow(HWND hWnd
)
1993 return NtUserCallHwndOpt(hWnd
, HWNDOPT_ROUTINE_SETTASKMANWINDOW
);
2000 SetProgmanWindow(HWND hWnd
)
2002 return NtUserCallHwndOpt(hWnd
, HWNDOPT_ROUTINE_SETPROGMANWINDOW
);
2009 GetProgmanWindow(VOID
)
2011 return (HWND
)NtUserGetThreadState(THREADSTATE_PROGMANWINDOW
);
2018 GetTaskmanWindow(VOID
)
2020 return (HWND
)NtUserGetThreadState(THREADSTATE_TASKMANWINDOW
);
2027 ScrollWindow(HWND hWnd
,
2031 CONST RECT
*prcClip
)
2033 return NtUserScrollWindowEx(hWnd
,
2040 (lpRect
? 0 : SW_SCROLLCHILDREN
) | SW_INVALIDATE
) != ERROR
;
2048 ScrollWindowEx(HWND hWnd
,
2051 CONST RECT
*prcScroll
,
2052 CONST RECT
*prcClip
,
2057 return NtUserScrollWindowEx(hWnd
,
2075 HWND
*list
= WIN_ListChildren( GetDesktopWindow() );
2077 if (!list
) return FALSE
;
2078 for (i
= 0; list
[i
]; i
++)
2080 if (IsWindowVisible( list
[i
] ) && GetWindow( list
[i
], GW_OWNER
)) break;
2082 retvalue
= (list
[i
] != 0);
2083 HeapFree( GetProcessHeap(), 0, list
);
2091 IsWindowInDestroy(HWND hWnd
)
2093 return NtUserIsWindowInDestroy(hWnd
);
2100 DisableProcessWindowsGhosting(VOID
)
2102 NtUserEnableProcessWindowGhosting(FALSE
);