Author: jimtabor
Date: Sat Dec 10 07:41:56 2011
New Revision: 54637
URL:
http://svn.reactos.org/svn/reactos?rev=54637&view=rev
Log:
[Win32k|User32]
- Fix Get/SetWindowPlacement and everything related. Which exposed the scroll bar over
write issue, it's not refreshing the client window when it is maximized. Next thing to
fix.
- Fix ShowWindowAsync, now restore and minimize all works. This is based on wine but in
reality it's based on Windows queuing event messages used in server side internal
calls. Also this patch includes the server side hooking points.
- Removed one ugly API.
- Fixes bug 6239, 6739 and client window restore from maximize and the incremental
crawling down issue when parent window is minimized then restored.
Modified:
trunk/reactos/dll/win32/user32/windows/input.c
trunk/reactos/dll/win32/user32/windows/window.c
trunk/reactos/dll/win32/user32/windows/winpos.c
trunk/reactos/include/reactos/win32k/ntuser.h
trunk/reactos/subsystems/win32/win32k/include/msgqueue.h
trunk/reactos/subsystems/win32/win32k/include/winpos.h
trunk/reactos/subsystems/win32/win32k/ntuser/message.c
trunk/reactos/subsystems/win32/win32k/ntuser/ntstubs.c
trunk/reactos/subsystems/win32/win32k/ntuser/window.c
trunk/reactos/subsystems/win32/win32k/ntuser/winpos.c
trunk/reactos/subsystems/win32/win32k/w32ksvc.db
trunk/reactos/subsystems/win32/win32k/w32ksvc.h
Modified: trunk/reactos/dll/win32/user32/windows/input.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/user32/windows/i…
==============================================================================
--- trunk/reactos/dll/win32/user32/windows/input.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/user32/windows/input.c [iso-8859-1] Sat Dec 10 07:41:56 2011
@@ -557,8 +557,6 @@
BYTE bScan,
DWORD dwFlags,
ULONG_PTR dwExtraInfo)
-
-
{
INPUT Input;
Modified: trunk/reactos/dll/win32/user32/windows/window.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/user32/windows/w…
==============================================================================
--- trunk/reactos/dll/win32/user32/windows/window.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/user32/windows/window.c [iso-8859-1] Sat Dec 10 07:41:56 2011
@@ -959,6 +959,13 @@
PWND Wnd = ValidateHwnd(hWnd);
if (!Wnd) return FALSE;
+ if (Wnd->style & WS_MINIMIZED)
+ {
+ lpRect->left = lpRect->top = 0;
+ lpRect->right = GetSystemMetrics(SM_CXMINIMIZED);
+ lpRect->bottom = GetSystemMetrics(SM_CYMINIMIZED);
+ return TRUE;
+ }
if ( hWnd != GetDesktopWindow()) // Wnd->fnid != FNID_DESKTOP )
{
/* lpRect->left = lpRect->top = 0;
Modified: trunk/reactos/dll/win32/user32/windows/winpos.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/user32/windows/w…
==============================================================================
--- trunk/reactos/dll/win32/user32/windows/winpos.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/user32/windows/winpos.c [iso-8859-1] Sat Dec 10 07:41:56 2011
@@ -68,26 +68,110 @@
if (!SetActiveWindow( hwndTo )) SetActiveWindow(0);
}
-
+#define EMPTYPOINT(pt) ((pt).x == -1 && (pt).y == -1)
UINT WINAPI
-WinPosGetMinMaxInfo(HWND hWnd, POINT* MaxSize, POINT* MaxPos,
- POINT* MinTrack, POINT* MaxTrack)
-{
- MINMAXINFO MinMax;
-
- if(NtUserGetMinMaxInfo(hWnd, &MinMax, TRUE))
- {
- MinMax.ptMaxTrackSize.x = max(MinMax.ptMaxTrackSize.x,
- MinMax.ptMinTrackSize.x);
- MinMax.ptMaxTrackSize.y = max(MinMax.ptMaxTrackSize.y,
- MinMax.ptMinTrackSize.y);
-
- if (MaxSize) *MaxSize = MinMax.ptMaxSize;
- if (MaxPos) *MaxPos = MinMax.ptMaxPosition;
- if (MinTrack) *MinTrack = MinMax.ptMinTrackSize;
- if (MaxTrack) *MaxTrack = MinMax.ptMaxTrackSize;
- }
+WinPosGetMinMaxInfo(HWND hwnd, POINT* maxSize, POINT* maxPos,
+ POINT* minTrack, POINT* maxTrack)
+{
+ MINMAXINFO MinMax;
+ HMONITOR monitor;
+ INT xinc, yinc;
+ LONG style = GetWindowLongW( hwnd, GWL_STYLE );
+ LONG adjustedStyle;
+ LONG exstyle = GetWindowLongW( hwnd, GWL_EXSTYLE );
+ RECT rc;
+ WND *win;
+
+ /* Compute default values */
+
+ GetWindowRect(hwnd, &rc);
+ MinMax.ptReserved.x = rc.left;
+ MinMax.ptReserved.y = rc.top;
+
+ if ((style & WS_CAPTION) == WS_CAPTION)
+ adjustedStyle = style & ~WS_BORDER; /* WS_CAPTION = WS_DLGFRAME | WS_BORDER
*/
+ else
+ adjustedStyle = style;
+
+ GetClientRect(GetAncestor(hwnd,GA_PARENT), &rc);
+ AdjustWindowRectEx(&rc, adjustedStyle, ((style & WS_POPUP) &&
GetMenu(hwnd)), exstyle);
+
+ xinc = -rc.left;
+ yinc = -rc.top;
+
+ MinMax.ptMaxSize.x = rc.right - rc.left;
+ MinMax.ptMaxSize.y = rc.bottom - rc.top;
+ if (style & (WS_DLGFRAME | WS_BORDER))
+ {
+ MinMax.ptMinTrackSize.x = GetSystemMetrics(SM_CXMINTRACK);
+ MinMax.ptMinTrackSize.y = GetSystemMetrics(SM_CYMINTRACK);
+ }
+ else
+ {
+ MinMax.ptMinTrackSize.x = 2 * xinc;
+ MinMax.ptMinTrackSize.y = 2 * yinc;
+ }
+ MinMax.ptMaxTrackSize.x = GetSystemMetrics(SM_CXMAXTRACK);
+ MinMax.ptMaxTrackSize.y = GetSystemMetrics(SM_CYMAXTRACK);
+ MinMax.ptMaxPosition.x = -xinc;
+ MinMax.ptMaxPosition.y = -yinc;
+
+ if ((win = ValidateHwnd( hwnd )) )//&& win != WND_DESKTOP && win !=
WND_OTHER_PROCESS)
+ {
+ if (!EMPTYPOINT(win->InternalPos.MaxPos)) MinMax.ptMaxPosition =
win->InternalPos.MaxPos;
+ }
+
+ SendMessageW( hwnd, WM_GETMINMAXINFO, 0, (LPARAM)&MinMax );
+
+ /* if the app didn't change the values, adapt them for the current monitor */
+
+ if ((monitor = MonitorFromWindow( hwnd, MONITOR_DEFAULTTOPRIMARY )))
+ {
+ RECT rc_work;
+ MONITORINFO mon_info;
+
+ mon_info.cbSize = sizeof(mon_info);
+ GetMonitorInfoW( monitor, &mon_info );
+
+ rc_work = mon_info.rcMonitor;
+
+ if (style & WS_MAXIMIZEBOX)
+ {
+ if ((style & WS_CAPTION) == WS_CAPTION || !(style & (WS_CHILD |
WS_POPUP)))
+ rc_work = mon_info.rcWork;
+ }
+
+ if (MinMax.ptMaxSize.x == GetSystemMetrics(SM_CXSCREEN) + 2 * xinc &&
+ MinMax.ptMaxSize.y == GetSystemMetrics(SM_CYSCREEN) + 2 * yinc)
+ {
+ MinMax.ptMaxSize.x = (rc_work.right - rc_work.left) + 2 * xinc;
+ MinMax.ptMaxSize.y = (rc_work.bottom - rc_work.top) + 2 * yinc;
+ }
+ if (MinMax.ptMaxPosition.x == -xinc && MinMax.ptMaxPosition.y == -yinc)
+ {
+ MinMax.ptMaxPosition.x = rc_work.left - xinc;
+ MinMax.ptMaxPosition.y = rc_work.top - yinc;
+ }
+ }
+
+ /* Some sanity checks */
+
+ TRACE("%d %d / %d %d / %d %d / %d %d\n",
+ MinMax.ptMaxSize.x, MinMax.ptMaxSize.y,
+ MinMax.ptMaxPosition.x, MinMax.ptMaxPosition.y,
+ MinMax.ptMaxTrackSize.x, MinMax.ptMaxTrackSize.y,
+ MinMax.ptMinTrackSize.x, MinMax.ptMinTrackSize.y);
+ MinMax.ptMaxTrackSize.x = max( MinMax.ptMaxTrackSize.x,
+ MinMax.ptMinTrackSize.x );
+ MinMax.ptMaxTrackSize.y = max( MinMax.ptMaxTrackSize.y,
+ MinMax.ptMinTrackSize.y );
+
+ if (maxSize) *maxSize = MinMax.ptMaxSize;
+ if (maxPos) *maxPos = MinMax.ptMaxPosition;
+ if (minTrack) *minTrack = MinMax.ptMinTrackSize;
+ if (maxTrack) *maxTrack = MinMax.ptMaxTrackSize;
+
return 0; //FIXME: what does it return?
}
Modified: trunk/reactos/include/reactos/win32k/ntuser.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/include/reactos/win32k/ntu…
==============================================================================
--- trunk/reactos/include/reactos/win32k/ntuser.h [iso-8859-1] (original)
+++ trunk/reactos/include/reactos/win32k/ntuser.h [iso-8859-1] Sat Dec 10 07:41:56 2011
@@ -132,6 +132,7 @@
WCHAR szDesktopName[1];
} DESKTOPINFO, *PDESKTOPINFO;
+#define CTI_THREADSYSLOCK 0x0001
#define CTI_INSENDMESSAGE 0x0002
typedef struct _CLIENTTHREADINFO
@@ -566,6 +567,9 @@
#define WS_EX2_HASOVERLAY 0X00000200
#define WS_EX2_CONSOLEWINDOW 0X00000400
#define WS_EX2_CHILDNOACTIVATE 0X00000800
+
+#define WPF_MININIT 0x0008
+#define WPF_MAXINIT 0x0010
typedef struct _WND
{
@@ -622,10 +626,10 @@
RECT NormalRect;
POINT IconPos;
POINT MaxPos;
+ UINT flags; // WPF_ flags.
} InternalPos;
UINT Unicode : 1; // !(WNDS_ANSICREATOR|WNDS_ANSIWINDOWPROC) ?
- /* Indicates whether the window is derived from a system class */
UINT InternalPosInitialized : 1;
UINT HideFocus : 1; // WS_EX_UISTATEFOCUSRECTHIDDEN ?
UINT HideAccel : 1; // WS_EX_UISTATEKBACCELHIDDEN ?
@@ -3213,8 +3217,8 @@
typedef struct tagKMDDELPARAM
{
- UINT_PTR uiLo;
- UINT_PTR uiHi;
+ UINT_PTR uiLo;
+ UINT_PTR uiHi;
} KMDDELPARAM, *PKMDDELPARAM;
@@ -3257,13 +3261,6 @@
HMENU hMenu,
UINT fByPos,
UINT gmdiFlags);
-
-BOOL
-NTAPI
-NtUserGetMinMaxInfo(
- HWND hwnd,
- MINMAXINFO *MinMaxInfo,
- BOOL SendMessage);
BOOL
NTAPI
Modified: trunk/reactos/subsystems/win32/win32k/include/msgqueue.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/in…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/include/msgqueue.h [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/win32k/include/msgqueue.h [iso-8859-1] Sat Dec 10
07:41:56 2011
@@ -141,6 +141,13 @@
#define QF_TRACKMOUSEFIRING 0x00080000
#define QF_CAPTURELOCKED 0x00100000
#define QF_ACTIVEWNDTRACKING 0x00200000
+
+/* internal messages codes */
+enum internal_event_message
+{
+ WM_ASYNC_SHOWWINDOW = 0x80000000,
+ WM_ASYNC_SETWINDOWPOS
+};
BOOL FASTCALL MsqIsHung(PUSER_MESSAGE_QUEUE MessageQueue);
VOID CALLBACK HungAppSysTimerProc(HWND,UINT,UINT_PTR,DWORD);
Modified: trunk/reactos/subsystems/win32/win32k/include/winpos.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/in…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/include/winpos.h [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/win32k/include/winpos.h [iso-8859-1] Sat Dec 10
07:41:56 2011
@@ -54,4 +54,3 @@
void FASTCALL co_WinPosSendSizeMove(PWND Window);
PWND FASTCALL co_WinPosWindowFromPoint(PWND ScopeWin, POINT *WinPoint, USHORT* HitTest);
VOID FASTCALL co_WinPosActivateOtherWindow(PWND Window);
-VOID FASTCALL WinPosInitInternalPos(PWND WindowObject, POINT *pt, RECTL *RestoreRect);
Modified: trunk/reactos/subsystems/win32/win32k/ntuser/message.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/nt…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/ntuser/message.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/win32k/ntuser/message.c [iso-8859-1] Sat Dec 10
07:41:56 2011
@@ -99,6 +99,7 @@
if (message >= 8*sizeof(message_pointer_flags)) return FALSE;
return (message_pointer_flags[message / 32] & SET(message)) != 0;
}
+#undef SET
#define MMS_SIZE_WPARAM -1
#define MMS_SIZE_WPARAMWCHAR -2
@@ -590,6 +591,39 @@
co_HOOK_CallHooks( WH_CALLWNDPROCRET, HC_ACTION, SameThread, (LPARAM)&CWPR );
}
+static LRESULT handle_internal_message( PWND pWnd, UINT msg, WPARAM wparam, LPARAM lparam
)
+{
+ LRESULT lRes;
+
+ if (!pWnd ||
+ pWnd == IntGetDesktopWindow() || // pWnd->fnid == FNID_DESKTOP
+ pWnd == IntGetMessageWindow() ) // pWnd->fnid == FNID_MESSAGEWND
+ return 0;
+
+ ERR("Internal Event Msg %p\n",msg);
+
+ switch(msg)
+ {
+ case WM_ASYNC_SHOWWINDOW:
+ return co_WinPosShowWindow( pWnd, wparam );
+ case WM_ASYNC_SETWINDOWPOS:
+ {
+ PWINDOWPOS winpos = (PWINDOWPOS)lparam;
+ if (!winpos) return 0;
+ lRes = co_WinPosSetWindowPos( pWnd,
+ winpos->hwndInsertAfter,
+ winpos->x,
+ winpos->y,
+ winpos->cx,
+ winpos->cy,
+ winpos->flags);
+ ExFreePoolWithTag(winpos, USERTAG_SWP);
+ return lRes;
+ }
+ }
+ return 0;
+}
+
LRESULT FASTCALL
IntDispatchMessage(PMSG pMsg)
{
@@ -648,6 +682,13 @@
// Need a window!
if ( !Window ) return 0;
+ if (pMsg->message == WM_PAINT) Window->state |= WNDS_PAINTNOTPROCESSED;
+
+ if ( Window->state & WNDS_SERVERSIDEWINDOWPROC )
+ {
+ TRACE("Dispatch: Server Side Window Procedure\n");
+ }
+
/* Since we are doing a callback on the same thread right away, there is
no need to copy the lparam to kernel mode and then back to usermode.
We just pretend it isn't a pointer */
@@ -662,6 +703,7 @@
if (pMsg->message == WM_PAINT)
{
+ Window->state2 &= ~WNDS2_WMPAINTSENT;
/* send a WM_NCPAINT and WM_ERASEBKGND if the non-client area is still invalid
*/
HRGN hrgn = IntSysCreateRectRgn( 0, 0, 0, 0 );
co_UserGetUpdateRgn( Window, hrgn, TRUE );
@@ -1096,7 +1138,7 @@
PWND DesktopWindow;
ULONG i;
- DesktopWindow = UserGetWindowObject(IntGetDesktopWindow());
+ DesktopWindow = UserGetDesktopWindow();
List = IntWinListChildren(DesktopWindow);
if (List != NULL)
@@ -1104,6 +1146,13 @@
UserPostMessage(DesktopWindow->head.h, Msg, wParam, lParam);
for (i = 0; List[i]; i++)
{
+ PWND pwnd = UserGetWindowObject(List[i]);
+ if (!pwnd) continue;
+
+ if ( pwnd->fnid == FNID_MENU || // Also need
pwnd->pcls->atomClassName == gaOleMainThreadWndClass
+ pwnd->pcls->atomClassName ==
gpsi->atomSysClass[ICLS_SWITCH] )
+ continue;
+
UserPostMessage(List[i], Msg, wParam, lParam);
}
ExFreePoolWithTag(List, USERTAG_WINDOWLIST);
@@ -1144,7 +1193,6 @@
}
return TRUE;
}
-
LRESULT FASTCALL
co_IntSendMessage( HWND hWnd,
@@ -1175,7 +1223,7 @@
INT lParamBufferSize;
LPARAM lParamPacked;
PTHREADINFO Win32Thread;
- ULONG_PTR Result = 0;
+ ULONG_PTR Hi, Lo, Result = 0;
DECLARE_RETURN(LRESULT);
USER_REFERENCE_ENTRY Ref;
@@ -1188,8 +1236,7 @@
Win32Thread = PsGetCurrentThreadWin32Thread();
-
- if ( NULL != Win32Thread &&
+ if ( Win32Thread &&
Window->head.pti->MessageQueue == Win32Thread->MessageQueue)
{
if (Win32Thread->TIF_flags & TIF_INCLEANUP)
@@ -1198,23 +1245,44 @@
RETURN( FALSE);
}
+ if (Msg & 0x80000000)
+ {
+ ERR("SMTS: Internal Message!\n");
+ Result = (ULONG_PTR)handle_internal_message( Window, Msg, wParam, lParam );
+ if (uResult) *uResult = Result;
+ RETURN( TRUE);
+ }
+
+ // Only happens when calling the client!
IntCallWndProc( Window, hWnd, Msg, wParam, lParam);
+ if ( Window->state & WNDS_SERVERSIDEWINDOWPROC )
+ {
+ TRACE("SMT: Server Side Window Procedure\n");
+ IoGetStackLimits(&Lo, &Hi);
+ // Handle it here. Safeguard against excessive recursions.
+ if (((ULONG_PTR)&uResult - Lo) < 4096 )
+ {
+ ERR("Server Callback Exceeded Stack!\n");
+ RETURN( FALSE);
+ }
+ /* Return after server side call, IntCallWndProcRet will not be called. */
+ }
/* See if this message type is present in the table */
MsgMemoryEntry = FindMsgMemory(Msg);
if (NULL == MsgMemoryEntry)
{
- lParamBufferSize = -1;
+ lParamBufferSize = -1;
}
else
{
- lParamBufferSize = MsgMemorySize(MsgMemoryEntry, wParam, lParam);
+ lParamBufferSize = MsgMemorySize(MsgMemoryEntry, wParam, lParam);
}
if (! NT_SUCCESS(PackParam(&lParamPacked, Msg, wParam, lParam, FALSE)))
{
- ERR("Failed to pack message parameters\n");
- RETURN( FALSE);
+ ERR("Failed to pack message parameters\n");
+ RETURN( FALSE);
}
Result = (ULONG_PTR)co_IntCallWindowProc( Window->lpfnWndProc,
@@ -1229,13 +1297,14 @@
*uResult = Result;
}
- IntCallWndProcRet( Window, hWnd, Msg, wParam, lParam, (LRESULT *)uResult);
-
if (! NT_SUCCESS(UnpackParam(lParamPacked, Msg, wParam, lParam, FALSE)))
{
ERR("Failed to unpack message parameters\n");
RETURN( TRUE);
}
+
+ // Only happens when calling the client!
+ IntCallWndProcRet( Window, hWnd, Msg, wParam, lParam, (LRESULT *)uResult);
RETURN( TRUE);
}
@@ -1283,7 +1352,7 @@
EngSetLastError(ERROR_TIMEOUT);
RETURN( FALSE);
}
- else if (! NT_SUCCESS(Status))
+ else if (!NT_SUCCESS(Status))
{
SetLastNtError(Status);
RETURN( FALSE);
@@ -1309,20 +1378,23 @@
HWND *Children;
HWND *Child;
- if (HWND_BROADCAST != hWnd)
+ if (hWnd != HWND_BROADCAST && hWnd != HWND_TOPMOST)
{
return co_IntSendMessageTimeoutSingle(hWnd, Msg, wParam, lParam, uFlags,
uTimeout, uResult);
}
- DesktopWindow = UserGetWindowObject(IntGetDesktopWindow());
+ DesktopWindow = UserGetDesktopWindow();
if (NULL == DesktopWindow)
{
- EngSetLastError(ERROR_INTERNAL_ERROR);
- return 0;
- }
-
- /* Send message to the desktop window too! */
- co_IntSendMessageTimeoutSingle(DesktopWindow->head.h, Msg, wParam, lParam, uFlags,
uTimeout, uResult);
+ EngSetLastError(ERROR_INTERNAL_ERROR);
+ return 0;
+ }
+
+ if (hWnd != HWND_TOPMOST)
+ {
+ /* Send message to the desktop window too! */
+ co_IntSendMessageTimeoutSingle(DesktopWindow->head.h, Msg, wParam, lParam,
uFlags, uTimeout, uResult);
+ }
Children = IntWinListChildren(DesktopWindow);
if (NULL == Children)
@@ -1332,7 +1404,26 @@
for (Child = Children; NULL != *Child; Child++)
{
- co_IntSendMessageTimeoutSingle(*Child, Msg, wParam, lParam, uFlags, uTimeout,
uResult);
+ if (hWnd == HWND_TOPMOST)
+ {
+ DesktopWindow = UserGetWindowObject(*Child);
+ if (DesktopWindow && DesktopWindow->ExStyle & WS_EX_TOPMOST)
+ {
+ ERR("HWND_TOPMOST Found\n");
+ co_IntSendMessageTimeoutSingle(*Child, Msg, wParam, lParam, uFlags,
uTimeout, uResult);
+ }
+ }
+ else
+ {
+ PWND pwnd = UserGetWindowObject(*Child);
+ if (!pwnd) continue;
+
+ if ( pwnd->fnid == FNID_MENU ||
+ pwnd->pcls->atomClassName == gpsi->atomSysClass[ICLS_SWITCH] )
+ continue;
+
+ co_IntSendMessageTimeoutSingle(*Child, Msg, wParam, lParam, uFlags, uTimeout,
uResult);
+ }
}
ExFreePool(Children);
@@ -1347,13 +1438,16 @@
LPARAM lParam)
{
ULONG_PTR Result = 0;
- co_IntSendMessageWithCallBack(hWnd,
- Msg,
- wParam,
- lParam,
- NULL,
- 0,
- &Result);
+ if (!co_IntSendMessageWithCallBack( hWnd,
+ Msg,
+ wParam,
+ lParam,
+ NULL,
+ 0,
+ &Result))
+ {
+ Result = ((ULONG_PTR)-1);
+ }
return Result;
}
/* MSDN:
@@ -1430,7 +1524,20 @@
RETURN(FALSE);
}
+ if (Msg & 0x80000000)
+ {
+ ERR("SMWCB: Internal Message!\n");
+ Result = (ULONG_PTR)handle_internal_message( Window, Msg, wParam, lParam );
+ if (uResult) *uResult = Result;
+ RETURN( TRUE);
+ }
+
IntCallWndProc( Window, hWnd, Msg, wParam, lParam);
+
+ if ( Window->state & WNDS_SERVERSIDEWINDOWPROC )
+ {
+ TRACE("SMWCB: Server Side Window Procedure\n");
+ }
Result = (ULONG_PTR)co_IntCallWindowProc( Window->lpfnWndProc,
!Window->Unicode,
@@ -1505,9 +1612,12 @@
END_CLEANUP;
}
-/* This function posts a message if the destination's message queue belongs to
-another thread, otherwise it sends the message. It does not support broadcast
-messages! */
+
+/*
+ This HACK function posts a message if the destination's message queue belongs to
+ another thread, otherwise it sends the message. It does not support broadcast
+ messages!
+*/
LRESULT FASTCALL
co_IntPostOrSendMessage( HWND hWnd,
UINT Msg,
@@ -1561,7 +1671,7 @@
MSG KernelModeMsg;
PMSGMEMORY MsgMemoryEntry;
- if (HWND_BROADCAST != hWnd)
+ if (hWnd != HWND_BROADCAST && hWnd != HWND_TOPMOST)
{
Window = UserGetWindowObject(hWnd);
if ( !Window )
@@ -1641,7 +1751,7 @@
PWND DesktopWindow;
ULONG i;
- DesktopWindow = UserGetWindowObject(IntGetDesktopWindow());
+ DesktopWindow = UserGetDesktopWindow();
List = IntWinListChildren(DesktopWindow);
if (List != NULL)
@@ -1649,21 +1759,22 @@
UserSendNotifyMessage(DesktopWindow->head.h, Msg, wParam, lParam);
for (i = 0; List[i]; i++)
{
- Ret = UserSendNotifyMessage(List[i], Msg, wParam, lParam);
+ PWND pwnd = UserGetWindowObject(List[i]);
+ if (!pwnd) continue;
+
+ if ( pwnd->fnid == FNID_MENU ||
+ pwnd->pcls->atomClassName == gpsi->atomSysClass[ICLS_SWITCH]
)
+ continue;
+
+ Ret = UserSendNotifyMessage(List[i], Msg, wParam, lParam);
}
ExFreePool(List);
}
}
else
{
- ULONG_PTR lResult = 0;
- Ret = co_IntSendMessageWithCallBack( hWnd,
- Msg,
- wParam,
- lParam,
- NULL,
- 0,
- &lResult);
+ Ret = co_IntSendMessageNoWait( hWnd, Msg, wParam, lParam);
+ if (-1 == (int) Ret || !Ret) Ret = FALSE;
}
return Ret;
}
@@ -2255,7 +2366,7 @@
ULONG i;
UINT fuFlags;
- pwndDesk = UserGetWindowObject(IntGetDesktopWindow());
+ pwndDesk = UserGetDesktopWindow();
List = IntWinListChildren(pwndDesk);
if (parm.flags & BSF_QUERY)
Modified: trunk/reactos/subsystems/win32/win32k/ntuser/ntstubs.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/nt…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/ntuser/ntstubs.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/win32k/ntuser/ntstubs.c [iso-8859-1] Sat Dec 10
07:41:56 2011
@@ -1043,21 +1043,6 @@
/*
* @unimplemented
*/
-DWORD APIENTRY
-NtUserSetInternalWindowPos(
- HWND hwnd,
- UINT showCmd,
- LPRECT rect,
- LPPOINT pt)
-{
- STUB
-
- return 0;
-}
-
-/*
- * @unimplemented
- */
BOOL APIENTRY
NtUserSetLayeredWindowAttributes(HWND hwnd,
COLORREF crKey,
Modified: trunk/reactos/subsystems/win32/win32k/ntuser/window.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/nt…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/ntuser/window.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/win32k/ntuser/window.c [iso-8859-1] Sat Dec 10 07:41:56
2011
@@ -1261,51 +1261,6 @@
Wnd->spwndPrev = Wnd->spwndNext = NULL;
}
-
-BOOL
-FASTCALL
-IntGetWindowPlacement(PWND Wnd, WINDOWPLACEMENT *lpwndpl)
-{
- POINT Size;
-
- if (!Wnd) return FALSE;
-
- if(lpwndpl->length != sizeof(WINDOWPLACEMENT))
- {
- return FALSE;
- }
-
- lpwndpl->flags = 0;
- if (0 == (Wnd->style & WS_VISIBLE))
- {
- lpwndpl->showCmd = SW_HIDE;
- }
- else if (0 != (Wnd->state2 & WNDS2_MAXIMIZEBUTTONDOWN) ||
- 0 != (Wnd->style & WS_MAXIMIZE))
- {
- lpwndpl->showCmd = SW_MAXIMIZE;
- }
- else if (0 != (Wnd->style & WS_MINIMIZE))
- {
- lpwndpl->showCmd = SW_MINIMIZE;
- }
- else if (0 != (Wnd->style & WS_VISIBLE))
- {
- lpwndpl->showCmd = SW_SHOWNORMAL;
- }
-
- Size.x = Wnd->rcWindow.left;
- Size.y = Wnd->rcWindow.top;
- WinPosInitInternalPos(Wnd, &Size,
- &Wnd->rcWindow);
-
- lpwndpl->rcNormalPosition = Wnd->InternalPos.NormalRect;
- lpwndpl->ptMinPosition = Wnd->InternalPos.IconPos;
- lpwndpl->ptMaxPosition = Wnd->InternalPos.MaxPos;
-
- return TRUE;
-}
-
/* FUNCTIONS *****************************************************************/
@@ -3019,80 +2974,6 @@
}
-/*
- * @implemented
- */
-DWORD APIENTRY
-NtUserGetInternalWindowPos( HWND hWnd,
- LPRECT rectWnd,
- LPPOINT ptIcon)
-{
- PWND Window;
- DWORD Ret = 0;
- BOOL Hit = FALSE;
- WINDOWPLACEMENT wndpl;
-
- UserEnterShared();
-
- if (!(Window = UserGetWindowObject(hWnd)))
- {
- Hit = FALSE;
- goto Exit;
- }
-
- _SEH2_TRY
- {
- if(rectWnd)
- {
- ProbeForWrite(rectWnd,
- sizeof(RECT),
- 1);
- }
- if(ptIcon)
- {
- ProbeForWrite(ptIcon,
- sizeof(POINT),
- 1);
- }
-
- }
- _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
- {
- SetLastNtError(_SEH2_GetExceptionCode());
- Hit = TRUE;
- }
- _SEH2_END;
-
- wndpl.length = sizeof(WINDOWPLACEMENT);
-
- if (IntGetWindowPlacement(Window, &wndpl) && !Hit)
- {
- _SEH2_TRY
- {
- if (rectWnd)
- {
- RtlCopyMemory(rectWnd, &wndpl.rcNormalPosition , sizeof(RECT));
- }
- if (ptIcon)
- {
- RtlCopyMemory(ptIcon, &wndpl.ptMinPosition, sizeof(POINT));
- }
-
- }
- _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
- {
- SetLastNtError(_SEH2_GetExceptionCode());
- Hit = TRUE;
- }
- _SEH2_END;
-
- if (!Hit) Ret = wndpl.showCmd;
- }
-Exit:
- UserLeave();
- return Ret;
-}
-
DWORD
APIENTRY
NtUserGetListBoxInfo(
@@ -3596,82 +3477,6 @@
}
/*
- * @implemented
- */
-BOOL APIENTRY
-NtUserGetWindowPlacement(HWND hWnd,
- WINDOWPLACEMENT *lpwndpl)
-{
- PWND Wnd;
- POINT Size;
- WINDOWPLACEMENT Safepl;
- NTSTATUS Status;
- DECLARE_RETURN(BOOL);
-
- TRACE("Enter NtUserGetWindowPlacement\n");
- UserEnterShared();
-
- if (!(Wnd = UserGetWindowObject(hWnd)))
- {
- RETURN( FALSE);
- }
-
- Status = MmCopyFromCaller(&Safepl, lpwndpl, sizeof(WINDOWPLACEMENT));
- if(!NT_SUCCESS(Status))
- {
- SetLastNtError(Status);
- RETURN( FALSE);
- }
- if(Safepl.length != sizeof(WINDOWPLACEMENT))
- {
- RETURN( FALSE);
- }
-
- Safepl.flags = 0;
- if (0 == (Wnd->style & WS_VISIBLE))
- {
- Safepl.showCmd = SW_HIDE;
- }
- else if ((0 != (Wnd->state2 & WNDS2_MAXIMIZEBUTTONDOWN) ||
- 0 != (Wnd->style & WS_MAXIMIZE)) &&
- 0 == (Wnd->style & WS_MINIMIZE))
- {
- Safepl.showCmd = SW_SHOWMAXIMIZED;
- }
- else if (0 != (Wnd->style & WS_MINIMIZE))
- {
- Safepl.showCmd = SW_SHOWMINIMIZED;
- }
- else if (0 != (Wnd->style & WS_VISIBLE))
- {
- Safepl.showCmd = SW_SHOWNORMAL;
- }
-
- Size.x = Wnd->rcWindow.left;
- Size.y = Wnd->rcWindow.top;
- WinPosInitInternalPos(Wnd, &Size,
- &Wnd->rcWindow);
-
- Safepl.rcNormalPosition = Wnd->InternalPos.NormalRect;
- Safepl.ptMinPosition = Wnd->InternalPos.IconPos;
- Safepl.ptMaxPosition = Wnd->InternalPos.MaxPos;
-
- Status = MmCopyToCaller(lpwndpl, &Safepl, sizeof(WINDOWPLACEMENT));
- if(!NT_SUCCESS(Status))
- {
- SetLastNtError(Status);
- RETURN( FALSE);
- }
-
- RETURN( TRUE);
-
-CLEANUP:
- TRACE("Leave NtUserGetWindowPlacement, ret=%i\n",_ret_);
- UserLeave();
- END_CLEANUP;
-}
-
-/*
QueryWindow based on KJK::Hyperion and James Tabor.
0 = QWUniqueProcessId
@@ -3827,7 +3632,6 @@
END_CLEANUP;
}
-
/*
* @implemented
*/
@@ -3871,57 +3675,6 @@
UserLeave();
END_CLEANUP;
}
-
-/*
- * @implemented
- */
-HWND APIENTRY
-NtUserWindowFromPoint(LONG X, LONG Y)
-{
- POINT pt;
- HWND Ret;
- PWND DesktopWindow = NULL, Window = NULL;
- USHORT hittest;
- DECLARE_RETURN(HWND);
- USER_REFERENCE_ENTRY Ref;
-
- TRACE("Enter NtUserWindowFromPoint\n");
- UserEnterExclusive();
-
- if ((DesktopWindow = UserGetWindowObject(IntGetDesktopWindow())))
- {
- //PTHREADINFO pti;
-
- pt.x = X;
- pt.y = Y;
-
- //hmm... threads live on desktops thus we have a reference on the desktop and
indirectly the desktop window
- //its possible this referencing is useless, thou it shouldnt hurt...
- UserRefObjectCo(DesktopWindow, &Ref);
-
- //pti = PsGetCurrentThreadWin32Thread();
- Window = co_WinPosWindowFromPoint(DesktopWindow, &pt, &hittest);
-
- if(Window)
- {
- Ret = Window->head.h;
-
- RETURN( Ret);
- }
- }
-
- RETURN( NULL);
-
-CLEANUP:
- if (Window) UserDereferenceObject(Window);
- if (DesktopWindow) UserDerefObjectCo(DesktopWindow);
-
- TRACE("Leave NtUserWindowFromPoint, ret=%i\n",_ret_);
- UserLeave();
- END_CLEANUP;
-
-}
-
/*
* NtUserDefSetText
Modified: trunk/reactos/subsystems/win32/win32k/ntuser/winpos.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/nt…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/ntuser/winpos.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/win32k/ntuser/winpos.c [iso-8859-1] Sat Dec 10 07:41:56
2011
@@ -24,6 +24,9 @@
(SWP_AGG_NOPOSCHANGE | SWP_FRAMECHANGED | SWP_HIDEWINDOW | SWP_SHOWWINDOW)
#define EMPTYPOINT(pt) ((pt).x == -1 && (pt).y == -1)
+#define PLACE_MIN 0x0001
+#define PLACE_MAX 0x0002
+#define PLACE_RECT 0x0004
/* FUNCTIONS *****************************************************************/
@@ -125,6 +128,25 @@
if (WndTo) UserDerefObjectCo(WndTo);
}
+BOOL
+FASTCALL
+WinPosShowIconTitle( PWND pWnd, BOOL bShow )
+{
+ HICON hIcon;
+ if (!pWnd->pcls || pWnd->fnid == FNID_DESKTOP) return FALSE;
+ if (!hIcon) hIcon = pWnd->pcls->hIconSm;
+ if (!hIcon) hIcon = pWnd->pcls->hIcon;
+ if (!hIcon) return FALSE;
+
+ if ( bShow )
+ {
+ // FIXME: Draw ICON!
+ }
+ else if (hIcon)
+ return FALSE;
+
+ return FALSE;
+}
UINT
FASTCALL
@@ -163,9 +185,13 @@
USER_REFERENCE_ENTRY Ref;
UserRefObjectCo(Child, &Ref);
- co_WinPosSetWindowPos(Child, 0, x + (xspacing - UserGetSystemMetrics(SM_CXICON))
/ 2,
- y - yspacing - UserGetSystemMetrics(SM_CYICON) / 2
- , 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE );
+ co_WinPosSetWindowPos( Child,
+ 0,
+ x + (xspacing - UserGetSystemMetrics(SM_CXICON)) / 2,
+ y - yspacing - UserGetSystemMetrics(SM_CYICON) / 2,
+ 0,
+ 0,
+ SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE );
UserDerefObjectCo(Child);
@@ -186,64 +212,320 @@
static VOID FASTCALL
WinPosFindIconPos(PWND Window, POINT *Pos)
{
- ERR("WinPosFindIconPos FIXME!\n");
+ RECT rect, rectParent;
+ PWND pwndChild, pwndParent;
+ HRGN hrgn, tmp;
+ int xspacing, yspacing;
+
+ pwndParent = Window->spwndParent;
+ if (pwndParent == UserGetDesktopWindow())
+ {
+ /* ReactOS doesn't support iconic minimize to desktop */
+ Pos->x = Pos->y = -32000;
+ return;
+ }
+
+ IntGetClientRect( pwndParent, &rectParent );
+ if ((Pos->x >= rectParent.left) && (Pos->x +
UserGetSystemMetrics(SM_CXICON) < rectParent.right) &&
+ (Pos->y >= rectParent.top) && (Pos->y +
UserGetSystemMetrics(SM_CYICON) < rectParent.bottom))
+ return; /* The icon already has a suitable position */
+
+ xspacing = UserGetSystemMetrics(SM_CXICONSPACING);
+ yspacing = UserGetSystemMetrics(SM_CYICONSPACING);
+
+ /* Check if another icon already occupies this spot */
+ /* FIXME: this is completely inefficient */
+
+ hrgn = IntSysCreateRectRgn( 0, 0, 0, 0 );
+ tmp = IntSysCreateRectRgn( 0, 0, 0, 0 );
+ for (pwndChild = pwndParent->spwndChild; pwndChild; pwndChild =
pwndChild->spwndNext)
+ {
+ if (pwndChild == Window) continue;
+ if ((pwndChild->style & (WS_VISIBLE|WS_MINIMIZE)) !=
(WS_VISIBLE|WS_MINIMIZE))
+ continue;
+ if ( pwndChild->spwndParent )
+ {
+ PWND Parent = pwndChild->spwndParent;
+ rect.left = rect.top = 0;
+ rect.right = Parent->rcWindow.right - Parent->rcWindow.left;
+ rect.bottom = Parent->rcWindow.bottom - Parent->rcWindow.top;
+ NtGdiSetRectRgn( tmp, rect.left, rect.top, rect.right, rect.bottom );
+ NtGdiCombineRgn( hrgn, hrgn, tmp, RGN_OR );
+ }
+ }
+ GreDeleteObject( tmp );
+
+ for (rect.bottom = rectParent.bottom; rect.bottom >= yspacing; rect.bottom -=
yspacing)
+ {
+ for (rect.left = rectParent.left; rect.left <= rectParent.right - xspacing;
rect.left += xspacing)
+ {
+ rect.right = rect.left + xspacing;
+ rect.top = rect.bottom - yspacing;
+ if (!IntRectInRegion( hrgn, &rect ))
+ {
+ /* No window was found, so it's OK for us */
+ Pos->x = rect.left + (xspacing - UserGetSystemMetrics(SM_CXICON)) /
2;
+ Pos->y = rect.top + (yspacing - UserGetSystemMetrics(SM_CYICON)) / 2;
+ GreDeleteObject( hrgn );
+ return;
+ }
+ }
+ }
+ GreDeleteObject( hrgn );
+ Pos->x = Pos->y = 0;
+ return;
}
VOID FASTCALL
-WinPosInitInternalPos(PWND Wnd, POINT *pt, RECTL *RestoreRect)
-{
- PWND Parent;
- UINT XInc, YInc;
+WinPosInitInternalPos(PWND Wnd, RECTL *RestoreRect)
+{
+ POINT Size;
+ RECTL Rect = *RestoreRect;
+
+ if (Wnd->spwndParent != UserGetDesktopWindow())
+ {
+ RECTL_vOffsetRect(&Rect,
+ -Wnd->spwndParent->rcClient.left,
+ -Wnd->spwndParent->rcClient.top);
+ }
+
+ Size.x = Rect.left;
+ Size.y = Rect.top;
if (!Wnd->InternalPosInitialized)
{
- RECTL WorkArea;
-
- Parent = Wnd->spwndParent;
- if(Parent)
- {
- if(IntIsDesktopWindow(Parent))
- UserSystemParametersInfo(SPI_GETWORKAREA, 0, &WorkArea, 0);
+ // FIXME: Use check point Atom..
+ Wnd->InternalPos.flags = 0;
+ Wnd->InternalPos.MaxPos.x = Wnd->InternalPos.MaxPos.y = -1;
+ Wnd->InternalPos.IconPos.x = Wnd->InternalPos.IconPos.y = -1;
+ Wnd->InternalPos.NormalRect = Rect;
+ Wnd->InternalPosInitialized = TRUE;
+ }
+
+ if (Wnd->style & WS_MINIMIZE)
+ {
+ Wnd->InternalPos.IconPos = Size;
+ Wnd->InternalPos.flags |= WPF_MININIT;
+ }
+ else if (Wnd->style & WS_MAXIMIZE)
+ {
+ Wnd->InternalPos.flags |= WPF_MAXINIT;
+
+ if ( Wnd->spwndParent == Wnd->head.rpdesk->pDeskInfo->spwnd )
+ {
+ if (Wnd->state & WNDS_MAXIMIZESTOMONITOR)
+ {
+ Wnd->InternalPos.flags &= ~WPF_MAXINIT;
+ Wnd->InternalPos.MaxPos.x = Wnd->InternalPos.MaxPos.y = -1;
+ }
else
- WorkArea = Parent->rcClient;
+ {
+ RECTL WorkArea;
+ PMONITOR pmonitor = IntMonitorFromRect(&Rect, MONITOR_DEFAULTTOPRIMARY
);
+
+ // FIXME: support DPI aware, rcWorkDPI/Real etc..
+ if (!(Wnd->style & WS_MAXIMIZEBOX) || (Wnd->state &
WNDS_HASCAPTION) || pmonitor->cFullScreen)
+ WorkArea = pmonitor->rcMonitor;
+ else
+ WorkArea = pmonitor->rcWork;
+
+ Wnd->InternalPos.MaxPos.x = Rect.left - WorkArea.left;
+ Wnd->InternalPos.MaxPos.y = Rect.top - WorkArea.top;
+ TRACE("WinPosIP 2 X %d Y
%d\n",Wnd->InternalPos.MaxPos.x,Wnd->InternalPos.MaxPos.y);
+ }
}
else
- UserSystemParametersInfo(SPI_GETWORKAREA, 0, &WorkArea, 0);
-
- Wnd->InternalPos.NormalRect = Wnd->rcWindow;
- IntGetWindowBorderMeasures(Wnd, &XInc, &YInc);
- Wnd->InternalPos.MaxPos.x = WorkArea.left - XInc;
- Wnd->InternalPos.MaxPos.y = WorkArea.top - YInc;
- Wnd->InternalPos.IconPos.x = WorkArea.left;
- Wnd->InternalPos.IconPos.y = WorkArea.bottom -
UserGetSystemMetrics(SM_CYMINIMIZED);
-
- Wnd->InternalPosInitialized = TRUE;
- }
- if (Wnd->style & WS_MINIMIZE)
- {
- Wnd->InternalPos.IconPos = *pt;
- }
- else if (Wnd->style & WS_MAXIMIZE)
- {
- Wnd->InternalPos.MaxPos = *pt;
- }
- else if (RestoreRect != NULL)
- {
- Wnd->InternalPos.NormalRect = *RestoreRect;
- }
+ Wnd->InternalPos.MaxPos = Size;
+ }
+ else
+ {
+ Wnd->InternalPos.NormalRect = Rect;
+ }
+}
+
+BOOL
+FASTCALL
+IntGetWindowPlacement(PWND Wnd, WINDOWPLACEMENT *lpwndpl)
+{
+ if (!Wnd) return FALSE;
+
+ if(lpwndpl->length != sizeof(WINDOWPLACEMENT))
+ {
+ return FALSE;
+ }
+
+ lpwndpl->flags = 0;
+
+ WinPosInitInternalPos(Wnd, &Wnd->rcWindow);
+
+ lpwndpl->showCmd = SW_HIDE;
+
+ if ( Wnd->style & WS_MINIMIZE )
+ lpwndpl->showCmd = SW_SHOWMINIMIZED;
+ else
+ lpwndpl->showCmd = ( Wnd->style & WS_MAXIMIZE ) ? SW_SHOWMAXIMIZED :
SW_SHOWNORMAL ;
+
+ lpwndpl->rcNormalPosition = Wnd->InternalPos.NormalRect;
+
+ if (Wnd->InternalPos.flags & WPF_MININIT) // Return if it was set!
+ {
+ lpwndpl->ptMinPosition.x = Wnd->InternalPos.IconPos.x;
+ lpwndpl->ptMinPosition.y = Wnd->InternalPos.IconPos.y;
+ }
+ else
+ lpwndpl->ptMinPosition.x = lpwndpl->ptMinPosition.y = -1;
+
+ if ( Wnd->InternalPos.flags & WPF_MAXINIT && // Return if set and not
maximized to monitor!
+ !(Wnd->state & WNDS_MAXIMIZESTOMONITOR))
+ {
+ lpwndpl->ptMaxPosition.x = Wnd->InternalPos.MaxPos.x;
+ lpwndpl->ptMaxPosition.y = Wnd->InternalPos.MaxPos.y;
+ }
+ else
+ lpwndpl->ptMaxPosition.x = lpwndpl->ptMaxPosition.y = -1;
+
+ if ( Wnd->spwndParent == Wnd->head.rpdesk->pDeskInfo->spwnd &&
+ !(Wnd->ExStyle & WS_EX_TOOLWINDOW))
+ {
+ PMONITOR pmonitor = IntMonitorFromRect(&lpwndpl->rcNormalPosition,
MONITOR_DEFAULTTOPRIMARY );
+
+ // FIXME: support DPI aware, rcWorkDPI/Real etc..
+ if (Wnd->InternalPos.flags & WPF_MININIT)
+ {
+ lpwndpl->ptMinPosition.x -= (pmonitor->rcWork.left -
pmonitor->rcMonitor.left);
+ lpwndpl->ptMinPosition.y -= (pmonitor->rcWork.top -
pmonitor->rcMonitor.top);
+ }
+ RECTL_vOffsetRect(&lpwndpl->rcNormalPosition,
+ pmonitor->rcMonitor.left - pmonitor->rcWork.left,
+ pmonitor->rcMonitor.top - pmonitor->rcWork.top);
+ }
+
+ if ( Wnd->InternalPos.flags & WPF_RESTORETOMAXIMIZED || Wnd->style &
WS_MAXIMIZE )
+ lpwndpl->flags |= WPF_RESTORETOMAXIMIZED;
+
+ if ( ((Wnd->style & (WS_CHILD|WS_POPUP)) == WS_CHILD) &&
Wnd->InternalPos.flags & WPF_SETMINPOSITION)
+ lpwndpl->flags |= WPF_SETMINPOSITION;
+
+ return TRUE;
+}
+
+/* make sure the specified rect is visible on screen */
+static void make_rect_onscreen( RECT *rect )
+{
+ PMONITOR pmonitor = IntMonitorFromRect( rect, MONITOR_DEFAULTTONEAREST ); // Wine
uses this.
+
+ // FIXME: support DPI aware, rcWorkDPI/Real etc..
+ if (!pmonitor) return;
+ /* FIXME: map coordinates from rcWork to rcMonitor */
+ if (rect->right <= pmonitor->rcWork.left)
+ {
+ rect->right += pmonitor->rcWork.left - rect->left;
+ rect->left = pmonitor->rcWork.left;
+ }
+ else if (rect->left >= pmonitor->rcWork.right)
+ {
+ rect->left += pmonitor->rcWork.right - rect->right;
+ rect->right = pmonitor->rcWork.right;
+ }
+ if (rect->bottom <= pmonitor->rcWork.top)
+ {
+ rect->bottom += pmonitor->rcWork.top - rect->top;
+ rect->top = pmonitor->rcWork.top;
+ }
+ else if (rect->top >= pmonitor->rcWork.bottom)
+ {
+ rect->top += pmonitor->rcWork.bottom - rect->bottom;
+ rect->bottom = pmonitor->rcWork.bottom;
+ }
+}
+
+/* make sure the specified point is visible on screen */
+static void make_point_onscreen( POINT *pt )
+{
+ RECT rect;
+
+ RECTL_vSetRect( &rect, pt->x, pt->y, pt->x + 1, pt->y + 1 );
+ make_rect_onscreen( &rect );
+ pt->x = rect.left;
+ pt->y = rect.top;
+}
+
+BOOL FASTCALL
+IntSetWindowPlacement(PWND Wnd, WINDOWPLACEMENT *wpl, UINT Flags)
+{
+ BOOL sAsync;
+ UINT SWP_Flags;
+
+ if ( Flags & PLACE_MIN) make_point_onscreen( &wpl->ptMinPosition );
+ if ( Flags & PLACE_MAX) make_point_onscreen( &wpl->ptMaxPosition );
+ if ( Flags & PLACE_RECT) make_rect_onscreen( &wpl->rcNormalPosition );
+
+ if (!Wnd || Wnd == Wnd->head.rpdesk->pDeskInfo->spwnd) return FALSE;
+
+ if ( Flags & PLACE_MIN ) Wnd->InternalPos.IconPos = wpl->ptMinPosition;
+ if ( Flags & PLACE_MAX ) Wnd->InternalPos.MaxPos = wpl->ptMaxPosition;
+ if ( Flags & PLACE_RECT) Wnd->InternalPos.NormalRect =
wpl->rcNormalPosition;
+
+ SWP_Flags = SWP_NOZORDER | SWP_NOACTIVATE | ((wpl->flags &
WPF_ASYNCWINDOWPLACEMENT) ? SWP_ASYNCWINDOWPOS : 0);
+
+ if (Wnd->style & WS_MINIMIZE )
+ {
+ if (Flags & PLACE_MIN)
+ {
+ co_WinPosSetWindowPos(Wnd, HWND_TOP,
+ wpl->ptMinPosition.x, wpl->ptMinPosition.y, 0, 0,
+ SWP_NOSIZE | SWP_Flags);
+ Wnd->InternalPos.flags |= WPF_MININIT;
+ }
+ }
+ else if (Wnd->style & WS_MAXIMIZE )
+ {
+ if (Flags & PLACE_MAX)
+ {
+ co_WinPosSetWindowPos(Wnd, HWND_TOP,
+ wpl->ptMaxPosition.x, wpl->ptMaxPosition.y, 0, 0,
+ SWP_NOSIZE | SWP_Flags);
+ Wnd->InternalPos.flags |= WPF_MAXINIT;
+ }
+ }
+ else if (Flags & PLACE_RECT)
+ {
+ co_WinPosSetWindowPos(Wnd, HWND_TOP,
+ wpl->rcNormalPosition.left, wpl->rcNormalPosition.top,
+ wpl->rcNormalPosition.right -
wpl->rcNormalPosition.left,
+ wpl->rcNormalPosition.bottom -
wpl->rcNormalPosition.top,
+ SWP_Flags);
+ }
+
+ sAsync = (Wnd->head.pti->MessageQueue != gptiCurrent->MessageQueue &&
wpl->flags & WPF_ASYNCWINDOWPLACEMENT);
+
+ if ( sAsync )
+ co_IntSendMessageNoWait( UserHMGetHandle(Wnd), WM_ASYNC_SHOWWINDOW,
wpl->showCmd, 0 );
+ else
+ co_WinPosShowWindow(Wnd, wpl->showCmd);
+
+ if ( Wnd->style & WS_MINIMIZE && !sAsync )
+ {
+ if ( wpl->flags & WPF_SETMINPOSITION )
+ Wnd->InternalPos.flags |= WPF_SETMINPOSITION;
+
+ if ( wpl->flags & WPF_RESTORETOMAXIMIZED )
+ Wnd->InternalPos.flags |= WPF_RESTORETOMAXIMIZED;
+ }
+ return TRUE;
}
UINT FASTCALL
co_WinPosMinMaximize(PWND Wnd, UINT ShowFlag, RECT* NewPos)
{
POINT Size;
+ WINDOWPLACEMENT wpl;
UINT SwpFlags = 0;
ASSERT_REFS_CO(Wnd);
- Size.x = Wnd->rcWindow.left;
- Size.y = Wnd->rcWindow.top;
- WinPosInitInternalPos(Wnd, &Size, &Wnd->rcWindow);
+ wpl.length = sizeof(wpl);
+ IntGetWindowPlacement( Wnd, &wpl );
if (co_HOOK_CallHooks( WH_CBT, HCBT_MINMAX, (WPARAM)Wnd->head.h, ShowFlag))
{
@@ -252,6 +534,8 @@
}
if (Wnd->style & WS_MINIMIZE)
{
+ if (ShowFlag == SW_MINIMIZE) return SWP_NOSIZE | SWP_NOMOVE;
+
if (!co_IntSendMessageNoWait(Wnd->head.h, WM_QUERYOPEN, 0, 0))
{
return(SWP_NOSIZE | SWP_NOMOVE);
@@ -264,18 +548,18 @@
{
if (Wnd->style & WS_MAXIMIZE)
{
- Wnd->state2 |= WNDS2_MAXIMIZEBUTTONDOWN;
+ Wnd->InternalPos.flags |= WPF_RESTORETOMAXIMIZED;
Wnd->style &= ~WS_MAXIMIZE;
}
else
{
- Wnd->state2 &= ~WNDS2_MAXIMIZEBUTTONDOWN;
+ Wnd->InternalPos.flags &= ~WPF_RESTORETOMAXIMIZED;
}
co_UserRedrawWindow(Wnd, NULL, 0, RDW_VALIDATE | RDW_NOERASE |
RDW_NOINTERNALPAINT);
Wnd->style |= WS_MINIMIZE;
- WinPosFindIconPos(Wnd, &Wnd->InternalPos.IconPos);
- RECTL_vSetRect(NewPos, Wnd->InternalPos.IconPos.x,
Wnd->InternalPos.IconPos.y,
+ WinPosFindIconPos(Wnd, &wpl.ptMinPosition);
+ RECTL_vSetRect(NewPos, wpl.ptMinPosition.x, wpl.ptMinPosition.y,
UserGetSystemMetrics(SM_CXMINIMIZED),
UserGetSystemMetrics(SM_CYMINIMIZED));
SwpFlags |= SWP_NOCOPYBITS;
@@ -284,17 +568,16 @@
case SW_MAXIMIZE:
{
- co_WinPosGetMinMaxInfo(Wnd, &Size, &Wnd->InternalPos.MaxPos,
- NULL, NULL);
+ co_WinPosGetMinMaxInfo(Wnd, &Size, &wpl.ptMaxPosition, NULL,
NULL);
+
TRACE("Maximize: %d,%d %dx%d\n",
- Wnd->InternalPos.MaxPos.x, Wnd->InternalPos.MaxPos.y, Size.x,
Size.y);
+ wpl.ptMaxPosition.x, wpl.ptMaxPosition.y, Size.x, Size.y);
if (Wnd->style & WS_MINIMIZE)
{
Wnd->style &= ~WS_MINIMIZE;
}
Wnd->style |= WS_MAXIMIZE;
- RECTL_vSetRect(NewPos, Wnd->InternalPos.MaxPos.x,
Wnd->InternalPos.MaxPos.y,
- Size.x, Size.y);
+ RECTL_vSetRect(NewPos, wpl.ptMaxPosition.x, wpl.ptMaxPosition.y, Size.x,
Size.y);
break;
}
@@ -303,18 +586,17 @@
if (Wnd->style & WS_MINIMIZE)
{
Wnd->style &= ~WS_MINIMIZE;
- if (Wnd->state2 & WNDS2_MAXIMIZEBUTTONDOWN)
+ if (Wnd->InternalPos.flags & WPF_RESTORETOMAXIMIZED)
{
- co_WinPosGetMinMaxInfo(Wnd, &Size,
- &Wnd->InternalPos.MaxPos, NULL,
NULL);
+ co_WinPosGetMinMaxInfo(Wnd, &Size, &wpl.ptMaxPosition, NULL,
NULL);
+
Wnd->style |= WS_MAXIMIZE;
- RECTL_vSetRect(NewPos, Wnd->InternalPos.MaxPos.x,
- Wnd->InternalPos.MaxPos.y, Size.x, Size.y);
+ RECTL_vSetRect(NewPos, wpl.ptMaxPosition.x, wpl.ptMaxPosition.y,
Size.x, Size.y);
break;
}
else
{
- *NewPos = Wnd->InternalPos.NormalRect;
+ *NewPos = wpl.rcNormalPosition;
NewPos->right -= NewPos->left;
NewPos->bottom -= NewPos->top;
break;
@@ -327,8 +609,8 @@
return 0;
}
Wnd->style &= ~WS_MAXIMIZE;
- Wnd->state2 &= ~WNDS2_MAXIMIZEBUTTONDOWN;
- *NewPos = Wnd->InternalPos.NormalRect;
+ Wnd->InternalPos.flags &= ~WPF_RESTORETOMAXIMIZED;
+ *NewPos = wpl.rcNormalPosition;
NewPos->right -= NewPos->left;
NewPos->bottom -= NewPos->top;
break;
@@ -455,7 +737,7 @@
MinMax.ptMaxPosition.x = -xinc;
MinMax.ptMaxPosition.y = -yinc;
- if (!EMPTYPOINT(Window->InternalPos.MaxPos)) MinMax.ptMaxPosition =
Window->InternalPos.MaxPos;
+ if (!EMPTYPOINT(Window->InternalPos.MaxPos)) MinMax.ptMaxPosition =
Window->InternalPos.MaxPos;
co_IntSendMessage(Window->head.h, WM_GETMINMAXINFO, 0, (LPARAM)&MinMax);
@@ -946,6 +1228,7 @@
if ( Window->head.h == IntGetDesktopWindow() &&
Window->head.pti->pEThread->ThreadsProcess != PsGetCurrentProcess())
{
+ ERR("Desktop Window...\n");
return FALSE;
}
bPointerInWindow = IntPtInWindow(Window, gpsi->ptCursor.x, gpsi->ptCursor.y);
@@ -1337,7 +1620,7 @@
ASSERT_REFS_CO(Window);
*ClientRect = *WindowRect;
- Result = co_IntSendMessageNoWait(Window->head.h, WM_NCCALCSIZE, FALSE, (LPARAM)
ClientRect);
+ Result = co_IntSendMessage(Window->head.h, WM_NCCALCSIZE, FALSE, (LPARAM)
ClientRect);
FixClientRect(ClientRect, WindowRect);
@@ -1347,7 +1630,11 @@
void FASTCALL
co_WinPosSendSizeMove(PWND Wnd)
{
+ RECTL Rect;
+ LPARAM lParam;
WPARAM wParam = SIZE_RESTORED;
+
+ IntGetClientRect(Wnd, &Rect);
Wnd->state &= ~WNDS_SENDSIZEMOVEMSGS;
if (Wnd->style & WS_MAXIMIZE)
@@ -1359,14 +1646,14 @@
wParam = SIZE_MINIMIZED;
}
- co_IntSendMessageNoWait(Wnd->head.h, WM_SIZE, wParam,
- MAKELONG(Wnd->rcClient.right -
- Wnd->rcClient.left,
- Wnd->rcClient.bottom -
- Wnd->rcClient.top));
- co_IntSendMessageNoWait(Wnd->head.h, WM_MOVE, 0,
- MAKELONG(Wnd->rcClient.left,
- Wnd->rcClient.top));
+ co_IntSendMessageNoWait(UserHMGetHandle(Wnd), WM_SIZE, wParam,
MAKELONG(Rect.right-Rect.left, Rect.bottom-Rect.top));
+
+ if (Wnd->spwndParent == UserGetDesktopWindow()) // Wnd->spwndParent->fnid !=
FNID_DESKTOP )
+ lParam = MAKELONG(Wnd->rcClient.left, Wnd->rcClient.top);
+ else
+ lParam = MAKELONG(Wnd->rcClient.left-Wnd->spwndParent->rcClient.left,
Wnd->rcClient.top-Wnd->spwndParent->rcClient.top);
+
+ co_IntSendMessageNoWait(UserHMGetHandle(Wnd), WM_MOVE, 0, lParam);
IntEngWindowChanged(Wnd, WOC_RGN_CLIENT);
}
@@ -1454,7 +1741,7 @@
break;
case SW_SHOWNOACTIVATE:
- Wnd->state2 &= ~WNDS2_MAXIMIZEBUTTONDOWN;
+ Wnd->InternalPos.flags &= ~WPF_RESTORETOMAXIMIZED;
//Swp |= SWP_NOZORDER;
Swp |= SWP_NOACTIVATE | SWP_NOZORDER;
/* Fall through. */
@@ -1734,7 +2021,7 @@
return retvalue;
}
-BOOL FASTCALL IntEndDeferWindowPosEx( HDWP hdwp )
+BOOL FASTCALL IntEndDeferWindowPosEx( HDWP hdwp, BOOL sAsync )
{
PSMWP pDWP;
PCVR winpos;
@@ -1764,13 +2051,30 @@
UserRefObjectCo(pwnd, &Ref);
- res = co_WinPosSetWindowPos( pwnd,
- winpos->pos.hwndInsertAfter,
- winpos->pos.x,
- winpos->pos.y,
- winpos->pos.cx,
- winpos->pos.cy,
- winpos->pos.flags);
+ if ( sAsync )
+ {
+ LRESULT lRes;
+ PWINDOWPOS ppos = ExAllocatePoolWithTag(PagedPool, sizeof(WINDOWPOS),
USERTAG_SWP);
+ if ( ppos )
+ {
+ *ppos = winpos->pos;
+ /* Yes it's a pointer inside Win32k! */
+ lRes = co_IntSendMessageNoWait( winpos->pos.hwnd, WM_ASYNC_SETWINDOWPOS,
0, (LPARAM)ppos);
+ /* We handle this the same way as Event Hooks and Hooks. */
+ if ( -1 == (int) lRes )
+ {
+ ExFreePoolWithTag(ppos, USERTAG_SWP);
+ }
+ }
+ }
+ else
+ res = co_WinPosSetWindowPos( pwnd,
+ winpos->pos.hwndInsertAfter,
+ winpos->pos.x,
+ winpos->pos.y,
+ winpos->pos.cx,
+ winpos->pos.cy,
+ winpos->pos.flags);
UserDerefObjectCo(pwnd);
}
@@ -1779,6 +2083,7 @@
UserDeleteObject(hdwp, otSMWP);
return res;
}
+
/*
* @implemented
@@ -1856,7 +2161,7 @@
BOOL Ret;
TRACE("Enter NtUserEndDeferWindowPosEx\n");
UserEnterExclusive();
- Ret = IntEndDeferWindowPosEx(WinPosInfo);
+ Ret = IntEndDeferWindowPosEx(WinPosInfo, (BOOL)Unknown1);
TRACE("Leave NtUserEndDeferWindowPosEx, ret=%i\n", Ret);
UserLeave();
return Ret;
@@ -1920,6 +2225,128 @@
return Ret;
}
+/*
+ * @implemented
+ */
+DWORD APIENTRY
+NtUserGetInternalWindowPos( HWND hWnd,
+ LPRECT rectWnd,
+ LPPOINT ptIcon)
+{
+ PWND Window;
+ DWORD Ret = 0;
+ BOOL Hit = FALSE;
+ WINDOWPLACEMENT wndpl;
+
+ UserEnterShared();
+
+ if (!(Window = UserGetWindowObject(hWnd)))
+ {
+ Hit = FALSE;
+ goto Exit;
+ }
+
+ _SEH2_TRY
+ {
+ if(rectWnd)
+ {
+ ProbeForWrite(rectWnd,
+ sizeof(RECT),
+ 1);
+ }
+ if(ptIcon)
+ {
+ ProbeForWrite(ptIcon,
+ sizeof(POINT),
+ 1);
+ }
+
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ SetLastNtError(_SEH2_GetExceptionCode());
+ Hit = TRUE;
+ }
+ _SEH2_END;
+
+ wndpl.length = sizeof(WINDOWPLACEMENT);
+
+ if (IntGetWindowPlacement(Window, &wndpl) && !Hit)
+ {
+ _SEH2_TRY
+ {
+ if (rectWnd)
+ {
+ RtlCopyMemory(rectWnd, &wndpl.rcNormalPosition , sizeof(RECT));
+ }
+ if (ptIcon)
+ {
+ RtlCopyMemory(ptIcon, &wndpl.ptMinPosition, sizeof(POINT));
+ }
+
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ SetLastNtError(_SEH2_GetExceptionCode());
+ Hit = TRUE;
+ }
+ _SEH2_END;
+
+ if (!Hit) Ret = wndpl.showCmd;
+ }
+Exit:
+ UserLeave();
+ return Ret;
+}
+
+/*
+ * @implemented
+ */
+BOOL APIENTRY
+NtUserGetWindowPlacement(HWND hWnd,
+ WINDOWPLACEMENT *lpwndpl)
+{
+ PWND Wnd;
+ WINDOWPLACEMENT Safepl;
+ NTSTATUS Status;
+ DECLARE_RETURN(BOOL);
+
+ TRACE("Enter NtUserGetWindowPlacement\n");
+ UserEnterShared();
+
+ if (!(Wnd = UserGetWindowObject(hWnd)))
+ {
+ RETURN( FALSE);
+ }
+
+ Status = MmCopyFromCaller(&Safepl, lpwndpl, sizeof(WINDOWPLACEMENT));
+ if(!NT_SUCCESS(Status))
+ {
+ SetLastNtError(Status);
+ RETURN( FALSE);
+ }
+ if(Safepl.length != sizeof(WINDOWPLACEMENT))
+ {
+ RETURN( FALSE);
+ }
+
+ IntGetWindowPlacement(Wnd, &Safepl);
+
+ Status = MmCopyToCaller(lpwndpl, &Safepl, sizeof(WINDOWPLACEMENT));
+ if(!NT_SUCCESS(Status))
+ {
+ SetLastNtError(Status);
+ RETURN( FALSE);
+ }
+
+ RETURN( TRUE);
+
+CLEANUP:
+ TRACE("Leave NtUserGetWindowPlacement, ret=%i\n",_ret_);
+ UserLeave();
+ END_CLEANUP;
+}
+
DWORD
APIENTRY
NtUserMinMaximize(
@@ -2085,8 +2512,9 @@
if (GreIsHandleValid(hRgn))
{
hrgnCopy = IntSysCreateRectRgn(0, 0, 0, 0);
-
- NtGdiCombineRgn(hrgnCopy, hRgn, 0, RGN_COPY);
+ /* The coordinates of a window's window region are relative to the
+ upper-left corner of the window, not the client area of the window. */
+ NtGdiCombineRgn( hrgnCopy, hRgn, 0, RGN_COPY);
}
else
RETURN( 0);
@@ -2095,9 +2523,6 @@
{
hrgnCopy = NULL;
}
-
- /* Delete the region passed by the caller */
- GreDeleteObject(hRgn);
if (Window->hrgnClip)
{
@@ -2119,6 +2544,81 @@
CLEANUP:
TRACE("Leave NtUserSetWindowRgn, ret=%i\n",_ret_);
+ UserLeave();
+ END_CLEANUP;
+}
+
+/*
+ * @implemented
+ */
+DWORD APIENTRY
+NtUserSetInternalWindowPos(
+ HWND hwnd,
+ UINT showCmd,
+ LPRECT lprect,
+ LPPOINT lppt)
+{
+ WINDOWPLACEMENT wndpl;
+ UINT flags;
+ PWND Wnd;
+ RECT rect;
+ POINT pt = {0};
+ DECLARE_RETURN(BOOL);
+ USER_REFERENCE_ENTRY Ref;
+
+ TRACE("Enter NtUserSetWindowPlacement\n");
+ UserEnterExclusive();
+
+ if (!(Wnd = UserGetWindowObject(hwnd)) || // FIXME:
+ Wnd == IntGetDesktopWindow() || // pWnd->fnid == FNID_DESKTOP
+ Wnd == IntGetMessageWindow() ) // pWnd->fnid == FNID_MESSAGEWND
+ {
+ RETURN( FALSE);
+ }
+
+ _SEH2_TRY
+ {
+ if (lppt)
+ {
+ ProbeForRead(lppt, sizeof(POINT), 1);
+ RtlCopyMemory(&pt, lppt, sizeof(POINT));
+ }
+ if (lprect)
+ {
+ ProbeForRead(lprect, sizeof(RECT), 1);
+ RtlCopyMemory(&rect, lprect, sizeof(RECT));
+ }
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ SetLastNtError(_SEH2_GetExceptionCode());
+ _SEH2_YIELD(RETURN( FALSE));
+ }
+ _SEH2_END
+
+ wndpl.length = sizeof(wndpl);
+ wndpl.showCmd = showCmd;
+ wndpl.flags = flags = 0;
+
+ if ( lppt )
+ {
+ flags |= PLACE_MIN;
+ wndpl.flags |= WPF_SETMINPOSITION;
+ wndpl.ptMinPosition = pt;
+ }
+ if ( lprect )
+ {
+ flags |= PLACE_RECT;
+ wndpl.rcNormalPosition = rect;
+ }
+
+ UserRefObjectCo(Wnd, &Ref);
+ IntSetWindowPlacement(Wnd, &wndpl, flags);
+ UserDerefObjectCo(Wnd);
+ RETURN(TRUE);
+
+CLEANUP:
+ TRACE("Leave NtUserSetWindowPlacement, ret=%i\n",_ret_);
UserLeave();
END_CLEANUP;
}
@@ -2132,6 +2632,7 @@
{
PWND Wnd;
WINDOWPLACEMENT Safepl;
+ UINT Flags;
DECLARE_RETURN(BOOL);
USER_REFERENCE_ENTRY Ref;
@@ -2162,25 +2663,10 @@
RETURN( FALSE);
}
+ Flags = PLACE_MAX | PLACE_RECT;
+ if (Safepl.flags & WPF_SETMINPOSITION) Flags |= PLACE_MIN;
UserRefObjectCo(Wnd, &Ref);
-
- if ((Wnd->style & (WS_MAXIMIZE | WS_MINIMIZE)) == 0)
- {
- co_WinPosSetWindowPos(Wnd, NULL,
- Safepl.rcNormalPosition.left, Safepl.rcNormalPosition.top,
- Safepl.rcNormalPosition.right -
Safepl.rcNormalPosition.left,
- Safepl.rcNormalPosition.bottom -
Safepl.rcNormalPosition.top,
- SWP_NOZORDER | SWP_NOACTIVATE);
- }
-
- /* FIXME - change window status */
- co_WinPosShowWindow(Wnd, Safepl.showCmd);
-
- Wnd->InternalPosInitialized = TRUE;
- Wnd->InternalPos.NormalRect = Safepl.rcNormalPosition;
- Wnd->InternalPos.IconPos = Safepl.ptMinPosition;
- Wnd->InternalPos.MaxPos = Safepl.ptMaxPosition;
-
+ IntSetWindowPlacement(Wnd, &Safepl, Flags);
UserDerefObjectCo(Wnd);
RETURN(TRUE);
@@ -2191,17 +2677,43 @@
}
/*
- * @unimplemented
+ * @implemented
*/
BOOL APIENTRY
NtUserShowWindowAsync(HWND hWnd, LONG nCmdShow)
{
-#if 0
- STUB
- return 0;
-#else
- return NtUserShowWindow(hWnd, nCmdShow);
-#endif
+ PWND Window;
+ BOOL ret;
+ DECLARE_RETURN(BOOL);
+ USER_REFERENCE_ENTRY Ref;
+
+ TRACE("Enter NtUserShowWindowAsync\n");
+ UserEnterExclusive();
+
+ if (!(Window = UserGetWindowObject(hWnd)) || // FIXME:
+ Window == IntGetDesktopWindow() || // pWnd->fnid == FNID_DESKTOP
+ Window == IntGetMessageWindow() ) // pWnd->fnid == FNID_MESSAGEWND
+ {
+ RETURN(FALSE);
+ }
+
+ if ( nCmdShow > SW_MAX )
+ {
+ EngSetLastError(ERROR_INVALID_PARAMETER);
+ RETURN(FALSE);
+ }
+
+ UserRefObjectCo(Window, &Ref);
+ ret = co_IntSendMessageNoWait( hWnd, WM_ASYNC_SHOWWINDOW, nCmdShow, 0 );
+ UserDerefObjectCo(Window);
+ if (-1 == (int) ret || !ret) ret = FALSE;
+
+ RETURN(ret);
+
+CLEANUP:
+ TRACE("Leave NtUserShowWindowAsync, ret=%i\n",_ret_);
+ UserLeave();
+ END_CLEANUP;
}
/*
@@ -2243,56 +2755,54 @@
END_CLEANUP;
}
-//// Ugly NtUser API ////
-BOOL
-APIENTRY
-NtUserGetMinMaxInfo(
- HWND hWnd,
- MINMAXINFO *MinMaxInfo,
- BOOL SendMessage)
-{
- POINT Size;
- PWND Window = NULL;
- MINMAXINFO SafeMinMax;
- NTSTATUS Status;
- BOOL ret;
+
+/*
+ * @implemented
+ */
+HWND APIENTRY
+NtUserWindowFromPoint(LONG X, LONG Y)
+{
+ POINT pt;
+ HWND Ret;
+ PWND DesktopWindow = NULL, Window = NULL;
+ USHORT hittest;
+ DECLARE_RETURN(HWND);
USER_REFERENCE_ENTRY Ref;
- TRACE("Enter NtUserGetMinMaxInfo\n");
+ TRACE("Enter NtUserWindowFromPoint\n");
UserEnterExclusive();
- if(!(Window = UserGetWindowObject(hWnd)))
- {
- ret = FALSE;
- goto cleanup;
- }
-
- UserRefObjectCo(Window, &Ref);
-
- Size.x = Window->rcWindow.left;
- Size.y = Window->rcWindow.top;
- WinPosInitInternalPos(Window, &Size,
- &Window->rcWindow);
-
- co_WinPosGetMinMaxInfo(Window, &SafeMinMax.ptMaxSize,
&SafeMinMax.ptMaxPosition,
- &SafeMinMax.ptMinTrackSize,
&SafeMinMax.ptMaxTrackSize);
-
- Status = MmCopyToCaller(MinMaxInfo, &SafeMinMax, sizeof(MINMAXINFO));
- if(!NT_SUCCESS(Status))
- {
- SetLastNtError(Status);
- ret = FALSE;
- goto cleanup;
- }
-
- ret = TRUE;
-
-cleanup:
- if (Window) UserDerefObjectCo(Window);
-
- TRACE("Leave NtUserGetMinMaxInfo, ret=%i\n", ret);
+ if ((DesktopWindow = UserGetWindowObject(IntGetDesktopWindow())))
+ {
+ //PTHREADINFO pti;
+
+ pt.x = X;
+ pt.y = Y;
+
+ //hmm... threads live on desktops thus we have a reference on the desktop and
indirectly the desktop window
+ //its possible this referencing is useless, thou it shouldnt hurt...
+ UserRefObjectCo(DesktopWindow, &Ref);
+
+ //pti = PsGetCurrentThreadWin32Thread();
+ Window = co_WinPosWindowFromPoint(DesktopWindow, &pt, &hittest);
+
+ if(Window)
+ {
+ Ret = Window->head.h;
+
+ RETURN( Ret);
+ }
+ }
+
+ RETURN( NULL);
+
+CLEANUP:
+ if (Window) UserDereferenceObject(Window);
+ if (DesktopWindow) UserDerefObjectCo(DesktopWindow);
+
+ TRACE("Leave NtUserWindowFromPoint, ret=%i\n",_ret_);
UserLeave();
- return ret;
+ END_CLEANUP;
}
/* EOF */
Modified: trunk/reactos/subsystems/win32/win32k/w32ksvc.db
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/w3…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/w32ksvc.db [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/win32k/w32ksvc.db [iso-8859-1] Sat Dec 10 07:41:56
2011
@@ -683,7 +683,6 @@
#
NtUserBuildMenuItemList 4
NtUserGetMenuDefaultItem 3
-NtUserGetMinMaxInfo 3
NtUserGetMonitorInfo 2
NtUserMenuInfo 3
NtUserMenuItemInfo 5
Modified: trunk/reactos/subsystems/win32/win32k/w32ksvc.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/w3…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/w32ksvc.h [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/win32k/w32ksvc.h [iso-8859-1] Sat Dec 10 07:41:56 2011
@@ -683,7 +683,6 @@
SVC_(UserBuildMenuItemList, 4)
SVC_(UserGetMenuDefaultItem, 3)
-SVC_(UserGetMinMaxInfo, 3)
SVC_(UserGetMonitorInfo, 2)
SVC_(UserMenuInfo, 3)
SVC_(UserMenuItemInfo, 5)