2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS kernel
5 * FILE: win32ss/user/ntuser/winpos.c
6 * PROGRAMER: Casper S. Hornstrup (chorns@users.sourceforge.net)
10 DBG_DEFAULT_CHANNEL(UserWinpos
);
12 /* GLOBALS *******************************************************************/
14 #define MINMAX_NOSWP (0x00010000)
16 #define SWP_EX_NOCOPY 0x0001
17 #define SWP_EX_PAINTSELF 0x0002
19 #define SWP_AGG_NOGEOMETRYCHANGE \
20 (SWP_NOSIZE | SWP_NOCLIENTSIZE | SWP_NOZORDER)
21 #define SWP_AGG_NOPOSCHANGE \
22 (SWP_NOSIZE | SWP_NOMOVE | SWP_NOCLIENTSIZE | SWP_NOCLIENTMOVE | SWP_NOZORDER)
23 #define SWP_AGG_STATUSFLAGS \
24 (SWP_AGG_NOPOSCHANGE | SWP_FRAMECHANGED | SWP_HIDEWINDOW | SWP_SHOWWINDOW)
26 #define EMPTYPOINT(pt) ((pt).x == -1 && (pt).y == -1)
27 #define PLACE_MIN 0x0001
28 #define PLACE_MAX 0x0002
29 #define PLACE_RECT 0x0004
31 VOID FASTCALL
IntLinkWindow(PWND Wnd
,PWND WndInsertAfter
);
33 /* FUNCTIONS *****************************************************************/
36 /***********************************************************************
39 static void dump_winpos_flags(UINT flags
)
41 static const DWORD dumped_flags
= (SWP_NOSIZE
| SWP_NOMOVE
| SWP_NOZORDER
| SWP_NOREDRAW
|
42 SWP_NOACTIVATE
| SWP_FRAMECHANGED
| SWP_SHOWWINDOW
|
43 SWP_HIDEWINDOW
| SWP_NOCOPYBITS
| SWP_NOOWNERZORDER
|
44 SWP_NOSENDCHANGING
| SWP_DEFERERASE
| SWP_ASYNCWINDOWPOS
|
45 SWP_NOCLIENTSIZE
| SWP_NOCLIENTMOVE
| SWP_STATECHANGED
);
47 if(flags
& SWP_NOSIZE
) TRACE(" SWP_NOSIZE");
48 if(flags
& SWP_NOMOVE
) TRACE(" SWP_NOMOVE");
49 if(flags
& SWP_NOZORDER
) TRACE(" SWP_NOZORDER");
50 if(flags
& SWP_NOREDRAW
) TRACE(" SWP_NOREDRAW");
51 if(flags
& SWP_NOACTIVATE
) TRACE(" SWP_NOACTIVATE");
52 if(flags
& SWP_FRAMECHANGED
) TRACE(" SWP_FRAMECHANGED");
53 if(flags
& SWP_SHOWWINDOW
) TRACE(" SWP_SHOWWINDOW");
54 if(flags
& SWP_HIDEWINDOW
) TRACE(" SWP_HIDEWINDOW");
55 if(flags
& SWP_NOCOPYBITS
) TRACE(" SWP_NOCOPYBITS");
56 if(flags
& SWP_NOOWNERZORDER
) TRACE(" SWP_NOOWNERZORDER");
57 if(flags
& SWP_NOSENDCHANGING
) TRACE(" SWP_NOSENDCHANGING");
58 if(flags
& SWP_DEFERERASE
) TRACE(" SWP_DEFERERASE");
59 if(flags
& SWP_ASYNCWINDOWPOS
) TRACE(" SWP_ASYNCWINDOWPOS");
60 if(flags
& SWP_NOCLIENTSIZE
) TRACE(" SWP_NOCLIENTSIZE");
61 if(flags
& SWP_NOCLIENTMOVE
) TRACE(" SWP_NOCLIENTMOVE");
62 if(flags
& SWP_STATECHANGED
) TRACE(" SWP_STATECHANGED");
64 if(flags
& ~dumped_flags
) TRACE(" %08x", flags
& ~dumped_flags
);
70 IntGetClientOrigin(PWND Window OPTIONAL
, LPPOINT Point
)
72 Window
= Window
? Window
: UserGetDesktopWindow();
75 Point
->x
= Point
->y
= 0;
78 Point
->x
= Window
->rcClient
.left
;
79 Point
->y
= Window
->rcClient
.top
;
86 * Returns client window rectangle relative to the upper-left corner of client area.
88 * \note Does not check the validity of the parameters
91 IntGetClientRect(PWND Wnd
, RECTL
*Rect
)
95 if (Wnd
->style
& WS_MINIMIZED
)
97 Rect
->left
= Rect
->top
= 0;
98 Rect
->right
= UserGetSystemMetrics(SM_CXMINIMIZED
);
99 Rect
->bottom
= UserGetSystemMetrics(SM_CYMINIMIZED
);
102 if ( Wnd
!= UserGetDesktopWindow()) // Wnd->fnid != FNID_DESKTOP )
104 *Rect
= Wnd
->rcClient
;
105 RECTL_vOffsetRect(Rect
, -Wnd
->rcClient
.left
, -Wnd
->rcClient
.top
);
109 Rect
->left
= Rect
->top
= 0;
110 Rect
->right
= Wnd
->rcClient
.right
;
111 Rect
->bottom
= Wnd
->rcClient
.bottom
;
112 /* Do this until Init bug is fixed. This sets 640x480, see InitMetrics.
113 Rect->right = UserGetSystemMetrics(SM_CXSCREEN);
114 Rect->bottom = UserGetSystemMetrics(SM_CYSCREEN);
120 IntGetWindowRect(PWND Wnd
, RECTL
*Rect
)
124 if (!Wnd
) return FALSE
;
125 if ( Wnd
!= UserGetDesktopWindow()) // Wnd->fnid != FNID_DESKTOP )
127 *Rect
= Wnd
->rcWindow
;
131 Rect
->left
= Rect
->top
= 0;
132 Rect
->right
= Wnd
->rcWindow
.right
;
133 Rect
->bottom
= Wnd
->rcWindow
.bottom
;
134 /* Do this until Init bug is fixed. This sets 640x480, see InitMetrics.
135 Rect->right = GetSystemMetrics(SM_CXSCREEN);
136 Rect->bottom = GetSystemMetrics(SM_CYSCREEN);
143 IntMapWindowPoints(PWND FromWnd
, PWND ToWnd
, LPPOINT lpPoints
, UINT cPoints
)
145 BOOL mirror_from
, mirror_to
;
150 /* Note: Desktop Top and Left is always 0! */
151 Delta
.x
= Delta
.y
= 0;
152 mirror_from
= mirror_to
= FALSE
;
154 if (FromWnd
&& FromWnd
!= UserGetDesktopWindow()) // FromWnd->fnid != FNID_DESKTOP)
156 if (FromWnd
->ExStyle
& WS_EX_LAYOUTRTL
)
160 Delta
.x
= -FromWnd
->rcClient
.right
;
163 Delta
.x
= FromWnd
->rcClient
.left
;
164 Delta
.y
= FromWnd
->rcClient
.top
;
167 if (ToWnd
&& ToWnd
!= UserGetDesktopWindow()) // ToWnd->fnid != FNID_DESKTOP)
169 if (ToWnd
->ExStyle
& WS_EX_LAYOUTRTL
)
173 Delta
.x
+= Change
* ToWnd
->rcClient
.right
;
176 Delta
.x
-= Change
* ToWnd
->rcClient
.left
;
177 Delta
.y
-= ToWnd
->rcClient
.top
;
180 for (i
= 0; i
!= cPoints
; i
++)
182 lpPoints
[i
].x
+= Delta
.x
;
183 lpPoints
[i
].x
*= Change
;
184 lpPoints
[i
].y
+= Delta
.y
;
187 if ((mirror_from
|| mirror_to
) && cPoints
== 2) /* special case for rectangle */
189 int tmp
= min(lpPoints
[0].x
, lpPoints
[1].x
);
190 lpPoints
[1].x
= max(lpPoints
[0].x
, lpPoints
[1].x
);
194 return MAKELONG(LOWORD(Delta
.x
), LOWORD(Delta
.y
));
198 IntClientToScreen(PWND Wnd
, LPPOINT lpPoint
)
200 if (Wnd
&& Wnd
->fnid
!= FNID_DESKTOP
)
202 if (Wnd
->ExStyle
& WS_EX_LAYOUTRTL
)
203 lpPoint
->x
= Wnd
->rcClient
.right
- lpPoint
->x
;
205 lpPoint
->x
+= Wnd
->rcClient
.left
;
206 lpPoint
->y
+= Wnd
->rcClient
.top
;
212 IntScreenToClient(PWND Wnd
, LPPOINT lpPoint
)
214 if (Wnd
&& Wnd
->fnid
!= FNID_DESKTOP
)
216 if (Wnd
->ExStyle
& WS_EX_LAYOUTRTL
)
217 lpPoint
->x
= Wnd
->rcClient
.right
- lpPoint
->x
;
219 lpPoint
->x
-= Wnd
->rcClient
.left
;
220 lpPoint
->y
-= Wnd
->rcClient
.top
;
225 BOOL FASTCALL
IsChildVisible(PWND pWnd
)
229 if ( (pWnd
->style
& (WS_POPUP
|WS_CHILD
)) != WS_CHILD
||
230 !(pWnd
= pWnd
->spwndParent
) )
233 while (pWnd
->style
& WS_VISIBLE
);
237 PWND FASTCALL
IntGetLastTopMostWindow(VOID
)
240 PDESKTOP rpdesk
= gptiCurrent
->rpdesk
;
243 (pWnd
= rpdesk
->pDeskInfo
->spwnd
->spwndChild
) &&
244 pWnd
->ExStyle
& WS_EX_TOPMOST
)
248 if (!pWnd
->spwndNext
) break;
249 if (!(pWnd
->spwndNext
->ExStyle
& WS_EX_TOPMOST
)) break;
250 pWnd
= pWnd
->spwndNext
;
258 SelectWindowRgn( PWND Window
, HRGN hRgnClip
)
260 if (Window
->hrgnClip
)
262 /* Delete no longer needed region handle */
263 IntGdiSetRegionOwner(Window
->hrgnClip
, GDI_OBJ_HMGR_POWNED
);
264 GreDeleteObject(Window
->hrgnClip
);
265 Window
->hrgnClip
= NULL
;
268 if (hRgnClip
> HRGN_WINDOW
)
270 /*if (Window != UserGetDesktopWindow()) // Window->fnid != FNID_DESKTOP)
272 NtGdiOffsetRgn(hRgnClip, Window->rcWindow.left, Window->rcWindow.top);
274 /* Set public ownership */
275 IntGdiSetRegionOwner(hRgnClip
, GDI_OBJ_HMGR_PUBLIC
);
277 Window
->hrgnClip
= hRgnClip
;
282 // This helps with CORE-6129 forcing modal dialog active when another app is minimized or closed.
284 BOOL FASTCALL
ActivateOtherWindowMin(PWND Wnd
)
286 BOOL ActivePrev
, FindTopWnd
;
287 PWND pWndTopMost
, pWndChild
, pWndSetActive
, pWndTemp
, pWndDesk
;
288 USER_REFERENCE_ENTRY Ref
;
289 PTHREADINFO pti
= gptiCurrent
;
291 //ERR("AOWM 1 %p\n",Wnd->head.h);
292 ActivePrev
= (pti
->MessageQueue
->spwndActivePrev
!= NULL
);
295 if ((pWndTopMost
= IntGetLastTopMostWindow()))
296 pWndChild
= pWndTopMost
->spwndNext
;
298 pWndChild
= Wnd
->spwndParent
->spwndChild
;
303 pWndSetActive
= pti
->MessageQueue
->spwndActivePrev
;
305 pWndSetActive
= pWndChild
;
311 if ( VerifyWnd(pWndSetActive
) &&
312 !(pWndSetActive
->ExStyle
& WS_EX_NOACTIVATE
) &&
313 (pWndSetActive
->style
& (WS_VISIBLE
|WS_DISABLED
)) == WS_VISIBLE
&&
314 (!(pWndSetActive
->style
& WS_ICONIC
) /* FIXME MinMax pos? */ ) )
316 if (!(pWndSetActive
->ExStyle
& WS_EX_TOOLWINDOW
) )
318 UserRefObjectCo(pWndSetActive
, &Ref
);
319 //ERR("ActivateOtherWindowMin Set FG 1\n");
320 co_IntSetForegroundWindow(pWndSetActive
);
321 UserDerefObjectCo(pWndSetActive
);
322 //ERR("AOWM 2 Exit Good %p\n",pWndSetActive->head.h);
325 if (!pWndTemp
) pWndTemp
= pWndSetActive
;
330 pWndSetActive
= pWndChild
;
333 pWndSetActive
= pWndSetActive
->spwndNext
;
336 if ( !FindTopWnd
) break;
341 pWndChild
= pWndChild
->spwndParent
->spwndChild
;
345 if (!(pWndDesk
= IntGetThreadDesktopWindow(pti
)))
350 pWndChild
= pWndDesk
->spwndChild
;
353 if ((pWndSetActive
= pWndTemp
))
355 UserRefObjectCo(pWndSetActive
, &Ref
);
356 //ERR("ActivateOtherWindowMin Set FG 2\n");
357 co_IntSetForegroundWindow(pWndSetActive
);
358 UserDerefObjectCo(pWndSetActive
);
359 //ERR("AOWM 3 Exit Good %p\n",pWndSetActive->head.h);
362 //ERR("AOWM 4 Bad\n");
366 /*******************************************************************
367 * can_activate_window
369 * Check if we can activate the specified window.
372 BOOL FASTCALL
can_activate_window( PWND Wnd OPTIONAL
)
376 if (!Wnd
) return FALSE
;
379 if (!(style
& WS_VISIBLE
)) return FALSE
;
380 if (style
& WS_MINIMIZE
) return FALSE
;
381 if ((style
& (WS_POPUP
|WS_CHILD
)) == WS_CHILD
) return FALSE
;
383 /* FIXME: This window could be disable because the child that closed
385 //return !(style & WS_DISABLED);
389 /*******************************************************************
390 * WinPosActivateOtherWindow
392 * Activates window other than pWnd.
395 co_WinPosActivateOtherWindow(PWND Wnd
)
398 USER_REFERENCE_ENTRY Ref
;
402 if (IntIsDesktopWindow(Wnd
))
404 IntSetFocusMessageQueue(NULL
);
408 /* If this is popup window, try to activate the owner first. */
409 if ((Wnd
->style
& WS_POPUP
) && (WndTo
= Wnd
->spwndOwner
))
411 TRACE("WPAOW Popup with Owner\n");
412 WndTo
= UserGetAncestor( WndTo
, GA_ROOT
);
413 if (can_activate_window(WndTo
)) goto done
;
416 /* Pick a next top-level window. */
417 /* FIXME: Search for non-tooltip windows first. */
421 if (!(WndTo
= WndTo
->spwndNext
)) break;
422 if (can_activate_window( WndTo
)) goto done
;
426 Fixes wine win.c:test_SetParent last ShowWindow test after popup dies.
427 Check for previous active window to bring to top.
431 WndTo
= Wnd
->head
.pti
->MessageQueue
->spwndActivePrev
;
432 if (can_activate_window( WndTo
)) goto done
;
435 // Find any window to bring to top. Works Okay for wine since it does not see X11 windows.
436 WndTo
= UserGetDesktopWindow();
437 WndTo
= WndTo
->spwndChild
;
449 if (can_activate_window( WndTo
)) goto done
;
450 if (!(WndTo
= WndTo
->spwndNext
)) break;
454 if (WndTo
) UserRefObjectCo(WndTo
, &Ref
);
456 if (gpqForeground
&& (!gpqForeground
->spwndActive
|| Wnd
== gpqForeground
->spwndActive
))
458 /* ReactOS can pass WndTo = NULL to co_IntSetForegroundWindow and returns FALSE. */
459 //ERR("WinPosActivateOtherWindow Set FG 0x%p hWnd %p\n",WndTo, WndTo ? WndTo->head.h : 0);
460 if (co_IntSetForegroundWindow(WndTo
))
462 if (WndTo
) UserDerefObjectCo(WndTo
);
466 //ERR("WinPosActivateOtherWindow Set Active 0x%p\n",WndTo);
467 if (!co_IntSetActiveWindow(WndTo
,FALSE
,TRUE
,FALSE
)) /* Ok for WndTo to be NULL here */
469 //ERR("WPAOW SA 1\n");
470 co_IntSetActiveWindow(NULL
,FALSE
,TRUE
,FALSE
);
472 if (WndTo
) UserDerefObjectCo(WndTo
);
476 WinPosInitInternalPos(PWND Wnd
, RECTL
*RestoreRect
)
479 RECTL Rect
= *RestoreRect
;
481 if (Wnd
->spwndParent
&& Wnd
->spwndParent
!= UserGetDesktopWindow())
483 RECTL_vOffsetRect(&Rect
,
484 -Wnd
->spwndParent
->rcClient
.left
,
485 -Wnd
->spwndParent
->rcClient
.top
);
491 if (!Wnd
->InternalPosInitialized
)
493 // FIXME: Use check point Atom..
494 Wnd
->InternalPos
.flags
= 0;
495 Wnd
->InternalPos
.MaxPos
.x
= Wnd
->InternalPos
.MaxPos
.y
= -1;
496 Wnd
->InternalPos
.IconPos
.x
= Wnd
->InternalPos
.IconPos
.y
= -1;
497 Wnd
->InternalPos
.NormalRect
= Rect
;
498 Wnd
->InternalPosInitialized
= TRUE
;
501 if (Wnd
->style
& WS_MINIMIZE
)
503 Wnd
->InternalPos
.IconPos
= Size
;
504 Wnd
->InternalPos
.flags
|= WPF_MININIT
;
506 else if (Wnd
->style
& WS_MAXIMIZE
)
508 Wnd
->InternalPos
.flags
|= WPF_MAXINIT
;
510 if ( Wnd
->spwndParent
== Wnd
->head
.rpdesk
->pDeskInfo
->spwnd
)
512 if (Wnd
->state
& WNDS_MAXIMIZESTOMONITOR
)
514 Wnd
->InternalPos
.flags
&= ~WPF_MAXINIT
;
515 Wnd
->InternalPos
.MaxPos
.x
= Wnd
->InternalPos
.MaxPos
.y
= -1;
520 PMONITOR pmonitor
= UserMonitorFromRect(&Rect
, MONITOR_DEFAULTTOPRIMARY
);
521 // FIXME: support DPI aware, rcWorkDPI/Real etc..
522 WorkArea
= pmonitor
->rcMonitor
;
524 if (Wnd
->style
& WS_MAXIMIZEBOX
)
525 { // Support (Wnd->state & WNDS_HASCAPTION) || pmonitor->cFullScreen too.
526 if ((Wnd
->style
& WS_CAPTION
) == WS_CAPTION
|| !(Wnd
->style
& (WS_CHILD
| WS_POPUP
)))
528 WorkArea
= pmonitor
->rcWork
;
533 Wnd
->InternalPos
.MaxPos
.x
= Rect
.left
- WorkArea
.left
;
534 Wnd
->InternalPos
.MaxPos
.y
= Rect
.top
- WorkArea
.top
;
536 /*ERR("WinPosIP 2 X %d = R.l %d - W.l %d | Y %d = R.t %d - W.t %d\n",
537 Wnd->InternalPos.MaxPos.x,
538 Rect.left, WorkArea.left,
539 Wnd->InternalPos.MaxPos.y,
540 Rect.top, WorkArea.top);*/
544 Wnd
->InternalPos
.MaxPos
= Size
;
548 Wnd
->InternalPos
.NormalRect
= Rect
;
554 IntGetWindowPlacement(PWND Wnd
, WINDOWPLACEMENT
*lpwndpl
)
556 if (!Wnd
) return FALSE
;
558 if(lpwndpl
->length
!= sizeof(WINDOWPLACEMENT
))
565 WinPosInitInternalPos(Wnd
, &Wnd
->rcWindow
);
567 lpwndpl
->showCmd
= SW_HIDE
;
569 if ( Wnd
->style
& WS_MINIMIZE
)
570 lpwndpl
->showCmd
= SW_SHOWMINIMIZED
;
572 lpwndpl
->showCmd
= ( Wnd
->style
& WS_MAXIMIZE
) ? SW_SHOWMAXIMIZED
: SW_SHOWNORMAL
;
574 lpwndpl
->rcNormalPosition
= Wnd
->InternalPos
.NormalRect
;
576 if (Wnd
->InternalPos
.flags
& WPF_MININIT
) // Return if it was set!
578 lpwndpl
->ptMinPosition
.x
= Wnd
->InternalPos
.IconPos
.x
;
579 lpwndpl
->ptMinPosition
.y
= Wnd
->InternalPos
.IconPos
.y
;
582 lpwndpl
->ptMinPosition
.x
= lpwndpl
->ptMinPosition
.y
= -1;
584 if ( Wnd
->InternalPos
.flags
& WPF_MAXINIT
&& // Return if set and not maximized to monitor!
585 !(Wnd
->state
& WNDS_MAXIMIZESTOMONITOR
))
587 lpwndpl
->ptMaxPosition
.x
= Wnd
->InternalPos
.MaxPos
.x
;
588 lpwndpl
->ptMaxPosition
.y
= Wnd
->InternalPos
.MaxPos
.y
;
591 lpwndpl
->ptMaxPosition
.x
= lpwndpl
->ptMaxPosition
.y
= -1;
593 if ( Wnd
->spwndParent
== Wnd
->head
.rpdesk
->pDeskInfo
->spwnd
&&
594 !(Wnd
->ExStyle
& WS_EX_TOOLWINDOW
))
596 PMONITOR pmonitor
= UserMonitorFromRect(&lpwndpl
->rcNormalPosition
, MONITOR_DEFAULTTOPRIMARY
);
598 // FIXME: support DPI aware, rcWorkDPI/Real etc..
599 if (Wnd
->InternalPos
.flags
& WPF_MININIT
)
601 lpwndpl
->ptMinPosition
.x
-= (pmonitor
->rcWork
.left
- pmonitor
->rcMonitor
.left
);
602 lpwndpl
->ptMinPosition
.y
-= (pmonitor
->rcWork
.top
- pmonitor
->rcMonitor
.top
);
604 RECTL_vOffsetRect(&lpwndpl
->rcNormalPosition
,
605 pmonitor
->rcMonitor
.left
- pmonitor
->rcWork
.left
,
606 pmonitor
->rcMonitor
.top
- pmonitor
->rcWork
.top
);
609 if ( Wnd
->InternalPos
.flags
& WPF_RESTORETOMAXIMIZED
|| Wnd
->style
& WS_MAXIMIZE
)
610 lpwndpl
->flags
|= WPF_RESTORETOMAXIMIZED
;
612 if ( ((Wnd
->style
& (WS_CHILD
|WS_POPUP
)) == WS_CHILD
) && Wnd
->InternalPos
.flags
& WPF_SETMINPOSITION
)
613 lpwndpl
->flags
|= WPF_SETMINPOSITION
;
618 /* make sure the specified rect is visible on screen */
619 static void make_rect_onscreen( RECT
*rect
)
621 PMONITOR pmonitor
= UserMonitorFromRect( rect
, MONITOR_DEFAULTTONEAREST
); // Wine uses this.
623 // FIXME: support DPI aware, rcWorkDPI/Real etc..
624 if (!pmonitor
) return;
625 /* FIXME: map coordinates from rcWork to rcMonitor */
626 if (rect
->right
<= pmonitor
->rcWork
.left
)
628 rect
->right
+= pmonitor
->rcWork
.left
- rect
->left
;
629 rect
->left
= pmonitor
->rcWork
.left
;
631 else if (rect
->left
>= pmonitor
->rcWork
.right
)
633 rect
->left
+= pmonitor
->rcWork
.right
- rect
->right
;
634 rect
->right
= pmonitor
->rcWork
.right
;
636 if (rect
->bottom
<= pmonitor
->rcWork
.top
)
638 rect
->bottom
+= pmonitor
->rcWork
.top
- rect
->top
;
639 rect
->top
= pmonitor
->rcWork
.top
;
641 else if (rect
->top
>= pmonitor
->rcWork
.bottom
)
643 rect
->top
+= pmonitor
->rcWork
.bottom
- rect
->bottom
;
644 rect
->bottom
= pmonitor
->rcWork
.bottom
;
648 /* make sure the specified point is visible on screen */
649 static void make_point_onscreen( POINT
*pt
)
653 RECTL_vSetRect( &rect
, pt
->x
, pt
->y
, pt
->x
+ 1, pt
->y
+ 1 );
654 make_rect_onscreen( &rect
);
660 IntSetWindowPlacement(PWND Wnd
, WINDOWPLACEMENT
*wpl
, UINT Flags
)
665 if ( Flags
& PLACE_MIN
) make_point_onscreen( &wpl
->ptMinPosition
);
666 if ( Flags
& PLACE_MAX
) make_point_onscreen( &wpl
->ptMaxPosition
);
667 if ( Flags
& PLACE_RECT
) make_rect_onscreen( &wpl
->rcNormalPosition
);
669 if (!Wnd
|| Wnd
== Wnd
->head
.rpdesk
->pDeskInfo
->spwnd
) return FALSE
;
671 if ( Flags
& PLACE_MIN
) Wnd
->InternalPos
.IconPos
= wpl
->ptMinPosition
;
672 if ( Flags
& PLACE_MAX
) Wnd
->InternalPos
.MaxPos
= wpl
->ptMaxPosition
;
673 if ( Flags
& PLACE_RECT
) Wnd
->InternalPos
.NormalRect
= wpl
->rcNormalPosition
;
675 SWP_Flags
= SWP_NOZORDER
| SWP_NOACTIVATE
| ((wpl
->flags
& WPF_ASYNCWINDOWPLACEMENT
) ? SWP_ASYNCWINDOWPOS
: 0);
677 if (Wnd
->style
& WS_MINIMIZE
)
679 if (Flags
& PLACE_MIN
|| Wnd
->InternalPos
.flags
& WPF_SETMINPOSITION
)
681 co_WinPosSetWindowPos(Wnd
, HWND_TOP
,
682 wpl
->ptMinPosition
.x
, wpl
->ptMinPosition
.y
, 0, 0,
683 SWP_NOSIZE
| SWP_Flags
);
684 Wnd
->InternalPos
.flags
|= WPF_MININIT
;
687 else if (Wnd
->style
& WS_MAXIMIZE
)
689 if (Flags
& PLACE_MAX
)
691 co_WinPosSetWindowPos(Wnd
, HWND_TOP
,
692 wpl
->ptMaxPosition
.x
, wpl
->ptMaxPosition
.y
, 0, 0,
693 SWP_NOSIZE
| SWP_Flags
);
694 Wnd
->InternalPos
.flags
|= WPF_MAXINIT
;
697 else if (Flags
& PLACE_RECT
)
699 co_WinPosSetWindowPos(Wnd
, HWND_TOP
,
700 wpl
->rcNormalPosition
.left
, wpl
->rcNormalPosition
.top
,
701 wpl
->rcNormalPosition
.right
- wpl
->rcNormalPosition
.left
,
702 wpl
->rcNormalPosition
.bottom
- wpl
->rcNormalPosition
.top
,
706 sAsync
= (Wnd
->head
.pti
->MessageQueue
!= gptiCurrent
->MessageQueue
&& wpl
->flags
& WPF_ASYNCWINDOWPLACEMENT
);
709 co_IntSendMessageNoWait( UserHMGetHandle(Wnd
), WM_ASYNC_SHOWWINDOW
, wpl
->showCmd
, 0 );
711 co_WinPosShowWindow(Wnd
, wpl
->showCmd
);
713 if ( Wnd
->style
& WS_MINIMIZE
&& !sAsync
)
715 if ( wpl
->flags
& WPF_SETMINPOSITION
)
716 Wnd
->InternalPos
.flags
|= WPF_SETMINPOSITION
;
718 if ( wpl
->flags
& WPF_RESTORETOMAXIMIZED
)
719 Wnd
->InternalPos
.flags
|= WPF_RESTORETOMAXIMIZED
;
726 co_WinPosArrangeIconicWindows(PWND parent
)
730 INT x
, y
, xspacing
, yspacing
, sx
, sy
;
732 ASSERT_REFS_CO(parent
);
734 IntGetClientRect( parent
, &rectParent
);
735 // FIXME: Support Minimize Metrics gspv.mm.iArrange.
736 // Default: ARW_BOTTOMLEFT
738 y
= rectParent
.bottom
;
740 xspacing
= UserGetSystemMetrics(SM_CXMINIMIZED
);
741 yspacing
= UserGetSystemMetrics(SM_CYMINIMIZED
);
743 Child
= parent
->spwndChild
;
746 if((Child
->style
& WS_MINIMIZE
) != 0 )
748 USER_REFERENCE_ENTRY Ref
;
749 UserRefObjectCo(Child
, &Ref
);
751 sx
= x
+ UserGetSystemMetrics(SM_CXBORDER
);
752 sy
= y
- yspacing
- UserGetSystemMetrics(SM_CYBORDER
);
754 Child
->InternalPos
.IconPos
.x
= sx
;
755 Child
->InternalPos
.IconPos
.y
= sy
;
756 Child
->InternalPos
.flags
|= WPF_MININIT
;
758 co_WinPosSetWindowPos( Child
, 0, sx
, sy
, xspacing
, yspacing
, SWP_NOZORDER
| SWP_NOACTIVATE
| SWP_NOCOPYBITS
| SWP_ASYNCWINDOWPOS
);
760 UserDerefObjectCo(Child
);
762 if (x
<= rectParent
.right
- xspacing
)
770 Child
= Child
->spwndNext
;
776 WinPosFindIconPos(PWND Window
, POINT
*Pos
)
779 PWND pwndChild
, pwndParent
;
780 int x
, y
, xspacing
, yspacing
;
782 pwndParent
= Window
->spwndParent
;
783 if (pwndParent
== UserGetDesktopWindow())
785 ERR("FIXME: Parent is Desktop, Min off screen!\n");
786 /* FIXME: ReactOS doesn't support iconic minimize to desktop */
787 Pos
->x
= Pos
->y
= -32000;
788 Window
->InternalPos
.flags
|= WPF_MININIT
;
789 Window
->InternalPos
.IconPos
.x
= Pos
->x
;
790 Window
->InternalPos
.IconPos
.y
= Pos
->y
;
794 IntGetClientRect( pwndParent
, &rectParent
);
795 // FIXME: Support Minimize Metrics gspv.mm.iArrange.
796 // Default: ARW_BOTTOMLEFT
798 y
= rectParent
.bottom
;
800 xspacing
= UserGetSystemMetrics(SM_CXMINIMIZED
);
801 yspacing
= UserGetSystemMetrics(SM_CYMINIMIZED
);
803 // Set to default position when minimized.
804 Pos
->x
= x
+ UserGetSystemMetrics(SM_CXBORDER
);
805 Pos
->y
= y
- yspacing
- UserGetSystemMetrics(SM_CYBORDER
);
807 for (pwndChild
= pwndParent
->spwndChild
; pwndChild
; pwndChild
= pwndChild
->spwndNext
)
809 if (pwndChild
== Window
) continue;
811 if ((pwndChild
->style
& (WS_VISIBLE
|WS_MINIMIZE
)) != (WS_VISIBLE
|WS_MINIMIZE
) )
816 if ( pwndChild
->InternalPos
.IconPos
.x
!= Pos
->x
&& pwndChild
->InternalPos
.IconPos
.y
!= Pos
->y
)
820 if (x
<= rectParent
.right
- xspacing
)
827 Pos
->x
= x
+ UserGetSystemMetrics(SM_CXBORDER
);
828 Pos
->y
= y
- yspacing
- UserGetSystemMetrics(SM_CYBORDER
);
831 Window
->InternalPos
.IconPos
.x
= Pos
->x
;
832 Window
->InternalPos
.IconPos
.y
= Pos
->y
;
833 Window
->InternalPos
.flags
|= WPF_MININIT
;
834 TRACE("Position is set! X:%d Y:%d\n",Pos
->x
,Pos
->y
);
839 co_WinPosMinMaximize(PWND Wnd
, UINT ShowFlag
, RECT
* NewPos
)
848 wpl
.length
= sizeof(wpl
);
849 IntGetWindowPlacement( Wnd
, &wpl
);
851 if (co_HOOK_CallHooks( WH_CBT
, HCBT_MINMAX
, (WPARAM
)Wnd
->head
.h
, ShowFlag
))
853 ERR("WinPosMinMaximize WH_CBT Call Hook return!\n");
854 return SWP_NOSIZE
| SWP_NOMOVE
;
856 if (Wnd
->style
& WS_MINIMIZE
)
861 case SW_SHOWMINNOACTIVE
:
862 case SW_SHOWMINIMIZED
:
863 case SW_FORCEMINIMIZE
:
864 return SWP_NOSIZE
| SWP_NOMOVE
;
866 if (!co_IntSendMessageNoWait(Wnd
->head
.h
, WM_QUERYOPEN
, 0, 0))
868 return(SWP_NOSIZE
| SWP_NOMOVE
);
870 SwpFlags
|= SWP_NOCOPYBITS
;
875 case SW_SHOWMINNOACTIVE
:
876 case SW_SHOWMINIMIZED
:
877 case SW_FORCEMINIMIZE
:
879 //ERR("MinMaximize Minimize\n");
880 if (Wnd
->style
& WS_MAXIMIZE
)
882 Wnd
->InternalPos
.flags
|= WPF_RESTORETOMAXIMIZED
;
886 Wnd
->InternalPos
.flags
&= ~WPF_RESTORETOMAXIMIZED
;
889 old_style
= IntSetStyle( Wnd
, WS_MINIMIZE
, WS_MAXIMIZE
);
891 co_UserRedrawWindow(Wnd
, NULL
, 0, RDW_VALIDATE
| RDW_NOERASE
| RDW_NOINTERNALPAINT
);
893 if (!(Wnd
->InternalPos
.flags
& WPF_SETMINPOSITION
))
894 Wnd
->InternalPos
.flags
&= ~WPF_MININIT
;
896 WinPosFindIconPos(Wnd
, &wpl
.ptMinPosition
);
898 /*if (!(old_style & WS_MINIMIZE))
900 SwpFlags |= SWP_STATECHANGED;
901 IntShowOwnedPopups(Wnd, FALSE);
904 RECTL_vSetRect(NewPos
, wpl
.ptMinPosition
.x
, wpl
.ptMinPosition
.y
,
905 wpl
.ptMinPosition
.x
+ UserGetSystemMetrics(SM_CXMINIMIZED
),
906 wpl
.ptMinPosition
.y
+ UserGetSystemMetrics(SM_CYMINIMIZED
));
907 SwpFlags
|= SWP_NOCOPYBITS
;
913 //ERR("MinMaximize Maximize\n");
914 if ((Wnd
->style
& WS_MAXIMIZE
) && (Wnd
->style
& WS_VISIBLE
))
916 SwpFlags
= SWP_NOSIZE
| SWP_NOMOVE
;
919 co_WinPosGetMinMaxInfo(Wnd
, &Size
, &wpl
.ptMaxPosition
, NULL
, NULL
);
921 /*ERR("Maximize: %d,%d %dx%d\n",
922 wpl.ptMaxPosition.x, wpl.ptMaxPosition.y, Size.x, Size.y);
924 old_style
= IntSetStyle( Wnd
, WS_MAXIMIZE
, WS_MINIMIZE
);
925 /*if (old_style & WS_MINIMIZE)
927 IntShowOwnedPopups(Wnd, TRUE);
930 if (!(old_style
& WS_MAXIMIZE
)) SwpFlags
|= SWP_STATECHANGED
;
931 RECTL_vSetRect(NewPos
, wpl
.ptMaxPosition
.x
, wpl
.ptMaxPosition
.y
,
932 //wpl.ptMaxPosition.x + Size.x, wpl.ptMaxPosition.y + Size.y);
937 case SW_SHOWNOACTIVATE
:
938 Wnd
->InternalPos
.flags
&= ~WPF_RESTORETOMAXIMIZED
;
942 case SW_SHOWDEFAULT
: /* FIXME: should have its own handler */
944 //ERR("MinMaximize Restore\n");
945 old_style
= IntSetStyle( Wnd
, 0, WS_MINIMIZE
| WS_MAXIMIZE
);
946 if (old_style
& WS_MINIMIZE
)
948 //IntShowOwnedPopups(Wnd, TRUE);
950 if (Wnd
->InternalPos
.flags
& WPF_RESTORETOMAXIMIZED
)
952 co_WinPosGetMinMaxInfo(Wnd
, &Size
, &wpl
.ptMaxPosition
, NULL
, NULL
);
953 IntSetStyle( Wnd
, WS_MAXIMIZE
, 0 );
954 SwpFlags
|= SWP_STATECHANGED
;
955 RECTL_vSetRect(NewPos
, wpl
.ptMaxPosition
.x
, wpl
.ptMaxPosition
.y
,
956 wpl
.ptMaxPosition
.x
+ Size
.x
, wpl
.ptMaxPosition
.y
+ Size
.y
);
961 *NewPos
= wpl
.rcNormalPosition
;
962 NewPos
->right
-= NewPos
->left
;
963 NewPos
->bottom
-= NewPos
->top
;
969 if (!(old_style
& WS_MAXIMIZE
))
973 SwpFlags
|= SWP_STATECHANGED
;
974 Wnd
->InternalPos
.flags
&= ~WPF_RESTORETOMAXIMIZED
;
975 *NewPos
= wpl
.rcNormalPosition
;
976 NewPos
->right
-= NewPos
->left
;
977 NewPos
->bottom
-= NewPos
->top
;
986 UserHasWindowEdge(DWORD Style
, DWORD ExStyle
)
988 if (Style
& WS_MINIMIZE
)
990 if (ExStyle
& WS_EX_DLGMODALFRAME
)
992 if (ExStyle
& WS_EX_STATICEDGE
)
994 if (Style
& WS_THICKFRAME
)
997 if (Style
== WS_DLGFRAME
|| Style
== WS_CAPTION
)
1003 IntGetWindowBorderMeasures(PWND Wnd
, UINT
*cx
, UINT
*cy
)
1005 if(HAS_DLGFRAME(Wnd
->style
, Wnd
->ExStyle
) && !(Wnd
->style
& WS_MINIMIZE
))
1007 *cx
= UserGetSystemMetrics(SM_CXDLGFRAME
);
1008 *cy
= UserGetSystemMetrics(SM_CYDLGFRAME
);
1012 if(HAS_THICKFRAME(Wnd
->style
, Wnd
->ExStyle
)&& !(Wnd
->style
& WS_MINIMIZE
))
1014 *cx
= UserGetSystemMetrics(SM_CXFRAME
);
1015 *cy
= UserGetSystemMetrics(SM_CYFRAME
);
1017 else if(HAS_THINFRAME(Wnd
->style
, Wnd
->ExStyle
))
1019 *cx
= UserGetSystemMetrics(SM_CXBORDER
);
1020 *cy
= UserGetSystemMetrics(SM_CYBORDER
);
1030 UserGetWindowBorders(DWORD Style
, DWORD ExStyle
, SIZE
*Size
, BOOL WithClient
)
1034 if (UserHasWindowEdge(Style
, ExStyle
))
1036 else if (ExStyle
& WS_EX_STATICEDGE
)
1038 if ((ExStyle
& WS_EX_CLIENTEDGE
) && WithClient
)
1040 if (Style
& WS_CAPTION
|| ExStyle
& WS_EX_DLGMODALFRAME
)
1042 Size
->cx
= Size
->cy
= Border
;
1043 if ((Style
& WS_THICKFRAME
) && !(Style
& WS_MINIMIZE
))
1045 Size
->cx
+= UserGetSystemMetrics(SM_CXFRAME
) - UserGetSystemMetrics(SM_CXDLGFRAME
);
1046 Size
->cy
+= UserGetSystemMetrics(SM_CYFRAME
) - UserGetSystemMetrics(SM_CYDLGFRAME
);
1048 Size
->cx
*= UserGetSystemMetrics(SM_CXBORDER
);
1049 Size
->cy
*= UserGetSystemMetrics(SM_CYBORDER
);
1053 UserAdjustWindowRectEx(LPRECT lpRect
,
1062 lpRect
->top
-= UserGetSystemMetrics(SM_CYMENU
);
1064 if ((dwStyle
& WS_CAPTION
) == WS_CAPTION
)
1066 if (dwExStyle
& WS_EX_TOOLWINDOW
)
1067 lpRect
->top
-= UserGetSystemMetrics(SM_CYSMCAPTION
);
1069 lpRect
->top
-= UserGetSystemMetrics(SM_CYCAPTION
);
1071 UserGetWindowBorders(dwStyle
, dwExStyle
, &BorderSize
, TRUE
);
1081 co_WinPosGetMinMaxInfo(PWND Window
, POINT
* MaxSize
, POINT
* MaxPos
,
1082 POINT
* MinTrack
, POINT
* MaxTrack
)
1087 LONG style
= Window
->style
;
1089 LONG exstyle
= Window
->ExStyle
;
1092 ASSERT_REFS_CO(Window
);
1094 /* Compute default values */
1096 rc
= Window
->rcWindow
;
1097 MinMax
.ptReserved
.x
= rc
.left
;
1098 MinMax
.ptReserved
.y
= rc
.top
;
1100 if ((style
& WS_CAPTION
) == WS_CAPTION
)
1101 adjustedStyle
= style
& ~WS_BORDER
; /* WS_CAPTION = WS_DLGFRAME | WS_BORDER */
1103 adjustedStyle
= style
;
1105 if(Window
->spwndParent
)
1106 IntGetClientRect(Window
->spwndParent
, &rc
);
1107 UserAdjustWindowRectEx(&rc
, adjustedStyle
, ((style
& WS_POPUP
) && Window
->IDMenu
), exstyle
);
1112 MinMax
.ptMaxSize
.x
= rc
.right
- rc
.left
;
1113 MinMax
.ptMaxSize
.y
= rc
.bottom
- rc
.top
;
1114 if (style
& (WS_DLGFRAME
| WS_BORDER
))
1116 MinMax
.ptMinTrackSize
.x
= UserGetSystemMetrics(SM_CXMINTRACK
);
1117 MinMax
.ptMinTrackSize
.y
= UserGetSystemMetrics(SM_CYMINTRACK
);
1121 MinMax
.ptMinTrackSize
.x
= 2 * xinc
;
1122 MinMax
.ptMinTrackSize
.y
= 2 * yinc
;
1124 MinMax
.ptMaxTrackSize
.x
= UserGetSystemMetrics(SM_CXMAXTRACK
);
1125 MinMax
.ptMaxTrackSize
.y
= UserGetSystemMetrics(SM_CYMAXTRACK
);
1126 MinMax
.ptMaxPosition
.x
= -xinc
;
1127 MinMax
.ptMaxPosition
.y
= -yinc
;
1129 if (!EMPTYPOINT(Window
->InternalPos
.MaxPos
)) MinMax
.ptMaxPosition
= Window
->InternalPos
.MaxPos
;
1131 co_IntSendMessage(Window
->head
.h
, WM_GETMINMAXINFO
, 0, (LPARAM
)&MinMax
);
1133 /* if the app didn't change the values, adapt them for the current monitor */
1134 if ((monitor
= UserGetPrimaryMonitor()))
1138 rc_work
= monitor
->rcMonitor
;
1140 if (style
& WS_MAXIMIZEBOX
)
1142 if ((style
& WS_CAPTION
) == WS_CAPTION
|| !(style
& (WS_CHILD
| WS_POPUP
)))
1143 rc_work
= monitor
->rcWork
;
1146 if (MinMax
.ptMaxSize
.x
== UserGetSystemMetrics(SM_CXSCREEN
) + 2 * xinc
&&
1147 MinMax
.ptMaxSize
.y
== UserGetSystemMetrics(SM_CYSCREEN
) + 2 * yinc
)
1149 MinMax
.ptMaxSize
.x
= (rc_work
.right
- rc_work
.left
) + 2 * xinc
;
1150 MinMax
.ptMaxSize
.y
= (rc_work
.bottom
- rc_work
.top
) + 2 * yinc
;
1152 if (MinMax
.ptMaxPosition
.x
== -xinc
&& MinMax
.ptMaxPosition
.y
== -yinc
)
1154 MinMax
.ptMaxPosition
.x
= rc_work
.left
- xinc
;
1155 MinMax
.ptMaxPosition
.y
= rc_work
.top
- yinc
;
1157 if (MinMax
.ptMaxSize
.x
>= (monitor
->rcMonitor
.right
- monitor
->rcMonitor
.left
) &&
1158 MinMax
.ptMaxSize
.y
>= (monitor
->rcMonitor
.bottom
- monitor
->rcMonitor
.top
) )
1159 Window
->state
|= WNDS_MAXIMIZESTOMONITOR
;
1161 Window
->state
&= ~WNDS_MAXIMIZESTOMONITOR
;
1165 MinMax
.ptMaxTrackSize
.x
= max(MinMax
.ptMaxTrackSize
.x
,
1166 MinMax
.ptMinTrackSize
.x
);
1167 MinMax
.ptMaxTrackSize
.y
= max(MinMax
.ptMaxTrackSize
.y
,
1168 MinMax
.ptMinTrackSize
.y
);
1171 *MaxSize
= MinMax
.ptMaxSize
;
1173 *MaxPos
= MinMax
.ptMaxPosition
;
1175 *MinTrack
= MinMax
.ptMinTrackSize
;
1177 *MaxTrack
= MinMax
.ptMaxTrackSize
;
1179 return 0; // FIXME: What does it return?
1184 IntValidateParent(PWND Child
, PREGION ValidateRgn
)
1186 PWND ParentWnd
= Child
;
1188 if (ParentWnd
->style
& WS_CHILD
)
1191 ParentWnd
= ParentWnd
->spwndParent
;
1192 while (ParentWnd
->style
& WS_CHILD
);
1195 ParentWnd
= Child
->spwndParent
;
1198 if (ParentWnd
->style
& WS_CLIPCHILDREN
)
1201 if (ParentWnd
->hrgnUpdate
!= 0)
1203 IntInvalidateWindows( ParentWnd
,
1205 RDW_VALIDATE
| RDW_NOCHILDREN
);
1208 ParentWnd
= ParentWnd
->spwndParent
;
1216 FixClientRect(PRECTL ClientRect
, PRECTL WindowRect
)
1218 if (ClientRect
->left
< WindowRect
->left
)
1220 ClientRect
->left
= WindowRect
->left
;
1222 else if (WindowRect
->right
< ClientRect
->left
)
1224 ClientRect
->left
= WindowRect
->right
;
1226 if (ClientRect
->right
< WindowRect
->left
)
1228 ClientRect
->right
= WindowRect
->left
;
1230 else if (WindowRect
->right
< ClientRect
->right
)
1232 ClientRect
->right
= WindowRect
->right
;
1234 if (ClientRect
->top
< WindowRect
->top
)
1236 ClientRect
->top
= WindowRect
->top
;
1238 else if (WindowRect
->bottom
< ClientRect
->top
)
1240 ClientRect
->top
= WindowRect
->bottom
;
1242 if (ClientRect
->bottom
< WindowRect
->top
)
1244 ClientRect
->bottom
= WindowRect
->top
;
1246 else if (WindowRect
->bottom
< ClientRect
->bottom
)
1248 ClientRect
->bottom
= WindowRect
->bottom
;
1251 /***********************************************************************
1254 * Compute the valid rects from the old and new client rect and WVR_* flags.
1255 * Helper for WM_NCCALCSIZE handling.
1259 get_valid_rects( RECTL
*old_client
, RECTL
*new_client
, UINT flags
, RECTL
*valid
)
1263 if (flags
& WVR_REDRAW
)
1265 RECTL_vSetEmptyRect( &valid
[0] );
1266 RECTL_vSetEmptyRect( &valid
[1] );
1270 if (flags
& WVR_VALIDRECTS
)
1272 if (!RECTL_bIntersectRect( &valid
[0], &valid
[0], new_client
) ||
1273 !RECTL_bIntersectRect( &valid
[1], &valid
[1], old_client
))
1275 RECTL_vSetEmptyRect( &valid
[0] );
1276 RECTL_vSetEmptyRect( &valid
[1] );
1279 flags
= WVR_ALIGNLEFT
| WVR_ALIGNTOP
;
1283 valid
[0] = *new_client
;
1284 valid
[1] = *old_client
;
1287 /* make sure the rectangles have the same size */
1288 cx
= min( valid
[0].right
- valid
[0].left
, valid
[1].right
- valid
[1].left
);
1289 cy
= min( valid
[0].bottom
- valid
[0].top
, valid
[1].bottom
- valid
[1].top
);
1291 if (flags
& WVR_ALIGNBOTTOM
)
1293 valid
[0].top
= valid
[0].bottom
- cy
;
1294 valid
[1].top
= valid
[1].bottom
- cy
;
1298 valid
[0].bottom
= valid
[0].top
+ cy
;
1299 valid
[1].bottom
= valid
[1].top
+ cy
;
1301 if (flags
& WVR_ALIGNRIGHT
)
1303 valid
[0].left
= valid
[0].right
- cx
;
1304 valid
[1].left
= valid
[1].right
- cx
;
1308 valid
[0].right
= valid
[0].left
+ cx
;
1309 valid
[1].right
= valid
[1].left
+ cx
;
1315 co_WinPosDoNCCALCSize(PWND Window
, PWINDOWPOS WinPos
, RECTL
* WindowRect
, RECTL
* ClientRect
, RECTL
* validRects
)
1320 ASSERT_REFS_CO(Window
);
1322 /* Send WM_NCCALCSIZE message to get new client area */
1323 if ((WinPos
->flags
& (SWP_FRAMECHANGED
| SWP_NOSIZE
)) != SWP_NOSIZE
)
1325 NCCALCSIZE_PARAMS params
;
1326 WINDOWPOS winposCopy
;
1328 params
.rgrc
[0] = *WindowRect
; // new coordinates of a window that has been moved or resized
1329 params
.rgrc
[1] = Window
->rcWindow
; // window before it was moved or resized
1330 params
.rgrc
[2] = Window
->rcClient
; // client area before the window was moved or resized
1332 Parent
= Window
->spwndParent
;
1333 if (0 != (Window
->style
& WS_CHILD
) && Parent
)
1335 RECTL_vOffsetRect(&(params
.rgrc
[0]), - Parent
->rcClient
.left
, - Parent
->rcClient
.top
);
1336 RECTL_vOffsetRect(&(params
.rgrc
[1]), - Parent
->rcClient
.left
, - Parent
->rcClient
.top
);
1337 RECTL_vOffsetRect(&(params
.rgrc
[2]), - Parent
->rcClient
.left
, - Parent
->rcClient
.top
);
1340 params
.lppos
= &winposCopy
;
1341 winposCopy
= *WinPos
;
1343 wvrFlags
= co_IntSendMessage(Window
->head
.h
, WM_NCCALCSIZE
, TRUE
, (LPARAM
) ¶ms
);
1345 /* If the application send back garbage, ignore it */
1346 if (params
.rgrc
[0].left
<= params
.rgrc
[0].right
&&
1347 params
.rgrc
[0].top
<= params
.rgrc
[0].bottom
)
1349 *ClientRect
= params
.rgrc
[0]; // First rectangle contains the coordinates of the new client rectangle resulting from the move or resize
1350 if ((Window
->style
& WS_CHILD
) && Parent
)
1352 RECTL_vOffsetRect(ClientRect
, Parent
->rcClient
.left
, Parent
->rcClient
.top
);
1354 FixClientRect(ClientRect
, WindowRect
);
1357 if (ClientRect
->left
!= Window
->rcClient
.left
||
1358 ClientRect
->top
!= Window
->rcClient
.top
)
1360 WinPos
->flags
&= ~SWP_NOCLIENTMOVE
;
1363 if (ClientRect
->right
- ClientRect
->left
!= Window
->rcClient
.right
- Window
->rcClient
.left
)
1365 WinPos
->flags
&= ~SWP_NOCLIENTSIZE
;
1368 wvrFlags
&= ~WVR_HREDRAW
;
1370 if (ClientRect
->bottom
- ClientRect
->top
!= Window
->rcClient
.bottom
- Window
->rcClient
.top
)
1372 WinPos
->flags
&= ~SWP_NOCLIENTSIZE
;
1375 wvrFlags
&= ~WVR_VREDRAW
;
1377 validRects
[0] = params
.rgrc
[1]; // second rectangle contains the valid destination rectangle
1378 validRects
[1] = params
.rgrc
[2]; // third rectangle contains the valid source rectangle
1382 if (!(WinPos
->flags
& SWP_NOMOVE
) &&
1383 (ClientRect
->left
!= Window
->rcClient
.left
||
1384 ClientRect
->top
!= Window
->rcClient
.top
))
1386 WinPos
->flags
&= ~SWP_NOCLIENTMOVE
;
1390 if (WinPos
->flags
& (SWP_NOCOPYBITS
| SWP_NOREDRAW
| SWP_SHOWWINDOW
| SWP_HIDEWINDOW
))
1392 RECTL_vSetEmptyRect( &validRects
[0] );
1393 RECTL_vSetEmptyRect( &validRects
[1] );
1395 else get_valid_rects( &Window
->rcClient
, ClientRect
, wvrFlags
, validRects
);
1402 co_WinPosDoWinPosChanging(PWND Window
,
1407 ASSERT_REFS_CO(Window
);
1409 /* Send WM_WINDOWPOSCHANGING message */
1411 if (!(WinPos
->flags
& SWP_NOSENDCHANGING
))
1413 TRACE("Sending WM_WINDOWPOSCHANGING to hwnd %p flags %04x.\n", Window
->head
.h
,WinPos
->flags
);
1414 co_IntSendMessage(Window
->head
.h
, WM_WINDOWPOSCHANGING
, 0, (LPARAM
) WinPos
);
1417 /* Calculate new position and size */
1419 *WindowRect
= Window
->rcWindow
;
1420 *ClientRect
= (Window
->style
& WS_MINIMIZE
) ? Window
->rcWindow
: Window
->rcClient
;
1422 if (!(WinPos
->flags
& SWP_NOSIZE
))
1424 if (Window
->style
& WS_MINIMIZE
)
1426 WindowRect
->right
= WindowRect
->left
+ UserGetSystemMetrics(SM_CXMINIMIZED
);
1427 WindowRect
->bottom
= WindowRect
->top
+ UserGetSystemMetrics(SM_CYMINIMIZED
);
1431 WindowRect
->right
= WindowRect
->left
+ WinPos
->cx
;
1432 WindowRect
->bottom
= WindowRect
->top
+ WinPos
->cy
;
1436 if (!(WinPos
->flags
& SWP_NOMOVE
))
1443 Parent
= Window
->spwndParent
;
1445 // Parent child position issue is in here. SetParent_W7 test CORE-6651.
1446 if (//((Window->style & WS_CHILD) != 0) && <- Fixes wine msg test_SetParent: "rects do not match", the last test.
1448 Parent
!= Window
->head
.rpdesk
->pDeskInfo
->spwnd
)
1450 TRACE("Not SWP_NOMOVE 1 Parent client offset X %d Y %d\n",X
,Y
);
1451 X
+= Parent
->rcClient
.left
;
1452 Y
+= Parent
->rcClient
.top
;
1453 TRACE("Not SWP_NOMOVE 2 Parent client offset X %d Y %d\n",X
,Y
);
1456 WindowRect
->left
= X
;
1457 WindowRect
->top
= Y
;
1458 WindowRect
->right
+= X
- Window
->rcWindow
.left
;
1459 WindowRect
->bottom
+= Y
- Window
->rcWindow
.top
;
1461 RECTL_vOffsetRect(ClientRect
, X
- Window
->rcWindow
.left
,
1462 Y
- Window
->rcWindow
.top
);
1464 WinPos
->flags
|= SWP_NOCLIENTMOVE
| SWP_NOCLIENTSIZE
;
1466 TRACE( "hwnd %p, after %p, swp %d,%d %dx%d flags %08x\n",
1467 WinPos
->hwnd
, WinPos
->hwndInsertAfter
, WinPos
->x
, WinPos
->y
,
1468 WinPos
->cx
, WinPos
->cy
, WinPos
->flags
);
1469 TRACE("WindowRect: %d %d %d %d\n", WindowRect
->left
,WindowRect
->top
,WindowRect
->right
,WindowRect
->bottom
);
1470 TRACE("ClientRect: %d %d %d %d\n", ClientRect
->left
,ClientRect
->top
,ClientRect
->right
,ClientRect
->bottom
);
1476 * Fix Z order taking into account owned popups -
1477 * basically we need to maintain them above the window that owns them
1479 * FIXME: hide/show owned popups when owner visibility changes.
1481 * ReactOS: See bug CORE-6129 and CORE-6554.
1485 // Pass all the win:test_children/popup_zorder tests except "move hwnd_F and its popups down" which is if'ed out.
1486 // Side effect, breaks more of the DeferWindowPos api tests, but wine breaks more!!!!
1489 WinPosDoOwnedPopups(PWND Window
, HWND hWndInsertAfter
)
1494 PWND DesktopWindow
, ChildObject
;
1497 TRACE("(%p) hInsertAfter = %p\n", Window
, hWndInsertAfter
);
1499 Style
= Window
->style
;
1501 if (Style
& WS_CHILD
)
1503 TRACE("Window is child\n");
1504 return hWndInsertAfter
;
1507 Owner
= Window
->spwndOwner
? Window
->spwndOwner
->head
.h
: NULL
;
1511 /* Make sure this popup stays above the owner */
1513 if (hWndInsertAfter
!= HWND_TOPMOST
)
1515 DesktopWindow
= UserGetDesktopWindow();
1516 List
= IntWinListChildren(DesktopWindow
);
1520 for (i
= 0; List
[i
]; i
++)
1522 BOOL topmost
= FALSE
;
1524 ChildObject
= ValidateHwndNoErr(List
[i
]);
1527 topmost
= (ChildObject
->ExStyle
& WS_EX_TOPMOST
) != 0;
1530 if (List
[i
] == Owner
)
1532 if (i
> 0) hWndInsertAfter
= List
[i
-1];
1533 else hWndInsertAfter
= topmost
? HWND_TOPMOST
: HWND_TOP
;
1537 if (hWndInsertAfter
== HWND_TOP
|| hWndInsertAfter
== HWND_NOTOPMOST
)
1539 if (!topmost
) break;
1541 else if (List
[i
] == hWndInsertAfter
) break;
1545 return hWndInsertAfter
;
1549 if (hWndInsertAfter
== HWND_BOTTOM
)
1551 ERR("Window is HWND_BOTTOM hwnd %p\n",hWndInsertAfter
);
1552 if (List
) ExFreePoolWithTag(List
, USERTAG_WINDOWLIST
);
1558 DesktopWindow
= UserGetDesktopWindow();
1559 List
= IntWinListChildren(DesktopWindow
);
1566 if (hWndInsertAfter
== HWND_TOP
|| hWndInsertAfter
== HWND_NOTOPMOST
)
1568 if (hWndInsertAfter
== HWND_NOTOPMOST
|| !(Window
->ExStyle
& WS_EX_TOPMOST
))
1570 TRACE("skip all the topmost windows\n");
1571 /* skip all the topmost windows */
1573 (ChildObject
= ValidateHwndNoErr(List
[i
])) &&
1574 (ChildObject
->ExStyle
& WS_EX_TOPMOST
)) i
++;
1577 else if (hWndInsertAfter
!= HWND_TOPMOST
)
1579 /* skip windows that are already placed correctly */
1580 for (i
= 0; List
[i
]; i
++)
1582 if (List
[i
] == hWndInsertAfter
) break;
1583 if (List
[i
] == UserHMGetHandle(Window
))
1585 ExFreePoolWithTag(List
, USERTAG_WINDOWLIST
);
1586 goto done
; /* nothing to do if window is moving backwards in z-order */
1591 for (; List
[i
]; i
++)
1594 USER_REFERENCE_ENTRY Ref
;
1596 if (List
[i
] == UserHMGetHandle(Window
))
1599 if (!(Wnd
= ValidateHwndNoErr(List
[i
])))
1602 Owner
= Wnd
->spwndOwner
? Wnd
->spwndOwner
->head
.h
: NULL
;
1604 if (Owner
!= UserHMGetHandle(Window
)) continue;
1606 UserRefObjectCo(Wnd
, &Ref
);
1607 TRACE( "moving %p owned by %p after %p\n", List
[i
], UserHMGetHandle(Window
), hWndInsertAfter
);
1608 co_WinPosSetWindowPos(Wnd
, hWndInsertAfter
, 0, 0, 0, 0,
1609 SWP_NOMOVE
| SWP_NOSIZE
| SWP_NOACTIVATE
| SWP_NOSENDCHANGING
| SWP_DEFERERASE
);
1611 UserDerefObjectCo(Wnd
);
1612 hWndInsertAfter
= List
[i
];
1614 ExFreePoolWithTag(List
, USERTAG_WINDOWLIST
);
1617 return hWndInsertAfter
;
1621 /***********************************************************************
1622 * WinPosInternalMoveWindow
1624 * Update WindowRect and ClientRect of Window and all of its children
1625 * We keep both WindowRect and ClientRect in screen coordinates internally
1629 WinPosInternalMoveWindow(PWND Window
, INT MoveX
, INT MoveY
)
1633 ASSERT(Window
!= Window
->spwndChild
);
1634 TRACE("InternalMoveWin X %d Y %d\n", MoveX
, MoveY
);
1636 Window
->rcWindow
.left
+= MoveX
;
1637 Window
->rcWindow
.right
+= MoveX
;
1638 Window
->rcWindow
.top
+= MoveY
;
1639 Window
->rcWindow
.bottom
+= MoveY
;
1641 Window
->rcClient
.left
+= MoveX
;
1642 Window
->rcClient
.right
+= MoveX
;
1643 Window
->rcClient
.top
+= MoveY
;
1644 Window
->rcClient
.bottom
+= MoveY
;
1646 for(Child
= Window
->spwndChild
; Child
; Child
= Child
->spwndNext
)
1648 WinPosInternalMoveWindow(Child
, MoveX
, MoveY
);
1653 * WinPosFixupSWPFlags
1655 * Fix redundant flags and values in the WINDOWPOS structure.
1659 WinPosFixupFlags(WINDOWPOS
*WinPos
, PWND Wnd
)
1664 /* Finally make sure that all coordinates are valid */
1665 if (WinPos
->x
< -32768) WinPos
->x
= -32768;
1666 else if (WinPos
->x
> 32767) WinPos
->x
= 32767;
1667 if (WinPos
->y
< -32768) WinPos
->y
= -32768;
1668 else if (WinPos
->y
> 32767) WinPos
->y
= 32767;
1670 WinPos
->cx
= max(WinPos
->cx
, 0);
1671 WinPos
->cy
= max(WinPos
->cy
, 0);
1673 Parent
= UserGetAncestor( Wnd
, GA_PARENT
);
1674 if (!IntIsWindowVisible( Parent
) &&
1675 /* Fix B : wine msg test_SetParent:WmSetParentSeq_2:25 wParam bits! */
1676 (WinPos
->flags
& SWP_AGG_STATUSFLAGS
) == SWP_AGG_NOPOSCHANGE
) WinPos
->flags
|= SWP_NOREDRAW
;
1678 if (Wnd
->style
& WS_VISIBLE
) WinPos
->flags
&= ~SWP_SHOWWINDOW
;
1681 WinPos
->flags
&= ~SWP_HIDEWINDOW
;
1682 if (!(WinPos
->flags
& SWP_SHOWWINDOW
)) WinPos
->flags
|= SWP_NOREDRAW
;
1685 /* Check for right size */
1686 if (Wnd
->rcWindow
.right
- Wnd
->rcWindow
.left
== WinPos
->cx
&&
1687 Wnd
->rcWindow
.bottom
- Wnd
->rcWindow
.top
== WinPos
->cy
)
1689 WinPos
->flags
|= SWP_NOSIZE
;
1694 IntClientToScreen( Parent
, &pt
);
1695 TRACE("WPFU C2S wpx %d wpy %d ptx %d pty %d\n",WinPos
->x
,WinPos
->y
,pt
.x
,pt
.y
);
1696 /* Check for right position */
1697 if (Wnd
->rcWindow
.left
== pt
.x
&& Wnd
->rcWindow
.top
== pt
.y
)
1699 //ERR("In right pos\n");
1700 WinPos
->flags
|= SWP_NOMOVE
;
1703 if ( WinPos
->hwnd
!= UserGetForegroundWindow() && (Wnd
->style
& (WS_POPUP
| WS_CHILD
)) != WS_CHILD
)
1705 /* Bring to the top when activating */
1706 if (!(WinPos
->flags
& (SWP_NOACTIVATE
|SWP_HIDEWINDOW
)) &&
1707 (WinPos
->flags
& SWP_NOZORDER
||
1708 (WinPos
->hwndInsertAfter
!= HWND_TOPMOST
&& WinPos
->hwndInsertAfter
!= HWND_NOTOPMOST
)))
1710 WinPos
->flags
&= ~SWP_NOZORDER
;
1711 WinPos
->hwndInsertAfter
= (0 != (Wnd
->ExStyle
& WS_EX_TOPMOST
) ? HWND_TOPMOST
: HWND_TOP
);
1715 /* Check hwndInsertAfter */
1716 if (!(WinPos
->flags
& SWP_NOZORDER
))
1718 /* Fix sign extension */
1719 if (WinPos
->hwndInsertAfter
== (HWND
)0xffff)
1721 WinPos
->hwndInsertAfter
= HWND_TOPMOST
;
1723 else if (WinPos
->hwndInsertAfter
== (HWND
)0xfffe)
1725 WinPos
->hwndInsertAfter
= HWND_NOTOPMOST
;
1728 if (WinPos
->hwndInsertAfter
== HWND_TOP
)
1730 /* Keep it topmost when it's already topmost */
1731 if ((Wnd
->ExStyle
& WS_EX_TOPMOST
) != 0)
1732 WinPos
->hwndInsertAfter
= HWND_TOPMOST
;
1734 if (IntGetWindow(WinPos
->hwnd
, GW_HWNDFIRST
) == WinPos
->hwnd
)
1736 WinPos
->flags
|= SWP_NOZORDER
;
1739 else if (WinPos
->hwndInsertAfter
== HWND_BOTTOM
)
1741 if (!(Wnd
->ExStyle
& WS_EX_TOPMOST
) && IntGetWindow(WinPos
->hwnd
, GW_HWNDLAST
) == WinPos
->hwnd
)
1742 WinPos
->flags
|= SWP_NOZORDER
;
1744 else if (WinPos
->hwndInsertAfter
== HWND_TOPMOST
)
1746 if ((Wnd
->ExStyle
& WS_EX_TOPMOST
) && IntGetWindow(WinPos
->hwnd
, GW_HWNDFIRST
) == WinPos
->hwnd
)
1747 WinPos
->flags
|= SWP_NOZORDER
;
1749 else if (WinPos
->hwndInsertAfter
== HWND_NOTOPMOST
)
1751 if (!(Wnd
->ExStyle
& WS_EX_TOPMOST
))
1752 WinPos
->flags
|= SWP_NOZORDER
;
1754 else /* hwndInsertAfter must be a sibling of the window */
1758 InsAfterWnd
= ValidateHwndNoErr(WinPos
->hwndInsertAfter
);
1764 if (InsAfterWnd
->spwndParent
!= Wnd
->spwndParent
)
1766 /* Note from wine User32 Win test_SetWindowPos:
1767 "Returns TRUE also for windows that are not siblings"
1768 "Does not seem to do anything even without passing flags, still returns TRUE"
1769 "Same thing the other way around."
1770 ".. and with these windows."
1777 * We don't need to change the Z order of hwnd if it's already
1778 * inserted after hwndInsertAfter or when inserting hwnd after
1781 if ((WinPos
->hwnd
== WinPos
->hwndInsertAfter
) ||
1782 ((InsAfterWnd
->spwndNext
) && (WinPos
->hwnd
== InsAfterWnd
->spwndNext
->head
.h
)))
1784 WinPos
->flags
|= SWP_NOZORDER
;
1793 /* x and y are always screen relative */
1795 co_WinPosSetWindowPos(
1797 HWND WndInsertAfter
,
1806 RECTL NewWindowRect
;
1807 RECTL NewClientRect
;
1808 RECTL valid_rects
[2];
1809 PREGION VisBefore
= NULL
;
1810 PREGION VisBeforeJustClient
= NULL
;
1811 PREGION VisAfter
= NULL
;
1812 PREGION CopyRgn
= NULL
;
1814 RECTL OldWindowRect
, OldClientRect
;
1819 BOOL bPointerInWindow
, PosChanged
= FALSE
;
1820 //PTHREADINFO pti = PsGetCurrentThreadWin32Thread();
1822 ASSERT_REFS_CO(Window
);
1824 TRACE("pwnd %p, after %p, %d,%d (%dx%d), flags %s",
1825 Window
, WndInsertAfter
, x
, y
, cx
, cy
, flags
);
1827 dump_winpos_flags(flags
);
1830 /* FIXME: Get current active window from active queue. Why? since r2915. */
1832 bPointerInWindow
= IntPtInWindow(Window
, gpsi
->ptCursor
.x
, gpsi
->ptCursor
.y
);
1834 WinPos
.hwnd
= Window
->head
.h
;
1835 WinPos
.hwndInsertAfter
= WndInsertAfter
;
1840 WinPos
.flags
= flags
;
1842 if ( flags
& SWP_ASYNCWINDOWPOS
)
1845 PWINDOWPOS ppos
= ExAllocatePoolWithTag(PagedPool
, sizeof(WINDOWPOS
), USERTAG_SWP
);
1848 WinPos
.flags
&= ~SWP_ASYNCWINDOWPOS
; // Clear flag.
1850 /* Yes it's a pointer inside Win32k! */
1851 lRes
= co_IntSendMessageNoWait( WinPos
.hwnd
, WM_ASYNC_SETWINDOWPOS
, 0, (LPARAM
)ppos
);
1852 /* We handle this the same way as Event Hooks and Hooks. */
1855 ExFreePoolWithTag(ppos
, USERTAG_SWP
);
1863 co_WinPosDoWinPosChanging(Window
, &WinPos
, &NewWindowRect
, &NewClientRect
);
1865 /* Does the window still exist? */
1866 if (!IntIsWindow(WinPos
.hwnd
))
1868 TRACE("WinPosSetWindowPos: Invalid handle 0x%p!\n",WinPos
.hwnd
);
1869 EngSetLastError(ERROR_INVALID_WINDOW_HANDLE
);
1873 /* Fix up the flags. */
1874 if (!WinPosFixupFlags(&WinPos
, Window
))
1880 Ancestor
= UserGetAncestor(Window
, GA_PARENT
);
1881 if ( (WinPos
.flags
& (SWP_NOZORDER
| SWP_HIDEWINDOW
| SWP_SHOWWINDOW
)) != SWP_NOZORDER
&&
1882 Ancestor
&& Ancestor
->head
.h
== IntGetDesktopWindow() )
1884 WinPos
.hwndInsertAfter
= WinPosDoOwnedPopups(Window
, WinPos
.hwndInsertAfter
);
1887 if (!(WinPos
.flags
& SWP_NOREDRAW
))
1889 /* Compute the visible region before the window position is changed */
1890 if (!(WinPos
.flags
& SWP_SHOWWINDOW
) &&
1891 (WinPos
.flags
& (SWP_NOMOVE
| SWP_NOSIZE
| SWP_NOZORDER
|
1892 SWP_HIDEWINDOW
| SWP_FRAMECHANGED
)) !=
1893 (SWP_NOMOVE
| SWP_NOSIZE
| SWP_NOZORDER
))
1895 VisBefore
= VIS_ComputeVisibleRegion(Window
, FALSE
, FALSE
,
1896 (Window
->style
& WS_CLIPSIBLINGS
) ? TRUE
: FALSE
);
1898 if ( VisBefore
!= NULL
&&
1899 REGION_Complexity(VisBefore
) == NULLREGION
)
1901 REGION_Delete(VisBefore
);
1906 REGION_bOffsetRgn(VisBefore
, -Window
->rcWindow
.left
, -Window
->rcWindow
.top
);
1909 /* Calculate the non client area for resizes, as this is used in the copy region */
1910 if (!(WinPos
.flags
& SWP_NOSIZE
))
1912 VisBeforeJustClient
= VIS_ComputeVisibleRegion(Window
, TRUE
, FALSE
,
1913 (Window
->style
& WS_CLIPSIBLINGS
) ? TRUE
: FALSE
);
1915 if ( VisBeforeJustClient
!= NULL
&&
1916 REGION_Complexity(VisBeforeJustClient
) == NULLREGION
)
1918 REGION_Delete(VisBeforeJustClient
);
1919 VisBeforeJustClient
= NULL
;
1921 else if(VisBeforeJustClient
)
1923 REGION_bOffsetRgn(VisBeforeJustClient
, -Window
->rcWindow
.left
, -Window
->rcWindow
.top
);
1930 if (Window
->hrgnNewFrame
)
1932 SelectWindowRgn( Window
, Window
->hrgnNewFrame
); // Should be PSMWP->acvr->hrgnClip
1933 Window
->hrgnNewFrame
= NULL
;
1936 WvrFlags
= co_WinPosDoNCCALCSize(Window
, &WinPos
, &NewWindowRect
, &NewClientRect
, valid_rects
);
1938 // ERR("co_WinPosDoNCCALCSize returned 0x%x\n valid dest: %d %d %d %d\n valid src : %d %d %d %d\n", WvrFlags,
1939 // valid_rects[0].left,valid_rects[0].top,valid_rects[0].right,valid_rects[0].bottom,
1940 // valid_rects[1].left,valid_rects[1].top,valid_rects[1].right,valid_rects[1].bottom);
1942 /* Validate link windows. (also take into account shell window in hwndShellWindow) */
1943 if (!(WinPos
.flags
& SWP_NOZORDER
) && WinPos
.hwnd
!= UserGetShellWindow())
1945 IntLinkHwnd(Window
, WinPos
.hwndInsertAfter
);
1948 OldWindowRect
= Window
->rcWindow
;
1949 OldClientRect
= Window
->rcClient
;
1951 if (NewClientRect
.left
!= OldClientRect
.left
||
1952 NewClientRect
.top
!= OldClientRect
.top
)
1954 // Move child window if their parent is moved. Keep Child window relative to Parent...
1955 WinPosInternalMoveWindow(Window
,
1956 NewClientRect
.left
- OldClientRect
.left
,
1957 NewClientRect
.top
- OldClientRect
.top
);
1961 Window
->rcWindow
= NewWindowRect
;
1962 Window
->rcClient
= NewClientRect
;
1964 /* erase parent when hiding or resizing child */
1965 if (WinPos
.flags
& SWP_HIDEWINDOW
)
1967 /* Clear the update region */
1968 co_UserRedrawWindow( Window
,
1971 RDW_VALIDATE
| RDW_NOFRAME
| RDW_NOERASE
| RDW_NOINTERNALPAINT
| RDW_ALLCHILDREN
);
1973 if (Window
->spwndParent
== UserGetDesktopWindow())
1974 co_IntShellHookNotify(HSHELL_WINDOWDESTROYED
, (WPARAM
)Window
->head
.h
, 0);
1976 Window
->style
&= ~WS_VISIBLE
; //IntSetStyle( Window, 0, WS_VISIBLE );
1977 Window
->head
.pti
->cVisWindows
--;
1978 IntNotifyWinEvent(EVENT_OBJECT_HIDE
, Window
, OBJID_WINDOW
, CHILDID_SELF
, WEF_SETBYWNDPTI
);
1980 else if (WinPos
.flags
& SWP_SHOWWINDOW
)
1982 if (Window
->spwndParent
== UserGetDesktopWindow() &&
1983 Window
->spwndOwner
== NULL
&&
1984 (!(Window
->ExStyle
& WS_EX_TOOLWINDOW
) ||
1985 (Window
->ExStyle
& WS_EX_APPWINDOW
)))
1986 co_IntShellHookNotify(HSHELL_WINDOWCREATED
, (WPARAM
)Window
->head
.h
, 0);
1988 Window
->style
|= WS_VISIBLE
; //IntSetStyle( Window, WS_VISIBLE, 0 );
1989 Window
->head
.pti
->cVisWindows
++;
1990 IntNotifyWinEvent(EVENT_OBJECT_SHOW
, Window
, OBJID_WINDOW
, CHILDID_SELF
, WEF_SETBYWNDPTI
);
1993 if (Window
->hrgnUpdate
!= NULL
&& Window
->hrgnUpdate
!= HRGN_WINDOW
)
1995 NtGdiOffsetRgn(Window
->hrgnUpdate
,
1996 NewWindowRect
.left
- OldWindowRect
.left
,
1997 NewWindowRect
.top
- OldWindowRect
.top
);
2000 DceResetActiveDCEs(Window
); // For WS_VISIBLE changes.
2002 if (!(WinPos
.flags
& SWP_NOREDRAW
))
2004 /* Determine the new visible region */
2005 VisAfter
= VIS_ComputeVisibleRegion(Window
, FALSE
, FALSE
,
2006 (Window
->style
& WS_CLIPSIBLINGS
) ? TRUE
: FALSE
);
2008 if ( VisAfter
!= NULL
&&
2009 REGION_Complexity(VisAfter
) == NULLREGION
)
2011 REGION_Delete(VisAfter
);
2016 REGION_bOffsetRgn(VisAfter
, -Window
->rcWindow
.left
, -Window
->rcWindow
.top
);
2020 * Determine which pixels can be copied from the old window position
2021 * to the new. Those pixels must be visible in both the old and new
2022 * position. Also, check the class style to see if the windows of this
2023 * class need to be completely repainted on (horizontal/vertical) size
2026 if ( ( VisBefore
!= NULL
&&
2028 !(WinPos
.flags
& SWP_NOCOPYBITS
) &&
2029 ((WinPos
.flags
& SWP_NOSIZE
) || !(WvrFlags
& WVR_REDRAW
)) &&
2030 !(Window
->ExStyle
& WS_EX_TRANSPARENT
) ) ||
2031 ( !PosChanged
&& (WinPos
.flags
& SWP_FRAMECHANGED
) && VisBefore
) )
2035 * If this is (also) a window resize, the whole nonclient area
2036 * needs to be repainted. So we limit the copy to the client area,
2037 * 'cause there is no use in copying it (would possibly cause
2038 * "flashing" too). However, if the copy region is already empty,
2039 * we don't have to crop (can't take anything away from an empty
2043 CopyRgn
= IntSysCreateRectpRgn(0, 0, 0, 0);
2044 if (WinPos
.flags
& SWP_NOSIZE
)
2045 RgnType
= IntGdiCombineRgn(CopyRgn
, VisAfter
, VisBefore
, RGN_AND
);
2046 else if (VisBeforeJustClient
!= NULL
)
2048 RgnType
= IntGdiCombineRgn(CopyRgn
, VisAfter
, VisBeforeJustClient
, RGN_AND
);
2049 REGION_Delete(VisBeforeJustClient
);
2052 /* No use in copying bits which are in the update region. */
2053 if (Window
->hrgnUpdate
!= NULL
)
2055 PREGION RgnUpdate
= REGION_LockRgn(Window
->hrgnUpdate
);
2058 REGION_bOffsetRgn(CopyRgn
, NewWindowRect
.left
, NewWindowRect
.top
);
2059 IntGdiCombineRgn(CopyRgn
, CopyRgn
, RgnUpdate
, RGN_DIFF
);
2060 REGION_bOffsetRgn(CopyRgn
, -NewWindowRect
.left
, -NewWindowRect
.top
);
2061 REGION_UnlockRgn(RgnUpdate
);
2066 * Now, get the bounding box of the copy region. If it's empty
2067 * there's nothing to copy. Also, it's no use copying bits onto
2070 if (REGION_GetRgnBox(CopyRgn
, &CopyRect
) == NULLREGION
)
2072 /* Nothing to copy, clean up */
2073 REGION_Delete(CopyRgn
);
2076 else if ( OldWindowRect
.left
!= NewWindowRect
.left
||
2077 OldWindowRect
.top
!= NewWindowRect
.top
||
2078 (WinPos
.flags
& SWP_FRAMECHANGED
) )
2080 HRGN DcRgn
= NtGdiCreateRectRgn(0, 0, 0, 0);
2081 PREGION DcRgnObj
= REGION_LockRgn(DcRgn
);
2084 * Small trick here: there is no function to bitblt a region. So
2085 * we set the region as the clipping region, take the bounding box
2086 * of the region and bitblt that. Since nothing outside the clipping
2087 * region is copied, this has the effect of bitblt'ing the region.
2089 * Since NtUserGetDCEx takes ownership of the clip region, we need
2090 * to create a copy of CopyRgn and pass that. We need CopyRgn later
2092 IntGdiCombineRgn(DcRgnObj
, CopyRgn
, NULL
, RGN_COPY
);
2093 REGION_bOffsetRgn(DcRgnObj
, NewWindowRect
.left
, NewWindowRect
.top
);
2094 REGION_UnlockRgn(DcRgnObj
);
2095 Dc
= UserGetDCEx( Window
,
2097 DCX_WINDOW
|DCX_CACHE
|DCX_INTERSECTRGN
|DCX_CLIPSIBLINGS
|DCX_KEEPCLIPRGN
);
2099 CopyRect
.left
, CopyRect
.top
,
2100 CopyRect
.right
- CopyRect
.left
,
2101 CopyRect
.bottom
- CopyRect
.top
,
2103 CopyRect
.left
+ (OldWindowRect
.left
- NewWindowRect
.left
),
2104 CopyRect
.top
+ (OldWindowRect
.top
- NewWindowRect
.top
),
2109 UserReleaseDC(Window
, Dc
, FALSE
);
2110 IntValidateParent(Window
, CopyRgn
);
2111 GreDeleteObject(DcRgn
);
2119 /////// Fixes NoPopup tests but breaks msg_paint tests.
2120 if ( !PosChanged
&& (WinPos
.flags
& SWP_FRAMECHANGED
) && VisBefore
)
2122 PWND Parent
= Window
->spwndParent
;
2123 ERR("SWP_FRAMECHANGED no chg\n");
2124 if ( !(Window
->style
& WS_CHILD
) && (Parent
) && (Parent
->style
& WS_CLIPCHILDREN
))
2126 ERR("SWP_FRAMECHANGED Parent WS_CLIPCHILDREN\n");
2127 //IntInvalidateWindows( Window, VisBefore, /*RDW_ERASE |*/ RDW_FRAME | RDW_INVALIDATE | RDW_ALLCHILDREN);
2131 /* We need to redraw what wasn't visible before */
2132 if (VisAfter
!= NULL
)
2134 PREGION DirtyRgn
= IntSysCreateRectpRgn(0, 0, 0, 0);
2137 if (CopyRgn
!= NULL
)
2139 RgnType
= IntGdiCombineRgn(DirtyRgn
, VisAfter
, CopyRgn
, RGN_DIFF
);
2143 RgnType
= IntGdiCombineRgn(DirtyRgn
, VisAfter
, 0, RGN_COPY
);
2146 if (RgnType
!= ERROR
&& RgnType
!= NULLREGION
)
2149 NtGdiOffsetRgn(DirtyRgn, Window->rcWindow.left, Window->rcWindow.top);
2150 IntInvalidateWindows( Window,
2152 RDW_ERASE | RDW_FRAME | RDW_INVALIDATE | RDW_ALLCHILDREN);
2154 GreDeleteObject(DirtyRgn);
2157 PWND Parent
= Window
->spwndParent
;
2159 REGION_bOffsetRgn( DirtyRgn
, Window
->rcWindow
.left
, Window
->rcWindow
.top
);
2161 if ( (Window
->style
& WS_CHILD
) && (Parent
) && !(Parent
->style
& WS_CLIPCHILDREN
))
2163 IntInvalidateWindows( Parent
, DirtyRgn
, RDW_ERASE
| RDW_INVALIDATE
);
2164 co_IntPaintWindows(Parent
, RDW_NOCHILDREN
, FALSE
);
2168 IntInvalidateWindows( Window
, DirtyRgn
, RDW_ERASE
| RDW_FRAME
| RDW_INVALIDATE
| RDW_ALLCHILDREN
);
2171 REGION_Delete(DirtyRgn
);
2175 if (CopyRgn
!= NULL
)
2177 REGION_Delete(CopyRgn
);
2180 /* Expose what was covered before but not covered anymore */
2181 if (VisBefore
!= NULL
)
2183 PREGION ExposedRgn
= IntSysCreateRectpRgn(0, 0, 0, 0);
2186 RgnType
= IntGdiCombineRgn(ExposedRgn
, VisBefore
, NULL
, RGN_COPY
);
2187 REGION_bOffsetRgn(ExposedRgn
,
2188 OldWindowRect
.left
- NewWindowRect
.left
,
2189 OldWindowRect
.top
- NewWindowRect
.top
);
2191 if (VisAfter
!= NULL
)
2192 RgnType
= IntGdiCombineRgn(ExposedRgn
, ExposedRgn
, VisAfter
, RGN_DIFF
);
2194 if (RgnType
!= ERROR
&& RgnType
!= NULLREGION
)
2196 co_VIS_WindowLayoutChanged(Window
, ExposedRgn
);
2198 REGION_Delete(ExposedRgn
);
2200 REGION_Delete(VisBefore
);
2203 if (VisAfter
!= NULL
)
2205 REGION_Delete(VisAfter
);
2209 if (!(WinPos
.flags
& (SWP_NOACTIVATE
|SWP_HIDEWINDOW
)))
2211 if ((Window
->style
& (WS_CHILD
| WS_POPUP
)) == WS_CHILD
)
2213 co_IntSendMessageNoWait(WinPos
.hwnd
, WM_CHILDACTIVATE
, 0, 0);
2217 //ERR("SetWindowPos Set FG Window!\n");
2218 if (Window
->state
& WNDS_BEINGACTIVATED
) // Inside SAW?
2219 co_IntSetActiveWindow(Window
, FALSE
, TRUE
, FALSE
); // Fixes Api AttachThreadInput tests.
2221 co_IntSetForegroundWindow(Window
); // Fixes SW_HIDE issues. Wine win test_SetActiveWindow & test_SetForegroundWindow.
2226 (WinPos
.flags
& SWP_FRAMECHANGED
) &&
2227 !(WinPos
.flags
& SWP_DEFERERASE
) && // Prevent sending WM_SYNCPAINT message.
2230 PWND Parent
= Window
->spwndParent
;
2231 if ( !(Window
->style
& WS_CHILD
) && (Parent
) && (Parent
->style
& WS_CLIPCHILDREN
))
2233 TRACE("SWP_FRAMECHANGED Parent WS_CLIPCHILDREN\n");
2234 UserSyncAndPaintWindows( Parent
, RDW_CLIPCHILDREN
);
2238 // Fix wine msg test_SetFocus, prevents sending WM_WINDOWPOSCHANGED.
2239 if ( VisBefore
== NULL
&&
2240 VisBeforeJustClient
== NULL
&&
2241 !(Window
->ExStyle
& WS_EX_TOPMOST
) &&
2242 (WinPos
.flags
& SWP_AGG_STATUSFLAGS
) == (SWP_AGG_NOPOSCHANGE
& ~SWP_NOZORDER
))
2244 TRACE("No drawing, set no Z order and no redraw!\n");
2245 WinPos
.flags
|= SWP_NOZORDER
|SWP_NOREDRAW
;
2248 /* And last, send the WM_WINDOWPOSCHANGED message */
2250 TRACE("\tstatus hwnd %p flags = %04x\n",Window
?Window
->head
.h
:NULL
,WinPos
.flags
& SWP_AGG_STATUSFLAGS
);
2252 if ((WinPos
.flags
& SWP_AGG_STATUSFLAGS
) != SWP_AGG_NOPOSCHANGE
)
2254 /* WM_WINDOWPOSCHANGED is sent even if SWP_NOSENDCHANGING is set
2255 and always contains final window position.
2257 WinPos
.x
= NewWindowRect
.left
;
2258 WinPos
.y
= NewWindowRect
.top
;
2259 WinPos
.cx
= NewWindowRect
.right
- NewWindowRect
.left
;
2260 WinPos
.cy
= NewWindowRect
.bottom
- NewWindowRect
.top
;
2261 TRACE("WM_WINDOWPOSCHANGED hwnd %p Flags %04x\n",WinPos
.hwnd
,WinPos
.flags
);
2262 co_IntSendMessageNoWait(WinPos
.hwnd
, WM_WINDOWPOSCHANGED
, 0, (LPARAM
) &WinPos
);
2265 if ( WinPos
.flags
& SWP_FRAMECHANGED
|| WinPos
.flags
& SWP_STATECHANGED
||
2266 !(WinPos
.flags
& SWP_NOCLIENTSIZE
) || !(WinPos
.flags
& SWP_NOCLIENTMOVE
) )
2268 PWND pWnd
= ValidateHwndNoErr(WinPos
.hwnd
);
2270 IntNotifyWinEvent(EVENT_OBJECT_LOCATIONCHANGE
, pWnd
, OBJID_WINDOW
, CHILDID_SELF
, WEF_SETBYWNDPTI
);
2273 if(bPointerInWindow
!= IntPtInWindow(Window
, gpsi
->ptCursor
.x
, gpsi
->ptCursor
.y
))
2275 /* Generate mouse move message */
2277 msg
.message
= WM_MOUSEMOVE
;
2278 msg
.wParam
= UserGetMouseButtonsState();
2279 msg
.lParam
= MAKELPARAM(gpsi
->ptCursor
.x
, gpsi
->ptCursor
.y
);
2280 msg
.pt
= gpsi
->ptCursor
;
2281 co_MsqInsertMouseMessage(&msg
, 0, 0, TRUE
);
2288 co_WinPosGetNonClientSize(PWND Window
, RECT
* WindowRect
, RECT
* ClientRect
)
2292 ASSERT_REFS_CO(Window
);
2294 *ClientRect
= *WindowRect
;
2295 Result
= co_IntSendMessageNoWait(Window
->head
.h
, WM_NCCALCSIZE
, FALSE
, (LPARAM
) ClientRect
);
2297 FixClientRect(ClientRect
, WindowRect
);
2303 co_WinPosSendSizeMove(PWND Wnd
)
2307 WPARAM wParam
= SIZE_RESTORED
;
2309 IntGetClientRect(Wnd
, &Rect
);
2310 lParam
= MAKELONG(Rect
.right
-Rect
.left
, Rect
.bottom
-Rect
.top
);
2312 Wnd
->state
&= ~WNDS_SENDSIZEMOVEMSGS
;
2314 if (Wnd
->style
& WS_MAXIMIZE
)
2316 wParam
= SIZE_MAXIMIZED
;
2318 else if (Wnd
->style
& WS_MINIMIZE
)
2320 wParam
= SIZE_MINIMIZED
;
2324 co_IntSendMessageNoWait(UserHMGetHandle(Wnd
), WM_SIZE
, wParam
, lParam
);
2326 if (Wnd
->spwndParent
== UserGetDesktopWindow()) // Wnd->spwndParent->fnid == FNID_DESKTOP )
2327 lParam
= MAKELONG(Wnd
->rcClient
.left
, Wnd
->rcClient
.top
);
2329 lParam
= MAKELONG(Wnd
->rcClient
.left
-Wnd
->spwndParent
->rcClient
.left
, Wnd
->rcClient
.top
-Wnd
->spwndParent
->rcClient
.top
);
2331 co_IntSendMessageNoWait(UserHMGetHandle(Wnd
), WM_MOVE
, 0, lParam
);
2333 IntEngWindowChanged(Wnd
, WOC_RGN_CLIENT
);
2337 ShowWindow does not set SWP_FRAMECHANGED!!! Fix wine msg test_SetParent:WmSetParentSeq_2:23 wParam bits!
2340 co_WinPosShowWindow(PWND Wnd
, INT Cmd
)
2343 UINT Swp
= 0, EventMsg
= 0;
2344 RECTL NewPos
= {0, 0, 0, 0};
2350 BOOL ShowOwned
= FALSE
;
2351 BOOL FirstTime
= FALSE
;
2352 ASSERT_REFS_CO(Wnd
);
2353 //KeRosDumpStackFrames(NULL, 20);
2354 pti
= PsGetCurrentThreadWin32Thread();
2355 WasVisible
= (Wnd
->style
& WS_VISIBLE
) != 0;
2358 TRACE("co_WinPosShowWindow START hwnd %p Cmd %d usicmd %u\n",
2359 Wnd
->head
.h
, Cmd
, pti
->ppi
->usi
.wShowWindow
);
2361 if ( pti
->ppi
->usi
.dwFlags
& STARTF_USESHOWWINDOW
)
2363 if ((Wnd
->style
& (WS_POPUP
|WS_CHILD
)) != WS_CHILD
)
2365 if ((Wnd
->style
& WS_CAPTION
) == WS_CAPTION
)
2367 if (Wnd
->spwndOwner
== NULL
)
2369 if ( Cmd
== SW_SHOWNORMAL
|| Cmd
== SW_SHOW
)
2371 Cmd
= SW_SHOWDEFAULT
;
2374 TRACE("co_WPSW FT 1\n");
2380 if ( Cmd
== SW_SHOWDEFAULT
)
2382 if ( pti
->ppi
->usi
.dwFlags
& STARTF_USESHOWWINDOW
)
2384 Cmd
= pti
->ppi
->usi
.wShowWindow
;
2386 TRACE("co_WPSW FT 2\n");
2392 pti
->ppi
->usi
.dwFlags
&= ~(STARTF_USEPOSITION
|STARTF_USESIZE
|STARTF_USESHOWWINDOW
);
2401 //ERR("co_WinPosShowWindow Exit Bad\n");
2404 Swp
|= SWP_HIDEWINDOW
| SWP_NOSIZE
| SWP_NOMOVE
;
2405 if (Wnd
!= pti
->MessageQueue
->spwndActive
)
2406 Swp
|= SWP_NOACTIVATE
| SWP_NOZORDER
;
2410 case SW_FORCEMINIMIZE
: /* FIXME: Does not work if thread is hung. */
2411 case SW_SHOWMINNOACTIVE
:
2412 Swp
|= SWP_NOACTIVATE
| SWP_NOZORDER
;
2414 case SW_SHOWMINIMIZED
:
2415 Swp
|= SWP_SHOWWINDOW
;
2419 Swp
|= SWP_NOACTIVATE
;
2420 if (!(style
& WS_MINIMIZE
))
2422 IntShowOwnedPopups(Wnd
, FALSE
);
2423 // Fix wine Win test_SetFocus todo #1 & #2,
2424 if (Cmd
== SW_SHOWMINIMIZED
)
2426 //ERR("co_WinPosShowWindow Set focus 1\n");
2427 if ((style
& (WS_CHILD
| WS_POPUP
)) == WS_CHILD
)
2428 co_UserSetFocus(Wnd
->spwndParent
);
2433 Swp
|= co_WinPosMinMaximize(Wnd
, Cmd
, &NewPos
);
2435 EventMsg
= EVENT_SYSTEM_MINIMIZESTART
;
2441 //ERR("co_WinPosShowWindow Exit Good\n");
2444 Swp
|= SWP_NOSIZE
| SWP_NOMOVE
;
2449 case SW_SHOWMAXIMIZED
:
2451 Swp
|= SWP_SHOWWINDOW
;
2452 if (!(style
& WS_MAXIMIZE
))
2456 Swp
|= co_WinPosMinMaximize(Wnd
, SW_MAXIMIZE
, &NewPos
);
2458 EventMsg
= EVENT_SYSTEM_MINIMIZEEND
;
2464 //ERR("co_WinPosShowWindow Exit Good 1\n");
2467 Swp
|= SWP_NOSIZE
| SWP_NOMOVE
;
2473 Swp
|= SWP_NOACTIVATE
| SWP_SHOWWINDOW
| SWP_NOSIZE
| SWP_NOMOVE
;
2474 if (style
& WS_CHILD
&& !(Wnd
->ExStyle
& WS_EX_MDICHILD
)) Swp
|= SWP_NOZORDER
;
2477 if (WasVisible
) return(TRUE
); // Nothing to do!
2478 Swp
|= SWP_SHOWWINDOW
| SWP_NOSIZE
| SWP_NOMOVE
;
2479 /* Don't activate the topmost window. */
2480 if (style
& WS_CHILD
&& !(Wnd
->ExStyle
& WS_EX_MDICHILD
)) Swp
|= SWP_NOACTIVATE
| SWP_NOZORDER
;
2483 case SW_SHOWNOACTIVATE
:
2484 Swp
|= SWP_NOACTIVATE
| SWP_NOZORDER
;
2487 case SW_SHOWDEFAULT
:
2489 if (!WasVisible
) Swp
|= SWP_SHOWWINDOW
;
2490 if (style
& (WS_MINIMIZE
| WS_MAXIMIZE
))
2492 Swp
|= co_WinPosMinMaximize(Wnd
, Cmd
, &NewPos
);
2493 if (style
& WS_MINIMIZE
) EventMsg
= EVENT_SYSTEM_MINIMIZEEND
;
2499 //ERR("co_WinPosShowWindow Exit Good 3\n");
2502 Swp
|= SWP_NOSIZE
| SWP_NOMOVE
;
2504 if ( style
& WS_CHILD
&&
2505 !(Wnd
->ExStyle
& WS_EX_MDICHILD
) &&
2506 !(Swp
& SWP_STATECHANGED
))
2507 Swp
|= SWP_NOACTIVATE
| SWP_NOZORDER
;
2511 //ERR("co_WinPosShowWindow Exit Good 4\n");
2515 ShowFlag
= (Cmd
!= SW_HIDE
);
2517 if ((ShowFlag
!= WasVisible
|| Cmd
== SW_SHOWNA
) && Cmd
!= SW_SHOWMAXIMIZED
&& !(Swp
& SWP_STATECHANGED
))
2519 co_IntSendMessageNoWait(Wnd
->head
.h
, WM_SHOWWINDOW
, ShowFlag
, 0);
2520 #if 0 // Fix wine msg test_SetParent:WmSetParentSeq_1:2
2521 if (!(Wnd
->state2
& WNDS2_WIN31COMPAT
)) // <------------- XP sets this bit!
2522 co_IntSendMessageNoWait(Wnd
->head
.h
, WM_SETVISIBLE
, ShowFlag
, 0);
2524 if (!VerifyWnd(Wnd
)) return WasVisible
;
2527 /* We can't activate a child window */
2528 if ((Wnd
->style
& WS_CHILD
) &&
2529 !(Wnd
->ExStyle
& WS_EX_MDICHILD
) &&
2532 //ERR("SWP Child No active and ZOrder\n");
2533 Swp
|= SWP_NOACTIVATE
| SWP_NOZORDER
;
2536 #if 0 // Explorer issues with common controls? Someone does not know how CS_SAVEBITS works.
2537 // Breaks startup and shutdown active window...
2538 if ((Wnd
->style
& (WS_POPUP
|WS_CHILD
)) != WS_CHILD
&&
2539 Wnd
->pcls
->style
& CS_SAVEBITS
&&
2540 ((Cmd
== SW_SHOW
) || (Cmd
== SW_NORMAL
)))
2542 ERR("WinPosShowWindow Set active\n");
2543 //UserSetActiveWindow(Wnd);
2544 co_IntSetForegroundWindow(Wnd
); // HACK
2545 Swp
|= SWP_NOACTIVATE
| SWP_NOZORDER
;
2549 if (IsChildVisible(Wnd
) || Swp
& SWP_STATECHANGED
)
2551 TRACE("Child is Vis %s or State changed %s. ShowFlag %s Swp %04x\n",
2552 (IsChildVisible(Wnd
) ? "TRUE" : "FALSE"), (Swp
& SWP_STATECHANGED
? "TRUE" : "FALSE"),
2553 (ShowFlag
? "TRUE" : "FALSE"),LOWORD(Swp
));
2554 co_WinPosSetWindowPos( Wnd
,
2555 0 != (Wnd
->ExStyle
& WS_EX_TOPMOST
) ? HWND_TOPMOST
: HWND_TOP
,
2558 NewPos
.right
, // NewPos.right - NewPos.left, when minimized and restore, the window becomes smaller.
2559 NewPos
.bottom
,// NewPos.bottom - NewPos.top,
2564 TRACE("Parent Vis?\n");
2565 /* if parent is not visible simply toggle WS_VISIBLE and return */
2566 if (ShowFlag
) IntSetStyle( Wnd
, WS_VISIBLE
, 0 );
2567 else IntSetStyle( Wnd
, 0, WS_VISIBLE
);
2570 if ( EventMsg
) IntNotifyWinEvent(EventMsg
, Wnd
, OBJID_WINDOW
, CHILDID_SELF
, WEF_SETBYWNDPTI
);
2572 if ( ShowOwned
) IntShowOwnedPopups(Wnd
, TRUE
);
2574 if ((Cmd
== SW_HIDE
) || (Cmd
== SW_MINIMIZE
))
2576 if ( Wnd
== pti
->MessageQueue
->spwndActive
&& pti
->MessageQueue
== IntGetFocusMessageQueue() )
2578 if ( Wnd
->spwndParent
== UserGetDesktopWindow())
2580 if (!ActivateOtherWindowMin(Wnd
))
2582 co_WinPosActivateOtherWindow(Wnd
);
2587 co_WinPosActivateOtherWindow(Wnd
);
2591 /* Revert focus to parent */
2592 if (Wnd
== pti
->MessageQueue
->spwndFocus
)
2594 Parent
= Wnd
->spwndParent
;
2595 if (Wnd
->spwndParent
== UserGetDesktopWindow()) Parent
= 0;
2596 co_UserSetFocus(Parent
);
2598 // Hide, just return.
2599 if (Cmd
== SW_HIDE
) return WasVisible
;
2602 /* FIXME: Check for window destruction. */
2604 if ((Wnd
->state
& WNDS_SENDSIZEMOVEMSGS
) &&
2605 !(Wnd
->state2
& WNDS2_INDESTROY
))
2607 co_WinPosSendSizeMove(Wnd
);
2610 /* if previous state was minimized Windows sets focus to the window */
2611 if (style
& WS_MINIMIZE
)
2613 co_UserSetFocus(Wnd
);
2614 // Fix wine Win test_SetFocus todo #3,
2615 if (!(style
& WS_CHILD
)) co_IntSendMessage(UserHMGetHandle(Wnd
), WM_ACTIVATE
, WA_ACTIVE
, 0);
2617 //ERR("co_WinPosShowWindow EXIT\n");
2622 co_WinPosSearchChildren(
2625 IN OUT USHORT
*HitTest
,
2630 PWND pwndChild
= NULL
;
2633 if (!(ScopeWin
->style
& WS_VISIBLE
))
2638 /* not in window or in window region */
2639 if (!IntPtInWindow(ScopeWin
, Point
->x
, Point
->y
))
2645 if ((ScopeWin
->ExStyle
& (WS_EX_LAYERED
|WS_EX_TRANSPARENT
)) == (WS_EX_LAYERED
|WS_EX_TRANSPARENT
))
2650 if (!Ignore
&& (ScopeWin
->style
& WS_DISABLED
))
2651 { /* disabled child */
2652 if ((ScopeWin
->style
& (WS_POPUP
|WS_CHILD
)) == WS_CHILD
) return NULL
;
2653 /* process the hit error */
2658 /* not minimized and check if point is inside the window */
2659 if (!(ScopeWin
->style
& WS_MINIMIZE
) &&
2660 RECTL_bPointInRect(&ScopeWin
->rcClient
, Point
->x
, Point
->y
) )
2662 UserReferenceObject(ScopeWin
);
2664 List
= IntWinListChildren(ScopeWin
);
2667 for (phWnd
= List
; *phWnd
; ++phWnd
)
2669 if (!(pwndChild
= ValidateHwndNoErr(*phWnd
)))
2674 pwndChild
= co_WinPosSearchChildren(pwndChild
, Point
, HitTest
, Ignore
);
2676 if (pwndChild
!= NULL
)
2678 /* We found a window. Don't send any more WM_NCHITTEST messages */
2679 ExFreePoolWithTag(List
, USERTAG_WINDOWLIST
);
2680 UserDereferenceObject(ScopeWin
);
2684 ExFreePoolWithTag(List
, USERTAG_WINDOWLIST
);
2686 UserDereferenceObject(ScopeWin
);
2689 if (ScopeWin
->head
.pti
== PsGetCurrentThreadWin32Thread())
2691 *HitTest
= (USHORT
)co_IntSendMessage(ScopeWin
->head
.h
, WM_NCHITTEST
, 0, MAKELONG(Point
->x
, Point
->y
));
2693 if ((*HitTest
) == (USHORT
)HTTRANSPARENT
)
2700 if (*HitTest
== HTNOWHERE
&& pwndChild
== NULL
) *HitTest
= HTCLIENT
;
2707 co_WinPosWindowFromPoint(
2710 IN OUT USHORT
* HitTest
,
2714 POINT Point
= *WinPoint
;
2715 USER_REFERENCE_ENTRY Ref
;
2717 if( ScopeWin
== NULL
)
2719 ScopeWin
= UserGetDesktopWindow();
2720 if(ScopeWin
== NULL
)
2724 *HitTest
= HTNOWHERE
;
2726 ASSERT_REFS_CO(ScopeWin
);
2727 UserRefObjectCo(ScopeWin
, &Ref
);
2729 Window
= co_WinPosSearchChildren(ScopeWin
, &Point
, HitTest
, Ignore
);
2731 UserDerefObjectCo(ScopeWin
);
2733 ASSERT_REFS_CO(Window
);
2734 ASSERT_REFS_CO(ScopeWin
);
2740 IntRealChildWindowFromPoint(PWND Parent
, LONG x
, LONG y
)
2744 PWND pwndHit
= NULL
;
2749 if (Parent
!= UserGetDesktopWindow())
2751 Pt
.x
+= Parent
->rcClient
.left
;
2752 Pt
.y
+= Parent
->rcClient
.top
;
2755 if (!IntPtInWindow(Parent
, Pt
.x
, Pt
.y
)) return NULL
;
2757 if ((List
= IntWinListChildren(Parent
)))
2759 for (phWnd
= List
; *phWnd
; phWnd
++)
2762 if ((Child
= ValidateHwndNoErr(*phWnd
)))
2764 if ( Child
->style
& WS_VISIBLE
&& IntPtInWindow(Child
, Pt
.x
, Pt
.y
) )
2766 if ( Child
->pcls
->atomClassName
!= gpsi
->atomSysClass
[ICLS_BUTTON
] ||
2767 (Child
->style
& BS_TYPEMASK
) != BS_GROUPBOX
)
2769 ExFreePoolWithTag(List
, USERTAG_WINDOWLIST
);
2776 ExFreePoolWithTag(List
, USERTAG_WINDOWLIST
);
2778 return pwndHit
? pwndHit
: Parent
;
2782 IntChildWindowFromPointEx(PWND Parent
, LONG x
, LONG y
, UINT uiFlags
)
2786 PWND pwndHit
= NULL
;
2791 if (Parent
!= UserGetDesktopWindow())
2793 if (Parent
->ExStyle
& WS_EX_LAYOUTRTL
)
2794 Pt
.x
= Parent
->rcClient
.right
- Pt
.x
;
2796 Pt
.x
+= Parent
->rcClient
.left
;
2797 Pt
.y
+= Parent
->rcClient
.top
;
2800 if (!IntPtInWindow(Parent
, Pt
.x
, Pt
.y
)) return NULL
;
2802 if ((List
= IntWinListChildren(Parent
)))
2804 for (phWnd
= List
; *phWnd
; phWnd
++)
2807 if ((Child
= ValidateHwndNoErr(*phWnd
)))
2809 if (uiFlags
& (CWP_SKIPINVISIBLE
|CWP_SKIPDISABLED
))
2811 if (!(Child
->style
& WS_VISIBLE
) && (uiFlags
& CWP_SKIPINVISIBLE
)) continue;
2812 if ((Child
->style
& WS_DISABLED
) && (uiFlags
& CWP_SKIPDISABLED
)) continue;
2815 if (uiFlags
& CWP_SKIPTRANSPARENT
)
2817 if (Child
->ExStyle
& WS_EX_TRANSPARENT
) continue;
2820 if (IntPtInWindow(Child
, Pt
.x
, Pt
.y
))
2827 ExFreePoolWithTag(List
, USERTAG_WINDOWLIST
);
2829 return pwndHit
? pwndHit
: Parent
;
2834 IntDeferWindowPos( HDWP hdwp
,
2845 HDWP retvalue
= hdwp
;
2847 TRACE("hdwp %p, hwnd %p, after %p, %d,%d (%dx%d), flags %08x\n",
2848 hdwp
, hwnd
, hwndAfter
, x
, y
, cx
, cy
, flags
);
2850 if (flags
& ~(SWP_NOSIZE
| SWP_NOMOVE
|
2851 SWP_NOZORDER
| SWP_NOREDRAW
|
2852 SWP_NOACTIVATE
| SWP_NOCOPYBITS
|
2853 SWP_NOOWNERZORDER
|SWP_SHOWWINDOW
|
2854 SWP_HIDEWINDOW
| SWP_FRAMECHANGED
))
2856 EngSetLastError(ERROR_INVALID_PARAMETER
);
2860 if (!(pDWP
= (PSMWP
)UserGetObject(gHandleTable
, hdwp
, TYPE_SETWINDOWPOS
)))
2862 EngSetLastError(ERROR_INVALID_DWP_HANDLE
);
2866 for (i
= 0; i
< pDWP
->ccvr
; i
++)
2868 if (pDWP
->acvr
[i
].pos
.hwnd
== hwnd
)
2870 /* Merge with the other changes */
2871 if (!(flags
& SWP_NOZORDER
))
2873 pDWP
->acvr
[i
].pos
.hwndInsertAfter
= hwndAfter
;
2875 if (!(flags
& SWP_NOMOVE
))
2877 pDWP
->acvr
[i
].pos
.x
= x
;
2878 pDWP
->acvr
[i
].pos
.y
= y
;
2880 if (!(flags
& SWP_NOSIZE
))
2882 pDWP
->acvr
[i
].pos
.cx
= cx
;
2883 pDWP
->acvr
[i
].pos
.cy
= cy
;
2885 pDWP
->acvr
[i
].pos
.flags
&= flags
| ~(SWP_NOSIZE
| SWP_NOMOVE
|
2886 SWP_NOZORDER
| SWP_NOREDRAW
|
2887 SWP_NOACTIVATE
| SWP_NOCOPYBITS
|
2889 pDWP
->acvr
[i
].pos
.flags
|= flags
& (SWP_SHOWWINDOW
| SWP_HIDEWINDOW
|
2894 if (pDWP
->ccvr
>= pDWP
->ccvrAlloc
)
2896 PCVR newpos
= ExAllocatePoolWithTag(PagedPool
, pDWP
->ccvrAlloc
* 2 * sizeof(CVR
), USERTAG_SWP
);
2902 RtlZeroMemory(newpos
, pDWP
->ccvrAlloc
* 2 * sizeof(CVR
));
2903 RtlCopyMemory(newpos
, pDWP
->acvr
, pDWP
->ccvrAlloc
* sizeof(CVR
));
2904 ExFreePoolWithTag(pDWP
->acvr
, USERTAG_SWP
);
2905 pDWP
->ccvrAlloc
*= 2;
2906 pDWP
->acvr
= newpos
;
2908 pDWP
->acvr
[pDWP
->ccvr
].pos
.hwnd
= hwnd
;
2909 pDWP
->acvr
[pDWP
->ccvr
].pos
.hwndInsertAfter
= hwndAfter
;
2910 pDWP
->acvr
[pDWP
->ccvr
].pos
.x
= x
;
2911 pDWP
->acvr
[pDWP
->ccvr
].pos
.y
= y
;
2912 pDWP
->acvr
[pDWP
->ccvr
].pos
.cx
= cx
;
2913 pDWP
->acvr
[pDWP
->ccvr
].pos
.cy
= cy
;
2914 pDWP
->acvr
[pDWP
->ccvr
].pos
.flags
= flags
;
2915 pDWP
->acvr
[pDWP
->ccvr
].hrgnClip
= NULL
;
2916 pDWP
->acvr
[pDWP
->ccvr
].hrgnInterMonitor
= NULL
;
2922 BOOL FASTCALL
IntEndDeferWindowPosEx( HDWP hdwp
, BOOL sAsync
)
2929 TRACE("%p\n", hdwp
);
2931 if (!(pDWP
= (PSMWP
)UserGetObject(gHandleTable
, hdwp
, TYPE_SETWINDOWPOS
)))
2933 EngSetLastError(ERROR_INVALID_DWP_HANDLE
);
2937 for (i
= 0, winpos
= pDWP
->acvr
; res
&& i
< pDWP
->ccvr
; i
++, winpos
++)
2940 USER_REFERENCE_ENTRY Ref
;
2942 TRACE("hwnd %p, after %p, %d,%d (%dx%d), flags %08x\n",
2943 winpos
->pos
.hwnd
, winpos
->pos
.hwndInsertAfter
, winpos
->pos
.x
, winpos
->pos
.y
,
2944 winpos
->pos
.cx
, winpos
->pos
.cy
, winpos
->pos
.flags
);
2946 pwnd
= ValidateHwndNoErr(winpos
->pos
.hwnd
);
2950 UserRefObjectCo(pwnd
, &Ref
);
2955 PWINDOWPOS ppos
= ExAllocatePoolWithTag(PagedPool
, sizeof(WINDOWPOS
), USERTAG_SWP
);
2958 *ppos
= winpos
->pos
;
2959 /* Yes it's a pointer inside Win32k! */
2960 lRes
= co_IntSendMessageNoWait( winpos
->pos
.hwnd
, WM_ASYNC_SETWINDOWPOS
, 0, (LPARAM
)ppos
);
2961 /* We handle this the same way as Event Hooks and Hooks. */
2964 ExFreePoolWithTag(ppos
, USERTAG_SWP
);
2969 res
= co_WinPosSetWindowPos( pwnd
,
2970 winpos
->pos
.hwndInsertAfter
,
2977 // Hack to pass tests.... Must have some work to do so clear the error.
2978 if (res
&& (winpos
->pos
.flags
& (SWP_NOMOVE
|SWP_NOSIZE
|SWP_NOZORDER
)) == SWP_NOZORDER
)
2979 EngSetLastError(ERROR_SUCCESS
);
2981 UserDerefObjectCo(pwnd
);
2983 ExFreePoolWithTag(pDWP
->acvr
, USERTAG_SWP
);
2984 UserDereferenceObject(pDWP
);
2985 UserDeleteObject(hdwp
, TYPE_SETWINDOWPOS
);
2993 NtUserChildWindowFromPointEx(HWND hwndParent
,
2999 TRACE("Enter NtUserChildWindowFromPointEx\n");
3000 UserEnterExclusive();
3001 if ((pwndParent
= UserGetWindowObject(hwndParent
)))
3003 pwndParent
= IntChildWindowFromPointEx(pwndParent
, x
, y
, uiFlags
);
3006 TRACE("Leave NtUserChildWindowFromPointEx\n");
3007 return pwndParent
? UserHMGetHandle(pwndParent
) : NULL
;
3014 NtUserEndDeferWindowPosEx(HDWP WinPosInfo
,
3018 TRACE("Enter NtUserEndDeferWindowPosEx\n");
3019 UserEnterExclusive();
3020 Ret
= IntEndDeferWindowPosEx(WinPosInfo
, (BOOL
)Unknown1
);
3021 TRACE("Leave NtUserEndDeferWindowPosEx, ret=%i\n", Ret
);
3030 NtUserDeferWindowPos(HDWP WinPosInfo
,
3032 HWND WndInsertAfter
,
3041 UINT Tmp
= ~(SWP_ASYNCWINDOWPOS
|SWP_DEFERERASE
|SWP_NOSENDCHANGING
|SWP_NOREPOSITION
|
3042 SWP_NOCOPYBITS
|SWP_HIDEWINDOW
|SWP_SHOWWINDOW
|SWP_FRAMECHANGED
|
3043 SWP_NOACTIVATE
|SWP_NOREDRAW
|SWP_NOZORDER
|SWP_NOMOVE
|SWP_NOSIZE
);
3045 TRACE("Enter NtUserDeferWindowPos\n");
3046 UserEnterExclusive();
3050 EngSetLastError(ERROR_INVALID_FLAGS
);
3054 pWnd
= UserGetWindowObject(Wnd
);
3055 if ( !pWnd
|| // FIXME:
3056 pWnd
== UserGetDesktopWindow() || // pWnd->fnid == FNID_DESKTOP
3057 pWnd
== UserGetMessageWindow() ) // pWnd->fnid == FNID_MESSAGEWND
3062 if ( WndInsertAfter
&&
3063 WndInsertAfter
!= HWND_BOTTOM
&&
3064 WndInsertAfter
!= HWND_TOPMOST
&&
3065 WndInsertAfter
!= HWND_NOTOPMOST
)
3067 pWndIA
= UserGetWindowObject(WndInsertAfter
);
3069 pWndIA
== UserGetDesktopWindow() ||
3070 pWndIA
== UserGetMessageWindow() )
3076 Ret
= IntDeferWindowPos(WinPosInfo
, Wnd
, WndInsertAfter
, x
, y
, cx
, cy
, Flags
);
3079 TRACE("Leave NtUserDeferWindowPos, ret=%p\n", Ret
);
3088 NtUserGetInternalWindowPos( HWND hWnd
,
3095 WINDOWPLACEMENT wndpl
;
3099 if (!(Window
= UserGetWindowObject(hWnd
)))
3109 ProbeForWrite(rectWnd
,
3115 ProbeForWrite(ptIcon
,
3121 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
3123 SetLastNtError(_SEH2_GetExceptionCode());
3128 wndpl
.length
= sizeof(WINDOWPLACEMENT
);
3130 if (IntGetWindowPlacement(Window
, &wndpl
) && !Hit
)
3136 RtlCopyMemory(rectWnd
, &wndpl
.rcNormalPosition
, sizeof(RECT
));
3140 RtlCopyMemory(ptIcon
, &wndpl
.ptMinPosition
, sizeof(POINT
));
3144 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
3146 SetLastNtError(_SEH2_GetExceptionCode());
3151 if (!Hit
) Ret
= wndpl
.showCmd
;
3162 NtUserGetWindowPlacement(HWND hWnd
,
3163 WINDOWPLACEMENT
*lpwndpl
)
3166 WINDOWPLACEMENT Safepl
;
3168 DECLARE_RETURN(BOOL
);
3170 TRACE("Enter NtUserGetWindowPlacement\n");
3173 if (!(Wnd
= UserGetWindowObject(hWnd
)))
3178 Status
= MmCopyFromCaller(&Safepl
, lpwndpl
, sizeof(WINDOWPLACEMENT
));
3179 if (!NT_SUCCESS(Status
))
3181 SetLastNtError(Status
);
3185 Safepl
.length
= sizeof(WINDOWPLACEMENT
);
3187 IntGetWindowPlacement(Wnd
, &Safepl
);
3189 Status
= MmCopyToCaller(lpwndpl
, &Safepl
, sizeof(WINDOWPLACEMENT
));
3190 if (!NT_SUCCESS(Status
))
3192 SetLastNtError(Status
);
3199 TRACE("Leave NtUserGetWindowPlacement, ret=%i\n",_ret_
);
3208 UINT cmd
, // Wine SW_ commands
3213 TRACE("Enter NtUserMinMaximize\n");
3214 UserEnterExclusive();
3216 pWnd
= UserGetWindowObject(hWnd
);
3217 if ( !pWnd
|| // FIXME:
3218 pWnd
== UserGetDesktopWindow() || // pWnd->fnid == FNID_DESKTOP
3219 pWnd
== UserGetMessageWindow() ) // pWnd->fnid == FNID_MESSAGEWND
3224 if ( cmd
> SW_MAX
|| pWnd
->state2
& WNDS2_INDESTROY
)
3226 EngSetLastError(ERROR_INVALID_PARAMETER
);
3230 cmd
|= Hide
? SW_HIDE
: 0;
3232 co_WinPosShowWindow(pWnd
, cmd
);
3235 TRACE("Leave NtUserMinMaximize\n");
3237 return 0; // Always NULL?
3252 return NtUserSetWindowPos(hWnd
, 0, X
, Y
, nWidth
, nHeight
,
3253 (bRepaint
? SWP_NOZORDER
| SWP_NOACTIVATE
:
3254 SWP_NOZORDER
| SWP_NOACTIVATE
| SWP_NOREDRAW
));
3261 NtUserRealChildWindowFromPoint(HWND Parent
,
3266 TRACE("Enter NtUserRealChildWindowFromPoint\n");
3268 if ((pwndParent
= UserGetWindowObject(Parent
)))
3270 pwndParent
= IntRealChildWindowFromPoint(pwndParent
, x
, y
);
3273 TRACE("Leave NtUserRealChildWindowFromPoint\n");
3274 return pwndParent
? UserHMGetHandle(pwndParent
) : NULL
;
3283 HWND hWndInsertAfter
,
3290 DECLARE_RETURN(BOOL
);
3291 PWND Window
, pWndIA
;
3293 USER_REFERENCE_ENTRY Ref
;
3295 TRACE("Enter NtUserSetWindowPos\n");
3296 UserEnterExclusive();
3298 if (!(Window
= UserGetWindowObject(hWnd
)) || // FIXME:
3299 Window
== UserGetDesktopWindow() || // pWnd->fnid == FNID_DESKTOP
3300 Window
== UserGetMessageWindow() ) // pWnd->fnid == FNID_MESSAGEWND
3302 ERR("NtUserSetWindowPos bad window handle!\n");
3306 if ( hWndInsertAfter
&&
3307 hWndInsertAfter
!= HWND_BOTTOM
&&
3308 hWndInsertAfter
!= HWND_TOPMOST
&&
3309 hWndInsertAfter
!= HWND_NOTOPMOST
)
3311 if (!(pWndIA
= UserGetWindowObject(hWndInsertAfter
)) ||
3312 pWndIA
== UserGetDesktopWindow() ||
3313 pWndIA
== UserGetMessageWindow() )
3315 ERR("NtUserSetWindowPos bad insert window handle!\n");
3320 /* First make sure that coordinates are valid for WM_WINDOWPOSCHANGING */
3321 if (!(uFlags
& SWP_NOMOVE
))
3323 if (X
< -32768) X
= -32768;
3324 else if (X
> 32767) X
= 32767;
3325 if (Y
< -32768) Y
= -32768;
3326 else if (Y
> 32767) Y
= 32767;
3328 if (!(uFlags
& SWP_NOSIZE
))
3331 else if (cx
> 32767) cx
= 32767;
3333 else if (cy
> 32767) cy
= 32767;
3336 UserRefObjectCo(Window
, &Ref
);
3337 ret
= co_WinPosSetWindowPos(Window
, hWndInsertAfter
, X
, Y
, cx
, cy
, uFlags
);
3338 UserDerefObjectCo(Window
);
3343 TRACE("Leave NtUserSetWindowPos, ret=%i\n",_ret_
);
3357 HRGN hrgnCopy
= NULL
;
3359 INT flags
= (SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
|SWP_NOACTIVATE
|SWP_FRAMECHANGED
|SWP_NOSIZE
|SWP_NOMOVE
);
3360 BOOLEAN Ret
= FALSE
;
3361 DECLARE_RETURN(INT
);
3363 TRACE("Enter NtUserSetWindowRgn\n");
3364 UserEnterExclusive();
3366 if (!(Window
= UserGetWindowObject(hWnd
)) || // FIXME:
3367 Window
== UserGetDesktopWindow() || // pWnd->fnid == FNID_DESKTOP
3368 Window
== UserGetMessageWindow() ) // pWnd->fnid == FNID_MESSAGEWND
3373 if (hRgn
) // The region will be deleted in user32.
3375 if (GreIsHandleValid(hRgn
))
3377 hrgnCopy
= NtGdiCreateRectRgn(0, 0, 0, 0);
3378 /* The coordinates of a window's window region are relative to the
3379 upper-left corner of the window, not the client area of the window. */
3380 NtGdiCombineRgn( hrgnCopy
, hRgn
, 0, RGN_COPY
);
3386 //// HACK 1 : Work around the lack of supporting DeferWindowPos.
3389 Window
->hrgnNewFrame
= hrgnCopy
; // Should be PSMWP->acvr->hrgnClip
3393 Window
->hrgnNewFrame
= HRGN_WINDOW
;
3396 Ret
= co_WinPosSetWindowPos(Window
, HWND_TOP
, 0, 0, 0, 0, bRedraw
? flags
: (flags
|SWP_NOREDRAW
) );
3401 TRACE("Leave NtUserSetWindowRgn, ret=%i\n",_ret_
);
3410 NtUserSetInternalWindowPos(
3416 WINDOWPLACEMENT wndpl
;
3421 DECLARE_RETURN(BOOL
);
3422 USER_REFERENCE_ENTRY Ref
;
3424 TRACE("Enter NtUserSetWindowPlacement\n");
3425 UserEnterExclusive();
3427 if (!(Wnd
= UserGetWindowObject(hwnd
)) || // FIXME:
3428 Wnd
== UserGetDesktopWindow() || // pWnd->fnid == FNID_DESKTOP
3429 Wnd
== UserGetMessageWindow() ) // pWnd->fnid == FNID_MESSAGEWND
3438 ProbeForRead(lppt
, sizeof(POINT
), 1);
3439 RtlCopyMemory(&pt
, lppt
, sizeof(POINT
));
3443 ProbeForRead(lprect
, sizeof(RECT
), 1);
3444 RtlCopyMemory(&rect
, lprect
, sizeof(RECT
));
3447 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
3449 SetLastNtError(_SEH2_GetExceptionCode());
3450 _SEH2_YIELD(RETURN( FALSE
));
3454 wndpl
.length
= sizeof(wndpl
);
3455 wndpl
.showCmd
= showCmd
;
3456 wndpl
.flags
= flags
= 0;
3461 wndpl
.flags
|= WPF_SETMINPOSITION
;
3462 wndpl
.ptMinPosition
= pt
;
3466 flags
|= PLACE_RECT
;
3467 wndpl
.rcNormalPosition
= rect
;
3470 UserRefObjectCo(Wnd
, &Ref
);
3471 IntSetWindowPlacement(Wnd
, &wndpl
, flags
);
3472 UserDerefObjectCo(Wnd
);
3476 TRACE("Leave NtUserSetWindowPlacement, ret=%i\n",_ret_
);
3485 NtUserSetWindowPlacement(HWND hWnd
,
3486 WINDOWPLACEMENT
*lpwndpl
)
3489 WINDOWPLACEMENT Safepl
;
3491 DECLARE_RETURN(BOOL
);
3492 USER_REFERENCE_ENTRY Ref
;
3494 TRACE("Enter NtUserSetWindowPlacement\n");
3495 UserEnterExclusive();
3497 if (!(Wnd
= UserGetWindowObject(hWnd
)) || // FIXME:
3498 Wnd
== UserGetDesktopWindow() || // pWnd->fnid == FNID_DESKTOP
3499 Wnd
== UserGetMessageWindow() ) // pWnd->fnid == FNID_MESSAGEWND
3506 ProbeForRead(lpwndpl
, sizeof(WINDOWPLACEMENT
), 1);
3507 RtlCopyMemory(&Safepl
, lpwndpl
, sizeof(WINDOWPLACEMENT
));
3509 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
3511 SetLastNtError(_SEH2_GetExceptionCode());
3512 _SEH2_YIELD(RETURN( FALSE
));
3516 if(Safepl
.length
!= sizeof(WINDOWPLACEMENT
))
3521 Flags
= PLACE_MAX
| PLACE_RECT
;
3522 if (Safepl
.flags
& WPF_SETMINPOSITION
) Flags
|= PLACE_MIN
;
3523 UserRefObjectCo(Wnd
, &Ref
);
3524 IntSetWindowPlacement(Wnd
, &Safepl
, Flags
);
3525 UserDerefObjectCo(Wnd
);
3529 TRACE("Leave NtUserSetWindowPlacement, ret=%i\n",_ret_
);
3538 NtUserShowWindowAsync(HWND hWnd
, LONG nCmdShow
)
3542 DECLARE_RETURN(BOOL
);
3543 USER_REFERENCE_ENTRY Ref
;
3545 TRACE("Enter NtUserShowWindowAsync\n");
3546 UserEnterExclusive();
3548 if (!(Window
= UserGetWindowObject(hWnd
)) || // FIXME:
3549 Window
== UserGetDesktopWindow() || // pWnd->fnid == FNID_DESKTOP
3550 Window
== UserGetMessageWindow() ) // pWnd->fnid == FNID_MESSAGEWND
3555 if ( nCmdShow
> SW_MAX
)
3557 EngSetLastError(ERROR_INVALID_PARAMETER
);
3561 UserRefObjectCo(Window
, &Ref
);
3562 ret
= co_IntSendMessageNoWait( hWnd
, WM_ASYNC_SHOWWINDOW
, nCmdShow
, 0 );
3563 UserDerefObjectCo(Window
);
3564 if (-1 == (int) ret
|| !ret
) ret
= FALSE
;
3569 TRACE("Leave NtUserShowWindowAsync, ret=%i\n",_ret_
);
3578 NtUserShowWindow(HWND hWnd
, LONG nCmdShow
)
3582 DECLARE_RETURN(BOOL
);
3583 USER_REFERENCE_ENTRY Ref
;
3585 TRACE("Enter NtUserShowWindow hWnd %p SW_ %d\n",hWnd
, nCmdShow
);
3586 UserEnterExclusive();
3588 if (!(Window
= UserGetWindowObject(hWnd
)) || // FIXME:
3589 Window
== UserGetDesktopWindow() || // pWnd->fnid == FNID_DESKTOP
3590 Window
== UserGetMessageWindow() ) // pWnd->fnid == FNID_MESSAGEWND
3595 if ( nCmdShow
> SW_MAX
|| Window
->state2
& WNDS2_INDESTROY
)
3597 EngSetLastError(ERROR_INVALID_PARAMETER
);
3601 UserRefObjectCo(Window
, &Ref
);
3602 ret
= co_WinPosShowWindow(Window
, nCmdShow
);
3603 UserDerefObjectCo(Window
);
3608 TRACE("Leave NtUserShowWindow, ret=%i\n",_ret_
);
3618 NtUserWindowFromPoint(LONG X
, LONG Y
)
3622 PWND DesktopWindow
= NULL
, Window
= NULL
;
3624 DECLARE_RETURN(HWND
);
3625 USER_REFERENCE_ENTRY Ref
;
3627 TRACE("Enter NtUserWindowFromPoint\n");
3628 UserEnterExclusive();
3630 if ((DesktopWindow
= UserGetWindowObject(IntGetDesktopWindow())))
3637 // Hmm... Threads live on desktops thus we have a reference on the desktop and indirectly the desktop window.
3638 // It is possible this referencing is useless, though it should not hurt...
3639 UserRefObjectCo(DesktopWindow
, &Ref
);
3641 //pti = PsGetCurrentThreadWin32Thread();
3642 Window
= co_WinPosWindowFromPoint(DesktopWindow
, &pt
, &hittest
, FALSE
);
3646 Ret
= UserHMGetHandle(Window
);
3655 if (DesktopWindow
) UserDerefObjectCo(DesktopWindow
);
3657 TRACE("Leave NtUserWindowFromPoint, ret=%p\n", _ret_
);