mirror of
https://github.com/reactos/reactos.git
synced 2025-08-05 17:52:56 +00:00
[Win32k]
- Implement the set of DeferWindowPos functions. Regedit (one of many application) uses it and allocated three when it should be four. This was a good test to verify the batch list growing routine. Instead of drawing per DeferWindowPos call, now a real list is created and run down as a batch. - ReactOS should handle this the correct way and a good test case is located here: http://bugs.winehq.org/show_bug.cgi?id=23187 - The code is from wine and modified for the use in ReactOS. svn path=/trunk/; revision=51089
This commit is contained in:
parent
f5912e7155
commit
115d07d686
7 changed files with 265 additions and 56 deletions
|
@ -65,17 +65,7 @@ AllowSetForegroundWindow(DWORD dwProcessId)
|
||||||
HDWP WINAPI
|
HDWP WINAPI
|
||||||
BeginDeferWindowPos(int nNumWindows)
|
BeginDeferWindowPos(int nNumWindows)
|
||||||
{
|
{
|
||||||
if (nNumWindows < 0)
|
return (HDWP)NtUserCallOneParam((DWORD_PTR)nNumWindows, ONEPARAM_ROUTINE_BEGINDEFERWNDPOS);
|
||||||
{
|
|
||||||
SetLastError(ERROR_INVALID_PARAMETER);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#if 0
|
|
||||||
UNIMPLEMENTED;
|
|
||||||
return (HDWP)0;
|
|
||||||
#else
|
|
||||||
return (HDWP)1;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -567,12 +557,7 @@ DeferWindowPos(HDWP hWinPosInfo,
|
||||||
int cy,
|
int cy,
|
||||||
UINT uFlags)
|
UINT uFlags)
|
||||||
{
|
{
|
||||||
#if 0
|
|
||||||
return NtUserDeferWindowPos(hWinPosInfo, hWnd, hWndInsertAfter, x, y, cx, cy, uFlags);
|
return NtUserDeferWindowPos(hWinPosInfo, hWnd, hWndInsertAfter, x, y, cx, cy, uFlags);
|
||||||
#else
|
|
||||||
SetWindowPos(hWnd, hWndInsertAfter, x, y, cx, cy, uFlags);
|
|
||||||
return hWinPosInfo;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -582,12 +567,7 @@ DeferWindowPos(HDWP hWinPosInfo,
|
||||||
BOOL WINAPI
|
BOOL WINAPI
|
||||||
EndDeferWindowPos(HDWP hWinPosInfo)
|
EndDeferWindowPos(HDWP hWinPosInfo)
|
||||||
{
|
{
|
||||||
#if 0
|
return NtUserEndDeferWindowPosEx(hWinPosInfo, 0);
|
||||||
UNIMPLEMENTED;
|
|
||||||
return FALSE;
|
|
||||||
#else
|
|
||||||
return TRUE;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1631,10 +1631,10 @@ NtUserEnableScrollBar(
|
||||||
UINT wSBflags,
|
UINT wSBflags,
|
||||||
UINT wArrows);
|
UINT wArrows);
|
||||||
|
|
||||||
DWORD
|
BOOL
|
||||||
NTAPI
|
NTAPI
|
||||||
NtUserEndDeferWindowPosEx(
|
NtUserEndDeferWindowPosEx(
|
||||||
DWORD Unknown0,
|
HDWP WinPosInfo,
|
||||||
DWORD Unknown1);
|
DWORD Unknown1);
|
||||||
|
|
||||||
BOOL NTAPI
|
BOOL NTAPI
|
||||||
|
|
|
@ -1,5 +1,32 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
typedef struct _CVR // Tag Ussw
|
||||||
|
{
|
||||||
|
WINDOWPOS pos;
|
||||||
|
LONG xClientNew;
|
||||||
|
LONG yClientNew;
|
||||||
|
LONG cxClientNew;
|
||||||
|
LONG cyClientNew;
|
||||||
|
RECT rcBlt;
|
||||||
|
LONG dxBlt;
|
||||||
|
LONG dyBlt;
|
||||||
|
UINT fsRE;
|
||||||
|
HRGN hrgnVisOld;
|
||||||
|
PTHREADINFO pti;
|
||||||
|
HRGN hrgnClip;
|
||||||
|
HRGN hrgnInterMonitor;
|
||||||
|
} CVR, *PCVR;
|
||||||
|
|
||||||
|
typedef struct _SMWP
|
||||||
|
{
|
||||||
|
HEAD head;
|
||||||
|
UINT bShellNotify:1;
|
||||||
|
UINT bHandle:1;
|
||||||
|
INT ccvr;
|
||||||
|
INT ccvrAlloc;
|
||||||
|
PCVR acvr;
|
||||||
|
} SMWP, *PSMWP;
|
||||||
|
|
||||||
#define IntPtInWindow(WndObject,x,y) \
|
#define IntPtInWindow(WndObject,x,y) \
|
||||||
((x) >= (WndObject)->rcWindow.left && \
|
((x) >= (WndObject)->rcWindow.left && \
|
||||||
(x) < (WndObject)->rcWindow.right && \
|
(x) < (WndObject)->rcWindow.right && \
|
||||||
|
@ -36,3 +63,5 @@ VOID FASTCALL co_WinPosActivateOtherWindow(PWND Window);
|
||||||
|
|
||||||
VOID FASTCALL WinPosInitInternalPos(PWND WindowObject,
|
VOID FASTCALL WinPosInitInternalPos(PWND WindowObject,
|
||||||
POINT *pt, RECTL *RestoreRect);
|
POINT *pt, RECTL *RestoreRect);
|
||||||
|
BOOL FASTCALL IntEndDeferWindowPosEx(HDWP);
|
||||||
|
HDWP FASTCALL IntDeferWindowPos(HDWP,HWND,HWND,INT,INT,INT,INT,UINT);
|
||||||
|
|
|
@ -1168,18 +1168,6 @@ NtUserDrawMenuBarTemp(
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* @unimplemented
|
|
||||||
*/
|
|
||||||
DWORD APIENTRY
|
|
||||||
NtUserEndDeferWindowPosEx(DWORD Unknown0,
|
|
||||||
DWORD Unknown1)
|
|
||||||
{
|
|
||||||
UNIMPLEMENTED
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* FillWindow: Called from User; Dialog, Edit and ListBox procs during a WM_ERASEBKGND.
|
* FillWindow: Called from User; Dialog, Edit and ListBox procs during a WM_ERASEBKGND.
|
||||||
*/
|
*/
|
||||||
|
@ -1205,7 +1193,7 @@ NtUserFlashWindowEx(IN PFLASHWINFO pfwi)
|
||||||
{
|
{
|
||||||
UNIMPLEMENTED
|
UNIMPLEMENTED
|
||||||
|
|
||||||
return 0;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1305,25 +1293,6 @@ NtUserWindowFromPhysicalPoint(POINT Point)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* @unimplemented
|
|
||||||
*/
|
|
||||||
HDWP APIENTRY
|
|
||||||
NtUserDeferWindowPos(HDWP WinPosInfo,
|
|
||||||
HWND Wnd,
|
|
||||||
HWND WndInsertAfter,
|
|
||||||
int x,
|
|
||||||
int y,
|
|
||||||
int cx,
|
|
||||||
int cy,
|
|
||||||
UINT Flags)
|
|
||||||
{
|
|
||||||
UNIMPLEMENTED
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* NtUserResolveDesktopForWOW
|
* NtUserResolveDesktopForWOW
|
||||||
*
|
*
|
||||||
|
|
|
@ -177,6 +177,7 @@ UserHandleOwnerByType(USER_OBJECT_TYPE type)
|
||||||
case otHook:
|
case otHook:
|
||||||
case otCallProc:
|
case otCallProc:
|
||||||
case otAccel:
|
case otAccel:
|
||||||
|
case otSMWP:
|
||||||
pi = GetW32ProcessInfo();
|
pi = GetW32ProcessInfo();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
|
@ -157,6 +157,38 @@ NtUserCallOneParam(
|
||||||
MsqPostQuitMessage(pti->MessageQueue, Param);
|
MsqPostQuitMessage(pti->MessageQueue, Param);
|
||||||
RETURN(TRUE);
|
RETURN(TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case ONEPARAM_ROUTINE_BEGINDEFERWNDPOS:
|
||||||
|
{
|
||||||
|
PSMWP psmwp;
|
||||||
|
HDWP hDwp = NULL;
|
||||||
|
if (Param < 0)
|
||||||
|
{
|
||||||
|
EngSetLastError(ERROR_INVALID_PARAMETER);
|
||||||
|
RETURN(0);
|
||||||
|
}
|
||||||
|
/* Windows allows zero count, in which case it allocates context for 8 moves */
|
||||||
|
if (Param == 0) Param = 8;
|
||||||
|
|
||||||
|
psmwp = (PSMWP) UserCreateObject( gHandleTable,
|
||||||
|
NULL,
|
||||||
|
(PHANDLE)&hDwp,
|
||||||
|
otSMWP,
|
||||||
|
sizeof(SMWP));
|
||||||
|
if (!psmwp) RETURN(0);
|
||||||
|
psmwp->acvr = ExAllocatePoolWithTag(PagedPool, Param * sizeof(CVR), USERTAG_SWP);
|
||||||
|
if (!psmwp->acvr)
|
||||||
|
{
|
||||||
|
UserDeleteObject(hDwp, otSMWP);
|
||||||
|
RETURN(0);
|
||||||
|
}
|
||||||
|
RtlZeroMemory(psmwp->acvr, Param * sizeof(CVR));
|
||||||
|
psmwp->bHandle = TRUE;
|
||||||
|
psmwp->ccvr = 0; // actualCount
|
||||||
|
psmwp->ccvrAlloc = Param; // suggestedCount
|
||||||
|
RETURN((DWORD_PTR)hDwp);
|
||||||
|
}
|
||||||
|
|
||||||
case ONEPARAM_ROUTINE_SHOWCURSOR:
|
case ONEPARAM_ROUTINE_SHOWCURSOR:
|
||||||
RETURN( (DWORD_PTR)UserShowCursor((BOOL)Param) );
|
RETURN( (DWORD_PTR)UserShowCursor((BOOL)Param) );
|
||||||
|
|
||||||
|
|
|
@ -1673,6 +1673,204 @@ co_WinPosWindowFromPoint(PWND ScopeWin, POINT *WinPoint, USHORT* HitTest)
|
||||||
return Window;
|
return Window;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
HDWP
|
||||||
|
FASTCALL
|
||||||
|
IntDeferWindowPos( HDWP hdwp,
|
||||||
|
HWND hwnd,
|
||||||
|
HWND hwndAfter,
|
||||||
|
INT x,
|
||||||
|
INT y,
|
||||||
|
INT cx,
|
||||||
|
INT cy,
|
||||||
|
UINT flags )
|
||||||
|
{
|
||||||
|
PSMWP pDWP;
|
||||||
|
int i;
|
||||||
|
HDWP retvalue = hdwp;
|
||||||
|
|
||||||
|
DPRINT("hdwp %p, hwnd %p, after %p, %d,%d (%dx%d), flags %08x\n",
|
||||||
|
hdwp, hwnd, hwndAfter, x, y, cx, cy, flags);
|
||||||
|
|
||||||
|
if (flags & ~(SWP_NOSIZE | SWP_NOMOVE |
|
||||||
|
SWP_NOZORDER | SWP_NOREDRAW |
|
||||||
|
SWP_NOACTIVATE | SWP_NOCOPYBITS |
|
||||||
|
SWP_NOOWNERZORDER|SWP_SHOWWINDOW |
|
||||||
|
SWP_HIDEWINDOW | SWP_FRAMECHANGED))
|
||||||
|
{
|
||||||
|
EngSetLastError(ERROR_INVALID_PARAMETER);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(pDWP = (PSMWP)UserGetObject(gHandleTable, hdwp, otSMWP)))
|
||||||
|
{
|
||||||
|
EngSetLastError(ERROR_INVALID_DWP_HANDLE);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < pDWP->ccvr; i++)
|
||||||
|
{
|
||||||
|
if (pDWP->acvr[i].pos.hwnd == hwnd)
|
||||||
|
{
|
||||||
|
/* Merge with the other changes */
|
||||||
|
if (!(flags & SWP_NOZORDER))
|
||||||
|
{
|
||||||
|
pDWP->acvr[i].pos.hwndInsertAfter = hwndAfter;
|
||||||
|
}
|
||||||
|
if (!(flags & SWP_NOMOVE))
|
||||||
|
{
|
||||||
|
pDWP->acvr[i].pos.x = x;
|
||||||
|
pDWP->acvr[i].pos.y = y;
|
||||||
|
}
|
||||||
|
if (!(flags & SWP_NOSIZE))
|
||||||
|
{
|
||||||
|
pDWP->acvr[i].pos.cx = cx;
|
||||||
|
pDWP->acvr[i].pos.cy = cy;
|
||||||
|
}
|
||||||
|
pDWP->acvr[i].pos.flags &= flags | ~(SWP_NOSIZE | SWP_NOMOVE |
|
||||||
|
SWP_NOZORDER | SWP_NOREDRAW |
|
||||||
|
SWP_NOACTIVATE | SWP_NOCOPYBITS|
|
||||||
|
SWP_NOOWNERZORDER);
|
||||||
|
pDWP->acvr[i].pos.flags |= flags & (SWP_SHOWWINDOW | SWP_HIDEWINDOW |
|
||||||
|
SWP_FRAMECHANGED);
|
||||||
|
goto END;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (pDWP->ccvr >= pDWP->ccvrAlloc)
|
||||||
|
{
|
||||||
|
PCVR newpos = ExAllocatePoolWithTag(PagedPool, pDWP->ccvrAlloc * 2 * sizeof(CVR), USERTAG_SWP);
|
||||||
|
if (!newpos)
|
||||||
|
{
|
||||||
|
retvalue = NULL;
|
||||||
|
goto END;
|
||||||
|
}
|
||||||
|
RtlZeroMemory(newpos, pDWP->ccvrAlloc * 2 * sizeof(CVR));
|
||||||
|
RtlCopyMemory(newpos, pDWP->acvr, pDWP->ccvrAlloc * sizeof(CVR));
|
||||||
|
ExFreePoolWithTag(pDWP->acvr, USERTAG_SWP);
|
||||||
|
pDWP->ccvrAlloc *= 2;
|
||||||
|
pDWP->acvr = newpos;
|
||||||
|
}
|
||||||
|
pDWP->acvr[pDWP->ccvr].pos.hwnd = hwnd;
|
||||||
|
pDWP->acvr[pDWP->ccvr].pos.hwndInsertAfter = hwndAfter;
|
||||||
|
pDWP->acvr[pDWP->ccvr].pos.x = x;
|
||||||
|
pDWP->acvr[pDWP->ccvr].pos.y = y;
|
||||||
|
pDWP->acvr[pDWP->ccvr].pos.cx = cx;
|
||||||
|
pDWP->acvr[pDWP->ccvr].pos.cy = cy;
|
||||||
|
pDWP->acvr[pDWP->ccvr].pos.flags = flags;
|
||||||
|
pDWP->acvr[pDWP->ccvr].hrgnClip = NULL;
|
||||||
|
pDWP->acvr[pDWP->ccvr].hrgnInterMonitor = NULL;
|
||||||
|
pDWP->ccvr++;
|
||||||
|
END:
|
||||||
|
return retvalue;
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL FASTCALL IntEndDeferWindowPosEx( HDWP hdwp )
|
||||||
|
{
|
||||||
|
PSMWP pDWP;
|
||||||
|
PCVR winpos;
|
||||||
|
BOOL res = TRUE;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
DPRINT("%p\n", hdwp);
|
||||||
|
|
||||||
|
if (!(pDWP = (PSMWP)UserGetObject(gHandleTable, hdwp, otSMWP)))
|
||||||
|
{
|
||||||
|
EngSetLastError(ERROR_INVALID_DWP_HANDLE);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0, winpos = pDWP->acvr; res && i < pDWP->ccvr; i++, winpos++)
|
||||||
|
{
|
||||||
|
DPRINT("hwnd %p, after %p, %d,%d (%dx%d), flags %08x\n",
|
||||||
|
winpos->pos.hwnd, winpos->pos.hwndInsertAfter, winpos->pos.x, winpos->pos.y,
|
||||||
|
winpos->pos.cx, winpos->pos.cy, winpos->pos.flags);
|
||||||
|
|
||||||
|
res = co_WinPosSetWindowPos( UserGetWindowObject(winpos->pos.hwnd),
|
||||||
|
winpos->pos.hwndInsertAfter,
|
||||||
|
winpos->pos.x,
|
||||||
|
winpos->pos.y,
|
||||||
|
winpos->pos.cx,
|
||||||
|
winpos->pos.cy,
|
||||||
|
winpos->pos.flags);
|
||||||
|
}
|
||||||
|
ExFreePoolWithTag(pDWP->acvr, USERTAG_SWP);
|
||||||
|
UserDeleteObject(hdwp, otSMWP);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @implemented
|
||||||
|
*/
|
||||||
|
BOOL APIENTRY
|
||||||
|
NtUserEndDeferWindowPosEx(HDWP WinPosInfo,
|
||||||
|
DWORD Unknown1)
|
||||||
|
{
|
||||||
|
BOOL Ret;
|
||||||
|
DPRINT("Enter NtUserEndDeferWindowPosEx\n");
|
||||||
|
UserEnterExclusive();
|
||||||
|
Ret = IntEndDeferWindowPosEx(WinPosInfo);
|
||||||
|
DPRINT("Leave NtUserEndDeferWindowPosEx, ret=%i\n", Ret);
|
||||||
|
UserLeave();
|
||||||
|
return Ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @implemented
|
||||||
|
*/
|
||||||
|
HDWP APIENTRY
|
||||||
|
NtUserDeferWindowPos(HDWP WinPosInfo,
|
||||||
|
HWND Wnd,
|
||||||
|
HWND WndInsertAfter,
|
||||||
|
int x,
|
||||||
|
int y,
|
||||||
|
int cx,
|
||||||
|
int cy,
|
||||||
|
UINT Flags)
|
||||||
|
{
|
||||||
|
PWND pWnd, pWndIA;
|
||||||
|
HDWP Ret = NULL;
|
||||||
|
UINT Tmp = ~(SWP_ASYNCWINDOWPOS|SWP_DEFERERASE|SWP_NOSENDCHANGING|SWP_NOREPOSITION|
|
||||||
|
SWP_NOCOPYBITS|SWP_HIDEWINDOW|SWP_SHOWWINDOW|SWP_FRAMECHANGED|
|
||||||
|
SWP_NOACTIVATE|SWP_NOREDRAW|SWP_NOZORDER|SWP_NOMOVE|SWP_NOSIZE);
|
||||||
|
|
||||||
|
DPRINT("Enter NtUsereferWindowPos\n");
|
||||||
|
UserEnterExclusive();
|
||||||
|
|
||||||
|
if ( Flags & Tmp )
|
||||||
|
{
|
||||||
|
EngSetLastError(ERROR_INVALID_FLAGS);
|
||||||
|
goto Exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
pWnd = UserGetWindowObject(Wnd);
|
||||||
|
if ( !pWnd ||
|
||||||
|
pWnd == IntGetDesktopWindow() ||
|
||||||
|
pWnd == IntGetMessageWindow() )
|
||||||
|
{
|
||||||
|
goto Exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( WndInsertAfter &&
|
||||||
|
WndInsertAfter != HWND_BOTTOM &&
|
||||||
|
WndInsertAfter != HWND_TOPMOST &&
|
||||||
|
WndInsertAfter != HWND_NOTOPMOST )
|
||||||
|
{
|
||||||
|
pWndIA = UserGetWindowObject(WndInsertAfter);
|
||||||
|
if ( !pWndIA ||
|
||||||
|
pWndIA == IntGetDesktopWindow() ||
|
||||||
|
pWndIA == IntGetMessageWindow() )
|
||||||
|
{
|
||||||
|
goto Exit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ret = IntDeferWindowPos(WinPosInfo, Wnd, WndInsertAfter, x, y, cx, cy, Flags);
|
||||||
|
|
||||||
|
Exit:
|
||||||
|
DPRINT("Leave NtUserDeferWindowPos, ret=%i\n", Ret);
|
||||||
|
UserLeave();
|
||||||
|
return Ret;
|
||||||
|
}
|
||||||
|
|
||||||
BOOL
|
BOOL
|
||||||
APIENTRY
|
APIENTRY
|
||||||
NtUserGetMinMaxInfo(
|
NtUserGetMinMaxInfo(
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue