mirror of
https://github.com/reactos/reactos.git
synced 2024-06-28 17:01:28 +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
|
@ -65,17 +65,7 @@ AllowSetForegroundWindow(DWORD dwProcessId)
|
|||
HDWP WINAPI
|
||||
BeginDeferWindowPos(int nNumWindows)
|
||||
{
|
||||
if (nNumWindows < 0)
|
||||
{
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return 0;
|
||||
}
|
||||
#if 0
|
||||
UNIMPLEMENTED;
|
||||
return (HDWP)0;
|
||||
#else
|
||||
return (HDWP)1;
|
||||
#endif
|
||||
return (HDWP)NtUserCallOneParam((DWORD_PTR)nNumWindows, ONEPARAM_ROUTINE_BEGINDEFERWNDPOS);
|
||||
}
|
||||
|
||||
|
||||
|
@ -567,12 +557,7 @@ DeferWindowPos(HDWP hWinPosInfo,
|
|||
int cy,
|
||||
UINT uFlags)
|
||||
{
|
||||
#if 0
|
||||
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
|
||||
EndDeferWindowPos(HDWP hWinPosInfo)
|
||||
{
|
||||
#if 0
|
||||
UNIMPLEMENTED;
|
||||
return FALSE;
|
||||
#else
|
||||
return TRUE;
|
||||
#endif
|
||||
return NtUserEndDeferWindowPosEx(hWinPosInfo, 0);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1631,10 +1631,10 @@ NtUserEnableScrollBar(
|
|||
UINT wSBflags,
|
||||
UINT wArrows);
|
||||
|
||||
DWORD
|
||||
BOOL
|
||||
NTAPI
|
||||
NtUserEndDeferWindowPosEx(
|
||||
DWORD Unknown0,
|
||||
HDWP WinPosInfo,
|
||||
DWORD Unknown1);
|
||||
|
||||
BOOL NTAPI
|
||||
|
|
|
@ -1,5 +1,32 @@
|
|||
#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) \
|
||||
((x) >= (WndObject)->rcWindow.left && \
|
||||
(x) < (WndObject)->rcWindow.right && \
|
||||
|
@ -36,3 +63,5 @@ VOID FASTCALL co_WinPosActivateOtherWindow(PWND Window);
|
|||
|
||||
VOID FASTCALL WinPosInitInternalPos(PWND WindowObject,
|
||||
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;
|
||||
}
|
||||
|
||||
/*
|
||||
* @unimplemented
|
||||
*/
|
||||
DWORD APIENTRY
|
||||
NtUserEndDeferWindowPosEx(DWORD Unknown0,
|
||||
DWORD Unknown1)
|
||||
{
|
||||
UNIMPLEMENTED
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* FillWindow: Called from User; Dialog, Edit and ListBox procs during a WM_ERASEBKGND.
|
||||
*/
|
||||
|
@ -1205,7 +1193,7 @@ NtUserFlashWindowEx(IN PFLASHWINFO pfwi)
|
|||
{
|
||||
UNIMPLEMENTED
|
||||
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1305,25 +1293,6 @@ NtUserWindowFromPhysicalPoint(POINT Point)
|
|||
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
|
||||
*
|
||||
|
|
|
@ -177,6 +177,7 @@ UserHandleOwnerByType(USER_OBJECT_TYPE type)
|
|||
case otHook:
|
||||
case otCallProc:
|
||||
case otAccel:
|
||||
case otSMWP:
|
||||
pi = GetW32ProcessInfo();
|
||||
break;
|
||||
|
||||
|
|
|
@ -157,6 +157,38 @@ NtUserCallOneParam(
|
|||
MsqPostQuitMessage(pti->MessageQueue, Param);
|
||||
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:
|
||||
RETURN( (DWORD_PTR)UserShowCursor((BOOL)Param) );
|
||||
|
||||
|
|
|
@ -1673,6 +1673,204 @@ co_WinPosWindowFromPoint(PWND ScopeWin, POINT *WinPoint, USHORT* HitTest)
|
|||
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
|
||||
APIENTRY
|
||||
NtUserGetMinMaxInfo(
|
||||
|
|
Loading…
Reference in a new issue