3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS user32.dll
5 * FILE: lib/user32/windows/window.c
6 * PURPOSE: Window management
7 * PROGRAMMER: Casper S. Hornstrup (chorns@users.sourceforge.net)
9 * 06-06-2001 CSH Created
12 /* INCLUDES ******************************************************************/
18 #include <user32/callback.h>
19 #include <user32/regcontrol.h>
24 static BOOL ControlsInitCalled = FALSE;
26 /* FUNCTIONS *****************************************************************/
28 WinHasThickFrameStyle(ULONG Style, ULONG ExStyle)
30 return((Style & WS_THICKFRAME) &&
31 (!((Style & (WS_DLGFRAME | WS_BORDER)) == WS_DLGFRAME)));
36 User32SendNCCALCSIZEMessageForKernel(PVOID Arguments, ULONG ArgumentLength)
38 PSENDNCCALCSIZEMESSAGE_CALLBACK_ARGUMENTS CallbackArgs;
39 SENDNCCALCSIZEMESSAGE_CALLBACK_RESULT Result;
42 DPRINT("User32SendNCCALCSIZEMessageForKernel.\n");
43 CallbackArgs = (PSENDNCCALCSIZEMESSAGE_CALLBACK_ARGUMENTS)Arguments;
44 if (ArgumentLength != sizeof(SENDNCCALCSIZEMESSAGE_CALLBACK_ARGUMENTS))
46 DPRINT("Wrong length.\n");
47 return(STATUS_INFO_LENGTH_MISMATCH);
49 Proc = (WNDPROC)NtUserGetWindowLong(CallbackArgs->Wnd, GWL_WNDPROC, FALSE);
50 DPRINT("Proc %X\n", Proc);
51 /* Call the window procedure; notice kernel messages are always unicode. */
52 if (CallbackArgs->Validate)
54 Result.Result = CallWindowProcW(Proc, CallbackArgs->Wnd, WM_NCCALCSIZE,
56 (LPARAM)&CallbackArgs->Params);
57 Result.Params = CallbackArgs->Params;
61 Result.Result = CallWindowProcW(Proc, CallbackArgs->Wnd, WM_NCCALCSIZE,
62 FALSE, (LPARAM)&CallbackArgs->Rect);
63 Result.Rect = CallbackArgs->Rect;
65 DPRINT("Returning result %d.\n", Result);
66 return(ZwCallbackReturn(&Result, sizeof(Result), STATUS_SUCCESS));
71 User32SendGETMINMAXINFOMessageForKernel(PVOID Arguments, ULONG ArgumentLength)
73 PSENDGETMINMAXINFO_CALLBACK_ARGUMENTS CallbackArgs;
74 SENDGETMINMAXINFO_CALLBACK_RESULT Result;
77 DPRINT("User32SendGETMINAXINFOMessageForKernel.\n");
78 CallbackArgs = (PSENDGETMINMAXINFO_CALLBACK_ARGUMENTS)Arguments;
79 if (ArgumentLength != sizeof(SENDGETMINMAXINFO_CALLBACK_ARGUMENTS))
81 DPRINT("Wrong length.\n");
82 return(STATUS_INFO_LENGTH_MISMATCH);
84 Proc = (WNDPROC)NtUserGetWindowLong(CallbackArgs->Wnd, GWL_WNDPROC, FALSE);
85 DPRINT("Proc %X\n", Proc);
86 /* Call the window procedure; notice kernel messages are always unicode. */
87 Result.Result = CallWindowProcW(Proc, CallbackArgs->Wnd, WM_GETMINMAXINFO,
88 0, (LPARAM)&CallbackArgs->MinMaxInfo);
89 Result.MinMaxInfo = CallbackArgs->MinMaxInfo;
90 DPRINT("Returning result %d.\n", Result);
91 return(ZwCallbackReturn(&Result, sizeof(Result), STATUS_SUCCESS));
96 User32SendCREATEMessageForKernel(PVOID Arguments, ULONG ArgumentLength)
98 PSENDCREATEMESSAGE_CALLBACK_ARGUMENTS CallbackArgs;
102 DPRINT("User32SendCREATEMessageForKernel.\n");
103 CallbackArgs = (PSENDCREATEMESSAGE_CALLBACK_ARGUMENTS)Arguments;
104 if (ArgumentLength != sizeof(SENDCREATEMESSAGE_CALLBACK_ARGUMENTS))
106 DPRINT("Wrong length.\n");
107 return(STATUS_INFO_LENGTH_MISMATCH);
109 Proc = (WNDPROC)NtUserGetWindowLong(CallbackArgs->Wnd, GWL_WNDPROC, FALSE);
110 DPRINT("Proc %X\n", Proc);
111 /* Call the window procedure; notice kernel messages are always unicode. */
112 Result = CallWindowProcW(Proc, CallbackArgs->Wnd, WM_CREATE, 0,
113 (LPARAM)&CallbackArgs->CreateStruct);
114 DPRINT("Returning result %d.\n", Result);
115 return(ZwCallbackReturn(&Result, sizeof(LRESULT), STATUS_SUCCESS));
120 User32SendNCCREATEMessageForKernel(PVOID Arguments, ULONG ArgumentLength)
122 PSENDNCCREATEMESSAGE_CALLBACK_ARGUMENTS CallbackArgs;
126 DPRINT("User32SendNCCREATEMessageForKernel.\n");
127 CallbackArgs = (PSENDNCCREATEMESSAGE_CALLBACK_ARGUMENTS)Arguments;
128 if (ArgumentLength != sizeof(SENDNCCREATEMESSAGE_CALLBACK_ARGUMENTS))
130 DPRINT("Wrong length.\n");
131 return(STATUS_INFO_LENGTH_MISMATCH);
133 Proc = (WNDPROC)NtUserGetWindowLong(CallbackArgs->Wnd, GWL_WNDPROC, FALSE);
134 DPRINT("Proc %X\n", Proc);
135 /* Call the window procedure; notice kernel messages are always unicode. */
136 Result = CallWindowProcW(Proc, CallbackArgs->Wnd, WM_NCCREATE, 0,
137 (LPARAM)&CallbackArgs->CreateStruct);
138 DPRINT("Returning result %d.\n", Result);
139 return(ZwCallbackReturn(&Result, sizeof(LRESULT), STATUS_SUCCESS));
144 User32SendWINDOWPOSCHANGINGMessageForKernel(PVOID Arguments, ULONG ArgumentLength)
146 PSENDWINDOWPOSCHANGING_CALLBACK_ARGUMENTS CallbackArgs;
150 DPRINT("User32SendWINDOWPOSCHANGINGMessageForKernel.\n");
151 CallbackArgs = (PSENDWINDOWPOSCHANGING_CALLBACK_ARGUMENTS)Arguments;
152 if (ArgumentLength != sizeof(SENDWINDOWPOSCHANGING_CALLBACK_ARGUMENTS))
154 DPRINT("Wrong length.\n");
155 return(STATUS_INFO_LENGTH_MISMATCH);
157 Proc = (WNDPROC)NtUserGetWindowLong(CallbackArgs->Wnd, GWL_WNDPROC, FALSE);
158 DPRINT("Proc %X\n", Proc);
159 /* Call the window procedure; notice kernel messages are always unicode. */
160 Result = CallWindowProcW(Proc, CallbackArgs->Wnd, WM_WINDOWPOSCHANGING, 0,
161 (LPARAM)&CallbackArgs->WindowPos);
162 DPRINT("Returning result %d.\n", Result);
163 return(ZwCallbackReturn(&Result, sizeof(LRESULT), STATUS_SUCCESS));
168 User32SendWINDOWPOSCHANGEDMessageForKernel(PVOID Arguments, ULONG ArgumentLength)
170 PSENDWINDOWPOSCHANGED_CALLBACK_ARGUMENTS CallbackArgs;
174 DPRINT("User32SendWINDOWPOSCHANGEDMessageForKernel.\n");
175 CallbackArgs = (PSENDWINDOWPOSCHANGED_CALLBACK_ARGUMENTS)Arguments;
176 if (ArgumentLength != sizeof(SENDWINDOWPOSCHANGED_CALLBACK_ARGUMENTS))
178 DPRINT("Wrong length.\n");
179 return(STATUS_INFO_LENGTH_MISMATCH);
181 Proc = (WNDPROC)NtUserGetWindowLong(CallbackArgs->Wnd, GWL_WNDPROC, FALSE);
182 DPRINT("Proc %X\n", Proc);
183 /* Call the window procedure; notice kernel messages are always unicode. */
184 Result = CallWindowProcW(Proc, CallbackArgs->Wnd, WM_WINDOWPOSCHANGED, 0,
185 (LPARAM)&CallbackArgs->WindowPos);
186 DPRINT("Returning result %d.\n", Result);
187 return(ZwCallbackReturn(&Result, sizeof(LRESULT), STATUS_SUCCESS));
192 User32SendSTYLECHANGINGMessageForKernel(PVOID Arguments, ULONG ArgumentLength)
194 PSENDSTYLECHANGING_CALLBACK_ARGUMENTS CallbackArgs;
198 DPRINT("User32SendSTYLECHANGINGMessageForKernel.\n");
199 CallbackArgs = (PSENDSTYLECHANGING_CALLBACK_ARGUMENTS)Arguments;
200 if (ArgumentLength != sizeof(SENDSTYLECHANGING_CALLBACK_ARGUMENTS))
202 DPRINT("Wrong length.\n");
203 return(STATUS_INFO_LENGTH_MISMATCH);
205 Proc = (WNDPROC)NtUserGetWindowLong(CallbackArgs->Wnd, GWL_WNDPROC, FALSE);
206 DPRINT("Proc %X\n", Proc);
207 /* Call the window procedure; notice kernel messages are always unicode. */
208 Result = CallWindowProcW(Proc, CallbackArgs->Wnd, WM_STYLECHANGING, CallbackArgs->WhichStyle,
209 (LPARAM)&CallbackArgs->Style);
210 DPRINT("Returning result %d.\n", Result);
211 return(ZwCallbackReturn(&Result, sizeof(LRESULT), STATUS_SUCCESS));
216 User32SendSTYLECHANGEDMessageForKernel(PVOID Arguments, ULONG ArgumentLength)
218 PSENDSTYLECHANGED_CALLBACK_ARGUMENTS CallbackArgs;
222 DPRINT("User32SendSTYLECHANGEDGMessageForKernel.\n");
223 CallbackArgs = (PSENDSTYLECHANGED_CALLBACK_ARGUMENTS)Arguments;
224 if (ArgumentLength != sizeof(SENDSTYLECHANGED_CALLBACK_ARGUMENTS))
226 DPRINT("Wrong length.\n");
227 return(STATUS_INFO_LENGTH_MISMATCH);
229 Proc = (WNDPROC)NtUserGetWindowLong(CallbackArgs->Wnd, GWL_WNDPROC, FALSE);
230 DPRINT("Proc %X\n", Proc);
231 /* Call the window procedure; notice kernel messages are always unicode. */
232 Result = CallWindowProcW(Proc, CallbackArgs->Wnd, WM_STYLECHANGED, CallbackArgs->WhichStyle,
233 (LPARAM)&CallbackArgs->Style);
234 DPRINT("Returning result %d.\n", Result);
235 return(ZwCallbackReturn(&Result, sizeof(LRESULT), STATUS_SUCCESS));
240 User32CallSendAsyncProcForKernel(PVOID Arguments, ULONG ArgumentLength)
242 PSENDASYNCPROC_CALLBACK_ARGUMENTS CallbackArgs;
244 DPRINT("User32CallSendAsyncProcKernel()\n");
245 CallbackArgs = (PSENDASYNCPROC_CALLBACK_ARGUMENTS)Arguments;
246 if (ArgumentLength != sizeof(WINDOWPROC_CALLBACK_ARGUMENTS))
248 return(STATUS_INFO_LENGTH_MISMATCH);
250 CallbackArgs->Callback(CallbackArgs->Wnd, CallbackArgs->Msg,
251 CallbackArgs->Context, CallbackArgs->Result);
252 return(STATUS_SUCCESS);
257 User32CallWindowProcFromKernel(PVOID Arguments, ULONG ArgumentLength)
259 PWINDOWPROC_CALLBACK_ARGUMENTS CallbackArgs;
262 CallbackArgs = (PWINDOWPROC_CALLBACK_ARGUMENTS)Arguments;
263 if (ArgumentLength != sizeof(WINDOWPROC_CALLBACK_ARGUMENTS))
265 return(STATUS_INFO_LENGTH_MISMATCH);
267 if (CallbackArgs->Proc == NULL)
269 CallbackArgs->Proc = (WNDPROC)NtUserGetWindowLong(CallbackArgs->Wnd, GWL_WNDPROC, FALSE);
271 Result = CallWindowProcW(CallbackArgs->Proc, CallbackArgs->Wnd,
272 CallbackArgs->Msg, CallbackArgs->wParam,
273 CallbackArgs->lParam);
274 return(ZwCallbackReturn(&Result, sizeof(LRESULT), STATUS_SUCCESS));
278 static void NC_AdjustRectOuter95 (LPRECT rect, DWORD style, BOOL menu, DWORD exStyle)
281 if(style & WS_ICONIC) return;
283 if ((exStyle & (WS_EX_STATICEDGE|WS_EX_DLGMODALFRAME)) ==
286 adjust = 1; /* for the outer frame always present */
291 if ((exStyle & WS_EX_DLGMODALFRAME) ||
292 (style & (WS_THICKFRAME|WS_DLGFRAME))) adjust = 2; /* outer */
294 if (style & WS_THICKFRAME)
295 adjust += ( GetSystemMetrics (SM_CXFRAME)
296 - GetSystemMetrics (SM_CXDLGFRAME)); /* The resize border */
297 if ((style & (WS_BORDER|WS_DLGFRAME)) ||
298 (exStyle & WS_EX_DLGMODALFRAME))
299 adjust++; /* The other border */
301 InflateRect (rect, adjust, adjust);
303 if ((style & WS_CAPTION) == WS_CAPTION)
305 if (exStyle & WS_EX_TOOLWINDOW)
306 rect->top -= GetSystemMetrics(SM_CYSMCAPTION);
308 rect->top -= GetSystemMetrics(SM_CYCAPTION);
310 if (menu) rect->top -= GetSystemMetrics(SM_CYMENU);
315 NC_AdjustRectInner95 (LPRECT rect, DWORD style, DWORD exStyle)
317 if(style & WS_ICONIC) return;
319 if (exStyle & WS_EX_CLIENTEDGE)
320 InflateRect(rect, GetSystemMetrics(SM_CXEDGE), GetSystemMetrics(SM_CYEDGE));
322 if (style & WS_VSCROLL)
324 if((exStyle & WS_EX_LEFTSCROLLBAR) != 0)
325 rect->left -= GetSystemMetrics(SM_CXVSCROLL);
327 rect->right += GetSystemMetrics(SM_CXVSCROLL);
329 if (style & WS_HSCROLL) rect->bottom += GetSystemMetrics(SM_CYHSCROLL);
337 AdjustWindowRectEx(LPRECT lpRect,
342 dwStyle &= (WS_DLGFRAME | WS_BORDER | WS_THICKFRAME | WS_CHILD);
343 dwExStyle &= (WS_EX_DLGMODALFRAME | WS_EX_CLIENTEDGE |
344 WS_EX_STATICEDGE | WS_EX_TOOLWINDOW);
345 if (dwExStyle & WS_EX_DLGMODALFRAME) dwStyle &= ~WS_THICKFRAME;
347 NC_AdjustRectOuter95( lpRect, dwStyle, bMenu, dwExStyle );
348 NC_AdjustRectInner95( lpRect, dwStyle, dwExStyle );
359 AdjustWindowRect(LPRECT lpRect,
363 return(AdjustWindowRectEx(lpRect, dwStyle, bMenu, 0));
371 AllowSetForegroundWindow(DWORD dwProcessId)
382 ArrangeIconicWindows(HWND hWnd)
393 BeginDeferWindowPos(int nNumWindows)
404 BringWindowToTop(HWND hWnd)
415 CascadeWindows(HWND hwndParent,
430 ChildWindowFromPoint(HWND hWndParent,
442 ChildWindowFromPointEx(HWND hwndParent,
455 CloseWindow(HWND hWnd)
457 SendMessageA(hWnd, WM_SYSCOMMAND, SC_CLOSE, 0);
459 return (WINBOOL)(hWnd);
466 CreateWindowExA(DWORD dwExStyle,
479 UNICODE_STRING WindowName;
480 UNICODE_STRING ClassName;
486 DbgPrint("[window] CreateWindowExA style %d, exstyle %d, parent %d\n", dwStyle, dwExStyle, hWndParent);
489 /* Register built-in controls if not already done */
490 if (! ControlsInitCalled)
493 ControlsInitCalled = TRUE;
496 if (IS_ATOM(lpClassName))
498 RtlInitUnicodeString(&ClassName, NULL);
499 ClassName.Buffer = (LPWSTR)lpClassName;
503 if (!RtlCreateUnicodeStringFromAsciiz(&(ClassName), (PCSZ)lpClassName))
505 SetLastError(ERROR_OUTOFMEMORY);
510 if (!RtlCreateUnicodeStringFromAsciiz(&WindowName, (PCSZ)lpWindowName))
512 if (!IS_ATOM(lpClassName))
514 RtlFreeUnicodeString(&ClassName);
516 SetLastError(ERROR_OUTOFMEMORY);
520 /* Fixup default coordinates. */
522 if (x == (LONG) CW_USEDEFAULT || nWidth == (LONG) CW_USEDEFAULT)
524 if (dwStyle & (WS_CHILD | WS_POPUP))
526 if (x == (LONG) CW_USEDEFAULT)
530 if (nWidth == (LONG) CW_USEDEFAULT)
532 nWidth = nHeight = 0;
539 GetStartupInfoA(&info);
541 if (x == (LONG) CW_USEDEFAULT)
543 if (y != (LONG) CW_USEDEFAULT)
547 x = (info.dwFlags & STARTF_USEPOSITION) ? info.dwX : 0;
548 y = (info.dwFlags & STARTF_USEPOSITION) ? info.dwY : 0;
551 if (nWidth == (LONG) CW_USEDEFAULT)
553 if (info.dwFlags & STARTF_USESIZE)
555 nWidth = info.dwXSize;
556 nHeight = info.dwYSize;
562 SystemParametersInfoA(SPI_GETWORKAREA, 0, &r, 0);
563 nWidth = (((r.right - r.left) * 3) / 4) - x;
564 nHeight = (((r.bottom - r.top) * 3) / 4) - y;
570 if(!hMenu && (dwStyle & (WS_OVERLAPPEDWINDOW | WS_POPUP)))
572 wce.cbSize = sizeof(WNDCLASSEXA);
573 if(GetClassInfoExA(hInstance, lpClassName, &wce) && wce.lpszMenuName)
575 hMenu = LoadMenuA(hInstance, wce.lpszMenuName);
579 Handle = NtUserCreateWindowEx(dwExStyle,
594 DbgPrint("[window] NtUserCreateWindowEx() == %d\n", Handle);
597 RtlFreeUnicodeString(&WindowName);
599 if (!IS_ATOM(lpClassName))
601 RtlFreeUnicodeString(&ClassName);
612 CreateWindowExW(DWORD dwExStyle,
614 LPCWSTR lpWindowName,
625 UNICODE_STRING WindowName;
626 UNICODE_STRING ClassName;
631 /* Register built-in controls if not already done */
632 if (! ControlsInitCalled)
635 ControlsInitCalled = TRUE;
638 if (IS_ATOM(lpClassName))
640 RtlInitUnicodeString(&ClassName, NULL);
641 ClassName.Buffer = (LPWSTR)lpClassName;
645 RtlInitUnicodeString(&ClassName, lpClassName);
648 RtlInitUnicodeString(&WindowName, lpWindowName);
650 /* Fixup default coordinates. */
652 if (x == (LONG) CW_USEDEFAULT || nWidth == (LONG) CW_USEDEFAULT)
654 if (dwStyle & (WS_CHILD | WS_POPUP))
656 if (x == (LONG) CW_USEDEFAULT)
660 if (nWidth == (LONG) CW_USEDEFAULT)
662 nWidth = nHeight = 0;
669 GetStartupInfoW(&info);
671 if (x == (LONG) CW_USEDEFAULT)
673 if (y != (LONG) CW_USEDEFAULT)
677 x = (info.dwFlags & STARTF_USEPOSITION) ? info.dwX : 0;
678 y = (info.dwFlags & STARTF_USEPOSITION) ? info.dwY : 0;
681 if (nWidth == (LONG) CW_USEDEFAULT)
683 if (info.dwFlags & STARTF_USESIZE)
685 nWidth = info.dwXSize;
686 nHeight = info.dwYSize;
692 SystemParametersInfoW(SPI_GETWORKAREA, 0, &r, 0);
693 nWidth = (((r.right - r.left) * 3) / 4) - x;
694 nHeight = (((r.bottom - r.top) * 3) / 4) - y;
700 if(!hMenu && (dwStyle & (WS_OVERLAPPEDWINDOW | WS_POPUP)))
702 wce.cbSize = sizeof(WNDCLASSEXW);
703 if(GetClassInfoExW(hInstance, lpClassName, &wce) && wce.lpszMenuName)
705 hMenu = LoadMenuW(hInstance, wce.lpszMenuName);
709 Handle = NtUserCreateWindowEx(dwExStyle,
731 DeferWindowPos(HDWP hWinPosInfo,
733 HWND hWndInsertAfter,
740 return NtUserDeferWindowPos(hWinPosInfo, hWnd, hWndInsertAfter, x, y, cx, cy, uFlags);
748 DestroyWindow(HWND hWnd)
750 return NtUserDestroyWindow(hWnd);
758 EndDeferWindowPos(HDWP hWinPosInfo)
769 GetDesktopWindow(VOID)
771 return NtUserGetDesktopWindow();
779 GetForegroundWindow(VOID)
791 ENUMWINDOWSPROC lpfn,
796 DWORD i, dwCount = 0;
802 SetLastError ( ERROR_INVALID_PARAMETER );
806 /* FIXME instead of always making two calls, should we use some
807 sort of persistent buffer and only grow it ( requiring a 2nd
808 call ) when the buffer wasn't already big enough? */
809 /* first get how many window entries there are */
811 dwCount = NtUserBuildHwndList (
812 hDesktop, hWndparent, bChildren, dwThreadId, lParam, NULL, 0 );
813 if ( !dwCount || GetLastError() )
816 /* allocate buffer to receive HWND handles */
817 hHeap = GetProcessHeap();
818 pHwnd = HeapAlloc ( hHeap, 0, sizeof(HWND)*(dwCount+1) );
821 SetLastError ( ERROR_NOT_ENOUGH_MEMORY );
825 /* now call kernel again to fill the buffer this time */
826 dwCount = NtUserBuildHwndList (
827 hDesktop, hWndparent, bChildren, dwThreadId, lParam, pHwnd, dwCount );
828 if ( !dwCount || GetLastError() )
831 HeapFree ( hHeap, 0, pHwnd );
835 /* call the user's callback function until we're done or
836 they tell us to quit */
837 for ( i = 0; i < dwCount; i++ )
839 /* FIXME I'm only getting NULLs from Thread Enumeration, and it's
840 * probably because I'm not doing it right in NtUserBuildHwndList.
841 * Once that's fixed, we shouldn't have to check for a NULL HWND
844 if ( !(ULONG)pHwnd[i] ) /* don't enumerate a NULL HWND */
846 if ( !(*lpfn)( pHwnd[i], lParam ) )
850 HeapFree ( hHeap, 0, pHwnd );
862 ENUMWINDOWSPROC lpEnumFunc,
866 hWndParent = GetDesktopWindow();
867 return User32EnumWindows ( NULL, hWndParent, lpEnumFunc, lParam, 0, FALSE );
876 EnumThreadWindows(DWORD dwThreadId,
877 ENUMWINDOWSPROC lpfn,
881 dwThreadId = GetCurrentThreadId();
882 return User32EnumWindows ( NULL, NULL, lpfn, lParam, dwThreadId, FALSE );
890 EnumWindows(ENUMWINDOWSPROC lpEnumFunc,
893 return User32EnumWindows ( NULL, NULL, lpEnumFunc, lParam, 0, FALSE );
904 ENUMWINDOWSPROC lpfn,
907 return User32EnumWindows ( hDesktop, NULL, lpfn, lParam, 0, FALSE );
915 FindWindowExA(HWND hwndParent,
929 FindWindowExW(HWND hwndParent,
934 UNICODE_STRING ucClassName;
935 UNICODE_STRING ucWindowName;
937 if (IS_ATOM(lpszClass))
939 RtlInitUnicodeString(&ucClassName, NULL);
940 ucClassName.Buffer = (LPWSTR)lpszClass;
944 RtlInitUnicodeString(&ucClassName, lpszClass);
947 // Window names can't be atoms, and if lpszWindow = NULL,
948 // RtlInitUnicodeString will clear it
950 RtlInitUnicodeString(&ucWindowName, lpszWindow);
953 return NtUserFindWindowEx(hwndParent, hwndChildAfter, &ucClassName, &ucWindowName);
961 FindWindowA(LPCSTR lpClassName, LPCSTR lpWindowName)
963 //FIXME: FindWindow does not search children, but FindWindowEx does.
964 // what should we do about this?
965 return FindWindowExA (NULL, NULL, lpClassName, lpWindowName);
973 FindWindowW(LPCWSTR lpClassName, LPCWSTR lpWindowName)
977 There was a FIXME here earlier, but I think it is just a documentation unclarity.
979 FindWindow only searches top level windows. What they mean is that child
980 windows of other windows than the desktop can be searched.
981 FindWindowExW never does a recursive search.
986 return FindWindowExW (NULL, NULL, lpClassName, lpWindowName);
995 GetAltTabInfoA(HWND hwnd,
1010 GetAltTabInfoW(HWND hwnd,
1025 GetAncestor(HWND hwnd, UINT gaFlags)
1027 return(NtUserGetAncestor(hwnd, gaFlags));
1035 GetClientRect(HWND hWnd, LPRECT lpRect)
1037 return(NtUserGetClientRect(hWnd, lpRect));
1045 GetGUIThreadInfo(DWORD idThread,
1046 LPGUITHREADINFO lpgui)
1057 GetLastActivePopup(HWND hWnd)
1059 return NtUserGetLastActivePopup(hWnd);
1067 GetParent(HWND hWnd)
1069 return NtUserGetParent(hWnd);
1077 GetProcessDefaultLayout(DWORD *pdwDefaultLayout)
1088 GetTitleBarInfo(HWND hwnd,
1100 GetWindow(HWND hWnd,
1103 return NtUserGetWindow(hWnd, uCmd);
1111 GetTopWindow(HWND hWnd)
1113 if (!hWnd) hWnd = GetDesktopWindow();
1114 return GetWindow( hWnd, GW_CHILD );
1122 GetWindowInfo(HWND hwnd,
1134 GetWindowModuleFileName(HWND hwnd,
1136 UINT cchFileNameMax)
1147 GetWindowModuleFileNameA(HWND hwnd,
1149 UINT cchFileNameMax)
1160 GetWindowModuleFileNameW(HWND hwnd,
1161 LPWSTR lpszFileName,
1162 UINT cchFileNameMax)
1173 GetWindowPlacement(HWND hWnd,
1174 WINDOWPLACEMENT *lpwndpl)
1185 GetWindowRect(HWND hWnd,
1188 return(NtUserGetWindowRect(hWnd, lpRect));
1196 GetWindowTextA(HWND hWnd, LPSTR lpString, int nMaxCount)
1198 return(SendMessageA(hWnd, WM_GETTEXT, nMaxCount, (LPARAM)lpString));
1206 GetWindowTextLengthA(HWND hWnd)
1208 return(SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0));
1216 GetWindowTextLengthW(HWND hWnd)
1218 return(SendMessageW(hWnd, WM_GETTEXTLENGTH, 0, 0));
1231 return(SendMessageW(hWnd, WM_GETTEXT, nMaxCount, (LPARAM)lpString));
1235 GetWindowThreadProcessId(HWND hWnd,
1236 LPDWORD lpdwProcessId)
1238 return NtUserGetWindowThreadProcessId(hWnd, lpdwProcessId);
1246 IsChild(HWND hWndParent,
1250 return ((HWND)NtUserGetWindowLong(hWnd, GWL_HWNDPARENT, FALSE)) == hWndParent;
1260 return (NtUserGetWindowLong( hWnd, GWL_STYLE, FALSE) & WS_MINIMIZE) != 0;
1270 DWORD WndProc = NtUserGetWindowLong(hWnd, GWL_WNDPROC, FALSE);
1271 return (0 != WndProc || ERROR_INVALID_HANDLE != GetLastError());
1279 IsWindowUnicode(HWND hWnd)
1281 return (WINBOOL)NtUserCallOneParam((DWORD)hWnd,ONEPARAM_ROUTINE_ISWINDOWUNICODE);
1289 IsWindowVisible(HWND hWnd)
1291 while (NtUserGetWindowLong(hWnd, GWL_STYLE, FALSE) & WS_CHILD)
1293 if (!(NtUserGetWindowLong(hWnd, GWL_STYLE, FALSE) & WS_VISIBLE))
1297 hWnd = GetAncestor(hWnd, GA_PARENT);
1299 return(NtUserGetWindowLong(hWnd, GWL_STYLE, FALSE) & WS_VISIBLE);
1311 // AG: I don't know if child windows are affected if the parent is
1312 // disabled. I think they stop processing messages but stay appearing
1315 return (! (NtUserGetWindowLong(hWnd, GWL_STYLE, FALSE) & WS_DISABLED));
1325 return NtUserGetWindowLong(hWnd, GWL_STYLE, FALSE) & WS_MAXIMIZE;
1333 LockSetForegroundWindow(UINT uLockCode)
1344 MoveWindow(HWND hWnd,
1351 return NtUserMoveWindow(hWnd, X, Y, nWidth, nHeight, bRepaint);
1359 AnimateWindow(HWND hwnd,
1363 /* FIXME Add animation code */
1365 /* If trying to show/hide and it's already *
1366 * shown/hidden or invalid window, fail with *
1367 * invalid parameter */
1370 visible = IsWindowVisible(hwnd);
1371 // if(!IsWindow(hwnd) ||
1372 // (visible && !(dwFlags & AW_HIDE)) ||
1373 // (!visible && (dwFlags & AW_HIDE)))
1375 SetLastError(ERROR_INVALID_PARAMETER);
1379 // ShowWindow(hwnd, (dwFlags & AW_HIDE) ? SW_HIDE : ((dwFlags & AW_ACTIVATE) ? SW_SHOW : SW_SHOWNA));
1391 if (! NtUserGetWindowLong(hWnd, GWL_STYLE, FALSE) & WS_MINIMIZE)
1393 // Not minimized - error?
1397 if (! SendMessageA(hWnd, WM_QUERYOPEN, 0, 0))
1399 // Window doesn't want to be opened - error?
1403 // Now we need to do the actual opening of the window, which is something
1404 // I'll leave to someone more capable :)
1415 RealChildWindowFromPoint(HWND hwndParent,
1416 POINT ptParentClientCoords)
1426 SetForegroundWindow(HWND hWnd)
1437 SetLayeredWindowAttributes(HWND hwnd,
1451 SetParent(HWND hWndChild,
1454 return NtUserSetParent(hWndChild, hWndNewParent);
1462 SetProcessDefaultLayout(DWORD dwDefaultLayout)
1473 SetWindowPlacement(HWND hWnd,
1474 CONST WINDOWPLACEMENT *lpwndpl)
1485 SetWindowPos(HWND hWnd,
1486 HWND hWndInsertAfter,
1493 return NtUserSetWindowPos(hWnd,hWndInsertAfter, X, Y, cx, cy, uFlags);
1501 SetWindowTextA(HWND hWnd,
1504 return SendMessageA(hWnd, WM_SETTEXT, 0, (LPARAM)lpString);
1512 SetWindowTextW(HWND hWnd,
1515 return SendMessageW(hWnd, WM_SETTEXT, 0, (LPARAM)lpString);
1523 ShowOwnedPopups(HWND hWnd,
1535 ShowWindow(HWND hWnd,
1538 return NtUserShowWindow(hWnd, nCmdShow);
1546 ShowWindowAsync(HWND hWnd,
1558 TileWindows(HWND hwndParent,
1573 UpdateLayeredWindow(HWND hwnd,
1580 BLENDFUNCTION *pblend,
1592 WindowFromPoint(POINT Point)
1603 MapWindowPoints(HWND hWndFrom, HWND hWndTo, LPPOINT lpPoints, UINT cPoints)
1605 POINT FromOffset, ToOffset;
1609 NtUserGetClientOrigin(hWndFrom, &FromOffset);
1610 NtUserGetClientOrigin(hWndTo, &ToOffset);
1611 XMove = FromOffset.x - ToOffset.x;
1612 YMove = FromOffset.y - ToOffset.y;
1614 for (i = 0; i < cPoints; i++)
1616 lpPoints[i].x += XMove;
1617 lpPoints[i].y += YMove;
1619 return(MAKELONG(LOWORD(XMove), LOWORD(YMove)));
1627 ScreenToClient(HWND hWnd, LPPOINT lpPoint)
1629 return(MapWindowPoints(NULL, hWnd, lpPoint, 1));
1637 ClientToScreen(HWND hWnd, LPPOINT lpPoint)
1639 return (MapWindowPoints( hWnd, NULL, lpPoint, 1 ));
1648 SetWindowContextHelpId(HWND hwnd,
1649 DWORD dwContextHelpId)
1651 return (WINBOOL)NtUserCallTwoParam((DWORD)hwnd, (DWORD)dwContextHelpId,
1652 TWOPARAM_ROUTINE_SETWNDCONTEXTHLPID);
1661 GetWindowContextHelpId(HWND hwnd)
1663 return NtUserCallOneParam((DWORD)hwnd, ONEPARAM_ROUTINE_GETWNDCONTEXTHLPID);
1671 InternalGetWindowText(HWND hWnd, LPWSTR lpString, int nMaxCount)
1675 if(lpString && (nMaxCount > 0))
1677 lps = RtlAllocateHeap(RtlGetProcessHeap(), 0, nMaxCount * sizeof(WCHAR));
1680 SetLastError(ERROR_OUTOFMEMORY);
1685 res = NtUserInternalGetWindowText(hWnd, lps, nMaxCount);
1689 RtlCopyMemory(lpString, lps, res * sizeof(WCHAR));
1690 lpString[res] = (WCHAR)"\0"; /* null-terminate the string */
1692 RtlFreeHeap(RtlGetProcessHeap(), 0, lps);
1703 IsHungAppWindow(HWND hwnd)
1705 /* FIXME: ReactOS doesnt identify hung app windows yet */
1714 SetLastErrorEx(DWORD dwErrCode, DWORD dwType)
1716 SetLastError(dwErrCode);
1730 SetLastError(ERROR_INVALID_WINDOW_HANDLE);
1735 SetLastError(ERROR_INVALID_MENU_HANDLE);
1738 return NtUserSetSystemMenu(hwnd, hMenu);
1752 SetLastError(ERROR_INVALID_WINDOW_HANDLE);
1755 return NtUserGetSystemMenu(hWnd, bRevert);