[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.

svn path=/trunk/; revision=54637
This commit is contained in:
James Tabor 2011-12-10 07:41:56 +00:00
parent e1207737c2
commit 527f83f57d
12 changed files with 922 additions and 473 deletions

View file

@ -557,8 +557,6 @@ keybd_event(
BYTE bScan,
DWORD dwFlags,
ULONG_PTR dwExtraInfo)
{
INPUT Input;

View file

@ -959,6 +959,13 @@ GetClientRect(HWND hWnd, LPRECT lpRect)
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;

View file

@ -68,26 +68,110 @@ WinPosActivateOtherWindow(HWND hwnd)
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)
WinPosGetMinMaxInfo(HWND hwnd, POINT* maxSize, POINT* maxPos,
POINT* minTrack, POINT* maxTrack)
{
MINMAXINFO MinMax;
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;
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);
/* 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;
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?
}

View file

@ -132,6 +132,7 @@ typedef struct _DESKTOPINFO
WCHAR szDesktopName[1];
} DESKTOPINFO, *PDESKTOPINFO;
#define CTI_THREADSYSLOCK 0x0001
#define CTI_INSENDMESSAGE 0x0002
typedef struct _CLIENTTHREADINFO
@ -567,6 +568,9 @@ typedef struct _SBINFOEX
#define WS_EX2_CONSOLEWINDOW 0X00000400
#define WS_EX2_CHILDNOACTIVATE 0X00000800
#define WPF_MININIT 0x0008
#define WPF_MAXINIT 0x0010
typedef struct _WND
{
THRDESKHEAD head;
@ -622,10 +626,10 @@ typedef struct _WND
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 tagKMDDEEXECUTEDATA
typedef struct tagKMDDELPARAM
{
UINT_PTR uiLo;
UINT_PTR uiHi;
UINT_PTR uiLo;
UINT_PTR uiHi;
} KMDDELPARAM, *PKMDDELPARAM;
@ -3258,13 +3262,6 @@ NtUserGetMenuDefaultItem(
UINT fByPos,
UINT gmdiFlags);
BOOL
NTAPI
NtUserGetMinMaxInfo(
HWND hwnd,
MINMAXINFO *MinMaxInfo,
BOOL SendMessage);
BOOL
NTAPI
NtUserGetMonitorInfo(

View file

@ -142,6 +142,13 @@ typedef struct _USER_MESSAGE_QUEUE
#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);
NTSTATUS FASTCALL co_MsqSendMessage(PUSER_MESSAGE_QUEUE MessageQueue,

View file

@ -54,4 +54,3 @@ BOOLEAN FASTCALL co_WinPosShowWindow(PWND Window, INT Cmd);
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);

View file

@ -99,6 +99,7 @@ static inline int is_pointer_message( UINT message )
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 @@ IntCallWndProcRet ( PWND Window, HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lPar
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 @@ IntDispatchMessage(PMSG pMsg)
// 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 @@ IntDispatchMessage(PMSG pMsg)
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 @@ UserPostMessage( HWND Wnd,
PWND DesktopWindow;
ULONG i;
DesktopWindow = UserGetWindowObject(IntGetDesktopWindow());
DesktopWindow = UserGetDesktopWindow();
List = IntWinListChildren(DesktopWindow);
if (List != NULL)
@ -1104,6 +1146,13 @@ UserPostMessage( HWND Wnd,
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);
@ -1145,7 +1194,6 @@ UserPostMessage( HWND Wnd,
return TRUE;
}
LRESULT FASTCALL
co_IntSendMessage( HWND hWnd,
UINT Msg,
@ -1175,7 +1223,7 @@ co_IntSendMessageTimeoutSingle( HWND hWnd,
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 @@ co_IntSendMessageTimeoutSingle( HWND hWnd,
Win32Thread = PsGetCurrentThreadWin32Thread();
if ( NULL != Win32Thread &&
if ( Win32Thread &&
Window->head.pti->MessageQueue == Win32Thread->MessageQueue)
{
if (Win32Thread->TIF_flags & TIF_INCLEANUP)
@ -1198,23 +1245,44 @@ co_IntSendMessageTimeoutSingle( HWND hWnd,
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,14 +1297,15 @@ co_IntSendMessageTimeoutSingle( HWND hWnd,
*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 @@ co_IntSendMessageTimeoutSingle( HWND hWnd,
EngSetLastError(ERROR_TIMEOUT);
RETURN( FALSE);
}
else if (! NT_SUCCESS(Status))
else if (!NT_SUCCESS(Status))
{
SetLastNtError(Status);
RETURN( FALSE);
@ -1309,20 +1378,23 @@ co_IntSendMessageTimeout( HWND hWnd,
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;
EngSetLastError(ERROR_INTERNAL_ERROR);
return 0;
}
/* Send message to the desktop window too! */
co_IntSendMessageTimeoutSingle(DesktopWindow->head.h, Msg, wParam, lParam, uFlags, uTimeout, uResult);
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 @@ co_IntSendMessageTimeout( HWND hWnd,
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 @@ co_IntSendMessageNoWait(HWND hWnd,
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,8 +1524,21 @@ co_IntSendMessageWithCallBack( HWND hWnd,
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,
hWnd,
@ -1505,9 +1612,12 @@ CLEANUP:
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 @@ co_IntDoSendMessage( HWND hWnd,
MSG KernelModeMsg;
PMSGMEMORY MsgMemoryEntry;
if (HWND_BROADCAST != hWnd)
if (hWnd != HWND_BROADCAST && hWnd != HWND_TOPMOST)
{
Window = UserGetWindowObject(hWnd);
if ( !Window )
@ -1641,7 +1751,7 @@ UserSendNotifyMessage( HWND hWnd,
PWND DesktopWindow;
ULONG i;
DesktopWindow = UserGetWindowObject(IntGetDesktopWindow());
DesktopWindow = UserGetDesktopWindow();
List = IntWinListChildren(DesktopWindow);
if (List != NULL)
@ -1649,21 +1759,22 @@ UserSendNotifyMessage( HWND hWnd,
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 @@ NtUserMessageCall( HWND hWnd,
ULONG i;
UINT fuFlags;
pwndDesk = UserGetWindowObject(IntGetDesktopWindow());
pwndDesk = UserGetDesktopWindow();
List = IntWinListChildren(pwndDesk);
if (parm.flags & BSF_QUERY)

View file

@ -1040,21 +1040,6 @@ NtUserSetImeOwnerWindow(DWORD Unknown0,
return 0;
}
/*
* @unimplemented
*/
DWORD APIENTRY
NtUserSetInternalWindowPos(
HWND hwnd,
UINT showCmd,
LPRECT rect,
LPPOINT pt)
{
STUB
return 0;
}
/*
* @unimplemented
*/

View file

@ -1262,51 +1262,6 @@ IntUnlinkWindow(PWND Wnd)
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 @@ CLEANUP:
}
/*
* @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(
@ -3595,82 +3476,6 @@ CLEANUP:
END_CLEANUP;
}
/*
* @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.
@ -3827,7 +3632,6 @@ CLEANUP:
END_CLEANUP;
}
/*
* @implemented
*/
@ -3872,57 +3676,6 @@ CLEANUP:
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
*

File diff suppressed because it is too large Load diff

View file

@ -683,7 +683,6 @@ NtGdiOffsetWindowOrgEx 4
#
NtUserBuildMenuItemList 4
NtUserGetMenuDefaultItem 3
NtUserGetMinMaxInfo 3
NtUserGetMonitorInfo 2
NtUserMenuInfo 3
NtUserMenuItemInfo 5

View file

@ -683,7 +683,6 @@ SVC_(GdiOffsetWindowOrgEx, 4)
SVC_(UserBuildMenuItemList, 4)
SVC_(UserGetMenuDefaultItem, 3)
SVC_(UserGetMinMaxInfo, 3)
SVC_(UserGetMonitorInfo, 2)
SVC_(UserMenuInfo, 3)
SVC_(UserMenuItemInfo, 5)