Author: jimtabor
Date: Wed Mar 1 16:51:13 2017
New Revision: 74015
URL:
http://svn.reactos.org/svn/reactos?rev=74015&view=rev
Log:
[NtUser]
- Move functions around.
Modified:
trunk/reactos/win32ss/user/ntuser/winpos.c
Modified: trunk/reactos/win32ss/user/ntuser/winpos.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/user/ntuser/winpos…
==============================================================================
--- trunk/reactos/win32ss/user/ntuser/winpos.c [iso-8859-1] (original)
+++ trunk/reactos/win32ss/user/ntuser/winpos.c [iso-8859-1] Wed Mar 1 16:51:13 2017
@@ -835,6 +835,1362 @@
Window->InternalPos.flags |= WPF_MININIT;
TRACE("Position is set! X:%d Y:%d\n",Pos->x,Pos->y);
return;
+}
+
+BOOL
+UserHasWindowEdge(DWORD Style, DWORD ExStyle)
+{
+ if (Style & WS_MINIMIZE)
+ return TRUE;
+ if (ExStyle & WS_EX_DLGMODALFRAME)
+ return TRUE;
+ if (ExStyle & WS_EX_STATICEDGE)
+ return FALSE;
+ if (Style & WS_THICKFRAME)
+ return TRUE;
+ Style &= WS_CAPTION;
+ if (Style == WS_DLGFRAME || Style == WS_CAPTION)
+ return TRUE;
+ return FALSE;
+}
+
+VOID FASTCALL
+IntGetWindowBorderMeasures(PWND Wnd, UINT *cx, UINT *cy)
+{
+ if(HAS_DLGFRAME(Wnd->style, Wnd->ExStyle) && !(Wnd->style &
WS_MINIMIZE))
+ {
+ *cx = UserGetSystemMetrics(SM_CXDLGFRAME);
+ *cy = UserGetSystemMetrics(SM_CYDLGFRAME);
+ }
+ else
+ {
+ if(HAS_THICKFRAME(Wnd->style, Wnd->ExStyle)&& !(Wnd->style &
WS_MINIMIZE))
+ {
+ *cx = UserGetSystemMetrics(SM_CXFRAME);
+ *cy = UserGetSystemMetrics(SM_CYFRAME);
+ }
+ else if(HAS_THINFRAME(Wnd->style, Wnd->ExStyle))
+ {
+ *cx = UserGetSystemMetrics(SM_CXBORDER);
+ *cy = UserGetSystemMetrics(SM_CYBORDER);
+ }
+ else
+ {
+ *cx = *cy = 0;
+ }
+ }
+}
+
+VOID
+UserGetWindowBorders(DWORD Style, DWORD ExStyle, SIZE *Size, BOOL WithClient)
+{
+ DWORD Border = 0;
+
+ if (UserHasWindowEdge(Style, ExStyle))
+ Border += 2;
+ else if (ExStyle & WS_EX_STATICEDGE)
+ Border += 1;
+ if ((ExStyle & WS_EX_CLIENTEDGE) && WithClient)
+ Border += 2;
+ if (Style & WS_CAPTION || ExStyle & WS_EX_DLGMODALFRAME)
+ Border ++;
+ Size->cx = Size->cy = Border;
+ if ((Style & WS_THICKFRAME) && !(Style & WS_MINIMIZE))
+ {
+ Size->cx += UserGetSystemMetrics(SM_CXFRAME) -
UserGetSystemMetrics(SM_CXDLGFRAME);
+ Size->cy += UserGetSystemMetrics(SM_CYFRAME) -
UserGetSystemMetrics(SM_CYDLGFRAME);
+ }
+ Size->cx *= UserGetSystemMetrics(SM_CXBORDER);
+ Size->cy *= UserGetSystemMetrics(SM_CYBORDER);
+}
+
+BOOL WINAPI
+UserAdjustWindowRectEx(LPRECT lpRect,
+ DWORD dwStyle,
+ BOOL bMenu,
+ DWORD dwExStyle)
+{
+ SIZE BorderSize;
+
+ if (bMenu)
+ {
+ lpRect->top -= UserGetSystemMetrics(SM_CYMENU);
+ }
+ if ((dwStyle & WS_CAPTION) == WS_CAPTION)
+ {
+ if (dwExStyle & WS_EX_TOOLWINDOW)
+ lpRect->top -= UserGetSystemMetrics(SM_CYSMCAPTION);
+ else
+ lpRect->top -= UserGetSystemMetrics(SM_CYCAPTION);
+ }
+ UserGetWindowBorders(dwStyle, dwExStyle, &BorderSize, TRUE);
+ RECTL_vInflateRect(
+ lpRect,
+ BorderSize.cx,
+ BorderSize.cy);
+
+ return TRUE;
+}
+
+UINT FASTCALL
+co_WinPosGetMinMaxInfo(PWND Window, POINT* MaxSize, POINT* MaxPos,
+ POINT* MinTrack, POINT* MaxTrack)
+{
+ MINMAXINFO MinMax;
+ PMONITOR monitor;
+ INT xinc, yinc;
+ LONG style = Window->style;
+ LONG adjustedStyle;
+ LONG exstyle = Window->ExStyle;
+ RECT rc;
+
+ ASSERT_REFS_CO(Window);
+
+ /* Compute default values */
+
+ rc = Window->rcWindow;
+ 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;
+
+ if(Window->spwndParent)
+ IntGetClientRect(Window->spwndParent, &rc);
+ UserAdjustWindowRectEx(&rc, adjustedStyle, ((style & WS_POPUP) &&
Window->IDMenu), 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 = UserGetSystemMetrics(SM_CXMINTRACK);
+ MinMax.ptMinTrackSize.y = UserGetSystemMetrics(SM_CYMINTRACK);
+ }
+ else
+ {
+ MinMax.ptMinTrackSize.x = 2 * xinc;
+ MinMax.ptMinTrackSize.y = 2 * yinc;
+ }
+ MinMax.ptMaxTrackSize.x = UserGetSystemMetrics(SM_CXMAXTRACK);
+ MinMax.ptMaxTrackSize.y = UserGetSystemMetrics(SM_CYMAXTRACK);
+ MinMax.ptMaxPosition.x = -xinc;
+ MinMax.ptMaxPosition.y = -yinc;
+
+ if (!EMPTYPOINT(Window->InternalPos.MaxPos)) MinMax.ptMaxPosition =
Window->InternalPos.MaxPos;
+
+ co_IntSendMessage(Window->head.h, WM_GETMINMAXINFO, 0, (LPARAM)&MinMax);
+
+ /* if the app didn't change the values, adapt them for the current monitor */
+ if ((monitor = UserGetPrimaryMonitor()))
+ {
+ RECT rc_work;
+
+ rc_work = monitor->rcMonitor;
+
+ if (style & WS_MAXIMIZEBOX)
+ {
+ if ((style & WS_CAPTION) == WS_CAPTION || !(style & (WS_CHILD |
WS_POPUP)))
+ rc_work = monitor->rcWork;
+ }
+
+ if (MinMax.ptMaxSize.x == UserGetSystemMetrics(SM_CXSCREEN) + 2 * xinc
&&
+ MinMax.ptMaxSize.y == UserGetSystemMetrics(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;
+ }
+ if (MinMax.ptMaxSize.x >= (monitor->rcMonitor.right -
monitor->rcMonitor.left) &&
+ MinMax.ptMaxSize.y >= (monitor->rcMonitor.bottom -
monitor->rcMonitor.top) )
+ Window->state |= WNDS_MAXIMIZESTOMONITOR;
+ else
+ Window->state &= ~WNDS_MAXIMIZESTOMONITOR;
+ }
+
+
+ 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?
+}
+
+static
+BOOL
+IntValidateParent(PWND Child, PREGION ValidateRgn)
+{
+ PWND ParentWnd = Child;
+
+ if (ParentWnd->style & WS_CHILD)
+ {
+ do
+ ParentWnd = ParentWnd->spwndParent;
+ while (ParentWnd->style & WS_CHILD);
+ }
+
+ ParentWnd = Child->spwndParent;
+ while (ParentWnd)
+ {
+ if (ParentWnd->style & WS_CLIPCHILDREN)
+ break;
+
+ if (ParentWnd->hrgnUpdate != 0)
+ {
+ IntInvalidateWindows( ParentWnd,
+ ValidateRgn,
+ RDW_VALIDATE | RDW_NOCHILDREN);
+ }
+
+ ParentWnd = ParentWnd->spwndParent;
+ }
+
+ return TRUE;
+}
+
+static
+VOID FASTCALL
+FixClientRect(PRECTL ClientRect, PRECTL WindowRect)
+{
+ if (ClientRect->left < WindowRect->left)
+ {
+ ClientRect->left = WindowRect->left;
+ }
+ else if (WindowRect->right < ClientRect->left)
+ {
+ ClientRect->left = WindowRect->right;
+ }
+ if (ClientRect->right < WindowRect->left)
+ {
+ ClientRect->right = WindowRect->left;
+ }
+ else if (WindowRect->right < ClientRect->right)
+ {
+ ClientRect->right = WindowRect->right;
+ }
+ if (ClientRect->top < WindowRect->top)
+ {
+ ClientRect->top = WindowRect->top;
+ }
+ else if (WindowRect->bottom < ClientRect->top)
+ {
+ ClientRect->top = WindowRect->bottom;
+ }
+ if (ClientRect->bottom < WindowRect->top)
+ {
+ ClientRect->bottom = WindowRect->top;
+ }
+ else if (WindowRect->bottom < ClientRect->bottom)
+ {
+ ClientRect->bottom = WindowRect->bottom;
+ }
+}
+/***********************************************************************
+ * get_valid_rects
+ *
+ * Compute the valid rects from the old and new client rect and WVR_* flags.
+ * Helper for WM_NCCALCSIZE handling.
+ */
+static
+VOID FASTCALL
+get_valid_rects( RECTL *old_client, RECTL *new_client, UINT flags, RECTL *valid )
+{
+ int cx, cy;
+
+ if (flags & WVR_REDRAW)
+ {
+ RECTL_vSetEmptyRect( &valid[0] );
+ RECTL_vSetEmptyRect( &valid[1] );
+ return;
+ }
+
+ if (flags & WVR_VALIDRECTS)
+ {
+ if (!RECTL_bIntersectRect( &valid[0], &valid[0], new_client ) ||
+ !RECTL_bIntersectRect( &valid[1], &valid[1], old_client ))
+ {
+ RECTL_vSetEmptyRect( &valid[0] );
+ RECTL_vSetEmptyRect( &valid[1] );
+ return;
+ }
+ flags = WVR_ALIGNLEFT | WVR_ALIGNTOP;
+ }
+ else
+ {
+ valid[0] = *new_client;
+ valid[1] = *old_client;
+ }
+
+ /* make sure the rectangles have the same size */
+ cx = min( valid[0].right - valid[0].left, valid[1].right - valid[1].left );
+ cy = min( valid[0].bottom - valid[0].top, valid[1].bottom - valid[1].top );
+
+ if (flags & WVR_ALIGNBOTTOM)
+ {
+ valid[0].top = valid[0].bottom - cy;
+ valid[1].top = valid[1].bottom - cy;
+ }
+ else
+ {
+ valid[0].bottom = valid[0].top + cy;
+ valid[1].bottom = valid[1].top + cy;
+ }
+ if (flags & WVR_ALIGNRIGHT)
+ {
+ valid[0].left = valid[0].right - cx;
+ valid[1].left = valid[1].right - cx;
+ }
+ else
+ {
+ valid[0].right = valid[0].left + cx;
+ valid[1].right = valid[1].left + cx;
+ }
+}
+
+static
+LONG FASTCALL
+co_WinPosDoNCCALCSize(PWND Window, PWINDOWPOS WinPos, RECTL* WindowRect, RECTL*
ClientRect, RECTL* validRects)
+{
+ PWND Parent;
+ UINT wvrFlags = 0;
+
+ ASSERT_REFS_CO(Window);
+
+ /* Send WM_NCCALCSIZE message to get new client area */
+ if ((WinPos->flags & (SWP_FRAMECHANGED | SWP_NOSIZE)) != SWP_NOSIZE)
+ {
+ NCCALCSIZE_PARAMS params;
+ WINDOWPOS winposCopy;
+
+ params.rgrc[0] = *WindowRect; // new coordinates of a window that has been
moved or resized
+ params.rgrc[1] = Window->rcWindow; // window before it was moved or resized
+ params.rgrc[2] = Window->rcClient; // client area before the window was moved or
resized
+
+ Parent = Window->spwndParent;
+ if (0 != (Window->style & WS_CHILD) && Parent)
+ {
+ RECTL_vOffsetRect(&(params.rgrc[0]), - Parent->rcClient.left, -
Parent->rcClient.top);
+ RECTL_vOffsetRect(&(params.rgrc[1]), - Parent->rcClient.left, -
Parent->rcClient.top);
+ RECTL_vOffsetRect(&(params.rgrc[2]), - Parent->rcClient.left, -
Parent->rcClient.top);
+ }
+
+ params.lppos = &winposCopy;
+ winposCopy = *WinPos;
+
+ wvrFlags = co_IntSendMessage(Window->head.h, WM_NCCALCSIZE, TRUE, (LPARAM)
¶ms);
+
+ /* If the application send back garbage, ignore it */
+ if (params.rgrc[0].left <= params.rgrc[0].right &&
+ params.rgrc[0].top <= params.rgrc[0].bottom)
+ {
+ *ClientRect = params.rgrc[0]; // First rectangle contains the coordinates of the
new client rectangle resulting from the move or resize
+ if ((Window->style & WS_CHILD) && Parent)
+ {
+ RECTL_vOffsetRect(ClientRect, Parent->rcClient.left,
Parent->rcClient.top);
+ }
+ FixClientRect(ClientRect, WindowRect);
+ }
+
+ if (ClientRect->left != Window->rcClient.left ||
+ ClientRect->top != Window->rcClient.top)
+ {
+ WinPos->flags &= ~SWP_NOCLIENTMOVE;
+ }
+
+ if (ClientRect->right - ClientRect->left != Window->rcClient.right -
Window->rcClient.left)
+ {
+ WinPos->flags &= ~SWP_NOCLIENTSIZE;
+ }
+ else
+ wvrFlags &= ~WVR_HREDRAW;
+
+ if (ClientRect->bottom - ClientRect->top != Window->rcClient.bottom -
Window->rcClient.top)
+ {
+ WinPos->flags &= ~SWP_NOCLIENTSIZE;
+ }
+ else
+ wvrFlags &= ~WVR_VREDRAW;
+
+ validRects[0] = params.rgrc[1]; // second rectangle contains the valid destination
rectangle
+ validRects[1] = params.rgrc[2]; // third rectangle contains the valid source
rectangle
+ }
+ else
+ {
+ if (!(WinPos->flags & SWP_NOMOVE) &&
+ (ClientRect->left != Window->rcClient.left ||
+ ClientRect->top != Window->rcClient.top))
+ {
+ WinPos->flags &= ~SWP_NOCLIENTMOVE;
+ }
+ }
+
+ if (WinPos->flags & (SWP_NOCOPYBITS | SWP_NOREDRAW | SWP_SHOWWINDOW |
SWP_HIDEWINDOW))
+ {
+ RECTL_vSetEmptyRect( &validRects[0] );
+ RECTL_vSetEmptyRect( &validRects[1] );
+ }
+ else get_valid_rects( &Window->rcClient, ClientRect, wvrFlags, validRects );
+
+ return wvrFlags;
+}
+
+static
+BOOL FASTCALL
+co_WinPosDoWinPosChanging(PWND Window,
+ PWINDOWPOS WinPos,
+ PRECTL WindowRect,
+ PRECTL ClientRect)
+{
+ ASSERT_REFS_CO(Window);
+
+ /* Send WM_WINDOWPOSCHANGING message */
+
+ if (!(WinPos->flags & SWP_NOSENDCHANGING))
+ {
+ TRACE("Sending WM_WINDOWPOSCHANGING to hwnd %p flags %04x.\n",
Window->head.h,WinPos->flags);
+ co_IntSendMessage(Window->head.h, WM_WINDOWPOSCHANGING, 0, (LPARAM) WinPos);
+ }
+
+ /* Calculate new position and size */
+
+ *WindowRect = Window->rcWindow;
+ *ClientRect = (Window->style & WS_MINIMIZE) ? Window->rcWindow :
Window->rcClient;
+
+ if (!(WinPos->flags & SWP_NOSIZE))
+ {
+ if (Window->style & WS_MINIMIZE)
+ {
+ WindowRect->right = WindowRect->left +
UserGetSystemMetrics(SM_CXMINIMIZED);
+ WindowRect->bottom = WindowRect->top +
UserGetSystemMetrics(SM_CYMINIMIZED);
+ }
+ else
+ {
+ WindowRect->right = WindowRect->left + WinPos->cx;
+ WindowRect->bottom = WindowRect->top + WinPos->cy;
+ }
+ }
+
+ if (!(WinPos->flags & SWP_NOMOVE))
+ {
+ INT X, Y;
+ PWND Parent;
+ X = WinPos->x;
+ Y = WinPos->y;
+
+ Parent = Window->spwndParent;
+
+ // Parent child position issue is in here. SetParent_W7 test CORE-6651.
+ if (//((Window->style & WS_CHILD) != 0) && <- Fixes wine msg
test_SetParent: "rects do not match", the last test.
+ Parent &&
+ Parent != Window->head.rpdesk->pDeskInfo->spwnd)
+ {
+ TRACE("Not SWP_NOMOVE 1 Parent client offset X %d Y %d\n",X,Y);
+ X += Parent->rcClient.left;
+ Y += Parent->rcClient.top;
+ TRACE("Not SWP_NOMOVE 2 Parent client offset X %d Y %d\n",X,Y);
+ }
+
+ WindowRect->left = X;
+ WindowRect->top = Y;
+ WindowRect->right += X - Window->rcWindow.left;
+ WindowRect->bottom += Y - Window->rcWindow.top;
+
+ RECTL_vOffsetRect(ClientRect, X - Window->rcWindow.left,
+ Y - Window->rcWindow.top);
+ }
+ WinPos->flags |= SWP_NOCLIENTMOVE | SWP_NOCLIENTSIZE;
+
+ TRACE( "hwnd %p, after %p, swp %d,%d %dx%d flags %08x\n",
+ WinPos->hwnd, WinPos->hwndInsertAfter, WinPos->x, WinPos->y,
+ WinPos->cx, WinPos->cy, WinPos->flags );
+ TRACE("WindowRect: %d %d %d %d\n",
WindowRect->left,WindowRect->top,WindowRect->right,WindowRect->bottom);
+ TRACE("ClientRect: %d %d %d %d\n",
ClientRect->left,ClientRect->top,ClientRect->right,ClientRect->bottom);
+
+ return TRUE;
+}
+
+/*
+ * Fix Z order taking into account owned popups -
+ * basically we need to maintain them above the window that owns them
+ *
+ * FIXME: hide/show owned popups when owner visibility changes.
+ *
+ * ReactOS: See bug CORE-6129 and CORE-6554.
+ *
+ */
+ ////
+ // Pass all the win:test_children/popup_zorder tests except "move hwnd_F and its
popups down" which is if'ed out.
+ // Side effect, breaks more of the DeferWindowPos api tests, but wine breaks more!!!!
+static
+HWND FASTCALL
+WinPosDoOwnedPopups(PWND Window, HWND hWndInsertAfter)
+{
+ HWND *List = NULL;
+ HWND Owner;
+ LONG Style;
+ PWND DesktopWindow, ChildObject;
+ int i;
+
+ TRACE("(%p) hInsertAfter = %p\n", Window, hWndInsertAfter );
+
+ Style = Window->style;
+
+ if (Style & WS_CHILD)
+ {
+ TRACE("Window is child\n");
+ return hWndInsertAfter;
+ }
+
+ Owner = Window->spwndOwner ? Window->spwndOwner->head.h : NULL;
+
+ if (Owner)
+ {
+ /* Make sure this popup stays above the owner */
+
+ if (hWndInsertAfter != HWND_TOPMOST)
+ {
+ DesktopWindow = UserGetDesktopWindow();
+ List = IntWinListChildren(DesktopWindow);
+
+ if (List != NULL)
+ {
+ for (i = 0; List[i]; i++)
+ {
+ BOOL topmost = FALSE;
+
+ ChildObject = ValidateHwndNoErr(List[i]);
+ if (ChildObject)
+ {
+ topmost = (ChildObject->ExStyle & WS_EX_TOPMOST) != 0;
+ }
+
+ if (List[i] == Owner)
+ {
+ if (i > 0) hWndInsertAfter = List[i-1];
+ else hWndInsertAfter = topmost ? HWND_TOPMOST : HWND_TOP;
+ break;
+ }
+
+ if (hWndInsertAfter == HWND_TOP || hWndInsertAfter == HWND_NOTOPMOST)
+ {
+ if (!topmost) break;
+ }
+ else if (List[i] == hWndInsertAfter) break;
+ }
+ }
+ else
+ return hWndInsertAfter;
+ }
+ }
+
+ if (hWndInsertAfter == HWND_BOTTOM)
+ {
+ ERR("Window is HWND_BOTTOM hwnd %p\n",hWndInsertAfter);
+ if (List) ExFreePoolWithTag(List, USERTAG_WINDOWLIST);
+ goto done;
+ }
+
+ if (!List)
+ {
+ DesktopWindow = UserGetDesktopWindow();
+ List = IntWinListChildren(DesktopWindow);
+ }
+
+ if (List != NULL)
+ {
+ i = 0;
+
+ if (hWndInsertAfter == HWND_TOP || hWndInsertAfter == HWND_NOTOPMOST)
+ {
+ if (hWndInsertAfter == HWND_NOTOPMOST || !(Window->ExStyle &
WS_EX_TOPMOST))
+ {
+ TRACE("skip all the topmost windows\n");
+ /* skip all the topmost windows */
+ while (List[i] &&
+ (ChildObject = ValidateHwndNoErr(List[i])) &&
+ (ChildObject->ExStyle & WS_EX_TOPMOST)) i++;
+ }
+ }
+ else if (hWndInsertAfter != HWND_TOPMOST)
+ {
+ /* skip windows that are already placed correctly */
+ for (i = 0; List[i]; i++)
+ {
+ if (List[i] == hWndInsertAfter) break;
+ if (List[i] == UserHMGetHandle(Window))
+ {
+ ExFreePoolWithTag(List, USERTAG_WINDOWLIST);
+ goto done; /* nothing to do if window is moving backwards in z-order */
+ }
+ }
+ }
+
+ for (; List[i]; i++)
+ {
+ PWND Wnd;
+ USER_REFERENCE_ENTRY Ref;
+
+ if (List[i] == UserHMGetHandle(Window))
+ break;
+
+ if (!(Wnd = ValidateHwndNoErr(List[i])))
+ continue;
+
+ Owner = Wnd->spwndOwner ? Wnd->spwndOwner->head.h : NULL;
+
+ if (Owner != UserHMGetHandle(Window)) continue;
+
+ UserRefObjectCo(Wnd, &Ref);
+ TRACE( "moving %p owned by %p after %p\n", List[i],
UserHMGetHandle(Window), hWndInsertAfter );
+ co_WinPosSetWindowPos(Wnd, hWndInsertAfter, 0, 0, 0, 0,
+ SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE |
SWP_NOSENDCHANGING| SWP_DEFERERASE);
+
+ UserDerefObjectCo(Wnd);
+ hWndInsertAfter = List[i];
+ }
+ ExFreePoolWithTag(List, USERTAG_WINDOWLIST);
+ }
+done:
+ return hWndInsertAfter;
+}
+////
+
+/***********************************************************************
+ * WinPosInternalMoveWindow
+ *
+ * Update WindowRect and ClientRect of Window and all of its children
+ * We keep both WindowRect and ClientRect in screen coordinates internally
+ */
+static
+VOID FASTCALL
+WinPosInternalMoveWindow(PWND Window, INT MoveX, INT MoveY)
+{
+ PWND Child;
+
+ ASSERT(Window != Window->spwndChild);
+ TRACE("InternalMoveWin X %d Y %d\n", MoveX, MoveY);
+
+ Window->rcWindow.left += MoveX;
+ Window->rcWindow.right += MoveX;
+ Window->rcWindow.top += MoveY;
+ Window->rcWindow.bottom += MoveY;
+
+ Window->rcClient.left += MoveX;
+ Window->rcClient.right += MoveX;
+ Window->rcClient.top += MoveY;
+ Window->rcClient.bottom += MoveY;
+
+ for(Child = Window->spwndChild; Child; Child = Child->spwndNext)
+ {
+ WinPosInternalMoveWindow(Child, MoveX, MoveY);
+ }
+}
+
+/*
+ * WinPosFixupSWPFlags
+ *
+ * Fix redundant flags and values in the WINDOWPOS structure.
+ */
+static
+BOOL FASTCALL
+WinPosFixupFlags(WINDOWPOS *WinPos, PWND Wnd)
+{
+ PWND Parent;
+ POINT pt;
+
+ /* Finally make sure that all coordinates are valid */
+ if (WinPos->x < -32768) WinPos->x = -32768;
+ else if (WinPos->x > 32767) WinPos->x = 32767;
+ if (WinPos->y < -32768) WinPos->y = -32768;
+ else if (WinPos->y > 32767) WinPos->y = 32767;
+
+ WinPos->cx = max(WinPos->cx, 0);
+ WinPos->cy = max(WinPos->cy, 0);
+
+ Parent = UserGetAncestor( Wnd, GA_PARENT );
+ if (!IntIsWindowVisible( Parent ) &&
+ /* Fix B : wine msg test_SetParent:WmSetParentSeq_2:25 wParam bits! */
+ (WinPos->flags & SWP_AGG_STATUSFLAGS) == SWP_AGG_NOPOSCHANGE)
WinPos->flags |= SWP_NOREDRAW;
+
+ if (Wnd->style & WS_VISIBLE) WinPos->flags &= ~SWP_SHOWWINDOW;
+ else
+ {
+ WinPos->flags &= ~SWP_HIDEWINDOW;
+ if (!(WinPos->flags & SWP_SHOWWINDOW)) WinPos->flags |= SWP_NOREDRAW;
+ }
+
+ /* Check for right size */
+ if (Wnd->rcWindow.right - Wnd->rcWindow.left == WinPos->cx &&
+ Wnd->rcWindow.bottom - Wnd->rcWindow.top == WinPos->cy)
+ {
+ WinPos->flags |= SWP_NOSIZE;
+ }
+
+ pt.x = WinPos->x;
+ pt.y = WinPos->y;
+ IntClientToScreen( Parent, &pt );
+ TRACE("WPFU C2S wpx %d wpy %d ptx %d pty
%d\n",WinPos->x,WinPos->y,pt.x,pt.y);
+ /* Check for right position */
+ if (Wnd->rcWindow.left == pt.x && Wnd->rcWindow.top == pt.y)
+ {
+ //ERR("In right pos\n");
+ WinPos->flags |= SWP_NOMOVE;
+ }
+
+ if ( WinPos->hwnd != UserGetForegroundWindow() && (Wnd->style &
(WS_POPUP | WS_CHILD)) != WS_CHILD)
+ {
+ /* Bring to the top when activating */
+ if (!(WinPos->flags & (SWP_NOACTIVATE|SWP_HIDEWINDOW)) &&
+ (WinPos->flags & SWP_NOZORDER ||
+ (WinPos->hwndInsertAfter != HWND_TOPMOST &&
WinPos->hwndInsertAfter != HWND_NOTOPMOST)))
+ {
+ WinPos->flags &= ~SWP_NOZORDER;
+ WinPos->hwndInsertAfter = (0 != (Wnd->ExStyle & WS_EX_TOPMOST) ?
HWND_TOPMOST : HWND_TOP);
+ }
+ }
+
+ /* Check hwndInsertAfter */
+ if (!(WinPos->flags & SWP_NOZORDER))
+ {
+ /* Fix sign extension */
+ if (WinPos->hwndInsertAfter == (HWND)0xffff)
+ {
+ WinPos->hwndInsertAfter = HWND_TOPMOST;
+ }
+ else if (WinPos->hwndInsertAfter == (HWND)0xfffe)
+ {
+ WinPos->hwndInsertAfter = HWND_NOTOPMOST;
+ }
+
+ if (WinPos->hwndInsertAfter == HWND_TOP)
+ {
+ /* Keep it topmost when it's already topmost */
+ if ((Wnd->ExStyle & WS_EX_TOPMOST) != 0)
+ WinPos->hwndInsertAfter = HWND_TOPMOST;
+
+ if (IntGetWindow(WinPos->hwnd, GW_HWNDFIRST) == WinPos->hwnd)
+ {
+ WinPos->flags |= SWP_NOZORDER;
+ }
+ }
+ else if (WinPos->hwndInsertAfter == HWND_BOTTOM)
+ {
+ if (!(Wnd->ExStyle & WS_EX_TOPMOST) &&
IntGetWindow(WinPos->hwnd, GW_HWNDLAST) == WinPos->hwnd)
+ WinPos->flags |= SWP_NOZORDER;
+ }
+ else if (WinPos->hwndInsertAfter == HWND_TOPMOST)
+ {
+ if ((Wnd->ExStyle & WS_EX_TOPMOST) &&
IntGetWindow(WinPos->hwnd, GW_HWNDFIRST) == WinPos->hwnd)
+ WinPos->flags |= SWP_NOZORDER;
+ }
+ else if (WinPos->hwndInsertAfter == HWND_NOTOPMOST)
+ {
+ if (!(Wnd->ExStyle & WS_EX_TOPMOST))
+ WinPos->flags |= SWP_NOZORDER;
+ }
+ else /* hwndInsertAfter must be a sibling of the window */
+ {
+ PWND InsAfterWnd;
+
+ InsAfterWnd = ValidateHwndNoErr(WinPos->hwndInsertAfter);
+ if(!InsAfterWnd)
+ {
+ return TRUE;
+ }
+
+ if (InsAfterWnd->spwndParent != Wnd->spwndParent)
+ {
+ /* Note from wine User32 Win test_SetWindowPos:
+ "Returns TRUE also for windows that are not siblings"
+ "Does not seem to do anything even without passing flags, still
returns TRUE"
+ "Same thing the other way around."
+ ".. and with these windows."
+ */
+ return FALSE;
+ }
+ else
+ {
+ /*
+ * We don't need to change the Z order of hwnd if it's already
+ * inserted after hwndInsertAfter or when inserting hwnd after
+ * itself.
+ */
+ if ((WinPos->hwnd == WinPos->hwndInsertAfter) ||
+ ((InsAfterWnd->spwndNext) && (WinPos->hwnd ==
InsAfterWnd->spwndNext->head.h)))
+ {
+ WinPos->flags |= SWP_NOZORDER;
+ }
+ }
+ }
+ }
+
+ return TRUE;
+}
+
+/* x and y are always screen relative */
+BOOLEAN FASTCALL
+co_WinPosSetWindowPos(
+ PWND Window,
+ HWND WndInsertAfter,
+ INT x,
+ INT y,
+ INT cx,
+ INT cy,
+ UINT flags
+ )
+{
+ WINDOWPOS WinPos;
+ RECTL NewWindowRect;
+ RECTL NewClientRect;
+ RECTL valid_rects[2];
+ PREGION VisBefore = NULL;
+ PREGION VisBeforeJustClient = NULL;
+ PREGION VisAfter = NULL;
+ PREGION CopyRgn = NULL;
+ ULONG WvrFlags = 0;
+ RECTL OldWindowRect, OldClientRect;
+ int RgnType;
+ HDC Dc;
+ RECTL CopyRect;
+ PWND Ancestor;
+ BOOL bPointerInWindow, PosChanged = FALSE;
+ PTHREADINFO pti = PsGetCurrentThreadWin32Thread();
+
+ ASSERT_REFS_CO(Window);
+
+ TRACE("pwnd %p, after %p, %d,%d (%dx%d), flags %s",
+ Window, WndInsertAfter, x, y, cx, cy, flags);
+#if DBG
+ dump_winpos_flags(flags);
+#endif
+
+ /* FIXME: Get current active window from active queue. Why? since r2915. */
+
+ bPointerInWindow = IntPtInWindow(Window, gpsi->ptCursor.x, gpsi->ptCursor.y);
+
+ WinPos.hwnd = Window->head.h;
+ WinPos.hwndInsertAfter = WndInsertAfter;
+ WinPos.x = x;
+ WinPos.y = y;
+ WinPos.cx = cx;
+ WinPos.cy = cy;
+ WinPos.flags = flags;
+
+ if ( flags & SWP_ASYNCWINDOWPOS )
+ {
+ LRESULT lRes;
+ PWINDOWPOS ppos = ExAllocatePoolWithTag(PagedPool, sizeof(WINDOWPOS),
USERTAG_SWP);
+ if ( ppos )
+ {
+ WinPos.flags &= ~SWP_ASYNCWINDOWPOS; // Clear flag.
+ *ppos = WinPos;
+ /* Yes it's a pointer inside Win32k! */
+ lRes = co_IntSendMessageNoWait( WinPos.hwnd, WM_ASYNC_SETWINDOWPOS, 0,
(LPARAM)ppos);
+ /* We handle this the same way as Event Hooks and Hooks. */
+ if ( !lRes )
+ {
+ ExFreePoolWithTag(ppos, USERTAG_SWP);
+ return FALSE;
+ }
+ return TRUE;
+ }
+ return FALSE;
+ }
+
+ co_WinPosDoWinPosChanging(Window, &WinPos, &NewWindowRect,
&NewClientRect);
+
+ /* Does the window still exist? */
+ if (!IntIsWindow(WinPos.hwnd))
+ {
+ TRACE("WinPosSetWindowPos: Invalid handle 0x%p!\n",WinPos.hwnd);
+ EngSetLastError(ERROR_INVALID_WINDOW_HANDLE);
+ return FALSE;
+ }
+
+ /* Fix up the flags. */
+ if (!WinPosFixupFlags(&WinPos, Window))
+ {
+ // See Note.
+ return TRUE;
+ }
+
+ Ancestor = UserGetAncestor(Window, GA_PARENT);
+ if ( (WinPos.flags & (SWP_NOZORDER | SWP_HIDEWINDOW | SWP_SHOWWINDOW)) !=
SWP_NOZORDER &&
+ Ancestor && Ancestor->head.h == IntGetDesktopWindow() )
+ {
+ WinPos.hwndInsertAfter = WinPosDoOwnedPopups(Window, WinPos.hwndInsertAfter);
+ }
+
+ if (!(WinPos.flags & SWP_NOREDRAW))
+ {
+ /* Compute the visible region before the window position is changed */
+ if (!(WinPos.flags & SWP_SHOWWINDOW) &&
+ (WinPos.flags & (SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER |
+ SWP_HIDEWINDOW | SWP_FRAMECHANGED)) !=
+ (SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER))
+ {
+ VisBefore = VIS_ComputeVisibleRegion(Window, FALSE, FALSE,
+ (Window->style & WS_CLIPSIBLINGS) ?
TRUE : FALSE);
+
+ if ( VisBefore != NULL &&
+ REGION_Complexity(VisBefore) == NULLREGION )
+ {
+ REGION_Delete(VisBefore);
+ VisBefore = NULL;
+ }
+ else if(VisBefore)
+ {
+ REGION_bOffsetRgn(VisBefore, -Window->rcWindow.left,
-Window->rcWindow.top);
+ }
+
+ /* Calculate the non client area for resizes, as this is used in the copy region
*/
+ if (!(WinPos.flags & SWP_NOSIZE))
+ {
+ VisBeforeJustClient = VIS_ComputeVisibleRegion(Window, TRUE, FALSE,
+ (Window->style & WS_CLIPSIBLINGS) ? TRUE : FALSE);
+
+ if ( VisBeforeJustClient != NULL &&
+ REGION_Complexity(VisBeforeJustClient) == NULLREGION )
+ {
+ REGION_Delete(VisBeforeJustClient);
+ VisBeforeJustClient = NULL;
+ }
+ else if(VisBeforeJustClient)
+ {
+ REGION_bOffsetRgn(VisBeforeJustClient, -Window->rcWindow.left,
-Window->rcWindow.top);
+ }
+ }
+ }
+ }
+
+ //// HACK 3
+ if (Window->hrgnNewFrame)
+ {
+ SelectWindowRgn( Window, Window->hrgnNewFrame ); // Should be
PSMWP->acvr->hrgnClip
+ Window->hrgnNewFrame = NULL;
+ }
+
+ WvrFlags = co_WinPosDoNCCALCSize(Window, &WinPos, &NewWindowRect,
&NewClientRect, valid_rects);
+
+// ERR("co_WinPosDoNCCALCSize returned 0x%x\n valid dest: %d %d %d %d\n valid src
: %d %d %d %d\n", WvrFlags,
+//
valid_rects[0].left,valid_rects[0].top,valid_rects[0].right,valid_rects[0].bottom,
+//
valid_rects[1].left,valid_rects[1].top,valid_rects[1].right,valid_rects[1].bottom);
+
+ /* Validate link windows. (also take into account shell window in hwndShellWindow) */
+ if (!(WinPos.flags & SWP_NOZORDER) && WinPos.hwnd !=
UserGetShellWindow())
+ {
+ IntLinkHwnd(Window, WinPos.hwndInsertAfter);
+ }
+
+ OldWindowRect = Window->rcWindow;
+ OldClientRect = Window->rcClient;
+
+ if (NewClientRect.left != OldClientRect.left ||
+ NewClientRect.top != OldClientRect.top)
+ {
+ // Move child window if their parent is moved. Keep Child window relative to
Parent...
+ WinPosInternalMoveWindow(Window,
+ NewClientRect.left - OldClientRect.left,
+ NewClientRect.top - OldClientRect.top);
+ PosChanged = TRUE;
+ }
+
+ Window->rcWindow = NewWindowRect;
+ Window->rcClient = NewClientRect;
+
+ /* erase parent when hiding or resizing child */
+ if (WinPos.flags & SWP_HIDEWINDOW)
+ {
+ /* Clear the update region */
+ co_UserRedrawWindow( Window,
+ NULL,
+ 0,
+ RDW_VALIDATE | RDW_NOFRAME | RDW_NOERASE | RDW_NOINTERNALPAINT
| RDW_ALLCHILDREN);
+
+ if (UserIsDesktopWindow(Window->spwndParent))
+ co_IntShellHookNotify(HSHELL_WINDOWDESTROYED, (WPARAM)Window->head.h, 0);
+
+ Window->style &= ~WS_VISIBLE; //IntSetStyle( Window, 0, WS_VISIBLE );
+ Window->head.pti->cVisWindows--;
+ IntNotifyWinEvent(EVENT_OBJECT_HIDE, Window, OBJID_WINDOW, CHILDID_SELF,
WEF_SETBYWNDPTI);
+ }
+ else if (WinPos.flags & SWP_SHOWWINDOW)
+ {
+ if (UserIsDesktopWindow(Window->spwndParent) &&
+ Window->spwndOwner == NULL &&
+ (!(Window->ExStyle & WS_EX_TOOLWINDOW) ||
+ (Window->ExStyle & WS_EX_APPWINDOW)))
+ co_IntShellHookNotify(HSHELL_WINDOWCREATED, (WPARAM)Window->head.h, 0);
+
+ Window->style |= WS_VISIBLE; //IntSetStyle( Window, WS_VISIBLE, 0 );
+ Window->head.pti->cVisWindows++;
+ IntNotifyWinEvent(EVENT_OBJECT_SHOW, Window, OBJID_WINDOW, CHILDID_SELF,
WEF_SETBYWNDPTI);
+ }
+
+ if (Window->hrgnUpdate != NULL && Window->hrgnUpdate != HRGN_WINDOW)
+ {
+ NtGdiOffsetRgn(Window->hrgnUpdate,
+ NewWindowRect.left - OldWindowRect.left,
+ NewWindowRect.top - OldWindowRect.top);
+ }
+
+ DceResetActiveDCEs(Window); // For WS_VISIBLE changes.
+
+ if (!(WinPos.flags & SWP_NOREDRAW))
+ {
+ /* Determine the new visible region */
+ VisAfter = VIS_ComputeVisibleRegion(Window, FALSE, FALSE,
+ (Window->style & WS_CLIPSIBLINGS) ? TRUE
: FALSE);
+
+ if ( VisAfter != NULL &&
+ REGION_Complexity(VisAfter) == NULLREGION )
+ {
+ REGION_Delete(VisAfter);
+ VisAfter = NULL;
+ }
+ else if(VisAfter)
+ {
+ REGION_bOffsetRgn(VisAfter, -Window->rcWindow.left,
-Window->rcWindow.top);
+ }
+
+ /*
+ * Determine which pixels can be copied from the old window position
+ * to the new. Those pixels must be visible in both the old and new
+ * position. Also, check the class style to see if the windows of this
+ * class need to be completely repainted on (horizontal/vertical) size
+ * change.
+ */
+ if ( ( VisBefore != NULL &&
+ VisAfter != NULL &&
+ !(WinPos.flags & SWP_NOCOPYBITS) &&
+ ((WinPos.flags & SWP_NOSIZE) || !(WvrFlags & WVR_REDRAW)) &&
+ !(Window->ExStyle & WS_EX_TRANSPARENT) ) ||
+ ( !PosChanged && (WinPos.flags & SWP_FRAMECHANGED) &&
VisBefore) )
+ {
+
+ /*
+ * If this is (also) a window resize, the whole nonclient area
+ * needs to be repainted. So we limit the copy to the client area,
+ * 'cause there is no use in copying it (would possibly cause
+ * "flashing" too). However, if the copy region is already empty,
+ * we don't have to crop (can't take anything away from an empty
+ * region...)
+ */
+
+ CopyRgn = IntSysCreateRectpRgn(0, 0, 0, 0);
+ if (WinPos.flags & SWP_NOSIZE)
+ RgnType = IntGdiCombineRgn(CopyRgn, VisAfter, VisBefore, RGN_AND);
+ else if (VisBeforeJustClient != NULL)
+ {
+ RgnType = IntGdiCombineRgn(CopyRgn, VisAfter, VisBeforeJustClient, RGN_AND);
+ REGION_Delete(VisBeforeJustClient);
+ }
+
+ /* Now use in copying bits which are in the update region. */
+ if (Window->hrgnUpdate != NULL)
+ {
+ PREGION RgnUpdate = REGION_LockRgn(Window->hrgnUpdate);
+ if (RgnUpdate)
+ {
+ REGION_bOffsetRgn(CopyRgn, NewWindowRect.left, NewWindowRect.top);
+ IntGdiCombineRgn(CopyRgn, CopyRgn, RgnUpdate, RGN_DIFF);
+ REGION_bOffsetRgn(CopyRgn, -NewWindowRect.left, -NewWindowRect.top);
+ REGION_UnlockRgn(RgnUpdate);
+ }
+ }
+
+ /*
+ * Now, get the bounding box of the copy region. If it's empty
+ * there's nothing to copy. Also, it's no use copying bits onto
+ * themselves.
+ */
+ if (REGION_GetRgnBox(CopyRgn, &CopyRect) == NULLREGION)
+ {
+ /* Nothing to copy, clean up */
+ REGION_Delete(CopyRgn);
+ CopyRgn = NULL;
+ }
+ else if ( OldWindowRect.left != NewWindowRect.left ||
+ OldWindowRect.top != NewWindowRect.top ||
+ (WinPos.flags & SWP_FRAMECHANGED) )
+ {
+ HRGN DcRgn = NtGdiCreateRectRgn(0, 0, 0, 0);
+ PREGION DcRgnObj = REGION_LockRgn(DcRgn);
+
+ /*
+ * Small trick here: there is no function to bitblt a region. So
+ * we set the region as the clipping region, take the bounding box
+ * of the region and bitblt that. Since nothing outside the clipping
+ * region is copied, this has the effect of bitblt'ing the region.
+ *
+ * Since NtUserGetDCEx takes ownership of the clip region, we need
+ * to create a copy of CopyRgn and pass that. We need CopyRgn later
+ */
+ IntGdiCombineRgn(DcRgnObj, CopyRgn, NULL, RGN_COPY);
+ REGION_bOffsetRgn(DcRgnObj, NewWindowRect.left, NewWindowRect.top);
+ REGION_UnlockRgn(DcRgnObj);
+ Dc = UserGetDCEx( Window,
+ DcRgn,
+
DCX_WINDOW|DCX_CACHE|DCX_INTERSECTRGN|DCX_CLIPSIBLINGS|DCX_KEEPCLIPRGN);
+ NtGdiBitBlt( Dc,
+ CopyRect.left, CopyRect.top,
+ CopyRect.right - CopyRect.left,
+ CopyRect.bottom - CopyRect.top,
+ Dc,
+ CopyRect.left + (OldWindowRect.left - NewWindowRect.left),
+ CopyRect.top + (OldWindowRect.top - NewWindowRect.top),
+ SRCCOPY,
+ 0,
+ 0);
+
+ UserReleaseDC(Window, Dc, FALSE);
+ IntValidateParent(Window, CopyRgn);
+ GreDeleteObject(DcRgn);
+ }
+ }
+ else
+ {
+ CopyRgn = NULL;
+ }
+#if 0
+ /////// Fixes NoPopup tests but breaks msg_paint tests.
+ if ( !PosChanged && (WinPos.flags & SWP_FRAMECHANGED) &&
VisBefore)
+ {
+ PWND Parent = Window->spwndParent;
+ ERR("SWP_FRAMECHANGED no chg\n");
+ if ( !(Window->style & WS_CHILD) && (Parent) &&
(Parent->style & WS_CLIPCHILDREN))
+ {
+ ERR("SWP_FRAMECHANGED Parent WS_CLIPCHILDREN\n");
+ //IntInvalidateWindows( Window, VisBefore, /*RDW_ERASE |*/ RDW_FRAME |
RDW_INVALIDATE | RDW_ALLCHILDREN);
+ }
+ }
+#endif
+ /* We need to redraw what wasn't visible before */
+ if (VisAfter != NULL)
+ {
+ PREGION DirtyRgn = IntSysCreateRectpRgn(0, 0, 0, 0);
+ if (DirtyRgn)
+ {
+ if (CopyRgn != NULL)
+ {
+ RgnType = IntGdiCombineRgn(DirtyRgn, VisAfter, CopyRgn, RGN_DIFF);
+ }
+ else
+ {
+ RgnType = IntGdiCombineRgn(DirtyRgn, VisAfter, 0, RGN_COPY);
+ }
+
+ if (RgnType != ERROR && RgnType != NULLREGION)
+ {
+ /* old code
+ NtGdiOffsetRgn(DirtyRgn, Window->rcWindow.left,
Window->rcWindow.top);
+ IntInvalidateWindows( Window,
+ DirtyRgn,
+ RDW_ERASE | RDW_FRAME | RDW_INVALIDATE | RDW_ALLCHILDREN);
+ }
+ GreDeleteObject(DirtyRgn);
+ */
+
+ PWND Parent = Window->spwndParent;
+
+ REGION_bOffsetRgn( DirtyRgn, Window->rcWindow.left,
Window->rcWindow.top);
+
+ if ( (Window->style & WS_CHILD) && (Parent) &&
!(Parent->style & WS_CLIPCHILDREN))
+ {
+ IntInvalidateWindows( Parent, DirtyRgn, RDW_ERASE | RDW_INVALIDATE);
+ co_IntPaintWindows(Parent, RDW_NOCHILDREN, FALSE);
+ }
+ else
+ {
+ IntInvalidateWindows( Window, DirtyRgn, RDW_ERASE | RDW_FRAME |
RDW_INVALIDATE | RDW_ALLCHILDREN);
+ }
+ }
+ REGION_Delete(DirtyRgn);
+ }
+ }
+
+ if (CopyRgn != NULL)
+ {
+ REGION_Delete(CopyRgn);
+ }
+
+ /* Expose what was covered before but not covered anymore */
+ if (VisBefore != NULL)
+ {
+ PREGION ExposedRgn = IntSysCreateRectpRgn(0, 0, 0, 0);
+ if (ExposedRgn)
+ {
+ RgnType = IntGdiCombineRgn(ExposedRgn, VisBefore, NULL, RGN_COPY);
+ REGION_bOffsetRgn(ExposedRgn,
+ OldWindowRect.left - NewWindowRect.left,
+ OldWindowRect.top - NewWindowRect.top);
+
+ if (VisAfter != NULL)
+ RgnType = IntGdiCombineRgn(ExposedRgn, ExposedRgn, VisAfter, RGN_DIFF);
+
+ if (RgnType != ERROR && RgnType != NULLREGION)
+ {
+ co_VIS_WindowLayoutChanged(Window, ExposedRgn);
+ }
+ REGION_Delete(ExposedRgn);
+ }
+ REGION_Delete(VisBefore);
+ }
+
+ if (VisAfter != NULL)
+ {
+ REGION_Delete(VisAfter);
+ }
+ }
+
+ if (!(WinPos.flags & (SWP_NOACTIVATE|SWP_HIDEWINDOW)))
+ {
+ if ((Window->style & (WS_CHILD | WS_POPUP)) == WS_CHILD)
+ {
+ co_IntSendMessageNoWait(WinPos.hwnd, WM_CHILDACTIVATE, 0, 0);
+ }
+ else
+ {
+ //ERR("SetWindowPos Set FG Window!\n");
+ if ( pti->MessageQueue->spwndActive != Window ||
+ pti->MessageQueue != gpqForeground )
+ {
+ //ERR("WPSWP : set active window\n");
+ if (!(Window->state & WNDS_BEINGACTIVATED)) // Inside SAW?
+ {
+ co_IntSetForegroundWindow(Window); // Fixes SW_HIDE issues. Wine win
test_SetActiveWindow & test_SetForegroundWindow.
+ }
+ }
+ }
+ }
+
+ if ( !PosChanged &&
+ (WinPos.flags & SWP_FRAMECHANGED) &&
+ !(WinPos.flags & SWP_DEFERERASE) && // Prevent sending
WM_SYNCPAINT message.
+ VisAfter )
+ {
+ PWND Parent = Window->spwndParent;
+ if ( !(Window->style & WS_CHILD) && (Parent) &&
(Parent->style & WS_CLIPCHILDREN))
+ {
+ TRACE("SWP_FRAMECHANGED Parent WS_CLIPCHILDREN\n");
+ UserSyncAndPaintWindows( Parent, RDW_CLIPCHILDREN);
+ }
+ }
+
+ // Fix wine msg test_SetFocus, prevents sending WM_WINDOWPOSCHANGED.
+ if ( VisBefore == NULL &&
+ VisBeforeJustClient == NULL &&
+ !(Window->ExStyle & WS_EX_TOPMOST) &&
+ (WinPos.flags & SWP_AGG_STATUSFLAGS) == (SWP_AGG_NOPOSCHANGE &
~SWP_NOZORDER))
+ {
+ TRACE("No drawing, set no Z order and no redraw!\n");
+ WinPos.flags |= SWP_NOZORDER|SWP_NOREDRAW;
+ }
+
+ /* And last, send the WM_WINDOWPOSCHANGED message */
+
+ TRACE("\tstatus hwnd %p flags =
%04x\n",Window?Window->head.h:NULL,WinPos.flags & SWP_AGG_STATUSFLAGS);
+
+ if ((WinPos.flags & SWP_AGG_STATUSFLAGS) != SWP_AGG_NOPOSCHANGE)
+ {
+ /* WM_WINDOWPOSCHANGED is sent even if SWP_NOSENDCHANGING is set
+ and always contains final window position.
+ */
+ WinPos.x = NewWindowRect.left;
+ WinPos.y = NewWindowRect.top;
+ WinPos.cx = NewWindowRect.right - NewWindowRect.left;
+ WinPos.cy = NewWindowRect.bottom - NewWindowRect.top;
+ TRACE("WM_WINDOWPOSCHANGED hwnd %p Flags
%04x\n",WinPos.hwnd,WinPos.flags);
+ co_IntSendMessageNoWait(WinPos.hwnd, WM_WINDOWPOSCHANGED, 0, (LPARAM)
&WinPos);
+ }
+
+ if ( WinPos.flags & SWP_FRAMECHANGED || WinPos.flags & SWP_STATECHANGED ||
+ !(WinPos.flags & SWP_NOCLIENTSIZE) || !(WinPos.flags & SWP_NOCLIENTMOVE) )
+ {
+ PWND pWnd = ValidateHwndNoErr(WinPos.hwnd);
+ if (pWnd)
+ IntNotifyWinEvent(EVENT_OBJECT_LOCATIONCHANGE, pWnd, OBJID_WINDOW, CHILDID_SELF,
WEF_SETBYWNDPTI);
+ }
+
+ if(bPointerInWindow != IntPtInWindow(Window, gpsi->ptCursor.x,
gpsi->ptCursor.y))
+ {
+ /* Generate mouse move message */
+ MSG msg;
+ msg.message = WM_MOUSEMOVE;
+ msg.wParam = UserGetMouseButtonsState();
+ msg.lParam = MAKELPARAM(gpsi->ptCursor.x, gpsi->ptCursor.y);
+ msg.pt = gpsi->ptCursor;
+ co_MsqInsertMouseMessage(&msg, 0, 0, TRUE);
+ }
+
+ return TRUE;
+}
+
+LRESULT FASTCALL
+co_WinPosGetNonClientSize(PWND Window, RECT* WindowRect, RECT* ClientRect)
+{
+ LRESULT Result;
+
+ ASSERT_REFS_CO(Window);
+
+ *ClientRect = *WindowRect;
+ Result = co_IntSendMessageNoWait(Window->head.h, WM_NCCALCSIZE, FALSE, (LPARAM)
ClientRect);
+
+ FixClientRect(ClientRect, WindowRect);
+
+ return Result;
+}
+
+void FASTCALL
+co_WinPosSendSizeMove(PWND Wnd)
+{
+ RECTL Rect;
+ LPARAM lParam;
+ WPARAM wParam = SIZE_RESTORED;
+
+ IntGetClientRect(Wnd, &Rect);
+ lParam = MAKELONG(Rect.right-Rect.left, Rect.bottom-Rect.top);
+
+ Wnd->state &= ~WNDS_SENDSIZEMOVEMSGS;
+
+ if (Wnd->style & WS_MAXIMIZE)
+ {
+ wParam = SIZE_MAXIMIZED;
+ }
+ else if (Wnd->style & WS_MINIMIZE)
+ {
+ wParam = SIZE_MINIMIZED;
+ lParam = 0;
+ }
+
+ co_IntSendMessageNoWait(UserHMGetHandle(Wnd), WM_SIZE, wParam, lParam);
+
+ if (UserIsDesktopWindow(Wnd->spwndParent))
+ 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);
}
UINT FASTCALL
@@ -984,1362 +2340,6 @@
return SwpFlags;
}
-BOOL
-UserHasWindowEdge(DWORD Style, DWORD ExStyle)
-{
- if (Style & WS_MINIMIZE)
- return TRUE;
- if (ExStyle & WS_EX_DLGMODALFRAME)
- return TRUE;
- if (ExStyle & WS_EX_STATICEDGE)
- return FALSE;
- if (Style & WS_THICKFRAME)
- return TRUE;
- Style &= WS_CAPTION;
- if (Style == WS_DLGFRAME || Style == WS_CAPTION)
- return TRUE;
- return FALSE;
-}
-
-VOID FASTCALL
-IntGetWindowBorderMeasures(PWND Wnd, UINT *cx, UINT *cy)
-{
- if(HAS_DLGFRAME(Wnd->style, Wnd->ExStyle) && !(Wnd->style &
WS_MINIMIZE))
- {
- *cx = UserGetSystemMetrics(SM_CXDLGFRAME);
- *cy = UserGetSystemMetrics(SM_CYDLGFRAME);
- }
- else
- {
- if(HAS_THICKFRAME(Wnd->style, Wnd->ExStyle)&& !(Wnd->style &
WS_MINIMIZE))
- {
- *cx = UserGetSystemMetrics(SM_CXFRAME);
- *cy = UserGetSystemMetrics(SM_CYFRAME);
- }
- else if(HAS_THINFRAME(Wnd->style, Wnd->ExStyle))
- {
- *cx = UserGetSystemMetrics(SM_CXBORDER);
- *cy = UserGetSystemMetrics(SM_CYBORDER);
- }
- else
- {
- *cx = *cy = 0;
- }
- }
-}
-
-VOID
-UserGetWindowBorders(DWORD Style, DWORD ExStyle, SIZE *Size, BOOL WithClient)
-{
- DWORD Border = 0;
-
- if (UserHasWindowEdge(Style, ExStyle))
- Border += 2;
- else if (ExStyle & WS_EX_STATICEDGE)
- Border += 1;
- if ((ExStyle & WS_EX_CLIENTEDGE) && WithClient)
- Border += 2;
- if (Style & WS_CAPTION || ExStyle & WS_EX_DLGMODALFRAME)
- Border ++;
- Size->cx = Size->cy = Border;
- if ((Style & WS_THICKFRAME) && !(Style & WS_MINIMIZE))
- {
- Size->cx += UserGetSystemMetrics(SM_CXFRAME) -
UserGetSystemMetrics(SM_CXDLGFRAME);
- Size->cy += UserGetSystemMetrics(SM_CYFRAME) -
UserGetSystemMetrics(SM_CYDLGFRAME);
- }
- Size->cx *= UserGetSystemMetrics(SM_CXBORDER);
- Size->cy *= UserGetSystemMetrics(SM_CYBORDER);
-}
-
-BOOL WINAPI
-UserAdjustWindowRectEx(LPRECT lpRect,
- DWORD dwStyle,
- BOOL bMenu,
- DWORD dwExStyle)
-{
- SIZE BorderSize;
-
- if (bMenu)
- {
- lpRect->top -= UserGetSystemMetrics(SM_CYMENU);
- }
- if ((dwStyle & WS_CAPTION) == WS_CAPTION)
- {
- if (dwExStyle & WS_EX_TOOLWINDOW)
- lpRect->top -= UserGetSystemMetrics(SM_CYSMCAPTION);
- else
- lpRect->top -= UserGetSystemMetrics(SM_CYCAPTION);
- }
- UserGetWindowBorders(dwStyle, dwExStyle, &BorderSize, TRUE);
- RECTL_vInflateRect(
- lpRect,
- BorderSize.cx,
- BorderSize.cy);
-
- return TRUE;
-}
-
-UINT FASTCALL
-co_WinPosGetMinMaxInfo(PWND Window, POINT* MaxSize, POINT* MaxPos,
- POINT* MinTrack, POINT* MaxTrack)
-{
- MINMAXINFO MinMax;
- PMONITOR monitor;
- INT xinc, yinc;
- LONG style = Window->style;
- LONG adjustedStyle;
- LONG exstyle = Window->ExStyle;
- RECT rc;
-
- ASSERT_REFS_CO(Window);
-
- /* Compute default values */
-
- rc = Window->rcWindow;
- 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;
-
- if(Window->spwndParent)
- IntGetClientRect(Window->spwndParent, &rc);
- UserAdjustWindowRectEx(&rc, adjustedStyle, ((style & WS_POPUP) &&
Window->IDMenu), 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 = UserGetSystemMetrics(SM_CXMINTRACK);
- MinMax.ptMinTrackSize.y = UserGetSystemMetrics(SM_CYMINTRACK);
- }
- else
- {
- MinMax.ptMinTrackSize.x = 2 * xinc;
- MinMax.ptMinTrackSize.y = 2 * yinc;
- }
- MinMax.ptMaxTrackSize.x = UserGetSystemMetrics(SM_CXMAXTRACK);
- MinMax.ptMaxTrackSize.y = UserGetSystemMetrics(SM_CYMAXTRACK);
- MinMax.ptMaxPosition.x = -xinc;
- MinMax.ptMaxPosition.y = -yinc;
-
- if (!EMPTYPOINT(Window->InternalPos.MaxPos)) MinMax.ptMaxPosition =
Window->InternalPos.MaxPos;
-
- co_IntSendMessage(Window->head.h, WM_GETMINMAXINFO, 0, (LPARAM)&MinMax);
-
- /* if the app didn't change the values, adapt them for the current monitor */
- if ((monitor = UserGetPrimaryMonitor()))
- {
- RECT rc_work;
-
- rc_work = monitor->rcMonitor;
-
- if (style & WS_MAXIMIZEBOX)
- {
- if ((style & WS_CAPTION) == WS_CAPTION || !(style & (WS_CHILD |
WS_POPUP)))
- rc_work = monitor->rcWork;
- }
-
- if (MinMax.ptMaxSize.x == UserGetSystemMetrics(SM_CXSCREEN) + 2 * xinc
&&
- MinMax.ptMaxSize.y == UserGetSystemMetrics(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;
- }
- if (MinMax.ptMaxSize.x >= (monitor->rcMonitor.right -
monitor->rcMonitor.left) &&
- MinMax.ptMaxSize.y >= (monitor->rcMonitor.bottom -
monitor->rcMonitor.top) )
- Window->state |= WNDS_MAXIMIZESTOMONITOR;
- else
- Window->state &= ~WNDS_MAXIMIZESTOMONITOR;
- }
-
-
- 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?
-}
-
-static
-BOOL
-IntValidateParent(PWND Child, PREGION ValidateRgn)
-{
- PWND ParentWnd = Child;
-
- if (ParentWnd->style & WS_CHILD)
- {
- do
- ParentWnd = ParentWnd->spwndParent;
- while (ParentWnd->style & WS_CHILD);
- }
-
- ParentWnd = Child->spwndParent;
- while (ParentWnd)
- {
- if (ParentWnd->style & WS_CLIPCHILDREN)
- break;
-
- if (ParentWnd->hrgnUpdate != 0)
- {
- IntInvalidateWindows( ParentWnd,
- ValidateRgn,
- RDW_VALIDATE | RDW_NOCHILDREN);
- }
-
- ParentWnd = ParentWnd->spwndParent;
- }
-
- return TRUE;
-}
-
-static
-VOID FASTCALL
-FixClientRect(PRECTL ClientRect, PRECTL WindowRect)
-{
- if (ClientRect->left < WindowRect->left)
- {
- ClientRect->left = WindowRect->left;
- }
- else if (WindowRect->right < ClientRect->left)
- {
- ClientRect->left = WindowRect->right;
- }
- if (ClientRect->right < WindowRect->left)
- {
- ClientRect->right = WindowRect->left;
- }
- else if (WindowRect->right < ClientRect->right)
- {
- ClientRect->right = WindowRect->right;
- }
- if (ClientRect->top < WindowRect->top)
- {
- ClientRect->top = WindowRect->top;
- }
- else if (WindowRect->bottom < ClientRect->top)
- {
- ClientRect->top = WindowRect->bottom;
- }
- if (ClientRect->bottom < WindowRect->top)
- {
- ClientRect->bottom = WindowRect->top;
- }
- else if (WindowRect->bottom < ClientRect->bottom)
- {
- ClientRect->bottom = WindowRect->bottom;
- }
-}
-/***********************************************************************
- * get_valid_rects
- *
- * Compute the valid rects from the old and new client rect and WVR_* flags.
- * Helper for WM_NCCALCSIZE handling.
- */
-static
-VOID FASTCALL
-get_valid_rects( RECTL *old_client, RECTL *new_client, UINT flags, RECTL *valid )
-{
- int cx, cy;
-
- if (flags & WVR_REDRAW)
- {
- RECTL_vSetEmptyRect( &valid[0] );
- RECTL_vSetEmptyRect( &valid[1] );
- return;
- }
-
- if (flags & WVR_VALIDRECTS)
- {
- if (!RECTL_bIntersectRect( &valid[0], &valid[0], new_client ) ||
- !RECTL_bIntersectRect( &valid[1], &valid[1], old_client ))
- {
- RECTL_vSetEmptyRect( &valid[0] );
- RECTL_vSetEmptyRect( &valid[1] );
- return;
- }
- flags = WVR_ALIGNLEFT | WVR_ALIGNTOP;
- }
- else
- {
- valid[0] = *new_client;
- valid[1] = *old_client;
- }
-
- /* make sure the rectangles have the same size */
- cx = min( valid[0].right - valid[0].left, valid[1].right - valid[1].left );
- cy = min( valid[0].bottom - valid[0].top, valid[1].bottom - valid[1].top );
-
- if (flags & WVR_ALIGNBOTTOM)
- {
- valid[0].top = valid[0].bottom - cy;
- valid[1].top = valid[1].bottom - cy;
- }
- else
- {
- valid[0].bottom = valid[0].top + cy;
- valid[1].bottom = valid[1].top + cy;
- }
- if (flags & WVR_ALIGNRIGHT)
- {
- valid[0].left = valid[0].right - cx;
- valid[1].left = valid[1].right - cx;
- }
- else
- {
- valid[0].right = valid[0].left + cx;
- valid[1].right = valid[1].left + cx;
- }
-}
-
-static
-LONG FASTCALL
-co_WinPosDoNCCALCSize(PWND Window, PWINDOWPOS WinPos, RECTL* WindowRect, RECTL*
ClientRect, RECTL* validRects)
-{
- PWND Parent;
- UINT wvrFlags = 0;
-
- ASSERT_REFS_CO(Window);
-
- /* Send WM_NCCALCSIZE message to get new client area */
- if ((WinPos->flags & (SWP_FRAMECHANGED | SWP_NOSIZE)) != SWP_NOSIZE)
- {
- NCCALCSIZE_PARAMS params;
- WINDOWPOS winposCopy;
-
- params.rgrc[0] = *WindowRect; // new coordinates of a window that has been
moved or resized
- params.rgrc[1] = Window->rcWindow; // window before it was moved or resized
- params.rgrc[2] = Window->rcClient; // client area before the window was moved or
resized
-
- Parent = Window->spwndParent;
- if (0 != (Window->style & WS_CHILD) && Parent)
- {
- RECTL_vOffsetRect(&(params.rgrc[0]), - Parent->rcClient.left, -
Parent->rcClient.top);
- RECTL_vOffsetRect(&(params.rgrc[1]), - Parent->rcClient.left, -
Parent->rcClient.top);
- RECTL_vOffsetRect(&(params.rgrc[2]), - Parent->rcClient.left, -
Parent->rcClient.top);
- }
-
- params.lppos = &winposCopy;
- winposCopy = *WinPos;
-
- wvrFlags = co_IntSendMessage(Window->head.h, WM_NCCALCSIZE, TRUE, (LPARAM)
¶ms);
-
- /* If the application send back garbage, ignore it */
- if (params.rgrc[0].left <= params.rgrc[0].right &&
- params.rgrc[0].top <= params.rgrc[0].bottom)
- {
- *ClientRect = params.rgrc[0]; // First rectangle contains the coordinates of the
new client rectangle resulting from the move or resize
- if ((Window->style & WS_CHILD) && Parent)
- {
- RECTL_vOffsetRect(ClientRect, Parent->rcClient.left,
Parent->rcClient.top);
- }
- FixClientRect(ClientRect, WindowRect);
- }
-
- if (ClientRect->left != Window->rcClient.left ||
- ClientRect->top != Window->rcClient.top)
- {
- WinPos->flags &= ~SWP_NOCLIENTMOVE;
- }
-
- if (ClientRect->right - ClientRect->left != Window->rcClient.right -
Window->rcClient.left)
- {
- WinPos->flags &= ~SWP_NOCLIENTSIZE;
- }
- else
- wvrFlags &= ~WVR_HREDRAW;
-
- if (ClientRect->bottom - ClientRect->top != Window->rcClient.bottom -
Window->rcClient.top)
- {
- WinPos->flags &= ~SWP_NOCLIENTSIZE;
- }
- else
- wvrFlags &= ~WVR_VREDRAW;
-
- validRects[0] = params.rgrc[1]; // second rectangle contains the valid destination
rectangle
- validRects[1] = params.rgrc[2]; // third rectangle contains the valid source
rectangle
- }
- else
- {
- if (!(WinPos->flags & SWP_NOMOVE) &&
- (ClientRect->left != Window->rcClient.left ||
- ClientRect->top != Window->rcClient.top))
- {
- WinPos->flags &= ~SWP_NOCLIENTMOVE;
- }
- }
-
- if (WinPos->flags & (SWP_NOCOPYBITS | SWP_NOREDRAW | SWP_SHOWWINDOW |
SWP_HIDEWINDOW))
- {
- RECTL_vSetEmptyRect( &validRects[0] );
- RECTL_vSetEmptyRect( &validRects[1] );
- }
- else get_valid_rects( &Window->rcClient, ClientRect, wvrFlags, validRects );
-
- return wvrFlags;
-}
-
-static
-BOOL FASTCALL
-co_WinPosDoWinPosChanging(PWND Window,
- PWINDOWPOS WinPos,
- PRECTL WindowRect,
- PRECTL ClientRect)
-{
- ASSERT_REFS_CO(Window);
-
- /* Send WM_WINDOWPOSCHANGING message */
-
- if (!(WinPos->flags & SWP_NOSENDCHANGING))
- {
- TRACE("Sending WM_WINDOWPOSCHANGING to hwnd %p flags %04x.\n",
Window->head.h,WinPos->flags);
- co_IntSendMessage(Window->head.h, WM_WINDOWPOSCHANGING, 0, (LPARAM) WinPos);
- }
-
- /* Calculate new position and size */
-
- *WindowRect = Window->rcWindow;
- *ClientRect = (Window->style & WS_MINIMIZE) ? Window->rcWindow :
Window->rcClient;
-
- if (!(WinPos->flags & SWP_NOSIZE))
- {
- if (Window->style & WS_MINIMIZE)
- {
- WindowRect->right = WindowRect->left +
UserGetSystemMetrics(SM_CXMINIMIZED);
- WindowRect->bottom = WindowRect->top +
UserGetSystemMetrics(SM_CYMINIMIZED);
- }
- else
- {
- WindowRect->right = WindowRect->left + WinPos->cx;
- WindowRect->bottom = WindowRect->top + WinPos->cy;
- }
- }
-
- if (!(WinPos->flags & SWP_NOMOVE))
- {
- INT X, Y;
- PWND Parent;
- X = WinPos->x;
- Y = WinPos->y;
-
- Parent = Window->spwndParent;
-
- // Parent child position issue is in here. SetParent_W7 test CORE-6651.
- if (//((Window->style & WS_CHILD) != 0) && <- Fixes wine msg
test_SetParent: "rects do not match", the last test.
- Parent &&
- Parent != Window->head.rpdesk->pDeskInfo->spwnd)
- {
- TRACE("Not SWP_NOMOVE 1 Parent client offset X %d Y %d\n",X,Y);
- X += Parent->rcClient.left;
- Y += Parent->rcClient.top;
- TRACE("Not SWP_NOMOVE 2 Parent client offset X %d Y %d\n",X,Y);
- }
-
- WindowRect->left = X;
- WindowRect->top = Y;
- WindowRect->right += X - Window->rcWindow.left;
- WindowRect->bottom += Y - Window->rcWindow.top;
-
- RECTL_vOffsetRect(ClientRect, X - Window->rcWindow.left,
- Y - Window->rcWindow.top);
- }
- WinPos->flags |= SWP_NOCLIENTMOVE | SWP_NOCLIENTSIZE;
-
- TRACE( "hwnd %p, after %p, swp %d,%d %dx%d flags %08x\n",
- WinPos->hwnd, WinPos->hwndInsertAfter, WinPos->x, WinPos->y,
- WinPos->cx, WinPos->cy, WinPos->flags );
- TRACE("WindowRect: %d %d %d %d\n",
WindowRect->left,WindowRect->top,WindowRect->right,WindowRect->bottom);
- TRACE("ClientRect: %d %d %d %d\n",
ClientRect->left,ClientRect->top,ClientRect->right,ClientRect->bottom);
-
- return TRUE;
-}
-
-/*
- * Fix Z order taking into account owned popups -
- * basically we need to maintain them above the window that owns them
- *
- * FIXME: hide/show owned popups when owner visibility changes.
- *
- * ReactOS: See bug CORE-6129 and CORE-6554.
- *
- */
- ////
- // Pass all the win:test_children/popup_zorder tests except "move hwnd_F and its
popups down" which is if'ed out.
- // Side effect, breaks more of the DeferWindowPos api tests, but wine breaks more!!!!
-static
-HWND FASTCALL
-WinPosDoOwnedPopups(PWND Window, HWND hWndInsertAfter)
-{
- HWND *List = NULL;
- HWND Owner;
- LONG Style;
- PWND DesktopWindow, ChildObject;
- int i;
-
- TRACE("(%p) hInsertAfter = %p\n", Window, hWndInsertAfter );
-
- Style = Window->style;
-
- if (Style & WS_CHILD)
- {
- TRACE("Window is child\n");
- return hWndInsertAfter;
- }
-
- Owner = Window->spwndOwner ? Window->spwndOwner->head.h : NULL;
-
- if (Owner)
- {
- /* Make sure this popup stays above the owner */
-
- if (hWndInsertAfter != HWND_TOPMOST)
- {
- DesktopWindow = UserGetDesktopWindow();
- List = IntWinListChildren(DesktopWindow);
-
- if (List != NULL)
- {
- for (i = 0; List[i]; i++)
- {
- BOOL topmost = FALSE;
-
- ChildObject = ValidateHwndNoErr(List[i]);
- if (ChildObject)
- {
- topmost = (ChildObject->ExStyle & WS_EX_TOPMOST) != 0;
- }
-
- if (List[i] == Owner)
- {
- if (i > 0) hWndInsertAfter = List[i-1];
- else hWndInsertAfter = topmost ? HWND_TOPMOST : HWND_TOP;
- break;
- }
-
- if (hWndInsertAfter == HWND_TOP || hWndInsertAfter == HWND_NOTOPMOST)
- {
- if (!topmost) break;
- }
- else if (List[i] == hWndInsertAfter) break;
- }
- }
- else
- return hWndInsertAfter;
- }
- }
-
- if (hWndInsertAfter == HWND_BOTTOM)
- {
- ERR("Window is HWND_BOTTOM hwnd %p\n",hWndInsertAfter);
- if (List) ExFreePoolWithTag(List, USERTAG_WINDOWLIST);
- goto done;
- }
-
- if (!List)
- {
- DesktopWindow = UserGetDesktopWindow();
- List = IntWinListChildren(DesktopWindow);
- }
-
- if (List != NULL)
- {
- i = 0;
-
- if (hWndInsertAfter == HWND_TOP || hWndInsertAfter == HWND_NOTOPMOST)
- {
- if (hWndInsertAfter == HWND_NOTOPMOST || !(Window->ExStyle &
WS_EX_TOPMOST))
- {
- TRACE("skip all the topmost windows\n");
- /* skip all the topmost windows */
- while (List[i] &&
- (ChildObject = ValidateHwndNoErr(List[i])) &&
- (ChildObject->ExStyle & WS_EX_TOPMOST)) i++;
- }
- }
- else if (hWndInsertAfter != HWND_TOPMOST)
- {
- /* skip windows that are already placed correctly */
- for (i = 0; List[i]; i++)
- {
- if (List[i] == hWndInsertAfter) break;
- if (List[i] == UserHMGetHandle(Window))
- {
- ExFreePoolWithTag(List, USERTAG_WINDOWLIST);
- goto done; /* nothing to do if window is moving backwards in z-order */
- }
- }
- }
-
- for (; List[i]; i++)
- {
- PWND Wnd;
- USER_REFERENCE_ENTRY Ref;
-
- if (List[i] == UserHMGetHandle(Window))
- break;
-
- if (!(Wnd = ValidateHwndNoErr(List[i])))
- continue;
-
- Owner = Wnd->spwndOwner ? Wnd->spwndOwner->head.h : NULL;
-
- if (Owner != UserHMGetHandle(Window)) continue;
-
- UserRefObjectCo(Wnd, &Ref);
- TRACE( "moving %p owned by %p after %p\n", List[i],
UserHMGetHandle(Window), hWndInsertAfter );
- co_WinPosSetWindowPos(Wnd, hWndInsertAfter, 0, 0, 0, 0,
- SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE |
SWP_NOSENDCHANGING| SWP_DEFERERASE);
-
- UserDerefObjectCo(Wnd);
- hWndInsertAfter = List[i];
- }
- ExFreePoolWithTag(List, USERTAG_WINDOWLIST);
- }
-done:
- return hWndInsertAfter;
-}
-////
-
-/***********************************************************************
- * WinPosInternalMoveWindow
- *
- * Update WindowRect and ClientRect of Window and all of its children
- * We keep both WindowRect and ClientRect in screen coordinates internally
- */
-static
-VOID FASTCALL
-WinPosInternalMoveWindow(PWND Window, INT MoveX, INT MoveY)
-{
- PWND Child;
-
- ASSERT(Window != Window->spwndChild);
- TRACE("InternalMoveWin X %d Y %d\n", MoveX, MoveY);
-
- Window->rcWindow.left += MoveX;
- Window->rcWindow.right += MoveX;
- Window->rcWindow.top += MoveY;
- Window->rcWindow.bottom += MoveY;
-
- Window->rcClient.left += MoveX;
- Window->rcClient.right += MoveX;
- Window->rcClient.top += MoveY;
- Window->rcClient.bottom += MoveY;
-
- for(Child = Window->spwndChild; Child; Child = Child->spwndNext)
- {
- WinPosInternalMoveWindow(Child, MoveX, MoveY);
- }
-}
-
-/*
- * WinPosFixupSWPFlags
- *
- * Fix redundant flags and values in the WINDOWPOS structure.
- */
-static
-BOOL FASTCALL
-WinPosFixupFlags(WINDOWPOS *WinPos, PWND Wnd)
-{
- PWND Parent;
- POINT pt;
-
- /* Finally make sure that all coordinates are valid */
- if (WinPos->x < -32768) WinPos->x = -32768;
- else if (WinPos->x > 32767) WinPos->x = 32767;
- if (WinPos->y < -32768) WinPos->y = -32768;
- else if (WinPos->y > 32767) WinPos->y = 32767;
-
- WinPos->cx = max(WinPos->cx, 0);
- WinPos->cy = max(WinPos->cy, 0);
-
- Parent = UserGetAncestor( Wnd, GA_PARENT );
- if (!IntIsWindowVisible( Parent ) &&
- /* Fix B : wine msg test_SetParent:WmSetParentSeq_2:25 wParam bits! */
- (WinPos->flags & SWP_AGG_STATUSFLAGS) == SWP_AGG_NOPOSCHANGE)
WinPos->flags |= SWP_NOREDRAW;
-
- if (Wnd->style & WS_VISIBLE) WinPos->flags &= ~SWP_SHOWWINDOW;
- else
- {
- WinPos->flags &= ~SWP_HIDEWINDOW;
- if (!(WinPos->flags & SWP_SHOWWINDOW)) WinPos->flags |= SWP_NOREDRAW;
- }
-
- /* Check for right size */
- if (Wnd->rcWindow.right - Wnd->rcWindow.left == WinPos->cx &&
- Wnd->rcWindow.bottom - Wnd->rcWindow.top == WinPos->cy)
- {
- WinPos->flags |= SWP_NOSIZE;
- }
-
- pt.x = WinPos->x;
- pt.y = WinPos->y;
- IntClientToScreen( Parent, &pt );
- TRACE("WPFU C2S wpx %d wpy %d ptx %d pty
%d\n",WinPos->x,WinPos->y,pt.x,pt.y);
- /* Check for right position */
- if (Wnd->rcWindow.left == pt.x && Wnd->rcWindow.top == pt.y)
- {
- //ERR("In right pos\n");
- WinPos->flags |= SWP_NOMOVE;
- }
-
- if ( WinPos->hwnd != UserGetForegroundWindow() && (Wnd->style &
(WS_POPUP | WS_CHILD)) != WS_CHILD)
- {
- /* Bring to the top when activating */
- if (!(WinPos->flags & (SWP_NOACTIVATE|SWP_HIDEWINDOW)) &&
- (WinPos->flags & SWP_NOZORDER ||
- (WinPos->hwndInsertAfter != HWND_TOPMOST &&
WinPos->hwndInsertAfter != HWND_NOTOPMOST)))
- {
- WinPos->flags &= ~SWP_NOZORDER;
- WinPos->hwndInsertAfter = (0 != (Wnd->ExStyle & WS_EX_TOPMOST) ?
HWND_TOPMOST : HWND_TOP);
- }
- }
-
- /* Check hwndInsertAfter */
- if (!(WinPos->flags & SWP_NOZORDER))
- {
- /* Fix sign extension */
- if (WinPos->hwndInsertAfter == (HWND)0xffff)
- {
- WinPos->hwndInsertAfter = HWND_TOPMOST;
- }
- else if (WinPos->hwndInsertAfter == (HWND)0xfffe)
- {
- WinPos->hwndInsertAfter = HWND_NOTOPMOST;
- }
-
- if (WinPos->hwndInsertAfter == HWND_TOP)
- {
- /* Keep it topmost when it's already topmost */
- if ((Wnd->ExStyle & WS_EX_TOPMOST) != 0)
- WinPos->hwndInsertAfter = HWND_TOPMOST;
-
- if (IntGetWindow(WinPos->hwnd, GW_HWNDFIRST) == WinPos->hwnd)
- {
- WinPos->flags |= SWP_NOZORDER;
- }
- }
- else if (WinPos->hwndInsertAfter == HWND_BOTTOM)
- {
- if (!(Wnd->ExStyle & WS_EX_TOPMOST) &&
IntGetWindow(WinPos->hwnd, GW_HWNDLAST) == WinPos->hwnd)
- WinPos->flags |= SWP_NOZORDER;
- }
- else if (WinPos->hwndInsertAfter == HWND_TOPMOST)
- {
- if ((Wnd->ExStyle & WS_EX_TOPMOST) &&
IntGetWindow(WinPos->hwnd, GW_HWNDFIRST) == WinPos->hwnd)
- WinPos->flags |= SWP_NOZORDER;
- }
- else if (WinPos->hwndInsertAfter == HWND_NOTOPMOST)
- {
- if (!(Wnd->ExStyle & WS_EX_TOPMOST))
- WinPos->flags |= SWP_NOZORDER;
- }
- else /* hwndInsertAfter must be a sibling of the window */
- {
- PWND InsAfterWnd;
-
- InsAfterWnd = ValidateHwndNoErr(WinPos->hwndInsertAfter);
- if(!InsAfterWnd)
- {
- return TRUE;
- }
-
- if (InsAfterWnd->spwndParent != Wnd->spwndParent)
- {
- /* Note from wine User32 Win test_SetWindowPos:
- "Returns TRUE also for windows that are not siblings"
- "Does not seem to do anything even without passing flags, still
returns TRUE"
- "Same thing the other way around."
- ".. and with these windows."
- */
- return FALSE;
- }
- else
- {
- /*
- * We don't need to change the Z order of hwnd if it's already
- * inserted after hwndInsertAfter or when inserting hwnd after
- * itself.
- */
- if ((WinPos->hwnd == WinPos->hwndInsertAfter) ||
- ((InsAfterWnd->spwndNext) && (WinPos->hwnd ==
InsAfterWnd->spwndNext->head.h)))
- {
- WinPos->flags |= SWP_NOZORDER;
- }
- }
- }
- }
-
- return TRUE;
-}
-
-/* x and y are always screen relative */
-BOOLEAN FASTCALL
-co_WinPosSetWindowPos(
- PWND Window,
- HWND WndInsertAfter,
- INT x,
- INT y,
- INT cx,
- INT cy,
- UINT flags
- )
-{
- WINDOWPOS WinPos;
- RECTL NewWindowRect;
- RECTL NewClientRect;
- RECTL valid_rects[2];
- PREGION VisBefore = NULL;
- PREGION VisBeforeJustClient = NULL;
- PREGION VisAfter = NULL;
- PREGION CopyRgn = NULL;
- ULONG WvrFlags = 0;
- RECTL OldWindowRect, OldClientRect;
- int RgnType;
- HDC Dc;
- RECTL CopyRect;
- PWND Ancestor;
- BOOL bPointerInWindow, PosChanged = FALSE;
- PTHREADINFO pti = PsGetCurrentThreadWin32Thread();
-
- ASSERT_REFS_CO(Window);
-
- TRACE("pwnd %p, after %p, %d,%d (%dx%d), flags %s",
- Window, WndInsertAfter, x, y, cx, cy, flags);
-#if DBG
- dump_winpos_flags(flags);
-#endif
-
- /* FIXME: Get current active window from active queue. Why? since r2915. */
-
- bPointerInWindow = IntPtInWindow(Window, gpsi->ptCursor.x, gpsi->ptCursor.y);
-
- WinPos.hwnd = Window->head.h;
- WinPos.hwndInsertAfter = WndInsertAfter;
- WinPos.x = x;
- WinPos.y = y;
- WinPos.cx = cx;
- WinPos.cy = cy;
- WinPos.flags = flags;
-
- if ( flags & SWP_ASYNCWINDOWPOS )
- {
- LRESULT lRes;
- PWINDOWPOS ppos = ExAllocatePoolWithTag(PagedPool, sizeof(WINDOWPOS),
USERTAG_SWP);
- if ( ppos )
- {
- WinPos.flags &= ~SWP_ASYNCWINDOWPOS; // Clear flag.
- *ppos = WinPos;
- /* Yes it's a pointer inside Win32k! */
- lRes = co_IntSendMessageNoWait( WinPos.hwnd, WM_ASYNC_SETWINDOWPOS, 0,
(LPARAM)ppos);
- /* We handle this the same way as Event Hooks and Hooks. */
- if ( !lRes )
- {
- ExFreePoolWithTag(ppos, USERTAG_SWP);
- return FALSE;
- }
- return TRUE;
- }
- return FALSE;
- }
-
- co_WinPosDoWinPosChanging(Window, &WinPos, &NewWindowRect,
&NewClientRect);
-
- /* Does the window still exist? */
- if (!IntIsWindow(WinPos.hwnd))
- {
- TRACE("WinPosSetWindowPos: Invalid handle 0x%p!\n",WinPos.hwnd);
- EngSetLastError(ERROR_INVALID_WINDOW_HANDLE);
- return FALSE;
- }
-
- /* Fix up the flags. */
- if (!WinPosFixupFlags(&WinPos, Window))
- {
- // See Note.
- return TRUE;
- }
-
- Ancestor = UserGetAncestor(Window, GA_PARENT);
- if ( (WinPos.flags & (SWP_NOZORDER | SWP_HIDEWINDOW | SWP_SHOWWINDOW)) !=
SWP_NOZORDER &&
- Ancestor && Ancestor->head.h == IntGetDesktopWindow() )
- {
- WinPos.hwndInsertAfter = WinPosDoOwnedPopups(Window, WinPos.hwndInsertAfter);
- }
-
- if (!(WinPos.flags & SWP_NOREDRAW))
- {
- /* Compute the visible region before the window position is changed */
- if (!(WinPos.flags & SWP_SHOWWINDOW) &&
- (WinPos.flags & (SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER |
- SWP_HIDEWINDOW | SWP_FRAMECHANGED)) !=
- (SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER))
- {
- VisBefore = VIS_ComputeVisibleRegion(Window, FALSE, FALSE,
- (Window->style & WS_CLIPSIBLINGS) ?
TRUE : FALSE);
-
- if ( VisBefore != NULL &&
- REGION_Complexity(VisBefore) == NULLREGION )
- {
- REGION_Delete(VisBefore);
- VisBefore = NULL;
- }
- else if(VisBefore)
- {
- REGION_bOffsetRgn(VisBefore, -Window->rcWindow.left,
-Window->rcWindow.top);
- }
-
- /* Calculate the non client area for resizes, as this is used in the copy region
*/
- if (!(WinPos.flags & SWP_NOSIZE))
- {
- VisBeforeJustClient = VIS_ComputeVisibleRegion(Window, TRUE, FALSE,
- (Window->style & WS_CLIPSIBLINGS) ? TRUE : FALSE);
-
- if ( VisBeforeJustClient != NULL &&
- REGION_Complexity(VisBeforeJustClient) == NULLREGION )
- {
- REGION_Delete(VisBeforeJustClient);
- VisBeforeJustClient = NULL;
- }
- else if(VisBeforeJustClient)
- {
- REGION_bOffsetRgn(VisBeforeJustClient, -Window->rcWindow.left,
-Window->rcWindow.top);
- }
- }
- }
- }
-
- //// HACK 3
- if (Window->hrgnNewFrame)
- {
- SelectWindowRgn( Window, Window->hrgnNewFrame ); // Should be
PSMWP->acvr->hrgnClip
- Window->hrgnNewFrame = NULL;
- }
-
- WvrFlags = co_WinPosDoNCCALCSize(Window, &WinPos, &NewWindowRect,
&NewClientRect, valid_rects);
-
-// ERR("co_WinPosDoNCCALCSize returned 0x%x\n valid dest: %d %d %d %d\n valid src
: %d %d %d %d\n", WvrFlags,
-//
valid_rects[0].left,valid_rects[0].top,valid_rects[0].right,valid_rects[0].bottom,
-//
valid_rects[1].left,valid_rects[1].top,valid_rects[1].right,valid_rects[1].bottom);
-
- /* Validate link windows. (also take into account shell window in hwndShellWindow) */
- if (!(WinPos.flags & SWP_NOZORDER) && WinPos.hwnd !=
UserGetShellWindow())
- {
- IntLinkHwnd(Window, WinPos.hwndInsertAfter);
- }
-
- OldWindowRect = Window->rcWindow;
- OldClientRect = Window->rcClient;
-
- if (NewClientRect.left != OldClientRect.left ||
- NewClientRect.top != OldClientRect.top)
- {
- // Move child window if their parent is moved. Keep Child window relative to
Parent...
- WinPosInternalMoveWindow(Window,
- NewClientRect.left - OldClientRect.left,
- NewClientRect.top - OldClientRect.top);
- PosChanged = TRUE;
- }
-
- Window->rcWindow = NewWindowRect;
- Window->rcClient = NewClientRect;
-
- /* erase parent when hiding or resizing child */
- if (WinPos.flags & SWP_HIDEWINDOW)
- {
- /* Clear the update region */
- co_UserRedrawWindow( Window,
- NULL,
- 0,
- RDW_VALIDATE | RDW_NOFRAME | RDW_NOERASE | RDW_NOINTERNALPAINT
| RDW_ALLCHILDREN);
-
- if (UserIsDesktopWindow(Window->spwndParent))
- co_IntShellHookNotify(HSHELL_WINDOWDESTROYED, (WPARAM)Window->head.h, 0);
-
- Window->style &= ~WS_VISIBLE; //IntSetStyle( Window, 0, WS_VISIBLE );
- Window->head.pti->cVisWindows--;
- IntNotifyWinEvent(EVENT_OBJECT_HIDE, Window, OBJID_WINDOW, CHILDID_SELF,
WEF_SETBYWNDPTI);
- }
- else if (WinPos.flags & SWP_SHOWWINDOW)
- {
- if (UserIsDesktopWindow(Window->spwndParent) &&
- Window->spwndOwner == NULL &&
- (!(Window->ExStyle & WS_EX_TOOLWINDOW) ||
- (Window->ExStyle & WS_EX_APPWINDOW)))
- co_IntShellHookNotify(HSHELL_WINDOWCREATED, (WPARAM)Window->head.h, 0);
-
- Window->style |= WS_VISIBLE; //IntSetStyle( Window, WS_VISIBLE, 0 );
- Window->head.pti->cVisWindows++;
- IntNotifyWinEvent(EVENT_OBJECT_SHOW, Window, OBJID_WINDOW, CHILDID_SELF,
WEF_SETBYWNDPTI);
- }
-
- if (Window->hrgnUpdate != NULL && Window->hrgnUpdate != HRGN_WINDOW)
- {
- NtGdiOffsetRgn(Window->hrgnUpdate,
- NewWindowRect.left - OldWindowRect.left,
- NewWindowRect.top - OldWindowRect.top);
- }
-
- DceResetActiveDCEs(Window); // For WS_VISIBLE changes.
-
- if (!(WinPos.flags & SWP_NOREDRAW))
- {
- /* Determine the new visible region */
- VisAfter = VIS_ComputeVisibleRegion(Window, FALSE, FALSE,
- (Window->style & WS_CLIPSIBLINGS) ? TRUE
: FALSE);
-
- if ( VisAfter != NULL &&
- REGION_Complexity(VisAfter) == NULLREGION )
- {
- REGION_Delete(VisAfter);
- VisAfter = NULL;
- }
- else if(VisAfter)
- {
- REGION_bOffsetRgn(VisAfter, -Window->rcWindow.left,
-Window->rcWindow.top);
- }
-
- /*
- * Determine which pixels can be copied from the old window position
- * to the new. Those pixels must be visible in both the old and new
- * position. Also, check the class style to see if the windows of this
- * class need to be completely repainted on (horizontal/vertical) size
- * change.
- */
- if ( ( VisBefore != NULL &&
- VisAfter != NULL &&
- !(WinPos.flags & SWP_NOCOPYBITS) &&
- ((WinPos.flags & SWP_NOSIZE) || !(WvrFlags & WVR_REDRAW)) &&
- !(Window->ExStyle & WS_EX_TRANSPARENT) ) ||
- ( !PosChanged && (WinPos.flags & SWP_FRAMECHANGED) &&
VisBefore) )
- {
-
- /*
- * If this is (also) a window resize, the whole nonclient area
- * needs to be repainted. So we limit the copy to the client area,
- * 'cause there is no use in copying it (would possibly cause
- * "flashing" too). However, if the copy region is already empty,
- * we don't have to crop (can't take anything away from an empty
- * region...)
- */
-
- CopyRgn = IntSysCreateRectpRgn(0, 0, 0, 0);
- if (WinPos.flags & SWP_NOSIZE)
- RgnType = IntGdiCombineRgn(CopyRgn, VisAfter, VisBefore, RGN_AND);
- else if (VisBeforeJustClient != NULL)
- {
- RgnType = IntGdiCombineRgn(CopyRgn, VisAfter, VisBeforeJustClient, RGN_AND);
- REGION_Delete(VisBeforeJustClient);
- }
-
- /* No use in copying bits which are in the update region. */
- if (Window->hrgnUpdate != NULL)
- {
- PREGION RgnUpdate = REGION_LockRgn(Window->hrgnUpdate);
- if (RgnUpdate)
- {
- REGION_bOffsetRgn(CopyRgn, NewWindowRect.left, NewWindowRect.top);
- IntGdiCombineRgn(CopyRgn, CopyRgn, RgnUpdate, RGN_DIFF);
- REGION_bOffsetRgn(CopyRgn, -NewWindowRect.left, -NewWindowRect.top);
- REGION_UnlockRgn(RgnUpdate);
- }
- }
-
- /*
- * Now, get the bounding box of the copy region. If it's empty
- * there's nothing to copy. Also, it's no use copying bits onto
- * themselves.
- */
- if (REGION_GetRgnBox(CopyRgn, &CopyRect) == NULLREGION)
- {
- /* Nothing to copy, clean up */
- REGION_Delete(CopyRgn);
- CopyRgn = NULL;
- }
- else if ( OldWindowRect.left != NewWindowRect.left ||
- OldWindowRect.top != NewWindowRect.top ||
- (WinPos.flags & SWP_FRAMECHANGED) )
- {
- HRGN DcRgn = NtGdiCreateRectRgn(0, 0, 0, 0);
- PREGION DcRgnObj = REGION_LockRgn(DcRgn);
-
- /*
- * Small trick here: there is no function to bitblt a region. So
- * we set the region as the clipping region, take the bounding box
- * of the region and bitblt that. Since nothing outside the clipping
- * region is copied, this has the effect of bitblt'ing the region.
- *
- * Since NtUserGetDCEx takes ownership of the clip region, we need
- * to create a copy of CopyRgn and pass that. We need CopyRgn later
- */
- IntGdiCombineRgn(DcRgnObj, CopyRgn, NULL, RGN_COPY);
- REGION_bOffsetRgn(DcRgnObj, NewWindowRect.left, NewWindowRect.top);
- REGION_UnlockRgn(DcRgnObj);
- Dc = UserGetDCEx( Window,
- DcRgn,
-
DCX_WINDOW|DCX_CACHE|DCX_INTERSECTRGN|DCX_CLIPSIBLINGS|DCX_KEEPCLIPRGN);
- NtGdiBitBlt( Dc,
- CopyRect.left, CopyRect.top,
- CopyRect.right - CopyRect.left,
- CopyRect.bottom - CopyRect.top,
- Dc,
- CopyRect.left + (OldWindowRect.left - NewWindowRect.left),
- CopyRect.top + (OldWindowRect.top - NewWindowRect.top),
- SRCCOPY,
- 0,
- 0);
-
- UserReleaseDC(Window, Dc, FALSE);
- IntValidateParent(Window, CopyRgn);
- GreDeleteObject(DcRgn);
- }
- }
- else
- {
- CopyRgn = NULL;
- }
-#if 0
- /////// Fixes NoPopup tests but breaks msg_paint tests.
- if ( !PosChanged && (WinPos.flags & SWP_FRAMECHANGED) &&
VisBefore)
- {
- PWND Parent = Window->spwndParent;
- ERR("SWP_FRAMECHANGED no chg\n");
- if ( !(Window->style & WS_CHILD) && (Parent) &&
(Parent->style & WS_CLIPCHILDREN))
- {
- ERR("SWP_FRAMECHANGED Parent WS_CLIPCHILDREN\n");
- //IntInvalidateWindows( Window, VisBefore, /*RDW_ERASE |*/ RDW_FRAME |
RDW_INVALIDATE | RDW_ALLCHILDREN);
- }
- }
-#endif
- /* We need to redraw what wasn't visible before */
- if (VisAfter != NULL)
- {
- PREGION DirtyRgn = IntSysCreateRectpRgn(0, 0, 0, 0);
- if (DirtyRgn)
- {
- if (CopyRgn != NULL)
- {
- RgnType = IntGdiCombineRgn(DirtyRgn, VisAfter, CopyRgn, RGN_DIFF);
- }
- else
- {
- RgnType = IntGdiCombineRgn(DirtyRgn, VisAfter, 0, RGN_COPY);
- }
-
- if (RgnType != ERROR && RgnType != NULLREGION)
- {
- /* old code
- NtGdiOffsetRgn(DirtyRgn, Window->rcWindow.left,
Window->rcWindow.top);
- IntInvalidateWindows( Window,
- DirtyRgn,
- RDW_ERASE | RDW_FRAME | RDW_INVALIDATE | RDW_ALLCHILDREN);
- }
- GreDeleteObject(DirtyRgn);
- */
-
- PWND Parent = Window->spwndParent;
-
- REGION_bOffsetRgn( DirtyRgn, Window->rcWindow.left,
Window->rcWindow.top);
-
- if ( (Window->style & WS_CHILD) && (Parent) &&
!(Parent->style & WS_CLIPCHILDREN))
- {
- IntInvalidateWindows( Parent, DirtyRgn, RDW_ERASE | RDW_INVALIDATE);
- co_IntPaintWindows(Parent, RDW_NOCHILDREN, FALSE);
- }
- else
- {
- IntInvalidateWindows( Window, DirtyRgn, RDW_ERASE | RDW_FRAME |
RDW_INVALIDATE | RDW_ALLCHILDREN);
- }
- }
- REGION_Delete(DirtyRgn);
- }
- }
-
- if (CopyRgn != NULL)
- {
- REGION_Delete(CopyRgn);
- }
-
- /* Expose what was covered before but not covered anymore */
- if (VisBefore != NULL)
- {
- PREGION ExposedRgn = IntSysCreateRectpRgn(0, 0, 0, 0);
- if (ExposedRgn)
- {
- RgnType = IntGdiCombineRgn(ExposedRgn, VisBefore, NULL, RGN_COPY);
- REGION_bOffsetRgn(ExposedRgn,
- OldWindowRect.left - NewWindowRect.left,
- OldWindowRect.top - NewWindowRect.top);
-
- if (VisAfter != NULL)
- RgnType = IntGdiCombineRgn(ExposedRgn, ExposedRgn, VisAfter, RGN_DIFF);
-
- if (RgnType != ERROR && RgnType != NULLREGION)
- {
- co_VIS_WindowLayoutChanged(Window, ExposedRgn);
- }
- REGION_Delete(ExposedRgn);
- }
- REGION_Delete(VisBefore);
- }
-
- if (VisAfter != NULL)
- {
- REGION_Delete(VisAfter);
- }
- }
-
- if (!(WinPos.flags & (SWP_NOACTIVATE|SWP_HIDEWINDOW)))
- {
- if ((Window->style & (WS_CHILD | WS_POPUP)) == WS_CHILD)
- {
- co_IntSendMessageNoWait(WinPos.hwnd, WM_CHILDACTIVATE, 0, 0);
- }
- else
- {
- //ERR("SetWindowPos Set FG Window!\n");
- if ( pti->MessageQueue->spwndActive != Window ||
- pti->MessageQueue != gpqForeground )
- {
- //ERR("WPSWP : set active window\n");
- if (!(Window->state & WNDS_BEINGACTIVATED)) // Inside SAW?
- {
- co_IntSetForegroundWindow(Window); // Fixes SW_HIDE issues. Wine win
test_SetActiveWindow & test_SetForegroundWindow.
- }
- }
- }
- }
-
- if ( !PosChanged &&
- (WinPos.flags & SWP_FRAMECHANGED) &&
- !(WinPos.flags & SWP_DEFERERASE) && // Prevent sending
WM_SYNCPAINT message.
- VisAfter )
- {
- PWND Parent = Window->spwndParent;
- if ( !(Window->style & WS_CHILD) && (Parent) &&
(Parent->style & WS_CLIPCHILDREN))
- {
- TRACE("SWP_FRAMECHANGED Parent WS_CLIPCHILDREN\n");
- UserSyncAndPaintWindows( Parent, RDW_CLIPCHILDREN);
- }
- }
-
- // Fix wine msg test_SetFocus, prevents sending WM_WINDOWPOSCHANGED.
- if ( VisBefore == NULL &&
- VisBeforeJustClient == NULL &&
- !(Window->ExStyle & WS_EX_TOPMOST) &&
- (WinPos.flags & SWP_AGG_STATUSFLAGS) == (SWP_AGG_NOPOSCHANGE &
~SWP_NOZORDER))
- {
- TRACE("No drawing, set no Z order and no redraw!\n");
- WinPos.flags |= SWP_NOZORDER|SWP_NOREDRAW;
- }
-
- /* And last, send the WM_WINDOWPOSCHANGED message */
-
- TRACE("\tstatus hwnd %p flags =
%04x\n",Window?Window->head.h:NULL,WinPos.flags & SWP_AGG_STATUSFLAGS);
-
- if ((WinPos.flags & SWP_AGG_STATUSFLAGS) != SWP_AGG_NOPOSCHANGE)
- {
- /* WM_WINDOWPOSCHANGED is sent even if SWP_NOSENDCHANGING is set
- and always contains final window position.
- */
- WinPos.x = NewWindowRect.left;
- WinPos.y = NewWindowRect.top;
- WinPos.cx = NewWindowRect.right - NewWindowRect.left;
- WinPos.cy = NewWindowRect.bottom - NewWindowRect.top;
- TRACE("WM_WINDOWPOSCHANGED hwnd %p Flags
%04x\n",WinPos.hwnd,WinPos.flags);
- co_IntSendMessageNoWait(WinPos.hwnd, WM_WINDOWPOSCHANGED, 0, (LPARAM)
&WinPos);
- }
-
- if ( WinPos.flags & SWP_FRAMECHANGED || WinPos.flags & SWP_STATECHANGED ||
- !(WinPos.flags & SWP_NOCLIENTSIZE) || !(WinPos.flags & SWP_NOCLIENTMOVE) )
- {
- PWND pWnd = ValidateHwndNoErr(WinPos.hwnd);
- if (pWnd)
- IntNotifyWinEvent(EVENT_OBJECT_LOCATIONCHANGE, pWnd, OBJID_WINDOW, CHILDID_SELF,
WEF_SETBYWNDPTI);
- }
-
- if(bPointerInWindow != IntPtInWindow(Window, gpsi->ptCursor.x,
gpsi->ptCursor.y))
- {
- /* Generate mouse move message */
- MSG msg;
- msg.message = WM_MOUSEMOVE;
- msg.wParam = UserGetMouseButtonsState();
- msg.lParam = MAKELPARAM(gpsi->ptCursor.x, gpsi->ptCursor.y);
- msg.pt = gpsi->ptCursor;
- co_MsqInsertMouseMessage(&msg, 0, 0, TRUE);
- }
-
- return TRUE;
-}
-
-LRESULT FASTCALL
-co_WinPosGetNonClientSize(PWND Window, RECT* WindowRect, RECT* ClientRect)
-{
- LRESULT Result;
-
- ASSERT_REFS_CO(Window);
-
- *ClientRect = *WindowRect;
- Result = co_IntSendMessageNoWait(Window->head.h, WM_NCCALCSIZE, FALSE, (LPARAM)
ClientRect);
-
- FixClientRect(ClientRect, WindowRect);
-
- return Result;
-}
-
-void FASTCALL
-co_WinPosSendSizeMove(PWND Wnd)
-{
- RECTL Rect;
- LPARAM lParam;
- WPARAM wParam = SIZE_RESTORED;
-
- IntGetClientRect(Wnd, &Rect);
- lParam = MAKELONG(Rect.right-Rect.left, Rect.bottom-Rect.top);
-
- Wnd->state &= ~WNDS_SENDSIZEMOVEMSGS;
-
- if (Wnd->style & WS_MAXIMIZE)
- {
- wParam = SIZE_MAXIMIZED;
- }
- else if (Wnd->style & WS_MINIMIZE)
- {
- wParam = SIZE_MINIMIZED;
- lParam = 0;
- }
-
- co_IntSendMessageNoWait(UserHMGetHandle(Wnd), WM_SIZE, wParam, lParam);
-
- if (UserIsDesktopWindow(Wnd->spwndParent))
- 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);
-}
-
/*
ShowWindow does not set SWP_FRAMECHANGED!!! Fix wine msg
test_SetParent:WmSetParentSeq_2:23 wParam bits!
*/