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>
20 /* FUNCTIONS *****************************************************************/
22 WinHasThickFrameStyle(ULONG Style, ULONG ExStyle)
24 return((Style & WS_THICKFRAME) &&
25 (!((Style & (WS_DLGFRAME | WS_BORDER)) == WS_DLGFRAME)));
29 User32SendNCCALCSIZEMessageForKernel(PVOID Arguments, ULONG ArgumentLength)
31 PSENDNCCALCSIZEMESSAGE_CALLBACK_ARGUMENTS CallbackArgs;
32 SENDNCCALCSIZEMESSAGE_CALLBACK_RESULT Result;
35 DbgPrint("User32SendNCCALCSIZEMessageForKernel.\n");
36 CallbackArgs = (PSENDNCCALCSIZEMESSAGE_CALLBACK_ARGUMENTS)Arguments;
37 if (ArgumentLength != sizeof(SENDNCCALCSIZEMESSAGE_CALLBACK_ARGUMENTS))
39 DbgPrint("Wrong length.\n");
40 return(STATUS_INFO_LENGTH_MISMATCH);
42 Proc = (WNDPROC)GetWindowLongW(CallbackArgs->Wnd, GWL_WNDPROC);
43 DbgPrint("Proc %X\n", Proc);
44 /* Call the window procedure; notice kernel messages are always unicode. */
45 if (CallbackArgs->Validate)
47 Result.Result = CallWindowProcW(Proc, CallbackArgs->Wnd, WM_NCCALCSIZE,
49 (LPARAM)&CallbackArgs->Params);
50 Result.Params = CallbackArgs->Params;
54 Result.Result = CallWindowProcW(Proc, CallbackArgs->Wnd, WM_NCCALCSIZE,
55 FALSE, (LPARAM)&CallbackArgs->Rect);
56 Result.Rect = CallbackArgs->Rect;
58 DbgPrint("Returning result %d.\n", Result);
59 return(ZwCallbackReturn(&Result, sizeof(Result), STATUS_SUCCESS));
63 User32SendGETMINMAXINFOMessageForKernel(PVOID Arguments, ULONG ArgumentLength)
65 PSENDGETMINMAXINFO_CALLBACK_ARGUMENTS CallbackArgs;
66 SENDGETMINMAXINFO_CALLBACK_RESULT Result;
69 DbgPrint("User32SendGETMINAXINFOMessageForKernel.\n");
70 CallbackArgs = (PSENDGETMINMAXINFO_CALLBACK_ARGUMENTS)Arguments;
71 if (ArgumentLength != sizeof(SENDGETMINMAXINFO_CALLBACK_ARGUMENTS))
73 DbgPrint("Wrong length.\n");
74 return(STATUS_INFO_LENGTH_MISMATCH);
76 Proc = (WNDPROC)GetWindowLongW(CallbackArgs->Wnd, GWL_WNDPROC);
77 DbgPrint("Proc %X\n", Proc);
78 /* Call the window procedure; notice kernel messages are always unicode. */
79 Result.Result = CallWindowProcW(Proc, CallbackArgs->Wnd, WM_GETMINMAXINFO,
80 0, (LPARAM)&CallbackArgs->MinMaxInfo);
81 Result.MinMaxInfo = CallbackArgs->MinMaxInfo;
82 DbgPrint("Returning result %d.\n", Result);
83 return(ZwCallbackReturn(&Result, sizeof(Result), STATUS_SUCCESS));
87 User32SendCREATEMessageForKernel(PVOID Arguments, ULONG ArgumentLength)
89 PSENDCREATEMESSAGE_CALLBACK_ARGUMENTS CallbackArgs;
93 DbgPrint("User32SendCREATEMessageForKernel.\n");
94 CallbackArgs = (PSENDCREATEMESSAGE_CALLBACK_ARGUMENTS)Arguments;
95 if (ArgumentLength != sizeof(SENDCREATEMESSAGE_CALLBACK_ARGUMENTS))
97 DbgPrint("Wrong length.\n");
98 return(STATUS_INFO_LENGTH_MISMATCH);
100 Proc = (WNDPROC)GetWindowLongW(CallbackArgs->Wnd, GWL_WNDPROC);
101 DbgPrint("Proc %X\n", Proc);
102 /* Call the window procedure; notice kernel messages are always unicode. */
103 Result = CallWindowProcW(Proc, CallbackArgs->Wnd, WM_CREATE, 0,
104 (LPARAM)&CallbackArgs->CreateStruct);
105 DbgPrint("Returning result %d.\n", Result);
106 return(ZwCallbackReturn(&Result, sizeof(LRESULT), STATUS_SUCCESS));
110 User32SendNCCREATEMessageForKernel(PVOID Arguments, ULONG ArgumentLength)
112 PSENDNCCREATEMESSAGE_CALLBACK_ARGUMENTS CallbackArgs;
116 DbgPrint("User32SendNCCREATEMessageForKernel.\n");
117 CallbackArgs = (PSENDNCCREATEMESSAGE_CALLBACK_ARGUMENTS)Arguments;
118 if (ArgumentLength != sizeof(SENDNCCREATEMESSAGE_CALLBACK_ARGUMENTS))
120 DbgPrint("Wrong length.\n");
121 return(STATUS_INFO_LENGTH_MISMATCH);
123 Proc = (WNDPROC)GetWindowLongW(CallbackArgs->Wnd, GWL_WNDPROC);
124 DbgPrint("Proc %X\n", Proc);
125 /* Call the window procedure; notice kernel messages are always unicode. */
126 Result = CallWindowProcW(Proc, CallbackArgs->Wnd, WM_NCCREATE, 0,
127 (LPARAM)&CallbackArgs->CreateStruct);
128 DbgPrint("Returning result %d.\n", Result);
129 return(ZwCallbackReturn(&Result, sizeof(LRESULT), STATUS_SUCCESS));
133 User32CallSendAsyncProcForKernel(PVOID Arguments, ULONG ArgumentLength)
135 PSENDASYNCPROC_CALLBACK_ARGUMENTS CallbackArgs;
137 DbgPrint("User32CallSendAsyncProcKernel()\n");
138 CallbackArgs = (PSENDASYNCPROC_CALLBACK_ARGUMENTS)Arguments;
139 if (ArgumentLength != sizeof(WINDOWPROC_CALLBACK_ARGUMENTS))
141 return(STATUS_INFO_LENGTH_MISMATCH);
143 CallbackArgs->Callback(CallbackArgs->Wnd, CallbackArgs->Msg,
144 CallbackArgs->Context, CallbackArgs->Result);
145 return(STATUS_SUCCESS);
149 User32CallWindowProcFromKernel(PVOID Arguments, ULONG ArgumentLength)
151 PWINDOWPROC_CALLBACK_ARGUMENTS CallbackArgs;
154 CallbackArgs = (PWINDOWPROC_CALLBACK_ARGUMENTS)Arguments;
155 if (ArgumentLength != sizeof(WINDOWPROC_CALLBACK_ARGUMENTS))
157 return(STATUS_INFO_LENGTH_MISMATCH);
159 if (CallbackArgs->Proc == NULL)
161 CallbackArgs->Proc = (WNDPROC)GetWindowLong(CallbackArgs->Wnd,
164 Result = CallWindowProcW(CallbackArgs->Proc, CallbackArgs->Wnd,
165 CallbackArgs->Msg, CallbackArgs->wParam,
166 CallbackArgs->lParam);
167 return(ZwCallbackReturn(&Result, sizeof(LRESULT), STATUS_SUCCESS));
170 static void NC_AdjustRectOuter95 (LPRECT rect, DWORD style, BOOL menu, DWORD exStyle)
173 if(style & WS_ICONIC) return;
175 if ((exStyle & (WS_EX_STATICEDGE|WS_EX_DLGMODALFRAME)) ==
178 adjust = 1; /* for the outer frame always present */
183 if ((exStyle & WS_EX_DLGMODALFRAME) ||
184 (style & (WS_THICKFRAME|WS_DLGFRAME))) adjust = 2; /* outer */
186 if (style & WS_THICKFRAME)
187 adjust += ( GetSystemMetrics (SM_CXFRAME)
188 - GetSystemMetrics (SM_CXDLGFRAME)); /* The resize border */
189 if ((style & (WS_BORDER|WS_DLGFRAME)) ||
190 (exStyle & WS_EX_DLGMODALFRAME))
191 adjust++; /* The other border */
193 InflateRect (rect, adjust, adjust);
195 if ((style & WS_CAPTION) == WS_CAPTION)
197 if (exStyle & WS_EX_TOOLWINDOW)
198 rect->top -= GetSystemMetrics(SM_CYSMCAPTION);
200 rect->top -= GetSystemMetrics(SM_CYCAPTION);
202 if (menu) rect->top -= GetSystemMetrics(SM_CYMENU);
206 NC_AdjustRectInner95 (LPRECT rect, DWORD style, DWORD exStyle)
208 if(style & WS_ICONIC) return;
210 if (exStyle & WS_EX_CLIENTEDGE)
211 InflateRect(rect, GetSystemMetrics(SM_CXEDGE), GetSystemMetrics(SM_CYEDGE));
213 if (style & WS_VSCROLL)
215 if((exStyle & WS_EX_LEFTSCROLLBAR) != 0)
216 rect->left -= GetSystemMetrics(SM_CXVSCROLL);
218 rect->right += GetSystemMetrics(SM_CXVSCROLL);
220 if (style & WS_HSCROLL) rect->bottom += GetSystemMetrics(SM_CYHSCROLL);
224 AdjustWindowRect(LPRECT lpRect,
228 return(AdjustWindowRectEx(lpRect, dwStyle, bMenu, 0));
232 AdjustWindowRectEx(LPRECT lpRect,
237 dwStyle &= (WS_DLGFRAME | WS_BORDER | WS_THICKFRAME | WS_CHILD);
238 dwExStyle &= (WS_EX_DLGMODALFRAME | WS_EX_CLIENTEDGE |
239 WS_EX_STATICEDGE | WS_EX_TOOLWINDOW);
240 if (dwExStyle & WS_EX_DLGMODALFRAME) dwStyle &= ~WS_THICKFRAME;
242 NC_AdjustRectOuter95( lpRect, dwStyle, bMenu, dwExStyle );
243 NC_AdjustRectInner95( lpRect, dwStyle, dwExStyle );
250 AllowSetForegroundWindow(DWORD dwProcessId)
256 AnimateWindow(HWND hwnd,
264 ArrangeIconicWindows(HWND hWnd)
270 BeginDeferWindowPos(int nNumWindows)
276 BringWindowToTop(HWND hWnd)
282 CascadeWindows(HWND hwndParent,
292 ChildWindowFromPoint(HWND hWndParent,
299 ChildWindowFromPointEx(HWND hwndParent,
307 CloseWindow(HWND hWnd)
309 SendMessageA(hWnd, WM_CLOSE, 0, 0);
310 SendMessageA(hWnd, WM_SYSCOMMAND, SC_CLOSE, 0);
312 return (WINBOOL)(hWnd);
316 CreateWindowExA(DWORD dwExStyle,
329 UNICODE_STRING WindowName;
330 UNICODE_STRING ClassName;
334 if (IS_ATOM(lpClassName))
336 RtlInitUnicodeString(&ClassName, NULL);
337 ClassName.Buffer = (LPWSTR)lpClassName;
341 if (!RtlCreateUnicodeStringFromAsciiz(&(ClassName), (PCSZ)lpClassName))
343 SetLastError(ERROR_OUTOFMEMORY);
348 if (!RtlCreateUnicodeStringFromAsciiz(&WindowName, (PCSZ)lpWindowName))
350 if (!IS_ATOM(lpClassName))
352 RtlFreeUnicodeString(&ClassName);
354 SetLastError(ERROR_OUTOFMEMORY);
358 /* Fixup default coordinates. */
360 if (x == (LONG) CW_USEDEFAULT || nWidth == (LONG) CW_USEDEFAULT)
362 if (dwStyle & (WS_CHILD | WS_POPUP))
364 if (x == (LONG) CW_USEDEFAULT)
368 if (nWidth == (LONG) CW_USEDEFAULT)
370 nWidth = nHeight = 0;
377 GetStartupInfoA(&info);
379 if (x == (LONG) CW_USEDEFAULT)
381 if (y != (LONG) CW_USEDEFAULT)
385 x = (info.dwFlags & STARTF_USEPOSITION) ? info.dwX : 0;
386 y = (info.dwFlags & STARTF_USEPOSITION) ? info.dwY : 0;
389 if (nWidth == (LONG) CW_USEDEFAULT)
391 if (info.dwFlags & STARTF_USESIZE)
393 nWidth = info.dwXSize;
394 nHeight = info.dwYSize;
400 SystemParametersInfoA(SPI_GETWORKAREA, 0, &r, 0);
401 nWidth = (((r.right - r.left) * 3) / 4) - x;
402 nHeight = (((r.bottom - r.top) * 3) / 4) - y;
408 Handle = NtUserCreateWindowEx(dwExStyle,
422 RtlFreeUnicodeString(&WindowName);
424 if (!IS_ATOM(lpClassName))
426 RtlFreeUnicodeString(&ClassName);
433 CreateWindowExW(DWORD dwExStyle,
435 LPCWSTR lpWindowName,
446 UNICODE_STRING WindowName;
447 UNICODE_STRING ClassName;
451 if (IS_ATOM(lpClassName))
453 RtlInitUnicodeString(&ClassName, NULL);
454 ClassName.Buffer = (LPWSTR)lpClassName;
458 RtlInitUnicodeString(&ClassName, lpClassName);
461 RtlInitUnicodeString(&WindowName, lpWindowName);
463 /* Fixup default coordinates. */
465 if (x == (LONG) CW_USEDEFAULT || nWidth == (LONG) CW_USEDEFAULT)
467 if (dwStyle & (WS_CHILD | WS_POPUP))
469 if (x == (LONG) CW_USEDEFAULT)
473 if (nWidth == (LONG) CW_USEDEFAULT)
475 nWidth = nHeight = 0;
482 GetStartupInfoW(&info);
484 if (x == (LONG) CW_USEDEFAULT)
486 if (y != (LONG) CW_USEDEFAULT)
490 x = (info.dwFlags & STARTF_USEPOSITION) ? info.dwX : 0;
491 y = (info.dwFlags & STARTF_USEPOSITION) ? info.dwY : 0;
494 if (nWidth == (LONG) CW_USEDEFAULT)
496 if (info.dwFlags & STARTF_USESIZE)
498 nWidth = info.dwXSize;
499 nHeight = info.dwYSize;
505 SystemParametersInfoW(SPI_GETWORKAREA, 0, &r, 0);
506 nWidth = (((r.right - r.left) * 3) / 4) - x;
507 nHeight = (((r.bottom - r.top) * 3) / 4) - y;
513 Handle = NtUserCreateWindowEx(dwExStyle,
531 DeferWindowPos(HDWP hWinPosInfo,
533 HWND hWndInsertAfter,
544 DestroyWindow(HWND hWnd)
546 SendMessageW(hWnd, WM_DESTROY, 0, 0);
547 SendMessageW(hWnd, WM_NCDESTROY, 0, 0);
549 return NtUserDestroyWindow(hWnd);
553 EndDeferWindowPos(HDWP hWinPosInfo)
559 EnumChildWindows(HWND hWndParent,
560 ENUMWINDOWSPROC lpEnumFunc,
567 EnumThreadWindows(DWORD dwThreadId,
568 ENUMWINDOWSPROC lpfn,
575 EnumWindows(ENUMWINDOWSPROC lpEnumFunc,
582 FindWindowA(LPCSTR lpClassName, LPCSTR lpWindowName)
584 //FIXME: FindWindow does not search children, but FindWindowEx does.
585 // what should we do about this?
586 return FindWindowExA (NULL, NULL, lpClassName, lpWindowName);
590 FindWindowExA(HWND hwndParent,
599 FindWindowW(LPCWSTR lpClassName, LPCWSTR lpWindowName)
601 //FIXME: FindWindow does not search children, but FindWindowEx does.
602 // what should we do about this?
603 return FindWindowExW (NULL, NULL, lpClassName, lpWindowName);
607 FindWindowExW(HWND hwndParent,
616 GetAltTabInfo(HWND hwnd,
626 GetAltTabInfoA(HWND hwnd,
636 GetAltTabInfoW(HWND hwnd,
646 GetAncestor(HWND hwnd, UINT gaFlags)
648 return(NtUserGetAncestor(hwnd, gaFlags));
652 GetClientRect(HWND hWnd, LPRECT lpRect)
654 return(NtUserGetClientRect(hWnd, lpRect));
658 GetDesktopWindow(VOID)
664 GetForegroundWindow(VOID)
670 GetGUIThreadInfo(DWORD idThread,
671 LPGUITHREADINFO lpgui)
677 GetLastActivePopup(HWND hWnd)
685 return NtUserGetAncestor(hWnd, GA_PARENT);
689 GetProcessDefaultLayout(DWORD *pdwDefaultLayout)
695 GetTitleBarInfo(HWND hwnd,
702 GetTopWindow(HWND hWnd)
715 GetWindowInfo(HWND hwnd,
722 GetWindowModuleFileName(HWND hwnd,
730 GetWindowModuleFileNameA(HWND hwnd,
738 GetWindowModuleFileNameW(HWND hwnd,
746 GetWindowPlacement(HWND hWnd,
747 WINDOWPLACEMENT *lpwndpl)
753 GetWindowRect(HWND hWnd,
756 return(NtUserGetWindowRect(hWnd, lpRect));
760 GetWindowTextA(HWND hWnd, LPSTR lpString, int nMaxCount)
762 return(SendMessageA(hWnd, WM_GETTEXT, nMaxCount, (LPARAM)lpString));
766 GetWindowTextLengthA(HWND hWnd)
768 return(SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0));
772 GetWindowTextLengthW(HWND hWnd)
778 GetWindowTextW(HWND hWnd,
786 GetWindowThreadProcessId(HWND hWnd,
787 LPDWORD lpdwProcessId)
793 IsChild(HWND hWndParent,
812 IsWindowUnicode(HWND hWnd)
818 IsWindowVisible(HWND hWnd)
820 while (GetWindowLong(hWnd, GWL_STYLE) & WS_CHILD)
822 if (!(GetWindowLong(hWnd, GWL_STYLE) & WS_VISIBLE))
826 hWnd = GetAncestor(hWnd, GA_PARENT);
828 return(GetWindowLong(hWnd, GWL_STYLE) & WS_VISIBLE);
834 ULONG uStyle = GetWindowLong(hWnd, GWL_STYLE);
836 return (uStyle & WS_MAXIMIZE);
840 LockSetForegroundWindow(UINT uLockCode)
846 MoveWindow(HWND hWnd,
853 return NtUserMoveWindow(hWnd, X, Y, nWidth, nHeight, bRepaint);
863 RealChildWindowFromPoint(HWND hwndParent,
864 POINT ptParentClientCoords)
870 RealGetWindowClass(HWND hwnd,
878 SetForegroundWindow(HWND hWnd)
884 SetLayeredWindowAttributes(HWND hwnd,
893 SetParent(HWND hWndChild,
900 SetProcessDefaultLayout(DWORD dwDefaultLayout)
906 SetWindowPlacement(HWND hWnd,
907 CONST WINDOWPLACEMENT *lpwndpl)
913 SetWindowPos(HWND hWnd,
914 HWND hWndInsertAfter,
925 SetWindowTextA(HWND hWnd,
932 SetWindowTextW(HWND hWnd,
939 ShowOwnedPopups(HWND hWnd,
946 ShowWindow(HWND hWnd,
949 return NtUserShowWindow(hWnd, nCmdShow);
953 ShowWindowAsync(HWND hWnd,
960 TileWindows(HWND hwndParent,
970 UpdateLayeredWindow(HWND hwnd,
977 BLENDFUNCTION *pblend,
984 WindowFromPoint(POINT Point)
990 MapWindowPoints(HWND hWndFrom, HWND hWndTo, LPPOINT lpPoints, UINT cPoints)
992 POINT FromOffset, ToOffset;
996 NtUserGetClientOrigin(hWndFrom, &FromOffset);
997 NtUserGetClientOrigin(hWndTo, &ToOffset);
998 XMove = FromOffset.x - ToOffset.x;
999 YMove = FromOffset.y - ToOffset.y;
1001 for (i = 0; i < cPoints; i++)
1003 lpPoints[i].x += XMove;
1004 lpPoints[i].y += YMove;
1006 return(MAKELONG(LOWORD(XMove), LOWORD(YMove)));
1011 ScreenToClient(HWND hWnd, LPPOINT lpPoint)
1013 return(MapWindowPoints(NULL, hWnd, lpPoint, 1));