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);
138 return HandleToUlong(hWnd
);
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 pWndParent
= ValidateHwnd(hWndParent
);
350 if (!pWndParent
) return NULL
;
352 pCls
= DesktopPtrToUser(pWndParent
->pcls
);
354 if (pCls
->fnid
!= FNID_MDICLIENT
) // wine uses WIN_ISMDICLIENT
356 WARN("WS_EX_MDICHILD, but parent %p is not MDIClient\n", hWndParent
);
360 /* lpParams of WM_[NC]CREATE is different for MDI children.
361 * MDICREATESTRUCT members have the originally passed values.
363 mdi
.szClass
= lpClassName
;
364 mdi
.szTitle
= lpWindowName
;
365 mdi
.hOwner
= hInstance
;
371 mdi
.lParam
= (LPARAM
)lpParam
;
373 lpParam
= (LPVOID
)&mdi
;
375 if (pWndParent
->style
& MDIS_ALLCHILDSTYLES
)
377 if (dwStyle
& WS_POPUP
)
379 WARN("WS_POPUP with MDIS_ALLCHILDSTYLES is not allowed\n");
382 dwStyle
|= (WS_CHILD
| WS_CLIPSIBLINGS
);
386 dwStyle
&= ~WS_POPUP
;
387 dwStyle
|= (WS_CHILD
| WS_VISIBLE
| WS_CLIPSIBLINGS
| WS_CAPTION
|
388 WS_SYSMENU
| WS_THICKFRAME
| WS_MINIMIZEBOX
| WS_MAXIMIZEBOX
);
391 top_child
= GetWindow(hWndParent
, GW_CHILD
);
395 /* Restore current maximized child */
396 if((dwStyle
& WS_VISIBLE
) && IsZoomed(top_child
))
398 TRACE("Restoring current maximized child %p\n", top_child
);
399 SendMessageW( top_child
, WM_SETREDRAW
, FALSE
, 0 );
400 ShowWindow(top_child
, SW_RESTORE
);
401 SendMessageW( top_child
, WM_SETREDRAW
, TRUE
, 0 );
405 MDI_CalcDefaultChildPos(hWndParent
, -1, mPos
, 0, &id
);
407 if (!(dwStyle
& WS_POPUP
)) hMenu
= UlongToHandle(id
);
409 if (dwStyle
& (WS_CHILD
| WS_POPUP
))
411 if (x
== CW_USEDEFAULT
|| x
== CW_USEDEFAULT16
)
416 if (nWidth
== CW_USEDEFAULT
|| nWidth
== CW_USEDEFAULT16
|| !nWidth
)
418 if (nHeight
== CW_USEDEFAULT
|| nHeight
== CW_USEDEFAULT16
|| !nHeight
)
423 hwnd
= User32CreateWindowEx(dwExStyle
,
444 CreateWindowExW(DWORD dwExStyle
,
446 LPCWSTR lpWindowName
,
457 MDICREATESTRUCTW mdi
;
460 if (!RegisterDefaultClasses
)
462 ERR("CreateWindowExW RegisterSystemControls\n");
463 RegisterSystemControls();
466 if (dwExStyle
& WS_EX_MDICHILD
)
474 pWndParent
= ValidateHwnd(hWndParent
);
476 if (!pWndParent
) return NULL
;
478 pCls
= DesktopPtrToUser(pWndParent
->pcls
);
480 if (pCls
->fnid
!= FNID_MDICLIENT
)
482 WARN("WS_EX_MDICHILD, but parent %p is not MDIClient\n", hWndParent
);
486 /* lpParams of WM_[NC]CREATE is different for MDI children.
487 * MDICREATESTRUCT members have the originally passed values.
489 mdi
.szClass
= lpClassName
;
490 mdi
.szTitle
= lpWindowName
;
491 mdi
.hOwner
= hInstance
;
497 mdi
.lParam
= (LPARAM
)lpParam
;
499 lpParam
= (LPVOID
)&mdi
;
501 if (pWndParent
->style
& MDIS_ALLCHILDSTYLES
)
503 if (dwStyle
& WS_POPUP
)
505 WARN("WS_POPUP with MDIS_ALLCHILDSTYLES is not allowed\n");
508 dwStyle
|= (WS_CHILD
| WS_CLIPSIBLINGS
);
512 dwStyle
&= ~WS_POPUP
;
513 dwStyle
|= (WS_CHILD
| WS_VISIBLE
| WS_CLIPSIBLINGS
| WS_CAPTION
|
514 WS_SYSMENU
| WS_THICKFRAME
| WS_MINIMIZEBOX
| WS_MAXIMIZEBOX
);
517 top_child
= GetWindow(hWndParent
, GW_CHILD
);
521 /* Restore current maximized child */
522 if((dwStyle
& WS_VISIBLE
) && IsZoomed(top_child
))
524 TRACE("Restoring current maximized child %p\n", top_child
);
525 SendMessageW( top_child
, WM_SETREDRAW
, FALSE
, 0 );
526 ShowWindow(top_child
, SW_RESTORE
);
527 SendMessageW( top_child
, WM_SETREDRAW
, TRUE
, 0 );
531 MDI_CalcDefaultChildPos(hWndParent
, -1, mPos
, 0, &id
);
533 if (!(dwStyle
& WS_POPUP
)) hMenu
= UlongToHandle(id
);
535 if (dwStyle
& (WS_CHILD
| WS_POPUP
))
537 if (x
== CW_USEDEFAULT
|| x
== CW_USEDEFAULT16
)
542 if (nWidth
== CW_USEDEFAULT
|| nWidth
== CW_USEDEFAULT16
|| !nWidth
)
544 if (nHeight
== CW_USEDEFAULT
|| nHeight
== CW_USEDEFAULT16
|| !nHeight
)
549 hwnd
= User32CreateWindowEx(dwExStyle
,
550 (LPCSTR
) lpClassName
,
551 (LPCSTR
) lpWindowName
,
569 DeferWindowPos(HDWP hWinPosInfo
,
571 HWND hWndInsertAfter
,
579 return NtUserDeferWindowPos(hWinPosInfo
, hWnd
, hWndInsertAfter
, x
, y
, cx
, cy
, uFlags
);
581 SetWindowPos(hWnd
, hWndInsertAfter
, x
, y
, cx
, cy
, uFlags
);
591 EndDeferWindowPos(HDWP hWinPosInfo
)
606 GetDesktopWindow(VOID
)
613 Wnd
= GetThreadDesktopWnd();
615 Ret
= UserHMGetHandle(Wnd
);
617 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
628 User32EnumWindows(HDESK hDesktop
,
635 DWORD i
, dwCount
= 0;
642 SetLastError ( ERROR_INVALID_PARAMETER
);
646 /* FIXME instead of always making two calls, should we use some
647 sort of persistent buffer and only grow it ( requiring a 2nd
648 call ) when the buffer wasn't already big enough? */
649 /* first get how many window entries there are */
650 Status
= NtUserBuildHwndList(hDesktop
,
657 if (!NT_SUCCESS(Status
))
660 /* allocate buffer to receive HWND handles */
661 hHeap
= GetProcessHeap();
662 pHwnd
= HeapAlloc(hHeap
, 0, sizeof(HWND
)*(dwCount
+1));
665 SetLastError ( ERROR_NOT_ENOUGH_MEMORY
);
669 /* now call kernel again to fill the buffer this time */
670 Status
= NtUserBuildHwndList(hDesktop
,
677 if (!NT_SUCCESS(Status
))
680 HeapFree(hHeap
, 0, pHwnd
);
692 /* call the user's callback function until we're done or
693 they tell us to quit */
694 for ( i
= 0; i
< dwCount
; i
++ )
696 /* FIXME I'm only getting NULLs from Thread Enumeration, and it's
697 * probably because I'm not doing it right in NtUserBuildHwndList.
698 * Once that's fixed, we shouldn't have to check for a NULL HWND
700 * This is now fixed in revision 50205. (jt)
702 if (!pHwnd
[i
]) /* don't enumerate a NULL HWND */
704 if (!(*lpfn
)(pHwnd
[i
], lParam
))
706 HeapFree ( hHeap
, 0, pHwnd
);
711 HeapFree(hHeap
, 0, pHwnd
);
720 EnumChildWindows(HWND hWndParent
,
721 WNDENUMPROC lpEnumFunc
,
726 return EnumWindows(lpEnumFunc
, lParam
);
728 return User32EnumWindows(NULL
, hWndParent
, lpEnumFunc
, lParam
, 0, TRUE
);
736 EnumThreadWindows(DWORD dwThreadId
,
741 dwThreadId
= GetCurrentThreadId();
742 return User32EnumWindows(NULL
, NULL
, lpfn
, lParam
, dwThreadId
, FALSE
);
750 EnumWindows(WNDENUMPROC lpEnumFunc
,
753 return User32EnumWindows(NULL
, NULL
, lpEnumFunc
, lParam
, 0, FALSE
);
761 EnumDesktopWindows(HDESK hDesktop
,
765 return User32EnumWindows(hDesktop
, NULL
, lpfn
, lParam
, 0, FALSE
);
773 FindWindowExA(HWND hwndParent
,
778 UNICODE_STRING ucClassName
, *pucClassName
= NULL
;
779 UNICODE_STRING ucWindowName
, *pucWindowName
= NULL
;
782 if (IS_ATOM(lpszClass
))
784 ucClassName
.Buffer
= (LPWSTR
)lpszClass
;
785 ucClassName
.Length
= 0;
786 pucClassName
= &ucClassName
;
788 else if (lpszClass
!= NULL
)
790 if (!RtlCreateUnicodeStringFromAsciiz(&ucClassName
,
793 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
796 pucClassName
= &ucClassName
;
799 if (lpszWindow
!= NULL
)
801 if (!RtlCreateUnicodeStringFromAsciiz(&ucWindowName
,
804 if (!IS_ATOM(lpszClass
) && lpszClass
!= NULL
)
805 RtlFreeUnicodeString(&ucWindowName
);
807 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
811 pucWindowName
= &ucWindowName
;
814 Result
= NtUserFindWindowEx(hwndParent
,
820 if (!IS_ATOM(lpszClass
) && lpszClass
!= NULL
)
821 RtlFreeUnicodeString(&ucClassName
);
822 if (lpszWindow
!= NULL
)
823 RtlFreeUnicodeString(&ucWindowName
);
833 FindWindowExW(HWND hwndParent
,
838 UNICODE_STRING ucClassName
, *pucClassName
= NULL
;
839 UNICODE_STRING ucWindowName
, *pucWindowName
= NULL
;
841 if (IS_ATOM(lpszClass
))
843 ucClassName
.Length
= 0;
844 ucClassName
.Buffer
= (LPWSTR
)lpszClass
;
845 pucClassName
= &ucClassName
;
847 else if (lpszClass
!= NULL
)
849 RtlInitUnicodeString(&ucClassName
,
851 pucClassName
= &ucClassName
;
854 if (lpszWindow
!= NULL
)
856 RtlInitUnicodeString(&ucWindowName
,
858 pucWindowName
= &ucWindowName
;
861 return NtUserFindWindowEx(hwndParent
,
873 FindWindowA(LPCSTR lpClassName
, LPCSTR lpWindowName
)
875 //FIXME: FindWindow does not search children, but FindWindowEx does.
876 // what should we do about this?
877 return FindWindowExA (NULL
, NULL
, lpClassName
, lpWindowName
);
885 FindWindowW(LPCWSTR lpClassName
, LPCWSTR lpWindowName
)
889 There was a FIXME here earlier, but I think it is just a documentation unclarity.
891 FindWindow only searches top level windows. What they mean is that child
892 windows of other windows than the desktop can be searched.
893 FindWindowExW never does a recursive search.
898 return FindWindowExW(NULL
, NULL
, lpClassName
, lpWindowName
);
907 GetAltTabInfoA(HWND hwnd
,
922 GetAltTabInfoW(HWND hwnd
,
937 GetAncestor(HWND hwnd
, UINT gaFlags
)
942 Wnd
= ValidateHwnd(hwnd
);
952 if (Wnd
->spwndParent
!= NULL
)
953 Ancestor
= DesktopPtrToUser(Wnd
->spwndParent
);
957 /* FIXME: Call win32k for now */
962 if (Ancestor
!= NULL
)
963 Ret
= UserHMGetHandle(Ancestor
);
965 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
971 if (!Wnd
) /* Fall back */
972 Ret
= NtUserGetAncestor(hwnd
, gaFlags
);
982 GetClientRect(HWND hWnd
, LPRECT lpRect
)
984 PWND Wnd
= ValidateHwnd(hWnd
);
988 lpRect
->left
= lpRect
->top
= 0;
989 lpRect
->right
= Wnd
->rcClient
.right
- Wnd
->rcClient
.left
;
990 lpRect
->bottom
= Wnd
->rcClient
.bottom
- Wnd
->rcClient
.top
;
1002 GetLastActivePopup(HWND hWnd
)
1007 Wnd
= ValidateHwnd(hWnd
);
1012 if (Wnd
->hWndLastActive
)
1013 Ret
= Wnd
->hWndLastActive
;
1015 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
1029 GetParent(HWND hWnd
)
1031 PWND Wnd
, WndParent
;
1034 Wnd
= ValidateHwnd(hWnd
);
1040 if (Wnd
->style
& WS_POPUP
)
1042 if (Wnd
->spwndOwner
!= NULL
)
1043 WndParent
= DesktopPtrToUser(Wnd
->spwndOwner
);
1045 else if (Wnd
->style
& WS_CHILD
)
1047 if (Wnd
->spwndParent
!= NULL
)
1048 WndParent
= DesktopPtrToUser(Wnd
->spwndParent
);
1051 if (WndParent
!= NULL
)
1052 Ret
= UserHMGetHandle(WndParent
);
1054 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
1069 GetProcessDefaultLayout(DWORD
*pdwDefaultLayout
)
1071 if (!pdwDefaultLayout
)
1073 SetLastError(ERROR_INVALID_PARAMETER
);
1079 *pdwDefaultLayout
= 0;
1088 GetWindow(HWND hWnd
,
1094 Wnd
= ValidateHwnd(hWnd
);
1104 if (Wnd
->spwndOwner
!= NULL
)
1105 FoundWnd
= DesktopPtrToUser(Wnd
->spwndOwner
);
1109 if(Wnd
->spwndParent
!= NULL
)
1111 FoundWnd
= DesktopPtrToUser(Wnd
->spwndParent
);
1112 if (FoundWnd
->spwndChild
!= NULL
)
1113 FoundWnd
= DesktopPtrToUser(FoundWnd
->spwndChild
);
1117 if (Wnd
->spwndNext
!= NULL
)
1118 FoundWnd
= DesktopPtrToUser(Wnd
->spwndNext
);
1122 if (Wnd
->spwndPrev
!= NULL
)
1123 FoundWnd
= DesktopPtrToUser(Wnd
->spwndPrev
);
1127 if (Wnd
->spwndChild
!= NULL
)
1128 FoundWnd
= DesktopPtrToUser(Wnd
->spwndChild
);
1133 while ( FoundWnd
->spwndNext
!= NULL
)
1134 FoundWnd
= DesktopPtrToUser(FoundWnd
->spwndNext
);
1142 if (FoundWnd
!= NULL
)
1143 Ret
= UserHMGetHandle(FoundWnd
);
1145 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
1159 GetTopWindow(HWND hWnd
)
1161 if (!hWnd
) hWnd
= GetDesktopWindow();
1162 return GetWindow(hWnd
, GW_CHILD
);
1170 GetWindowInfo(HWND hWnd
,
1178 if ( !pwi
|| pwi
->cbSize
!= sizeof(WINDOWINFO
))
1179 SetLastError(ERROR_INVALID_PARAMETER
); // Just set the error and go!
1181 pWnd
= ValidateHwnd(hWnd
);
1185 UserGetWindowBorders(pWnd
->style
, pWnd
->ExStyle
, &Size
, FALSE
);
1189 pCls
= DesktopPtrToUser(pWnd
->pcls
);
1190 pwi
->rcWindow
= pWnd
->rcWindow
;
1191 pwi
->rcClient
= pWnd
->rcClient
;
1192 pwi
->dwStyle
= pWnd
->style
;
1193 pwi
->dwExStyle
= pWnd
->ExStyle
;
1194 pwi
->cxWindowBorders
= Size
.cx
;
1195 pwi
->cyWindowBorders
= Size
.cy
;
1196 pwi
->dwWindowStatus
= 0;
1197 if (pWnd
->state
& WNDS_ACTIVEFRAME
)
1198 pwi
->dwWindowStatus
= WS_ACTIVECAPTION
;
1199 pwi
->atomWindowType
= (pCls
? pCls
->atomClassName
: 0 );
1201 if ( pWnd
->state2
& WNDS2_WIN50COMPAT
)
1203 pwi
->wCreatorVersion
= 0x500;
1205 else if ( pWnd
->state2
& WNDS2_WIN40COMPAT
)
1207 pwi
->wCreatorVersion
= 0x400;
1209 else if ( pWnd
->state2
& WNDS2_WIN31COMPAT
)
1211 pwi
->wCreatorVersion
= 0x30A;
1215 pwi
->wCreatorVersion
= 0x300;
1220 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
1234 GetWindowModuleFileNameA(HWND hwnd
,
1236 UINT cchFileNameMax
)
1238 PWND Wnd
= ValidateHwnd(hwnd
);
1243 return GetModuleFileNameA(Wnd
->hModule
, lpszFileName
, cchFileNameMax
);
1251 GetWindowModuleFileNameW(HWND hwnd
,
1252 LPWSTR lpszFileName
,
1253 UINT cchFileNameMax
)
1255 PWND Wnd
= ValidateHwnd(hwnd
);
1260 return GetModuleFileNameW( Wnd
->hModule
, lpszFileName
, cchFileNameMax
);
1268 GetWindowRect(HWND hWnd
,
1271 PWND Wnd
= ValidateHwnd(hWnd
);
1275 *lpRect
= Wnd
->rcWindow
;
1287 GetWindowTextA(HWND hWnd
, LPSTR lpString
, int nMaxCount
)
1293 if (lpString
== NULL
)
1296 Wnd
= ValidateHwnd(hWnd
);
1302 if (!TestWindowProcess( Wnd
))
1306 /* do not send WM_GETTEXT messages to other processes */
1307 Length
= Wnd
->strName
.Length
/ sizeof(WCHAR
);
1310 Buffer
= DesktopPtrToUser(Wnd
->strName
.Buffer
);
1313 if (!WideCharToMultiByte(CP_ACP
,
1322 lpString
[nMaxCount
- 1] = '\0';
1335 Wnd
= NULL
; /* Don't send a message */
1338 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
1342 Wnd
= NULL
; /* Don't send a message */
1347 Length
= SendMessageA(hWnd
, WM_GETTEXT
, nMaxCount
, (LPARAM
)lpString
);
1357 GetWindowTextLengthA(HWND hWnd
)
1359 return(SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0));
1367 GetWindowTextLengthW(HWND hWnd
)
1369 return(SendMessageW(hWnd
, WM_GETTEXTLENGTH
, 0, 0));
1377 GetWindowTextW(HWND hWnd
, LPWSTR lpString
, int nMaxCount
)
1383 if (lpString
== NULL
)
1386 Wnd
= ValidateHwnd(hWnd
);
1392 if (!TestWindowProcess( Wnd
))
1396 /* do not send WM_GETTEXT messages to other processes */
1397 Length
= Wnd
->strName
.Length
/ sizeof(WCHAR
);
1400 Buffer
= DesktopPtrToUser(Wnd
->strName
.Buffer
);
1403 RtlCopyMemory(lpString
,
1405 (Length
+ 1) * sizeof(WCHAR
));
1417 Wnd
= NULL
; /* Don't send a message */
1420 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
1424 Wnd
= NULL
; /* Don't send a message */
1429 Length
= SendMessageW(hWnd
, WM_GETTEXT
, nMaxCount
, (LPARAM
)lpString
);
1435 GetWindowThreadProcessId(HWND hWnd
,
1436 LPDWORD lpdwProcessId
)
1440 PWND pWnd
= ValidateHwnd(hWnd
);
1442 if (!pWnd
) return Ret
;
1444 ti
= pWnd
->head
.pti
;
1448 if (ti
== GetW32ThreadInfo())
1449 { // We are current.
1450 //FIXME("Current!\n");
1452 *lpdwProcessId
= (DWORD_PTR
)NtCurrentTeb()->ClientId
.UniqueProcess
;
1453 Ret
= (DWORD_PTR
)NtCurrentTeb()->ClientId
.UniqueThread
;
1456 { // Ask kernel for info.
1457 //FIXME("Kernel call!\n");
1459 *lpdwProcessId
= NtUserQueryWindow(hWnd
, QUERY_WINDOW_UNIQUE_PROCESS_ID
);
1460 Ret
= NtUserQueryWindow(hWnd
, QUERY_WINDOW_UNIQUE_THREAD_ID
);
1471 IsChild(HWND hWndParent
,
1474 PWND WndParent
, DesktopWnd
, Wnd
;
1477 WndParent
= ValidateHwnd(hWndParent
);
1480 Wnd
= ValidateHwnd(hWnd
);
1484 DesktopWnd
= GetThreadDesktopWnd();
1490 while (Wnd
!= NULL
&& ((Wnd
->style
& (WS_POPUP
|WS_CHILD
)) == WS_CHILD
))
1492 if (Wnd
->spwndParent
!= NULL
)
1494 Wnd
= DesktopPtrToUser(Wnd
->spwndParent
);
1496 if (Wnd
== WndParent
)
1506 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
1522 PWND Wnd
= ValidateHwnd(hWnd
);
1525 return (Wnd
->style
& WS_MINIMIZE
) != 0;
1537 PWND Wnd
= ValidateHwndNoErr(hWnd
);
1540 /* FIXME: If window is being destroyed return FALSE! */
1552 IsWindowUnicode(HWND hWnd
)
1554 PWND Wnd
= ValidateHwnd(hWnd
);
1557 return Wnd
->Unicode
;
1567 IsWindowVisible(HWND hWnd
)
1570 PWND Wnd
= ValidateHwnd(hWnd
);
1580 if (!(Wnd
->style
& WS_VISIBLE
))
1586 if (Wnd
->spwndParent
!= NULL
)
1587 Wnd
= DesktopPtrToUser(Wnd
->spwndParent
);
1591 } while (Wnd
!= NULL
);
1593 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
1608 IsWindowEnabled(HWND hWnd
)
1610 // AG: I don't know if child windows are affected if the parent is
1611 // disabled. I think they stop processing messages but stay appearing
1614 return !(GetWindowLongPtrW(hWnd
, GWL_STYLE
) & WS_DISABLED
);
1624 return (GetWindowLongPtrW(hWnd
, GWL_STYLE
) & WS_MAXIMIZE
) != 0;
1632 LockSetForegroundWindow(UINT uLockCode
)
1643 AnimateWindow(HWND hwnd
,
1647 /* FIXME Add animation code */
1649 /* If trying to show/hide and it's already *
1650 * shown/hidden or invalid window, fail with *
1651 * invalid parameter */
1654 visible
= IsWindowVisible(hwnd
);
1655 if(!IsWindow(hwnd
) ||
1656 (visible
&& !(dwFlags
& AW_HIDE
)) ||
1657 (!visible
&& (dwFlags
& AW_HIDE
)))
1659 SetLastError(ERROR_INVALID_PARAMETER
);
1663 ShowWindow(hwnd
, (dwFlags
& AW_HIDE
) ? SW_HIDE
: ((dwFlags
& AW_ACTIVATE
) ? SW_SHOW
: SW_SHOWNA
));
1675 if (!(GetWindowLongPtrW(hWnd
, GWL_STYLE
) & WS_MINIMIZE
))
1678 ShowWindow(hWnd
,SW_RESTORE
);
1687 RealChildWindowFromPoint(HWND hwndParent
,
1688 POINT ptParentClientCoords
)
1690 return ChildWindowFromPointEx(hwndParent
, ptParentClientCoords
, CWP_SKIPTRANSPARENT
);
1697 SetForegroundWindow(HWND hWnd
)
1699 return NtUserCallHwndLock(hWnd
, HWNDLOCK_ROUTINE_SETFOREGROUNDWINDOW
);
1707 SetProcessDefaultLayout(DWORD dwDefaultLayout
)
1709 if (dwDefaultLayout
== 0)
1721 SetWindowTextA(HWND hWnd
,
1725 if(!GetWindowThreadProcessId(hWnd
, &ProcessId
))
1730 if(ProcessId
!= GetCurrentProcessId())
1732 /* do not send WM_GETTEXT messages to other processes */
1734 DefSetText(hWnd
, (PCWSTR
)lpString
, TRUE
);
1736 if ((GetWindowLongPtrW(hWnd
, GWL_STYLE
) & WS_CAPTION
) == WS_CAPTION
)
1738 DefWndNCPaint(hWnd
, (HRGN
)1, -1);
1743 return SendMessageA(hWnd
, WM_SETTEXT
, 0, (LPARAM
)lpString
);
1751 SetWindowTextW(HWND hWnd
,
1755 if(!GetWindowThreadProcessId(hWnd
, &ProcessId
))
1760 if(ProcessId
!= GetCurrentProcessId())
1762 /* do not send WM_GETTEXT messages to other processes */
1764 DefSetText(hWnd
, lpString
, FALSE
);
1766 if ((GetWindowLongPtrW(hWnd
, GWL_STYLE
) & WS_CAPTION
) == WS_CAPTION
)
1768 DefWndNCPaint(hWnd
, (HRGN
)1, -1);
1773 return SendMessageW(hWnd
, WM_SETTEXT
, 0, (LPARAM
)lpString
);
1781 ShowOwnedPopups(HWND hWnd
,
1784 return (BOOL
)NtUserCallTwoParam((DWORD_PTR
)hWnd
, fShow
, TWOPARAM_ROUTINE_SHOWOWNEDPOPUPS
);
1792 UpdateLayeredWindow( HWND hwnd
,
1802 if ( dwFlags
& ULW_EX_NORESIZE
)
1803 dwFlags
= ~(ULW_EX_NORESIZE
|ULW_OPAQUE
|ULW_ALPHA
|ULW_COLORKEY
);
1804 return NtUserUpdateLayeredWindow( hwnd
,
1820 UpdateLayeredWindowIndirect(HWND hwnd
,
1821 const UPDATELAYEREDWINDOWINFO
*info
)
1823 if (info
&& info
->cbSize
== sizeof(info
))
1825 return NtUserUpdateLayeredWindow( hwnd
,
1827 (POINT
*)info
->pptDst
,
1828 (SIZE
*)info
->psize
,
1830 (POINT
*)info
->pptSrc
,
1832 (BLENDFUNCTION
*)info
->pblend
,
1834 (RECT
*)info
->prcDirty
);
1836 SetLastError(ERROR_INVALID_PARAMETER
);
1845 WindowFromPoint(POINT Point
)
1847 //TODO: Determine what the actual parameters to
1848 // NtUserWindowFromPoint are.
1849 return NtUserWindowFromPoint(Point
.x
, Point
.y
);
1857 MapWindowPoints(HWND hWndFrom
, HWND hWndTo
, LPPOINT lpPoints
, UINT cPoints
)
1859 PWND FromWnd
, ToWnd
;
1863 FromWnd
= ValidateHwndOrDesk(hWndFrom
);
1867 ToWnd
= ValidateHwndOrDesk(hWndTo
);
1871 Delta
.x
= FromWnd
->rcClient
.left
- ToWnd
->rcClient
.left
;
1872 Delta
.y
= FromWnd
->rcClient
.top
- ToWnd
->rcClient
.top
;
1874 for (i
= 0; i
!= cPoints
; i
++)
1876 lpPoints
[i
].x
+= Delta
.x
;
1877 lpPoints
[i
].y
+= Delta
.y
;
1880 return MAKELONG(LOWORD(Delta
.x
), LOWORD(Delta
.y
));
1888 ScreenToClient(HWND hWnd
, LPPOINT lpPoint
)
1890 PWND Wnd
, DesktopWnd
;
1892 Wnd
= ValidateHwnd(hWnd
);
1896 DesktopWnd
= GetThreadDesktopWnd();
1898 lpPoint
->x
+= DesktopWnd
->rcClient
.left
- Wnd
->rcClient
.left
;
1899 lpPoint
->y
+= DesktopWnd
->rcClient
.top
- Wnd
->rcClient
.top
;
1909 ClientToScreen(HWND hWnd
, LPPOINT lpPoint
)
1911 PWND Wnd
, DesktopWnd
;
1913 Wnd
= ValidateHwnd(hWnd
);
1917 DesktopWnd
= GetThreadDesktopWnd();
1919 lpPoint
->x
+= Wnd
->rcClient
.left
- DesktopWnd
->rcClient
.left
;
1920 lpPoint
->y
+= Wnd
->rcClient
.top
- DesktopWnd
->rcClient
.top
;
1930 SetWindowContextHelpId(HWND hwnd
,
1931 DWORD dwContextHelpId
)
1933 return NtUserSetWindowContextHelpId(hwnd
, dwContextHelpId
);
1941 GetWindowContextHelpId(HWND hwnd
)
1943 return NtUserCallHwnd(hwnd
, HWND_ROUTINE_GETWNDCONTEXTHLPID
);
1950 InternalGetWindowText(HWND hWnd
, LPWSTR lpString
, int nMaxCount
)
1952 INT Ret
= NtUserInternalGetWindowText(hWnd
, lpString
, nMaxCount
);
1962 IsHungAppWindow(HWND hwnd
)
1964 return (NtUserQueryWindow(hwnd
, QUERY_WINDOW_ISHUNG
) != 0);
1971 SetLastErrorEx(DWORD dwErrCode
, DWORD dwType
)
1973 SetLastError(dwErrCode
);
1982 return (HWND
)NtUserGetThreadState(THREADSTATE_FOCUSWINDOW
);
1986 GetRealWindowOwner(HWND hwnd
)
1988 return NtUserQueryWindow(hwnd
, QUERY_WINDOW_REAL_ID
);
1995 SetTaskmanWindow(HWND hWnd
)
1997 return NtUserCallHwndOpt(hWnd
, HWNDOPT_ROUTINE_SETTASKMANWINDOW
);
2004 SetProgmanWindow(HWND hWnd
)
2006 return NtUserCallHwndOpt(hWnd
, HWNDOPT_ROUTINE_SETPROGMANWINDOW
);
2013 GetProgmanWindow(VOID
)
2015 return (HWND
)NtUserGetThreadState(THREADSTATE_PROGMANWINDOW
);
2022 GetTaskmanWindow(VOID
)
2024 return (HWND
)NtUserGetThreadState(THREADSTATE_TASKMANWINDOW
);
2031 ScrollWindow(HWND hWnd
,
2035 CONST RECT
*prcClip
)
2037 return NtUserScrollWindowEx(hWnd
,
2044 (lpRect
? 0 : SW_SCROLLCHILDREN
) | SW_INVALIDATE
) != ERROR
;
2052 ScrollWindowEx(HWND hWnd
,
2055 CONST RECT
*prcScroll
,
2056 CONST RECT
*prcClip
,
2061 return NtUserScrollWindowEx(hWnd
,
2079 HWND
*list
= WIN_ListChildren( GetDesktopWindow() );
2081 if (!list
) return FALSE
;
2082 for (i
= 0; list
[i
]; i
++)
2084 if (IsWindowVisible( list
[i
] ) && GetWindow( list
[i
], GW_OWNER
)) break;
2086 retvalue
= (list
[i
] != 0);
2087 HeapFree( GetProcessHeap(), 0, list
);
2095 IsWindowInDestroy(HWND hWnd
)
2098 pwnd
= ValidateHwnd(hWnd
);
2101 return ((pwnd
->state2
& WNDS2_INDESTROY
) == WNDS2_INDESTROY
);
2108 DisableProcessWindowsGhosting(VOID
)
2110 NtUserEnableProcessWindowGhosting(FALSE
);