#define PLACE_MAX 0x0002
#define PLACE_RECT 0x0004
+VOID FASTCALL IntLinkWindow(PWND Wnd,PWND WndInsertAfter);
+
/* FUNCTIONS *****************************************************************/
BOOL FASTCALL
IntGetClientOrigin(PWND Window OPTIONAL, LPPOINT Point)
{
- Window = Window ? Window : UserGetWindowObject(IntGetDesktopWindow());
+ Window = Window ? Window : UserGetDesktopWindow();
if (Window == NULL)
{
Point->x = Point->y = 0;
Rect->bottom = UserGetSystemMetrics(SM_CYMINIMIZED);
return;
}
- if ( Wnd != UserGetDesktopWindow()) // Wnd->fnid != FNID_DESKTOP )
+ if ( Wnd != UserGetDesktopWindow()) // Wnd->fnid != FNID_DESKTOP )
{
*Rect = Wnd->rcClient;
RECTL_vOffsetRect(Rect, -Wnd->rcClient.left, -Wnd->rcClient.top);
Delta.y -= ToWnd->rcClient.top;
}
- if (mirror_from) Delta.x = -Delta.x;
-
for (i = 0; i != cPoints; i++)
{
lpPoints[i].x += Delta.x;
return MAKELONG(LOWORD(Delta.x), LOWORD(Delta.y));
}
+BOOL FASTCALL
+IntClientToScreen(PWND Wnd, LPPOINT lpPoint)
+{
+ if (Wnd && Wnd->fnid != FNID_DESKTOP )
+ {
+ if (Wnd->ExStyle & WS_EX_LAYOUTRTL)
+ lpPoint->x = Wnd->rcClient.right - lpPoint->x;
+ else
+ lpPoint->x += Wnd->rcClient.left;
+ lpPoint->y += Wnd->rcClient.top;
+ }
+ return TRUE;
+}
+
+BOOL FASTCALL
+IntScreenToClient(PWND Wnd, LPPOINT lpPoint)
+{
+ if (Wnd && Wnd->fnid != FNID_DESKTOP )
+ {
+ if (Wnd->ExStyle & WS_EX_LAYOUTRTL)
+ lpPoint->x = Wnd->rcClient.right - lpPoint->x;
+ else
+ lpPoint->x -= Wnd->rcClient.left;
+ lpPoint->y -= Wnd->rcClient.top;
+ }
+ return TRUE;
+}
+
+BOOL FASTCALL IsChildVisible(PWND pWnd)
+{
+ do
+ {
+ if ( (pWnd->style & (WS_POPUP|WS_CHILD)) != WS_CHILD ||
+ !(pWnd = pWnd->spwndParent) )
+ return TRUE;
+ }
+ while (pWnd->style & WS_VISIBLE);
+ return FALSE;
+}
+
+PWND FASTCALL IntGetLastTopMostWindow(VOID)
+{
+ PWND pWnd;
+ PDESKTOP rpdesk = gptiCurrent->rpdesk;
+
+ if ( rpdesk &&
+ (pWnd = rpdesk->pDeskInfo->spwnd->spwndChild) &&
+ pWnd->ExStyle & WS_EX_TOPMOST)
+ {
+ for (;;)
+ {
+ if (!pWnd->spwndNext) break;
+ if (!(pWnd->spwndNext->ExStyle & WS_EX_TOPMOST)) break;
+ pWnd = pWnd->spwndNext;
+ }
+ return pWnd;
+ }
+ return NULL;
+}
+
+//
+// This helps with CORE-6129 forcing modal dialog active when another app is minimized or closed.
+//
+BOOL FASTCALL ActivateOtherWindowMin(PWND Wnd)
+{
+ BOOL ActivePrev, FindTopWnd;
+ PWND pWndTopMost, pWndChild, pWndSetActive, pWndTemp, pWndDesk;
+ USER_REFERENCE_ENTRY Ref;
+ PTHREADINFO pti = gptiCurrent;
+
+ //ERR("AOWM 1\n");
+ ActivePrev = (pti->MessageQueue->spwndActivePrev != NULL);
+ FindTopWnd = TRUE;
+
+ if ((pWndTopMost = IntGetLastTopMostWindow()))
+ pWndChild = pWndTopMost->spwndNext;
+ else
+ pWndChild = Wnd->spwndParent->spwndChild;
+
+ for (;;)
+ {
+ if ( ActivePrev )
+ pWndSetActive = pti->MessageQueue->spwndActivePrev;
+ else
+ pWndSetActive = pWndChild;
+
+ pWndTemp = NULL;
+
+ while(pWndSetActive)
+ {
+ if ( VerifyWnd(pWndSetActive) &&
+ !(pWndSetActive->ExStyle & WS_EX_NOACTIVATE) &&
+ (pWndSetActive->style & (WS_VISIBLE|WS_DISABLED)) == WS_VISIBLE &&
+ (!(pWndSetActive->style & WS_ICONIC) /* FIXME MinMax pos? */ ) )
+ {
+ if (!(pWndSetActive->ExStyle & WS_EX_TOOLWINDOW) )
+ {
+ UserRefObjectCo(pWndSetActive, &Ref);
+ //ERR("ActivateOtherWindowMin Set FG 1\n");
+ co_IntSetForegroundWindow(pWndSetActive);
+ UserDerefObjectCo(pWndSetActive);
+ //ERR("AOWM 2 Exit Good\n");
+ return TRUE;
+ }
+ if (!pWndTemp ) pWndTemp = pWndSetActive;
+ }
+ if ( ActivePrev )
+ {
+ ActivePrev = FALSE;
+ pWndSetActive = pWndChild;
+ }
+ else
+ pWndSetActive = pWndSetActive->spwndNext;
+ }
+
+ if ( !FindTopWnd ) break;
+ FindTopWnd = FALSE;
+
+ if ( pWndChild )
+ {
+ pWndChild = pWndChild->spwndParent->spwndChild;
+ continue;
+ }
+
+ if (!(pWndDesk = IntGetThreadDesktopWindow(pti)))
+ {
+ pWndChild = NULL;
+ continue;
+ }
+ pWndChild = pWndDesk->spwndChild;
+ }
+
+ if ((pWndSetActive = pWndTemp))
+ {
+ UserRefObjectCo(pWndSetActive, &Ref);
+ //ERR("ActivateOtherWindowMin Set FG 2\n");
+ co_IntSetForegroundWindow(pWndSetActive);
+ UserDerefObjectCo(pWndSetActive);
+ //ERR("AOWM 3 Exit Good\n");
+ return TRUE;
+ }
+ //ERR("AOWM 4 Bad\n");
+ return FALSE;
+}
+
/*******************************************************************
* can_activate_window
*
if (!Wnd) return FALSE;
style = Wnd->style;
- if (!(style & WS_VISIBLE) &&
- Wnd->head.pti->pEThread->ThreadsProcess != CsrProcess) return FALSE;
- if ((style & WS_MINIMIZE) &&
- Wnd->head.pti->pEThread->ThreadsProcess != CsrProcess) return FALSE;
+ if (!(style & WS_VISIBLE)) return FALSE;
+ if (style & WS_MINIMIZE) return FALSE;
if ((style & (WS_POPUP|WS_CHILD)) == WS_CHILD) return FALSE;
return TRUE;
- /* FIXME: This window could be disable because the child that closed
+ /* FIXME: This window could be disable because the child that closed
was a popup. */
//return !(style & WS_DISABLED);
}
co_WinPosActivateOtherWindow(PWND Wnd)
{
PWND WndTo = NULL;
- HWND Fg, previous;
USER_REFERENCE_ENTRY Ref;
ASSERT_REFS_CO(Wnd);
if (WndTo) UserRefObjectCo(WndTo, &Ref);
- Fg = UserGetForegroundWindow();
- if ((!Fg || Wnd->head.h == Fg) && WndTo) // FIXME: Ok if WndTo is NULL??
+ if (!gpqForeground || Wnd == gpqForeground->spwndActive)
{
- /* FIXME: Wine can pass WndTo = NULL to co_IntSetForegroundWindow. Hmm... */
+ /* ReactOS can pass WndTo = NULL to co_IntSetForegroundWindow and returns FALSE. */
+ //ERR("WinPosActivateOtherWindow Set FG 0x%p\n",WndTo);
if (co_IntSetForegroundWindow(WndTo))
{
- UserDerefObjectCo(WndTo);
+ if (WndTo) UserDerefObjectCo(WndTo);
return;
}
}
-
- if (!co_IntSetActiveWindow(WndTo,&previous,FALSE,TRUE) || /* Ok for WndTo to be NULL here */
- !previous)
- co_IntSetActiveWindow(0,NULL,FALSE,TRUE);
-
- if (WndTo) UserDerefObjectCo(WndTo);
-}
-
-UINT
-FASTCALL
-co_WinPosArrangeIconicWindows(PWND parent)
-{
- RECTL rectParent;
- INT i, x, y, xspacing, yspacing, sx, sy;
- HWND *List = IntWinListChildren(parent);
-
- ASSERT_REFS_CO(parent);
-
- /* Check if we found any children */
- if(List == NULL)
+ //ERR("WinPosActivateOtherWindow Set Active 0x%p\n",WndTo);
+ if (!co_IntSetActiveWindow(WndTo,FALSE,TRUE,FALSE)) /* Ok for WndTo to be NULL here */
{
- return 0;
+ co_IntSetActiveWindow(NULL,FALSE,TRUE,FALSE);
}
-
- IntGetClientRect( parent, &rectParent );
- // FIXME: Support gspv.mm.iArrange.
- x = rectParent.left;
- y = rectParent.bottom;
-
- xspacing = (UserGetSystemMetrics(SM_CXMINSPACING)/2)+UserGetSystemMetrics(SM_CXBORDER);
- yspacing = (UserGetSystemMetrics(SM_CYMINSPACING)/2)+UserGetSystemMetrics(SM_CYBORDER);
-
- //ERR("X:%d Y:%d XS:%d YS:%d\n",x,y,xspacing,yspacing);
-
- for(i = 0; List[i]; i++)
- {
- PWND Child;
-
- if (!(Child = UserGetWindowObject(List[i])))
- continue;
-
- if((Child->style & WS_MINIMIZE) != 0 )
- {
- USER_REFERENCE_ENTRY Ref;
- UserRefObjectCo(Child, &Ref);
-
- sx = x + UserGetSystemMetrics(SM_CXBORDER);
- sy = y - yspacing - UserGetSystemMetrics(SM_CYBORDER);
-
- co_WinPosSetWindowPos( Child, 0, sx, sy, 0, 0,
- SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE );
-
- Child->InternalPos.IconPos.x = sx;
- Child->InternalPos.IconPos.y = sy;
- Child->InternalPos.flags |= WPF_MININIT;
- Child->InternalPos.flags &= ~WPF_SETMINPOSITION;
-
- UserDerefObjectCo(Child);
-
- if (x <= (rectParent.right - UserGetSystemMetrics(SM_CXMINSPACING)))
- x += xspacing;
- else
- {
- x = rectParent.left;
- y -= yspacing;
- }
- //ERR("X:%d Y:%d\n",x,y);
- }
- }
- ExFreePool(List);
- return yspacing;
-}
-
-static VOID FASTCALL
-WinPosFindIconPos(PWND Window, POINT *Pos)
-{
- RECT rectParent;
- PWND pwndChild, pwndParent;
- int x, y, xspacing, yspacing;
-
- pwndParent = Window->spwndParent;
- if (pwndParent == UserGetDesktopWindow())
- {
- /* ReactOS doesn't support iconic minimize to desktop */
- Pos->x = Pos->y = -32000;
- Window->InternalPos.flags |= WPF_MININIT;
- Window->InternalPos.IconPos.x = Pos->x;
- Window->InternalPos.IconPos.y = Pos->y;
- return;
- }
-
- IntGetClientRect( pwndParent, &rectParent );
- // FIXME: Support gspv.mm.iArrange.
- x = rectParent.left;
- y = rectParent.bottom;
-
- xspacing = (UserGetSystemMetrics(SM_CXMINSPACING)/2)+UserGetSystemMetrics(SM_CXBORDER);
- yspacing = (UserGetSystemMetrics(SM_CYMINSPACING)/2)+UserGetSystemMetrics(SM_CYBORDER);
-
- //ERR("X:%d Y:%d XS:%d YS:%d\n",Pos->x,Pos->y,xspacing,yspacing);
-
- // Set to default position when minimized.
- Pos->x = x + UserGetSystemMetrics(SM_CXBORDER);
- Pos->y = y - yspacing - UserGetSystemMetrics(SM_CYBORDER);
-
- for (pwndChild = pwndParent->spwndChild; pwndChild; pwndChild = pwndChild->spwndNext)
- {
- if (pwndChild == Window) continue;
-
- if (pwndChild->style & WS_VISIBLE)
- {
- //ERR("Loop!\n");
- continue;
- }
- //ERR("Pos Child X %d Y %d!\n", pwndChild->InternalPos.IconPos.x, pwndChild->InternalPos.IconPos.y);
- if ( pwndChild->InternalPos.IconPos.x == Pos->x &&
- pwndChild->InternalPos.IconPos.y == Pos->y )
- {
- if (x <= rectParent.right - UserGetSystemMetrics(SM_CXMINSPACING))
- x += xspacing;
- else
- {
- x = rectParent.left;
- y -= yspacing;
- }
- Pos->x = x + UserGetSystemMetrics(SM_CXBORDER);
- Pos->y = y - yspacing - UserGetSystemMetrics(SM_CYBORDER);
- }
- }
- Window->InternalPos.IconPos.x = Pos->x;
- Window->InternalPos.IconPos.y = Pos->y;
- Window->InternalPos.flags |= WPF_MININIT;
- //ERR("Position is set! X:%d Y:%d\n",Pos->x,Pos->y);
- return;
+ if (WndTo) UserDerefObjectCo(WndTo);
}
VOID FASTCALL
Wnd->InternalPos.MaxPos.x,
Rect.left, WorkArea.left,
Wnd->InternalPos.MaxPos.y,
- Rect.top, WorkArea.top);
- */
+ Rect.top, WorkArea.top);*/
}
}
else
return TRUE;
}
+UINT
+FASTCALL
+co_WinPosArrangeIconicWindows(PWND parent)
+{
+ RECTL rectParent;
+ PWND Child;
+ INT x, y, xspacing, yspacing, sx, sy;
+
+ ASSERT_REFS_CO(parent);
+
+ IntGetClientRect( parent, &rectParent );
+ // FIXME: Support Minimize Metrics gspv.mm.iArrange.
+ // Default: ARW_BOTTOMLEFT
+ x = rectParent.left;
+ y = rectParent.bottom;
+
+ xspacing = UserGetSystemMetrics(SM_CXMINIMIZED);
+ yspacing = UserGetSystemMetrics(SM_CYMINIMIZED);
+
+ Child = parent->spwndChild;
+ while(Child)
+ {
+ if((Child->style & WS_MINIMIZE) != 0 )
+ {
+ USER_REFERENCE_ENTRY Ref;
+ UserRefObjectCo(Child, &Ref);
+
+ sx = x + UserGetSystemMetrics(SM_CXBORDER);
+ sy = y - yspacing - UserGetSystemMetrics(SM_CYBORDER);
+
+ Child->InternalPos.IconPos.x = sx;
+ Child->InternalPos.IconPos.y = sy;
+ Child->InternalPos.flags |= WPF_MININIT;
+
+ co_WinPosSetWindowPos( Child, 0, sx, sy, xspacing, yspacing, SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOCOPYBITS | SWP_ASYNCWINDOWPOS);
+
+ UserDerefObjectCo(Child);
+
+ if (x <= rectParent.right - xspacing)
+ x += xspacing;
+ else
+ {
+ x = rectParent.left;
+ y -= yspacing;
+ }
+ }
+ Child = Child->spwndNext;
+ }
+ return yspacing;
+}
+
+static VOID FASTCALL
+WinPosFindIconPos(PWND Window, POINT *Pos)
+{
+ RECT rectParent;
+ PWND pwndChild, pwndParent;
+ int x, y, xspacing, yspacing;
+
+ pwndParent = Window->spwndParent;
+ if (pwndParent == UserGetDesktopWindow())
+ {
+ //ERR("Parent is Desktop, Min off screen!\n");
+ /* ReactOS doesn't support iconic minimize to desktop */
+ Pos->x = Pos->y = -32000;
+ Window->InternalPos.flags |= WPF_MININIT;
+ Window->InternalPos.IconPos.x = Pos->x;
+ Window->InternalPos.IconPos.y = Pos->y;
+ return;
+ }
+
+ IntGetClientRect( pwndParent, &rectParent );
+ // FIXME: Support Minimize Metrics gspv.mm.iArrange.
+ // Default: ARW_BOTTOMLEFT
+ x = rectParent.left;
+ y = rectParent.bottom;
+
+ xspacing = UserGetSystemMetrics(SM_CXMINIMIZED);
+ yspacing = UserGetSystemMetrics(SM_CYMINIMIZED);
+
+ // Set to default position when minimized.
+ Pos->x = x + UserGetSystemMetrics(SM_CXBORDER);
+ Pos->y = y - yspacing - UserGetSystemMetrics(SM_CYBORDER);
+
+ for (pwndChild = pwndParent->spwndChild; pwndChild; pwndChild = pwndChild->spwndNext)
+ {
+ if (pwndChild == Window) continue;
+
+ if ((pwndChild->style & (WS_VISIBLE|WS_MINIMIZE)) != (WS_VISIBLE|WS_MINIMIZE) )
+ {
+ continue;
+ }
+
+ if ( pwndChild->InternalPos.IconPos.x != Pos->x && pwndChild->InternalPos.IconPos.y != Pos->y )
+ {
+ break;
+ }
+ if (x <= rectParent.right - xspacing)
+ x += xspacing;
+ else
+ {
+ x = rectParent.left;
+ y -= yspacing;
+ }
+ Pos->x = x + UserGetSystemMetrics(SM_CXBORDER);
+ Pos->y = y - yspacing - UserGetSystemMetrics(SM_CYBORDER);
+ }
+
+ Window->InternalPos.IconPos.x = Pos->x;
+ Window->InternalPos.IconPos.y = Pos->y;
+ Window->InternalPos.flags |= WPF_MININIT;
+ TRACE("Position is set! X:%d Y:%d\n",Pos->x,Pos->y);
+ return;
+}
+
UINT FASTCALL
co_WinPosMinMaximize(PWND Wnd, UINT ShowFlag, RECT* NewPos)
{
POINT Size;
WINDOWPLACEMENT wpl;
+ LONG old_style;
UINT SwpFlags = 0;
ASSERT_REFS_CO(Wnd);
}
if (Wnd->style & WS_MINIMIZE)
{
- if (ShowFlag == SW_MINIMIZE) return SWP_NOSIZE | SWP_NOMOVE;
-
+ switch (ShowFlag)
+ {
+ case SW_SHOWMINNOACTIVE:
+ case SW_SHOWMINIMIZED:
+ case SW_FORCEMINIMIZE:
+ case SW_MINIMIZE:
+ return SWP_NOSIZE | SWP_NOMOVE;
+ }
if (!co_IntSendMessageNoWait(Wnd->head.h, WM_QUERYOPEN, 0, 0))
{
return(SWP_NOSIZE | SWP_NOMOVE);
}
switch (ShowFlag)
{
+ case SW_SHOWMINNOACTIVE:
+ case SW_SHOWMINIMIZED:
+ case SW_FORCEMINIMIZE:
case SW_MINIMIZE:
{
+ //ERR("MinMaximize Minimize\n");
if (Wnd->style & WS_MAXIMIZE)
{
Wnd->InternalPos.flags |= WPF_RESTORETOMAXIMIZED;
- Wnd->style &= ~WS_MAXIMIZE;
- SwpFlags |= SWP_STATECHANGED;
}
else
{
Wnd->InternalPos.flags &= ~WPF_RESTORETOMAXIMIZED;
}
- co_UserRedrawWindow(Wnd, NULL, 0, RDW_VALIDATE | RDW_NOERASE |
- RDW_NOINTERNALPAINT);
- Wnd->style |= WS_MINIMIZE;
+
+ old_style = IntSetStyle( Wnd, WS_MINIMIZE, WS_MAXIMIZE );
+
+ co_UserRedrawWindow(Wnd, NULL, 0, RDW_VALIDATE | RDW_NOERASE | RDW_NOINTERNALPAINT);
+
if (!(Wnd->InternalPos.flags & WPF_SETMINPOSITION))
Wnd->InternalPos.flags &= ~WPF_MININIT;
+
WinPosFindIconPos(Wnd, &wpl.ptMinPosition);
- /*ERR("Minimize: %d,%d %dx%d\n",
- wpl.ptMinPosition.x, wpl.ptMinPosition.y, UserGetSystemMetrics(SM_CXMINIMIZED),
- UserGetSystemMetrics(SM_CYMINIMIZED));
- */
+
+ if (!(old_style & WS_MINIMIZE)) SwpFlags |= SWP_STATECHANGED;
+
RECTL_vSetRect(NewPos, wpl.ptMinPosition.x, wpl.ptMinPosition.y,
-// wpl.ptMinPosition.x + UserGetSystemMetrics(SM_CXMINIMIZED),
-// wpl.ptMinPosition.y + UserGetSystemMetrics(SM_CYMINIMIZED));
- UserGetSystemMetrics(SM_CXMINIMIZED),
- UserGetSystemMetrics(SM_CYMINIMIZED));
+ wpl.ptMinPosition.x + UserGetSystemMetrics(SM_CXMINIMIZED),
+ wpl.ptMinPosition.y + UserGetSystemMetrics(SM_CYMINIMIZED));
SwpFlags |= SWP_NOCOPYBITS;
break;
}
case SW_MAXIMIZE:
{
+ //ERR("MinMaximize Maximize\n");
+ if ((Wnd->style & WS_MAXIMIZE) && (Wnd->style & WS_VISIBLE))
+ {
+ SwpFlags = SWP_NOSIZE | SWP_NOMOVE;
+ break;
+ }
co_WinPosGetMinMaxInfo(Wnd, &Size, &wpl.ptMaxPosition, NULL, NULL);
/*ERR("Maximize: %d,%d %dx%d\n",
wpl.ptMaxPosition.x, wpl.ptMaxPosition.y, Size.x, Size.y);
*/
- if (Wnd->style & WS_MINIMIZE)
- {
- SwpFlags |= SWP_STATECHANGED;
- Wnd->style &= ~WS_MINIMIZE;
- }
- Wnd->style |= WS_MAXIMIZE;
+ old_style = IntSetStyle( Wnd, WS_MAXIMIZE, WS_MINIMIZE );
+
+ if (!(old_style & WS_MAXIMIZE)) SwpFlags |= SWP_STATECHANGED;
RECTL_vSetRect(NewPos, wpl.ptMaxPosition.x, wpl.ptMaxPosition.y,
-// wpl.ptMaxPosition.x + Size.x, wpl.ptMaxPosition.y + Size.y);
+ //wpl.ptMaxPosition.x + Size.x, wpl.ptMaxPosition.y + Size.y);
Size.x, Size.y);
break;
}
+ case SW_SHOWNOACTIVATE:
+ Wnd->InternalPos.flags &= ~WPF_RESTORETOMAXIMIZED;
+ /* fall through */
+ case SW_SHOWNORMAL:
case SW_RESTORE:
+ case SW_SHOWDEFAULT: /* FIXME: should have its own handler */
{
- if (Wnd->style & WS_MINIMIZE)
+ //ERR("MinMaximize Restore\n");
+ old_style = IntSetStyle( Wnd, 0, WS_MINIMIZE | WS_MAXIMIZE );
+ if (old_style & WS_MINIMIZE)
{
- Wnd->style &= ~WS_MINIMIZE;
if (Wnd->InternalPos.flags & WPF_RESTORETOMAXIMIZED)
{
co_WinPosGetMinMaxInfo(Wnd, &Size, &wpl.ptMaxPosition, NULL, NULL);
+ IntSetStyle( Wnd, WS_MAXIMIZE, 0 );
SwpFlags |= SWP_STATECHANGED;
- Wnd->style |= WS_MAXIMIZE;
- /*ERR("Restore to Max: %d,%d %dx%d\n",
- wpl.ptMaxPosition.x, wpl.ptMaxPosition.y, Size.x, Size.y);
- */
RECTL_vSetRect(NewPos, wpl.ptMaxPosition.x, wpl.ptMaxPosition.y,
-// wpl.ptMaxPosition.x + Size.x, wpl.ptMaxPosition.y + Size.y);
- Size.x, Size.y);
+ wpl.ptMaxPosition.x + Size.x, wpl.ptMaxPosition.y + Size.y);
break;
}
else
{
*NewPos = wpl.rcNormalPosition;
- /*ERR("Restore Max: %d,%d %dx%d\n",
- NewPos->left, NewPos->top, NewPos->right - NewPos->left, NewPos->bottom - NewPos->top);
- */
NewPos->right -= NewPos->left;
NewPos->bottom -= NewPos->top;
break;
}
else
{
- if (!(Wnd->style & WS_MAXIMIZE))
+ if (!(old_style & WS_MAXIMIZE))
{
- return 0;
+ break;
}
- Wnd->style &= ~WS_MAXIMIZE;
SwpFlags |= SWP_STATECHANGED;
Wnd->InternalPos.flags &= ~WPF_RESTORETOMAXIMIZED;
*NewPos = wpl.rcNormalPosition;
- /*ERR("Restore Min: %d,%d %dx%d\n",
- NewPos->left, NewPos->top, NewPos->right - NewPos->left, NewPos->bottom - NewPos->top);
- */
NewPos->right -= NewPos->left;
NewPos->bottom -= NewPos->top;
break;
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,
- RECT* WindowRect, RECT* ClientRect)
+co_WinPosDoNCCALCSize(PWND Window, PWINDOWPOS WinPos, RECTL* WindowRect, RECTL* ClientRect, RECTL* validRects)
{
PWND Parent;
UINT wvrFlags = 0;
NCCALCSIZE_PARAMS params;
WINDOWPOS winposCopy;
- params.rgrc[0] = *WindowRect;
- params.rgrc[1] = Window->rcWindow;
- params.rgrc[2] = Window->rcClient;
+ 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);
+ 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;
if (params.rgrc[0].left <= params.rgrc[0].right &&
params.rgrc[0].top <= params.rgrc[0].bottom)
{
- *ClientRect = params.rgrc[0];
+ *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);
+ RECTL_vOffsetRect(ClientRect, Parent->rcClient.left, Parent->rcClient.top);
}
FixClientRect(ClientRect, WindowRect);
}
- /* FIXME: WVR_ALIGNxxx */
-
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) ||
- (ClientRect->bottom - ClientRect->top !=
- Window->rcClient.bottom - Window->rcClient.top))
+ 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))
+ 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;
}
PRECTL WindowRect,
PRECTL ClientRect)
{
- INT X, Y;
-
ASSERT_REFS_CO(Window);
+ /* Send WM_WINDOWPOSCHANGING message */
+
if (!(WinPos->flags & SWP_NOSENDCHANGING))
{
+ TRACE("Sending WM_WINDOWPOSCHANGING to hwnd %p.\n", Window->head.h);
co_IntSendMessageNoWait(Window->head.h, WM_WINDOWPOSCHANGING, 0, (LPARAM) WinPos);
}
+ /* Calculate new position and size */
+
*WindowRect = Window->rcWindow;
- *ClientRect = Window->rcClient;
+ *ClientRect = (Window->style & WS_MINIMIZE) ? Window->rcWindow : Window->rcClient;
if (!(WinPos->flags & SWP_NOSIZE))
{
- WindowRect->right = WindowRect->left + WinPos->cx;
- WindowRect->bottom = WindowRect->top + WinPos->cy;
+ 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;
- if ((0 != (Window->style & WS_CHILD)) && Parent)
+
+ if (((Window->style & WS_CHILD) != 0) &&
+ 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->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);
- }
+ 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)
PWND DesktopWindow, ChildObject;
int i;
+ TRACE("(%p) hInsertAfter = %p\n", Window, hWndInsertAfter );
+
Owner = Window->spwndOwner ? Window->spwndOwner->head.h : NULL;
Style = Window->style;
- if ((Style & WS_POPUP) && Owner)
+ if (Style & WS_CHILD)
+ {
+ TRACE("Window is child\n");
+ return hWndInsertAfter;
+ }
+
+ if (Owner)
{
/* Make sure this popup stays above the owner */
- HWND hWndLocalPrev = HWND_TOPMOST;
if (hWndInsertAfter != HWND_TOPMOST)
{
- DesktopWindow = UserGetWindowObject(IntGetDesktopWindow());
+ 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 (HWND_TOP == hWndInsertAfter)
+ }
+
+ if (hWndInsertAfter == HWND_TOP || hWndInsertAfter == HWND_NOTOPMOST)
{
- ChildObject = UserGetWindowObject(List[i]);
- if (NULL != ChildObject)
- {
- if (0 == (ChildObject->ExStyle & WS_EX_TOPMOST))
- {
- break;
- }
- }
+ if (!topmost) break;
}
- if (List[i] != Window->head.h)
- hWndLocalPrev = List[i];
- if (hWndLocalPrev == hWndInsertAfter)
- break;
+ else if (List[i] == hWndInsertAfter) break;
}
- hWndInsertAfter = hWndLocalPrev;
}
+ else
+ return hWndInsertAfter;
}
}
- else if (Style & WS_CHILD)
+
+ if (hWndInsertAfter == HWND_BOTTOM)
{
- return hWndInsertAfter;
+ ERR("Window is HWND_BOTTOM\n");
+ if (List) ExFreePoolWithTag(List, USERTAG_WINDOWLIST);
+ goto done;
}
if (!List)
{
- DesktopWindow = UserGetWindowObject(IntGetDesktopWindow());
+ DesktopWindow = UserGetDesktopWindow();
List = IntWinListChildren(DesktopWindow);
}
+
if (List != NULL)
{
- for (i = 0; List[i]; i++)
+ 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] == Window->head.h)
+ if (List[i] == UserHMGetHandle(Window))
break;
- if (!(Wnd = UserGetWindowObject(List[i])))
+ if (!(Wnd = ValidateHwndNoErr(List[i])))
continue;
- if (Wnd->style & WS_POPUP && Wnd->spwndOwner == Window)
- {
- USER_REFERENCE_ENTRY Ref;
- UserRefObjectCo(Wnd, &Ref);
+ Owner = Wnd->spwndOwner ? Wnd->spwndOwner->head.h : NULL;
- co_WinPosSetWindowPos(Wnd, hWndInsertAfter, 0, 0, 0, 0,
- SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE | SWP_NOSENDCHANGING);
+ if (Owner != UserHMGetHandle(Window)) continue;
- UserDerefObjectCo(Wnd);
+ 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);
- hWndInsertAfter = List[i];
- }
+ UserDerefObjectCo(Wnd);
+ hWndInsertAfter = List[i];
}
- ExFreePool(List);
+ ExFreePoolWithTag(List, USERTAG_WINDOWLIST);
}
-
+done:
return hWndInsertAfter;
}
+////
/***********************************************************************
* WinPosInternalMoveWindow
PWND Child;
ASSERT(Window != Window->spwndChild);
+ TRACE("InternalMoveWin X %d Y %d\n", MoveX, MoveY);
Window->rcWindow.left += MoveX;
Window->rcWindow.right += MoveX;
BOOL FASTCALL
WinPosFixupFlags(WINDOWPOS *WinPos, PWND Wnd)
{
- if (Wnd->style & WS_VISIBLE)
- {
- WinPos->flags &= ~SWP_SHOWWINDOW;
- }
+ 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 )) 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;
+ if (!(WinPos->flags & SWP_SHOWWINDOW)) WinPos->flags |= SWP_NOREDRAW;
}
- WinPos->cx = max(WinPos->cx, 0);
- WinPos->cy = max(WinPos->cy, 0);
-
/* 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 == WinPos->x &&
- Wnd->rcWindow.top == WinPos->y)
+ if (Wnd->rcWindow.left == pt.x && Wnd->rcWindow.top == pt.y)
{
+ //ERR("In right pos\n");
WinPos->flags |= SWP_NOMOVE;
}
if ((Wnd->style & (WS_POPUP | WS_CHILD)) != WS_CHILD)
{
/* Bring to the top when activating */
- if (!(WinPos->flags & SWP_NOACTIVATE))
+ 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);
- return TRUE;
+ WinPos->hwndInsertAfter = (0 != (Wnd->ExStyle & WS_EX_TOPMOST) ? HWND_TOPMOST : HWND_TOP);
}
}
WinPos->hwndInsertAfter = HWND_NOTOPMOST;
}
- if (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)
{
- WinPos->hwndInsertAfter = HWND_TOP;
+ if (!(Wnd->ExStyle & WS_EX_TOPMOST) && IntGetWindow(WinPos->hwnd, GW_HWNDLAST) == WinPos->hwnd)
+ WinPos->flags |= SWP_NOZORDER;
}
- else if (HWND_TOP == WinPos->hwndInsertAfter
- && 0 != (Wnd->ExStyle & WS_EX_TOPMOST))
+ else if (WinPos->hwndInsertAfter == HWND_TOPMOST)
{
- /* Keep it topmost when it's already topmost */
- WinPos->hwndInsertAfter = HWND_TOPMOST;
+ if ((Wnd->ExStyle & WS_EX_TOPMOST) && IntGetWindow(WinPos->hwnd, GW_HWNDFIRST) == WinPos->hwnd)
+ WinPos->flags |= SWP_NOZORDER;
}
-
- /* hwndInsertAfter must be a sibling of the window */
- if (HWND_TOPMOST != WinPos->hwndInsertAfter
- && HWND_TOP != WinPos->hwndInsertAfter
- && HWND_NOTOPMOST != WinPos->hwndInsertAfter
- && HWND_BOTTOM != WinPos->hwndInsertAfter)
+ 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 = UserGetWindowObject(WinPos->hwndInsertAfter);
+ InsAfterWnd = ValidateHwndNoErr(WinPos->hwndInsertAfter);
if(!InsAfterWnd)
{
return TRUE;
INT cx,
INT cy,
UINT flags
-)
+ )
{
WINDOWPOS WinPos;
RECTL NewWindowRect;
RECTL NewClientRect;
- PROSRGNDATA VisRgn;
- HRGN VisBefore = NULL;
- HRGN VisAfter = NULL;
- HRGN DirtyRgn = NULL;
- HRGN ExposedRgn = NULL;
- HRGN CopyRgn = NULL;
+ RECTL valid_rects[2];
+ PREGION VisBefore = NULL;
+ PREGION VisBeforeJustClient = NULL;
+ PREGION VisAfter = NULL;
+ PREGION CopyRgn = NULL;
ULONG WvrFlags = 0;
RECTL OldWindowRect, OldClientRect;
int RgnType;
ASSERT_REFS_CO(Window);
- /* FIXME: Get current active window from active queue. */
- /*
- * Only allow CSRSS to mess with the desktop window
- */
-
- if ( Window->head.h == IntGetDesktopWindow() &&
- Window->head.pti->ppi != PsGetCurrentProcessWin32Process())
- {
- ERR("Desktop Window...\n");
- return FALSE;
- }
+ /* FIXME: Get current active window from active queue. Why? since r2915. */
bPointerInWindow = IntPtInWindow(Window, gpsi->ptCursor.x, gpsi->ptCursor.y);
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;
}
}
Ancestor = UserGetAncestor(Window, GA_PARENT);
- if ( (WinPos.flags & (SWP_NOZORDER | SWP_HIDEWINDOW | SWP_SHOWWINDOW)) !=
- SWP_NOZORDER &&
+ if ( (WinPos.flags & (SWP_NOZORDER | SWP_HIDEWINDOW | SWP_SHOWWINDOW)) != SWP_NOZORDER &&
Ancestor && Ancestor->head.h == IntGetDesktopWindow() )
{
WinPos.hwndInsertAfter = WinPosDoOwnedPopups(Window, WinPos.hwndInsertAfter);
{
VisBefore = VIS_ComputeVisibleRegion(Window, FALSE, FALSE,
(Window->style & WS_CLIPSIBLINGS) ? TRUE : FALSE);
- VisRgn = NULL;
if ( VisBefore != NULL &&
- (VisRgn = (PROSRGNDATA)RGNOBJAPI_Lock(VisBefore, NULL)) &&
- REGION_Complexity(VisRgn) == NULLREGION )
+ REGION_Complexity(VisBefore) == NULLREGION )
{
- RGNOBJAPI_Unlock(VisRgn);
- GreDeleteObject(VisBefore);
+ REGION_Delete(VisBefore);
VisBefore = NULL;
}
- else if(VisRgn)
+ else if(VisBefore)
+ {
+ IntGdiOffsetRgn(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))
{
- RGNOBJAPI_Unlock(VisRgn);
- NtGdiOffsetRgn(VisBefore, -Window->rcWindow.left, -Window->rcWindow.top);
+ 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)
+ {
+ IntGdiOffsetRgn(VisBeforeJustClient, -Window->rcWindow.left, -Window->rcWindow.top);
+ }
}
}
}
- WvrFlags = co_WinPosDoNCCALCSize(Window, &WinPos, &NewWindowRect, &NewClientRect);
+ WvrFlags = co_WinPosDoNCCALCSize(Window, &WinPos, &NewWindowRect, &NewClientRect, valid_rects);
- TRACE("co_WinPosDoNCCALCSize returned %d\n", WvrFlags);
+// 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);
- /* Relink windows. (also take into account shell window in hwndShellWindow) */
+ /* Validate link windows. (also take into account shell window in hwndShellWindow) */
if (!(WinPos.flags & SWP_NOZORDER) && WinPos.hwnd != UserGetShellWindow())
{
- IntLinkHwnd(Window, WndInsertAfter);
+ IntLinkHwnd(Window, WinPos.hwndInsertAfter);
}
OldWindowRect = Window->rcWindow;
OldClientRect = Window->rcClient;
- if (OldClientRect.bottom - OldClientRect.top ==
- NewClientRect.bottom - NewClientRect.top)
- {
- WvrFlags &= ~WVR_VREDRAW;
- }
-
- if (OldClientRect.right - OldClientRect.left ==
- NewClientRect.right - NewClientRect.left)
- {
- WvrFlags &= ~WVR_HREDRAW;
- }
-
- /* FIXME: Actually do something with WVR_VALIDRECTS */
-
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);
Window->rcWindow = NewWindowRect;
Window->rcClient = NewClientRect;
+ /* erase parent when hiding or resizing child */
if (WinPos.flags & SWP_HIDEWINDOW)
{
/* Clear the update region */
RDW_VALIDATE | RDW_NOFRAME | RDW_NOERASE | RDW_NOINTERNALPAINT | RDW_ALLCHILDREN);
if (Window->spwndParent == UserGetDesktopWindow())
- co_IntShellHookNotify(HSHELL_WINDOWDESTROYED, (LPARAM)Window->head.h);
+ co_IntShellHookNotify(HSHELL_WINDOWDESTROYED, (WPARAM)Window->head.h, 0);
- Window->style &= ~WS_VISIBLE;
+ 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 (Window->spwndParent == UserGetDesktopWindow())
- co_IntShellHookNotify(HSHELL_WINDOWCREATED, (LPARAM)Window->head.h);
+ co_IntShellHookNotify(HSHELL_WINDOWCREATED, (WPARAM)Window->head.h, 0);
- Window->style |= WS_VISIBLE;
+ 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)
NewWindowRect.top - OldWindowRect.top);
}
- DceResetActiveDCEs(Window);
+ 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);
- VisRgn = NULL;
if ( VisAfter != NULL &&
- (VisRgn = (PROSRGNDATA)RGNOBJAPI_Lock(VisAfter, NULL)) &&
- REGION_Complexity(VisRgn) == NULLREGION )
+ REGION_Complexity(VisAfter) == NULLREGION )
{
- RGNOBJAPI_Unlock(VisRgn);
- GreDeleteObject(VisAfter);
+ REGION_Delete(VisAfter);
VisAfter = NULL;
}
- else if(VisRgn)
+ else if(VisAfter)
{
- RGNOBJAPI_Unlock(VisRgn);
- NtGdiOffsetRgn(VisAfter, -Window->rcWindow.left, -Window->rcWindow.top);
+ IntGdiOffsetRgn(VisAfter, -Window->rcWindow.left, -Window->rcWindow.top);
}
/*
((WinPos.flags & SWP_NOSIZE) || !(WvrFlags & WVR_REDRAW)) &&
!(Window->ExStyle & WS_EX_TRANSPARENT) )
{
- CopyRgn = IntSysCreateRectRgn(0, 0, 0, 0);
- RgnType = NtGdiCombineRgn(CopyRgn, VisAfter, VisBefore, RGN_AND);
/*
* If this is (also) a window resize, the whole nonclient area
* we don't have to crop (can't take anything away from an empty
* region...)
*/
- if (!(WinPos.flags & SWP_NOSIZE) &&
- RgnType != ERROR &&
- RgnType != NULLREGION )
+
+ CopyRgn = IntSysCreateRectpRgn(0, 0, 0, 0);
+ if (WinPos.flags & SWP_NOSIZE)
+ RgnType = IntGdiCombineRgn(CopyRgn, VisAfter, VisBefore, RGN_AND);
+ else if (VisBeforeJustClient != NULL)
{
- PROSRGNDATA pCopyRgn;
- RECTL ORect = OldClientRect;
- RECTL NRect = NewClientRect;
- RECTL_vOffsetRect(&ORect, - OldWindowRect.left, - OldWindowRect.top);
- RECTL_vOffsetRect(&NRect, - NewWindowRect.left, - NewWindowRect.top);
- RECTL_bIntersectRect(&CopyRect, &ORect, &NRect);
- pCopyRgn = RGNOBJAPI_Lock(CopyRgn, NULL);
- REGION_CropAndOffsetRegion(pCopyRgn, pCopyRgn, &CopyRect, NULL);
- RGNOBJAPI_Unlock(pCopyRgn);
+ 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)
{
- NtGdiOffsetRgn(CopyRgn, NewWindowRect.left, NewWindowRect.top);
- NtGdiCombineRgn(CopyRgn, CopyRgn, Window->hrgnUpdate, RGN_DIFF);
- NtGdiOffsetRgn(CopyRgn, -NewWindowRect.left, -NewWindowRect.top);
+ PREGION RgnUpdate = RGNOBJAPI_Lock(Window->hrgnUpdate, NULL);
+ if (RgnUpdate)
+ {
+ IntGdiOffsetRgn(CopyRgn, NewWindowRect.left, NewWindowRect.top);
+ IntGdiCombineRgn(CopyRgn, CopyRgn, RgnUpdate, RGN_DIFF);
+ IntGdiOffsetRgn(CopyRgn, -NewWindowRect.left, -NewWindowRect.top);
+ RGNOBJAPI_Unlock(RgnUpdate);
+ }
}
/*
* there's nothing to copy. Also, it's no use copying bits onto
* themselves.
*/
- if ( (VisRgn = (PROSRGNDATA)RGNOBJAPI_Lock(CopyRgn, NULL)) &&
- REGION_GetRgnBox(VisRgn, &CopyRect) == NULLREGION)
+ if (REGION_GetRgnBox(CopyRgn, &CopyRect) == NULLREGION)
{
/* Nothing to copy, clean up */
- RGNOBJAPI_Unlock(VisRgn);
- GreDeleteObject(CopyRgn);
+ REGION_Delete(CopyRgn);
CopyRgn = NULL;
}
else if (OldWindowRect.left != NewWindowRect.left ||
OldWindowRect.top != NewWindowRect.top)
{
- if(VisRgn)
- {
- RGNOBJAPI_Unlock(VisRgn);
- }
+ HRGN DcRgn = NtGdiCreateRectRgn(0, 0, 0, 0);
+ PREGION DcRgnObj = RGNOBJAPI_Lock(DcRgn, NULL);
/*
* Small trick here: there is no function to bitblt a region. So
* Since NtUserGetDCEx takes ownership of the clip region, we need
* to create a copy of CopyRgn and pass that. We need CopyRgn later
*/
- NtGdiOffsetRgn(CopyRgn, NewWindowRect.left, NewWindowRect.top);
+ IntGdiCombineRgn(DcRgnObj, CopyRgn, NULL, RGN_COPY);
+ IntGdiOffsetRgn(DcRgnObj, NewWindowRect.left, NewWindowRect.top);
+ RGNOBJAPI_Unlock(DcRgnObj);
Dc = UserGetDCEx( Window,
- CopyRgn,
+ DcRgn,
DCX_WINDOW|DCX_CACHE|DCX_INTERSECTRGN|DCX_CLIPSIBLINGS|DCX_KEEPCLIPRGN);
NtGdiBitBlt( Dc,
CopyRect.left, CopyRect.top,
UserReleaseDC(Window, Dc, FALSE);
IntValidateParent(Window, CopyRgn, FALSE);
- NtGdiOffsetRgn(CopyRgn, -NewWindowRect.left, -NewWindowRect.top);
- }
- else if(VisRgn)
- {
- RGNOBJAPI_Unlock(VisRgn);
+ GreDeleteObject(DcRgn);
}
}
else
/* We need to redraw what wasn't visible before */
if (VisAfter != NULL)
{
- DirtyRgn = IntSysCreateRectRgn(0, 0, 0, 0);
- if (CopyRgn != NULL)
- {
- RgnType = NtGdiCombineRgn(DirtyRgn, VisAfter, CopyRgn, RGN_DIFF);
- }
- else
- {
- RgnType = NtGdiCombineRgn(DirtyRgn, VisAfter, 0, RGN_COPY);
- }
- if (RgnType != ERROR && RgnType != NULLREGION)
+ PREGION DirtyRgn = IntSysCreateRectpRgn(0, 0, 0, 0);
+ if (DirtyRgn)
{
- /* 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;
-
- NtGdiOffsetRgn( 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_ERASENOW, FALSE);
- }
- else
- {
+ 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);
- }
+ RDW_ERASE | RDW_FRAME | RDW_INVALIDATE | RDW_ALLCHILDREN);
+ }
+ GreDeleteObject(DirtyRgn);
+ */
+
+ PWND Parent = Window->spwndParent;
+
+ IntGdiOffsetRgn( 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_ERASENOW, FALSE);
+ }
+ else
+ {
+ IntInvalidateWindows( Window,
+ DirtyRgn,
+ RDW_ERASE | RDW_FRAME | RDW_INVALIDATE | RDW_ALLCHILDREN);
+ }
+ }
+ REGION_Delete(DirtyRgn);
}
- GreDeleteObject(DirtyRgn);
}
if (CopyRgn != NULL)
{
- GreDeleteObject(CopyRgn);
+ REGION_Delete(CopyRgn);
}
/* Expose what was covered before but not covered anymore */
if (VisBefore != NULL)
{
- ExposedRgn = IntSysCreateRectRgn(0, 0, 0, 0);
- RgnType = NtGdiCombineRgn(ExposedRgn, VisBefore, NULL, RGN_COPY);
- NtGdiOffsetRgn( ExposedRgn,
- OldWindowRect.left - NewWindowRect.left,
- OldWindowRect.top - NewWindowRect.top);
-
- if (VisAfter != NULL)
- RgnType = NtGdiCombineRgn(ExposedRgn, ExposedRgn, VisAfter, RGN_DIFF);
-
- if (RgnType != ERROR && RgnType != NULLREGION)
+ PREGION ExposedRgn = IntSysCreateRectpRgn(0, 0, 0, 0);
+ if (ExposedRgn)
{
- co_VIS_WindowLayoutChanged(Window, ExposedRgn);
+ RgnType = IntGdiCombineRgn(ExposedRgn, VisBefore, NULL, RGN_COPY);
+ IntGdiOffsetRgn( 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);
}
- GreDeleteObject(ExposedRgn);
- GreDeleteObject(VisBefore);
+ REGION_Delete(VisBefore);
}
if (VisAfter != NULL)
{
- GreDeleteObject(VisAfter);
+ REGION_Delete(VisAfter);
}
}
- if (!(WinPos.flags & SWP_NOACTIVATE))//(SWP_NOACTIVATE|SWP_HIDEWINDOW)))
+ if (!(WinPos.flags & (SWP_NOACTIVATE|SWP_HIDEWINDOW)))
{
if ((Window->style & (WS_CHILD | WS_POPUP)) == WS_CHILD)
{
}
else
{
- TRACE("SetWindowPos Set FG Window!\n");
- co_IntSetForegroundWindow(Window);
+ //ERR("SetWindowPos Set FG Window!\n");
+ if (Window->state & WNDS_BEINGACTIVATED) // Inside SAW?
+ co_IntSetActiveWindow(Window, FALSE, TRUE, FALSE); // Fixes Api AttachThreadInput tests.
+ else
+ co_IntSetForegroundWindow(Window); // Fixes SW_HIDE issues. Wine win test_SetActiveWindow & test_SetForegroundWindow.
}
}
+ /* And last, send the WM_WINDOWPOSCHANGED message */
+
+ TRACE("\tstatus flags = %04x\n", WinPos.flags & SWP_AGG_STATUSFLAGS);
+
if ((WinPos.flags & SWP_AGG_STATUSFLAGS) != SWP_AGG_NOPOSCHANGE)
{
/* WM_WINDOWPOSCHANGED is sent even if SWP_NOSENDCHANGING is set
if ( WinPos.flags & SWP_FRAMECHANGED || WinPos.flags & SWP_STATECHANGED ||
!(WinPos.flags & SWP_NOCLIENTSIZE) || !(WinPos.flags & SWP_NOCLIENTMOVE) )
{
- PWND pWnd = UserGetWindowObject(WinPos.hwnd);
+ PWND pWnd = ValidateHwndNoErr(WinPos.hwnd);
if (pWnd)
IntNotifyWinEvent(EVENT_OBJECT_LOCATIONCHANGE, pWnd, OBJID_WINDOW, CHILDID_SELF, WEF_SETBYWNDPTI);
}
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, MAKELONG(Rect.right-Rect.left, Rect.bottom-Rect.top));
+ co_IntSendMessageNoWait(UserHMGetHandle(Wnd), WM_SIZE, wParam, lParam);
- if (Wnd->spwndParent == UserGetDesktopWindow()) // Wnd->spwndParent->fnid != FNID_DESKTOP )
+ if (Wnd->spwndParent == UserGetDesktopWindow()) // Wnd->spwndParent->fnid == FNID_DESKTOP )
lParam = MAKELONG(Wnd->rcClient.left, Wnd->rcClient.top);
else
lParam = MAKELONG(Wnd->rcClient.left-Wnd->spwndParent->rcClient.left, Wnd->rcClient.top-Wnd->spwndParent->rcClient.top);
co_WinPosShowWindow(PWND Wnd, INT Cmd)
{
BOOLEAN WasVisible;
- UINT Swp = 0;
- RECTL NewPos;
+ UINT Swp = 0, EventMsg = 0;
+ RECTL NewPos = {0, 0, 0, 0};
BOOLEAN ShowFlag;
LONG style;
PWND Parent;
- // HRGN VisibleRgn;
-
+ PTHREADINFO pti;
+ //HRGN VisibleRgn;
+ BOOL ShowOwned = FALSE;
ASSERT_REFS_CO(Wnd);
+ //ERR("co_WinPosShowWindow START\n");
+ pti = PsGetCurrentThreadWin32Thread();
WasVisible = (Wnd->style & WS_VISIBLE) != 0;
style = Wnd->style;
{
if (!WasVisible)
{
+ //ERR("co_WinPosShowWindow Exit Bad\n");
return(FALSE);
}
Swp |= SWP_HIDEWINDOW | SWP_NOSIZE | SWP_NOMOVE;
- if (Wnd->head.h != UserGetActiveWindow())
+ if (Wnd != pti->MessageQueue->spwndActive)
Swp |= SWP_NOACTIVATE | SWP_NOZORDER;
break;
}
+ case SW_FORCEMINIMIZE: /* FIXME: Does not work if thread is hung. */
case SW_SHOWMINNOACTIVE:
Swp |= SWP_NOACTIVATE | SWP_NOZORDER;
/* Fall through. */
Swp |= SWP_NOACTIVATE;
if (!(style & WS_MINIMIZE))
{
- Swp |= co_WinPosMinMaximize(Wnd, SW_MINIMIZE, &NewPos) |
+ IntShowOwnedPopups(Wnd, FALSE );
+
+ // Fix wine Win test_SetFocus todo #1 & #2,
+ if (Cmd == SW_SHOWMINIMIZED)
+ {
+ //ERR("co_WinPosShowWindow Set focus 1\n");
+ if ((style & (WS_CHILD | WS_POPUP)) == WS_CHILD)
+ co_UserSetFocus(Wnd->spwndParent);
+ else
+ co_UserSetFocus(0);
+ }
+
+ Swp |= co_WinPosMinMaximize(Wnd, Cmd, &NewPos) |
SWP_FRAMECHANGED;
+
+ EventMsg = EVENT_SYSTEM_MINIMIZESTART;
}
else
{
- Swp |= SWP_NOSIZE | SWP_NOMOVE;
- if (! WasVisible)
+ if (!WasVisible)
{
Swp |= SWP_FRAMECHANGED;
}
+ else ////
+ {
+ //ERR("co_WinPosShowWindow Exit Good\n");
+ return TRUE;
+ }
+ Swp |= SWP_NOSIZE | SWP_NOMOVE;
}
break;
}
Swp |= SWP_SHOWWINDOW;
if (!(style & WS_MAXIMIZE))
{
+ ShowOwned = TRUE;
+
Swp |= co_WinPosMinMaximize(Wnd, SW_MAXIMIZE, &NewPos) |
SWP_FRAMECHANGED;
+
+ EventMsg = EVENT_SYSTEM_MINIMIZEEND;
}
else
{
- Swp |= SWP_NOSIZE | SWP_NOMOVE;
- if (! WasVisible)
+ if (!WasVisible)
{
Swp |= SWP_FRAMECHANGED;
}
+ else ////
+ {
+ //ERR("co_WinPosShowWindow Exit Good 1\n");
+ return TRUE;
+ }
+ Swp |= SWP_NOSIZE | SWP_NOMOVE;
}
break;
}
case SW_SHOWNA:
- Swp |= SWP_NOACTIVATE | SWP_NOZORDER;
- /* Fall through. */
+ Swp |= SWP_NOACTIVATE | SWP_SHOWWINDOW | SWP_NOSIZE | SWP_NOMOVE;
+ if (style & WS_CHILD && !(Wnd->ExStyle & WS_EX_MDICHILD)) Swp |= SWP_NOZORDER;
+ break;
case SW_SHOW:
- if (WasVisible) return(TRUE); // Nothing to do!
+ if (WasVisible) return(TRUE); // Nothing to do!
Swp |= SWP_SHOWWINDOW | SWP_NOSIZE | SWP_NOMOVE;
/* Don't activate the topmost window. */
- if (style & WS_CHILD) Swp |= SWP_NOACTIVATE | SWP_NOZORDER;
+ if (style & WS_CHILD && !(Wnd->ExStyle & WS_EX_MDICHILD)) Swp |= SWP_NOACTIVATE | SWP_NOZORDER;
break;
case SW_SHOWNOACTIVATE:
- Wnd->InternalPos.flags &= ~WPF_RESTORETOMAXIMIZED;
- //Swp |= SWP_NOZORDER;
Swp |= SWP_NOACTIVATE | SWP_NOZORDER;
/* Fall through. */
case SW_SHOWNORMAL:
case SW_SHOWDEFAULT:
case SW_RESTORE:
- Swp |= SWP_SHOWWINDOW;
+ if (!WasVisible) Swp |= SWP_SHOWWINDOW;
if (style & (WS_MINIMIZE | WS_MAXIMIZE))
{
- Swp |= co_WinPosMinMaximize(Wnd, SW_RESTORE, &NewPos) |
+ Swp |= co_WinPosMinMaximize(Wnd, Cmd, &NewPos) |
SWP_FRAMECHANGED;
+
+ if (style & WS_MINIMIZE) EventMsg = EVENT_SYSTEM_MINIMIZEEND;
}
else
{
- Swp |= SWP_NOSIZE | SWP_NOMOVE;
- if (! WasVisible)
+ if (!WasVisible)
{
Swp |= SWP_FRAMECHANGED;
}
+ else ////
+ {
+ //ERR("co_WinPosShowWindow Exit Good 3\n");
+ return TRUE;
+ }
+ Swp |= SWP_NOSIZE | SWP_NOMOVE;
}
+ if ( style & WS_CHILD &&
+ !(Wnd->ExStyle & WS_EX_MDICHILD) &&
+ !(Swp & SWP_STATECHANGED))
+ Swp |= SWP_NOACTIVATE | SWP_NOZORDER;
break;
+
+ default:
+ //ERR("co_WinPosShowWindow Exit Good 4\n");
+ return WasVisible;
}
ShowFlag = (Cmd != SW_HIDE);
- if (ShowFlag != WasVisible)
+ if ((ShowFlag != WasVisible || Cmd == SW_SHOWNA) && Cmd != SW_SHOWMAXIMIZED && !(Swp & SWP_STATECHANGED))
{
co_IntSendMessageNoWait(Wnd->head.h, WM_SHOWWINDOW, ShowFlag, 0);
if (!(Wnd->state2 & WNDS2_WIN31COMPAT))
co_IntSendMessageNoWait(Wnd->head.h, WM_SETVISIBLE, ShowFlag, 0);
+ if (!VerifyWnd(Wnd)) return WasVisible;
}
/* We can't activate a child window */
if ((Wnd->style & WS_CHILD) &&
- !(Wnd->ExStyle & WS_EX_MDICHILD))
+ !(Wnd->ExStyle & WS_EX_MDICHILD) &&
+ Cmd != SW_SHOWNA)
{
+ //ERR("SWP Child No active and ZOrder\n");
Swp |= SWP_NOACTIVATE | SWP_NOZORDER;
}
-#if 0 // Explorer issues with common controls. Someone does not know how CS_SAVEBITS works.
+#if 0 // Explorer issues with common controls? Someone does not know how CS_SAVEBITS works.
+ // Breaks startup and shutdown active window...
if ((Wnd->style & (WS_POPUP|WS_CHILD)) != WS_CHILD &&
Wnd->pcls->style & CS_SAVEBITS &&
((Cmd == SW_SHOW) || (Cmd == SW_NORMAL)))
{
- co_IntSetActiveWindow(Wnd,NULL,FALSE,TRUE);
+ ERR("WinPosShowWindow Set active\n");
+ UserSetActiveWindow(Wnd);
Swp |= SWP_NOACTIVATE | SWP_NOZORDER;
}
#endif
+ if (IsChildVisible(Wnd) || Swp & SWP_STATECHANGED)
+ {
+ TRACE("Child is Vis %s or State changed %s. ShowFlag %s\n",
+ (IsChildVisible(Wnd) ? "TRUE" : "FALSE"), (Swp & SWP_STATECHANGED ? "TRUE" : "FALSE"),
+ (ShowFlag ? "TRUE" : "FALSE"));
co_WinPosSetWindowPos( Wnd,
0 != (Wnd->ExStyle & WS_EX_TOPMOST) ? HWND_TOPMOST : HWND_TOP,
NewPos.left,
NewPos.right, //NewPos.right - NewPos.left,
NewPos.bottom, //NewPos.bottom - NewPos.top,
LOWORD(Swp));
+ }
+ else
+ {
+ TRACE("Parent Vis?\n");
+ /* if parent is not visible simply toggle WS_VISIBLE and return */
+ if (ShowFlag) IntSetStyle( Wnd, WS_VISIBLE, 0 );
+ else IntSetStyle( Wnd, 0, WS_VISIBLE );
+ }
+
+ if ( EventMsg ) IntNotifyWinEvent(EventMsg, Wnd, OBJID_WINDOW, CHILDID_SELF, WEF_SETBYWNDPTI);
+
+ if ( ShowOwned ) IntShowOwnedPopups(Wnd, TRUE );
if ((Cmd == SW_HIDE) || (Cmd == SW_MINIMIZE))
{
- PTHREADINFO pti = PsGetCurrentThreadWin32Thread();
-
- // and Rule #1.
- if (Wnd == pti->MessageQueue->spwndActive && pti->MessageQueue == IntGetFocusMessageQueue())
+ if ( Wnd == pti->MessageQueue->spwndActive && pti->MessageQueue == IntGetFocusMessageQueue() )
{
- co_WinPosActivateOtherWindow(Wnd);
+ if ( Wnd->spwndParent == UserGetDesktopWindow())
+ {
+ if(!ActivateOtherWindowMin(Wnd))
+ co_WinPosActivateOtherWindow(Wnd);
+ }
+ else
+ co_WinPosActivateOtherWindow(Wnd);
}
/* Revert focus to parent */
{
Parent = Wnd->spwndParent;
if (Wnd->spwndParent == UserGetDesktopWindow()) Parent = 0;
- co_UserSetFocus(Parent);
+ co_UserSetFocus(Parent);
}
}
}
/* if previous state was minimized Windows sets focus to the window */
- if (style & WS_MINIMIZE) co_UserSetFocus(Wnd);
-
+ if (style & WS_MINIMIZE)
+ {
+ co_UserSetFocus(Wnd);
+ // Fix wine Win test_SetFocus todo #3,
+ if (!(style & WS_CHILD)) co_IntSendMessageNoWait(UserHMGetHandle(Wnd), WM_ACTIVATE, WA_ACTIVE, 0);
+ }
+ //ERR("co_WinPosShowWindow EXIT\n");
return(WasVisible);
}
co_WinPosSearchChildren(
PWND ScopeWin,
POINT *Point,
- USHORT *HitTest
+ USHORT *HitTest,
+ BOOL Ignore
)
{
PWND pwndChild;
return NULL;
}
- if ((ScopeWin->style & WS_DISABLED))
+ if (!Ignore && (ScopeWin->style & WS_DISABLED))
{
return NULL;
}
UserReferenceObject(ScopeWin);
- if (Point->x - ScopeWin->rcClient.left < ScopeWin->rcClient.right &&
- Point->y - ScopeWin->rcClient.top < ScopeWin->rcClient.bottom )
+ if ( RECTL_bPointInRect(&ScopeWin->rcClient, Point->x, Point->y) )
{
List = IntWinListChildren(ScopeWin);
if(List)
{
for (phWnd = List; *phWnd; ++phWnd)
{
- if (!(pwndChild = UserGetWindowObject(*phWnd)))
+ if (!(pwndChild = ValidateHwndNoErr(*phWnd)))
{
continue;
}
- pwndChild = co_WinPosSearchChildren(pwndChild, Point, HitTest);
+ pwndChild = co_WinPosSearchChildren(pwndChild, Point, HitTest, Ignore);
if(pwndChild != NULL)
{
/* We found a window. Don't send any more WM_NCHITTEST messages */
- ExFreePool(List);
+ ExFreePoolWithTag(List, USERTAG_WINDOWLIST);
UserDereferenceObject(ScopeWin);
return pwndChild;
}
}
- ExFreePool(List);
+ ExFreePoolWithTag(List, USERTAG_WINDOWLIST);
}
}
- *HitTest = (USHORT)co_IntSendMessage(ScopeWin->head.h, WM_NCHITTEST, 0,
- MAKELONG(Point->x, Point->y));
- if ((*HitTest) == (USHORT)HTTRANSPARENT)
+ if (ScopeWin->head.pti == PsGetCurrentThreadWin32Thread())
{
- UserDereferenceObject(ScopeWin);
- return NULL;
+ *HitTest = (USHORT)co_IntSendMessage(ScopeWin->head.h, WM_NCHITTEST, 0,
+ MAKELONG(Point->x, Point->y));
+ if ((*HitTest) == (USHORT)HTTRANSPARENT)
+ {
+ UserDereferenceObject(ScopeWin);
+ return NULL;
+ }
}
+ else
+ *HitTest = HTCLIENT;
return ScopeWin;
}
PWND FASTCALL
-co_WinPosWindowFromPoint(PWND ScopeWin, POINT *WinPoint, USHORT* HitTest)
+co_WinPosWindowFromPoint(PWND ScopeWin, POINT *WinPoint, USHORT* HitTest, BOOL Ignore)
{
PWND Window;
POINT Point = *WinPoint;
ASSERT_REFS_CO(ScopeWin);
UserRefObjectCo(ScopeWin, &Ref);
- Window = co_WinPosSearchChildren(ScopeWin, &Point, HitTest);
+ Window = co_WinPosSearchChildren(ScopeWin, &Point, HitTest, Ignore);
UserDerefObjectCo(ScopeWin);
- if(Window)
+ if (Window)
ASSERT_REFS_CO(Window);
ASSERT_REFS_CO(ScopeWin);
return Window;
}
+PWND FASTCALL
+IntRealChildWindowFromPoint(PWND Parent, LONG x, LONG y)
+{
+ POINTL Pt;
+ HWND *List, *phWnd;
+ PWND pwndHit = NULL;
+
+ Pt.x = x;
+ Pt.y = y;
+
+ if (Parent != UserGetDesktopWindow())
+ {
+ Pt.x += Parent->rcClient.left;
+ Pt.y += Parent->rcClient.top;
+ }
+
+ if (!IntPtInWindow(Parent, Pt.x, Pt.y)) return NULL;
+
+ if ((List = IntWinListChildren(Parent)))
+ {
+ for (phWnd = List; *phWnd; phWnd++)
+ {
+ PWND Child;
+ if ((Child = ValidateHwndNoErr(*phWnd)))
+ {
+ if ( Child->style & WS_VISIBLE && IntPtInWindow(Child, Pt.x, Pt.y) )
+ {
+ if ( Child->pcls->atomClassName != gpsi->atomSysClass[ICLS_BUTTON] ||
+ (Child->style & BS_TYPEMASK) != BS_GROUPBOX )
+ {
+ ExFreePoolWithTag(List, USERTAG_WINDOWLIST);
+ return Child;
+ }
+ pwndHit = Child;
+ }
+ }
+ }
+ ExFreePoolWithTag(List, USERTAG_WINDOWLIST);
+ }
+ return pwndHit ? pwndHit : Parent;
+}
+
+PWND APIENTRY
+IntChildWindowFromPointEx(PWND Parent, LONG x, LONG y, UINT uiFlags)
+{
+ POINTL Pt;
+ HWND *List, *phWnd;
+ PWND pwndHit = NULL;
+
+ Pt.x = x;
+ Pt.y = y;
+
+ if (Parent != UserGetDesktopWindow())
+ {
+ if (Parent->ExStyle & WS_EX_LAYOUTRTL)
+ Pt.x = Parent->rcClient.right - Pt.x;
+ else
+ Pt.x += Parent->rcClient.left;
+ Pt.y += Parent->rcClient.top;
+ }
+
+ if (!IntPtInWindow(Parent, Pt.x, Pt.y)) return NULL;
+
+ if ((List = IntWinListChildren(Parent)))
+ {
+ for (phWnd = List; *phWnd; phWnd++)
+ {
+ PWND Child;
+ if ((Child = ValidateHwndNoErr(*phWnd)))
+ {
+ if (uiFlags & (CWP_SKIPINVISIBLE|CWP_SKIPDISABLED))
+ {
+ if (!(Child->style & WS_VISIBLE) && (uiFlags & CWP_SKIPINVISIBLE)) continue;
+ if ((Child->style & WS_DISABLED) && (uiFlags & CWP_SKIPDISABLED)) continue;
+ }
+
+ if (uiFlags & CWP_SKIPTRANSPARENT)
+ {
+ if (Child->ExStyle & WS_EX_TRANSPARENT) continue;
+ }
+
+ if (IntPtInWindow(Child, Pt.x, Pt.y))
+ {
+ pwndHit = Child;
+ break;
+ }
+ }
+ }
+ ExFreePoolWithTag(List, USERTAG_WINDOWLIST);
+ }
+ return pwndHit ? pwndHit : Parent;
+}
+
HDWP
FASTCALL
IntDeferWindowPos( HDWP hdwp,
return NULL;
}
- if (!(pDWP = (PSMWP)UserGetObject(gHandleTable, hdwp, otSMWP)))
+ if (!(pDWP = (PSMWP)UserGetObject(gHandleTable, hdwp, TYPE_SETWINDOWPOS)))
{
EngSetLastError(ERROR_INVALID_DWP_HANDLE);
return NULL;
TRACE("%p\n", hdwp);
- if (!(pDWP = (PSMWP)UserGetObject(gHandleTable, hdwp, otSMWP)))
+ if (!(pDWP = (PSMWP)UserGetObject(gHandleTable, hdwp, TYPE_SETWINDOWPOS)))
{
EngSetLastError(ERROR_INVALID_DWP_HANDLE);
return FALSE;
winpos->pos.hwnd, winpos->pos.hwndInsertAfter, winpos->pos.x, winpos->pos.y,
winpos->pos.cx, winpos->pos.cy, winpos->pos.flags);
- pwnd = UserGetWindowObject(winpos->pos.hwnd);
+ pwnd = ValidateHwndNoErr(winpos->pos.hwnd);
if (!pwnd)
continue;
/* Yes it's a pointer inside Win32k! */
lRes = co_IntSendMessageNoWait( winpos->pos.hwnd, WM_ASYNC_SETWINDOWPOS, 0, (LPARAM)ppos);
/* We handle this the same way as Event Hooks and Hooks. */
- if ( -1 == (int) lRes )
+ if ( !lRes )
{
ExFreePoolWithTag(ppos, USERTAG_SWP);
}
winpos->pos.cy,
winpos->pos.flags);
+ // Hack to pass tests.... Must have some work to do so clear the error.
+ if (res && (winpos->pos.flags & (SWP_NOMOVE|SWP_NOSIZE|SWP_NOZORDER)) == SWP_NOZORDER )
+ EngSetLastError(ERROR_SUCCESS);
+
UserDerefObjectCo(pwnd);
}
ExFreePoolWithTag(pDWP->acvr, USERTAG_SWP);
UserDereferenceObject(pDWP);
- UserDeleteObject(hdwp, otSMWP);
+ UserDeleteObject(hdwp, TYPE_SETWINDOWPOS);
return res;
}
-
/*
* @implemented
*/
LONG y,
UINT uiFlags)
{
- PWND Parent;
- POINTL Pt;
- HWND Ret;
- HWND *List, *phWnd;
-
- if(!(Parent = UserGetWindowObject(hwndParent)))
- {
- return NULL;
- }
-
- Pt.x = x;
- Pt.y = y;
-
- if(Parent->head.h != IntGetDesktopWindow())
- {
- Pt.x += Parent->rcClient.left;
- Pt.y += Parent->rcClient.top;
- }
-
- if(!IntPtInWindow(Parent, Pt.x, Pt.y))
- {
- return NULL;
- }
-
- Ret = Parent->head.h;
- if((List = IntWinListChildren(Parent)))
+ PWND pwndParent;
+ TRACE("Enter NtUserChildWindowFromPointEx\n");
+ UserEnterExclusive();
+ if ((pwndParent = UserGetWindowObject(hwndParent)))
{
- for(phWnd = List; *phWnd; phWnd++)
- {
- PWND Child;
- if((Child = UserGetWindowObject(*phWnd)))
- {
- if(!(Child->style & WS_VISIBLE) && (uiFlags & CWP_SKIPINVISIBLE))
- {
- continue;
- }
- if((Child->style & WS_DISABLED) && (uiFlags & CWP_SKIPDISABLED))
- {
- continue;
- }
- if((Child->ExStyle & WS_EX_TRANSPARENT) && (uiFlags & CWP_SKIPTRANSPARENT))
- {
- continue;
- }
- if(IntPtInWindow(Child, Pt.x, Pt.y))
- {
- Ret = Child->head.h;
- break;
- }
- }
- }
- ExFreePool(List);
+ pwndParent = IntChildWindowFromPointEx(pwndParent, x, y, uiFlags);
}
-
- return Ret;
+ UserLeave();
+ TRACE("Leave NtUserChildWindowFromPointEx\n");
+ return pwndParent ? UserHMGetHandle(pwndParent) : NULL;
}
/*
Ret = IntDeferWindowPos(WinPosInfo, Wnd, WndInsertAfter, x, y, cx, cy, Flags);
Exit:
- TRACE("Leave NtUserDeferWindowPos, ret=%i\n", Ret);
+ TRACE("Leave NtUserDeferWindowPos, ret=%p\n", Ret);
UserLeave();
return Ret;
}
UINT cmd, // Wine SW_ commands
BOOL Hide)
{
- RECTL NewPos;
- UINT SwFlags;
PWND pWnd;
TRACE("Enter NtUserMinMaximize\n");
goto Exit;
}
- co_WinPosMinMaximize(pWnd, cmd, &NewPos);
-
- SwFlags = Hide ? SWP_NOACTIVATE|SWP_NOZORDER|SWP_FRAMECHANGED : SWP_NOZORDER|SWP_FRAMECHANGED;
-
- co_WinPosSetWindowPos( pWnd,
- NULL,
- NewPos.left,
- NewPos.top,
- NewPos.right, //NewPos.right - NewPos.left,
- NewPos.bottom, //NewPos.bottom - NewPos.top,
- SwFlags);
+ cmd |= Hide ? SW_HIDE : 0;
co_WinPosShowWindow(pWnd, cmd);
SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOREDRAW));
}
+/*
+ * @implemented
+ */
+HWND APIENTRY
+NtUserRealChildWindowFromPoint(HWND Parent,
+ LONG x,
+ LONG y)
+{
+ PWND pwndParent;
+ TRACE("Enter NtUserRealChildWindowFromPoint\n");
+ UserEnterShared();
+ if ((pwndParent = UserGetWindowObject(Parent)))
+ {
+ pwndParent = IntRealChildWindowFromPoint(pwndParent, x, y);
+ }
+ UserLeave();
+ TRACE("Leave NtUserRealChildWindowFromPoint\n");
+ return pwndParent ? UserHMGetHandle(pwndParent) : NULL;
+}
+
/*
* @implemented
*/
UserEnterExclusive();
if (!(Window = UserGetWindowObject(hWnd)) || // FIXME:
-// Due to desktopbg.c
-// Window == UserGetDesktopWindow() || // pWnd->fnid == FNID_DESKTOP
+ Window == UserGetDesktopWindow() || // pWnd->fnid == FNID_DESKTOP
Window == UserGetMessageWindow() ) // pWnd->fnid == FNID_MESSAGEWND
{
ERR("NtUserSetWindowPos bad window handle!\n");
HRGN hRgn,
BOOL bRedraw)
{
- HRGN hrgnCopy;
+ HRGN hrgnCopy = NULL;
PWND Window;
INT flags = (SWP_NOCLIENTSIZE|SWP_NOCLIENTMOVE|SWP_NOACTIVATE|SWP_FRAMECHANGED|SWP_NOSIZE|SWP_NOMOVE);
BOOLEAN Ret = FALSE;
{
if (GreIsHandleValid(hRgn))
{
- hrgnCopy = IntSysCreateRectRgn(0, 0, 0, 0);
+ hrgnCopy = NtGdiCreateRectRgn(0, 0, 0, 0);
/* The coordinates of a window's window region are relative to the
upper-left corner of the window, not the client area of the window. */
NtGdiCombineRgn( hrgnCopy, hRgn, 0, RGN_COPY);
else
RETURN( 0);
}
- else
- {
- hrgnCopy = NULL;
- }
if (Window->hrgnClip)
{
UserRefObjectCo(DesktopWindow, &Ref);
//pti = PsGetCurrentThreadWin32Thread();
- Window = co_WinPosWindowFromPoint(DesktopWindow, &pt, &hittest);
+ Window = co_WinPosWindowFromPoint(DesktopWindow, &pt, &hittest, FALSE);
- if(Window)
+ if (Window)
{
- Ret = Window->head.h;
+ Ret = UserHMGetHandle(Window);
RETURN( Ret);
}
if (Window) UserDereferenceObject(Window);
if (DesktopWindow) UserDerefObjectCo(DesktopWindow);
- TRACE("Leave NtUserWindowFromPoint, ret=%i\n",_ret_);
+ TRACE("Leave NtUserWindowFromPoint, ret=%p\n", _ret_);
UserLeave();
END_CLEANUP;
}