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 (!UserIsDesktopWindow(Wnd
))
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 (!UserIsDesktopWindow(Wnd
))
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
&& !UserIsDesktopWindow(FromWnd
))
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
&& !UserIsDesktopWindow(ToWnd
))
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 (!UserIsDesktopWindow(Window))
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 //ERR("WinPosActivateOtherWindow Set Focus Msg Q No window!\n");
405 IntSetFocusMessageQueue(NULL
);
409 /* If this is popup window, try to activate the owner first. */
410 if ((Wnd
->style
& WS_POPUP
) && (WndTo
= Wnd
->spwndOwner
))
412 TRACE("WPAOW Popup with Owner\n");
413 WndTo
= UserGetAncestor( WndTo
, GA_ROOT
);
414 if (can_activate_window(WndTo
)) goto done
;
417 /* Pick a next top-level window. */
418 /* FIXME: Search for non-tooltip windows first. */
422 if (!(WndTo
= WndTo
->spwndNext
)) break;
423 if (can_activate_window( WndTo
)) goto done
;
427 Fixes wine win.c:test_SetParent last ShowWindow test after popup dies.
428 Check for previous active window to bring to top.
432 WndTo
= Wnd
->head
.pti
->MessageQueue
->spwndActivePrev
;
433 if (can_activate_window( WndTo
)) goto done
;
436 // Find any window to bring to top. Works Okay for wine since it does not see X11 windows.
437 WndTo
= UserGetDesktopWindow();
438 WndTo
= WndTo
->spwndChild
;
441 //ERR("WinPosActivateOtherWindow No window!\n");
451 if (can_activate_window( WndTo
)) goto done
;
452 if (!(WndTo
= WndTo
->spwndNext
)) break;
456 if (WndTo
) UserRefObjectCo(WndTo
, &Ref
);
458 if (gpqForeground
&& (!gpqForeground
->spwndActive
|| Wnd
== gpqForeground
->spwndActive
))
460 /* ReactOS can pass WndTo = NULL to co_IntSetForegroundWindow and returns FALSE. */
461 //ERR("WinPosActivateOtherWindow Set FG 0x%p hWnd %p\n",WndTo, WndTo ? WndTo->head.h : 0);
462 if (co_IntSetForegroundWindow(WndTo
))
464 if (WndTo
) UserDerefObjectCo(WndTo
);
468 //ERR("WinPosActivateOtherWindow Set Active 0x%p\n",WndTo);
469 if (!UserSetActiveWindow(WndTo
)) /* Ok for WndTo to be NULL here */
471 //ERR("WPAOW SA 1\n");
472 UserSetActiveWindow(NULL
);
474 if (WndTo
) UserDerefObjectCo(WndTo
);
478 WinPosInitInternalPos(PWND Wnd
, RECTL
*RestoreRect
)
481 RECTL Rect
= *RestoreRect
;
483 if (Wnd
->spwndParent
&& !UserIsDesktopWindow(Wnd
->spwndParent
))
485 RECTL_vOffsetRect(&Rect
,
486 -Wnd
->spwndParent
->rcClient
.left
,
487 -Wnd
->spwndParent
->rcClient
.top
);
493 if (!Wnd
->InternalPosInitialized
)
495 // FIXME: Use check point Atom..
496 Wnd
->InternalPos
.flags
= 0;
497 Wnd
->InternalPos
.MaxPos
.x
= Wnd
->InternalPos
.MaxPos
.y
= -1;
498 Wnd
->InternalPos
.IconPos
.x
= Wnd
->InternalPos
.IconPos
.y
= -1;
499 Wnd
->InternalPos
.NormalRect
= Rect
;
500 Wnd
->InternalPosInitialized
= TRUE
;
503 if (Wnd
->style
& WS_MINIMIZE
)
505 Wnd
->InternalPos
.IconPos
= Size
;
506 Wnd
->InternalPos
.flags
|= WPF_MININIT
;
508 else if (Wnd
->style
& WS_MAXIMIZE
)
510 Wnd
->InternalPos
.flags
|= WPF_MAXINIT
;
512 if ( Wnd
->spwndParent
== Wnd
->head
.rpdesk
->pDeskInfo
->spwnd
)
514 if (Wnd
->state
& WNDS_MAXIMIZESTOMONITOR
)
516 Wnd
->InternalPos
.flags
&= ~WPF_MAXINIT
;
517 Wnd
->InternalPos
.MaxPos
.x
= Wnd
->InternalPos
.MaxPos
.y
= -1;
522 PMONITOR pmonitor
= UserMonitorFromRect(&Rect
, MONITOR_DEFAULTTOPRIMARY
);
523 // FIXME: support DPI aware, rcWorkDPI/Real etc..
524 WorkArea
= pmonitor
->rcMonitor
;
526 if (Wnd
->style
& WS_MAXIMIZEBOX
)
527 { // Support (Wnd->state & WNDS_HASCAPTION) || pmonitor->cFullScreen too.
528 if ((Wnd
->style
& WS_CAPTION
) == WS_CAPTION
|| !(Wnd
->style
& (WS_CHILD
| WS_POPUP
)))
530 WorkArea
= pmonitor
->rcWork
;
535 Wnd
->InternalPos
.MaxPos
.x
= Rect
.left
- WorkArea
.left
;
536 Wnd
->InternalPos
.MaxPos
.y
= Rect
.top
- WorkArea
.top
;
538 /*ERR("WinPosIP 2 X %d = R.l %d - W.l %d | Y %d = R.t %d - W.t %d\n",
539 Wnd->InternalPos.MaxPos.x,
540 Rect.left, WorkArea.left,
541 Wnd->InternalPos.MaxPos.y,
542 Rect.top, WorkArea.top);*/
546 Wnd
->InternalPos
.MaxPos
= Size
;
550 Wnd
->InternalPos
.NormalRect
= Rect
;
556 IntGetWindowPlacement(PWND Wnd
, WINDOWPLACEMENT
*lpwndpl
)
558 if (!Wnd
) return FALSE
;
560 if(lpwndpl
->length
!= sizeof(WINDOWPLACEMENT
))
567 WinPosInitInternalPos(Wnd
, &Wnd
->rcWindow
);
569 lpwndpl
->showCmd
= SW_HIDE
;
571 if ( Wnd
->style
& WS_MINIMIZE
)
572 lpwndpl
->showCmd
= SW_SHOWMINIMIZED
;
574 lpwndpl
->showCmd
= ( Wnd
->style
& WS_MAXIMIZE
) ? SW_SHOWMAXIMIZED
: SW_SHOWNORMAL
;
576 lpwndpl
->rcNormalPosition
= Wnd
->InternalPos
.NormalRect
;
578 if (Wnd
->InternalPos
.flags
& WPF_MININIT
) // Return if it was set!
580 lpwndpl
->ptMinPosition
.x
= Wnd
->InternalPos
.IconPos
.x
;
581 lpwndpl
->ptMinPosition
.y
= Wnd
->InternalPos
.IconPos
.y
;
584 lpwndpl
->ptMinPosition
.x
= lpwndpl
->ptMinPosition
.y
= -1;
586 if ( Wnd
->InternalPos
.flags
& WPF_MAXINIT
&& // Return if set and not maximized to monitor!
587 !(Wnd
->state
& WNDS_MAXIMIZESTOMONITOR
))
589 lpwndpl
->ptMaxPosition
.x
= Wnd
->InternalPos
.MaxPos
.x
;
590 lpwndpl
->ptMaxPosition
.y
= Wnd
->InternalPos
.MaxPos
.y
;
593 lpwndpl
->ptMaxPosition
.x
= lpwndpl
->ptMaxPosition
.y
= -1;
595 if ( Wnd
->spwndParent
== Wnd
->head
.rpdesk
->pDeskInfo
->spwnd
&&
596 !(Wnd
->ExStyle
& WS_EX_TOOLWINDOW
))
598 PMONITOR pmonitor
= UserMonitorFromRect(&lpwndpl
->rcNormalPosition
, MONITOR_DEFAULTTOPRIMARY
);
600 // FIXME: support DPI aware, rcWorkDPI/Real etc..
601 if (Wnd
->InternalPos
.flags
& WPF_MININIT
)
603 lpwndpl
->ptMinPosition
.x
-= (pmonitor
->rcWork
.left
- pmonitor
->rcMonitor
.left
);
604 lpwndpl
->ptMinPosition
.y
-= (pmonitor
->rcWork
.top
- pmonitor
->rcMonitor
.top
);
606 RECTL_vOffsetRect(&lpwndpl
->rcNormalPosition
,
607 pmonitor
->rcMonitor
.left
- pmonitor
->rcWork
.left
,
608 pmonitor
->rcMonitor
.top
- pmonitor
->rcWork
.top
);
611 if ( Wnd
->InternalPos
.flags
& WPF_RESTORETOMAXIMIZED
|| Wnd
->style
& WS_MAXIMIZE
)
612 lpwndpl
->flags
|= WPF_RESTORETOMAXIMIZED
;
614 if ( ((Wnd
->style
& (WS_CHILD
|WS_POPUP
)) == WS_CHILD
) && Wnd
->InternalPos
.flags
& WPF_SETMINPOSITION
)
615 lpwndpl
->flags
|= WPF_SETMINPOSITION
;
620 /* make sure the specified rect is visible on screen */
621 static void make_rect_onscreen( RECT
*rect
)
623 PMONITOR pmonitor
= UserMonitorFromRect( rect
, MONITOR_DEFAULTTONEAREST
); // Wine uses this.
625 // FIXME: support DPI aware, rcWorkDPI/Real etc..
626 if (!pmonitor
) return;
627 /* FIXME: map coordinates from rcWork to rcMonitor */
628 if (rect
->right
<= pmonitor
->rcWork
.left
)
630 rect
->right
+= pmonitor
->rcWork
.left
- rect
->left
;
631 rect
->left
= pmonitor
->rcWork
.left
;
633 else if (rect
->left
>= pmonitor
->rcWork
.right
)
635 rect
->left
+= pmonitor
->rcWork
.right
- rect
->right
;
636 rect
->right
= pmonitor
->rcWork
.right
;
638 if (rect
->bottom
<= pmonitor
->rcWork
.top
)
640 rect
->bottom
+= pmonitor
->rcWork
.top
- rect
->top
;
641 rect
->top
= pmonitor
->rcWork
.top
;
643 else if (rect
->top
>= pmonitor
->rcWork
.bottom
)
645 rect
->top
+= pmonitor
->rcWork
.bottom
- rect
->bottom
;
646 rect
->bottom
= pmonitor
->rcWork
.bottom
;
650 /* make sure the specified point is visible on screen */
651 static void make_point_onscreen( POINT
*pt
)
655 RECTL_vSetRect( &rect
, pt
->x
, pt
->y
, pt
->x
+ 1, pt
->y
+ 1 );
656 make_rect_onscreen( &rect
);
662 IntSetWindowPlacement(PWND Wnd
, WINDOWPLACEMENT
*wpl
, UINT Flags
)
667 if ( Flags
& PLACE_MIN
) make_point_onscreen( &wpl
->ptMinPosition
);
668 if ( Flags
& PLACE_MAX
) make_point_onscreen( &wpl
->ptMaxPosition
);
669 if ( Flags
& PLACE_RECT
) make_rect_onscreen( &wpl
->rcNormalPosition
);
671 if (!Wnd
|| Wnd
== Wnd
->head
.rpdesk
->pDeskInfo
->spwnd
) return FALSE
;
673 if ( Flags
& PLACE_MIN
) Wnd
->InternalPos
.IconPos
= wpl
->ptMinPosition
;
674 if ( Flags
& PLACE_MAX
) Wnd
->InternalPos
.MaxPos
= wpl
->ptMaxPosition
;
675 if ( Flags
& PLACE_RECT
) Wnd
->InternalPos
.NormalRect
= wpl
->rcNormalPosition
;
677 SWP_Flags
= SWP_NOZORDER
| SWP_NOACTIVATE
| ((wpl
->flags
& WPF_ASYNCWINDOWPLACEMENT
) ? SWP_ASYNCWINDOWPOS
: 0);
679 if (Wnd
->style
& WS_MINIMIZE
)
681 if (Flags
& PLACE_MIN
|| Wnd
->InternalPos
.flags
& WPF_SETMINPOSITION
)
683 co_WinPosSetWindowPos(Wnd
, HWND_TOP
,
684 wpl
->ptMinPosition
.x
, wpl
->ptMinPosition
.y
, 0, 0,
685 SWP_NOSIZE
| SWP_Flags
);
686 Wnd
->InternalPos
.flags
|= WPF_MININIT
;
689 else if (Wnd
->style
& WS_MAXIMIZE
)
691 if (Flags
& PLACE_MAX
)
693 co_WinPosSetWindowPos(Wnd
, HWND_TOP
,
694 wpl
->ptMaxPosition
.x
, wpl
->ptMaxPosition
.y
, 0, 0,
695 SWP_NOSIZE
| SWP_Flags
);
696 Wnd
->InternalPos
.flags
|= WPF_MAXINIT
;
699 else if (Flags
& PLACE_RECT
)
701 co_WinPosSetWindowPos(Wnd
, HWND_TOP
,
702 wpl
->rcNormalPosition
.left
, wpl
->rcNormalPosition
.top
,
703 wpl
->rcNormalPosition
.right
- wpl
->rcNormalPosition
.left
,
704 wpl
->rcNormalPosition
.bottom
- wpl
->rcNormalPosition
.top
,
708 sAsync
= (Wnd
->head
.pti
->MessageQueue
!= gptiCurrent
->MessageQueue
&& wpl
->flags
& WPF_ASYNCWINDOWPLACEMENT
);
711 co_IntSendMessageNoWait( UserHMGetHandle(Wnd
), WM_ASYNC_SHOWWINDOW
, wpl
->showCmd
, 0 );
713 co_WinPosShowWindow(Wnd
, wpl
->showCmd
);
715 if ( Wnd
->style
& WS_MINIMIZE
&& !sAsync
)
717 if ( wpl
->flags
& WPF_SETMINPOSITION
)
718 Wnd
->InternalPos
.flags
|= WPF_SETMINPOSITION
;
720 if ( wpl
->flags
& WPF_RESTORETOMAXIMIZED
)
721 Wnd
->InternalPos
.flags
|= WPF_RESTORETOMAXIMIZED
;
728 co_WinPosArrangeIconicWindows(PWND parent
)
732 INT x
, y
, xspacing
, yspacing
, sx
, sy
;
734 ASSERT_REFS_CO(parent
);
736 IntGetClientRect( parent
, &rectParent
);
737 // FIXME: Support Minimize Metrics gspv.mm.iArrange.
738 // Default: ARW_BOTTOMLEFT
740 y
= rectParent
.bottom
;
742 xspacing
= UserGetSystemMetrics(SM_CXMINIMIZED
);
743 yspacing
= UserGetSystemMetrics(SM_CYMINIMIZED
);
745 Child
= parent
->spwndChild
;
748 if((Child
->style
& WS_MINIMIZE
) != 0 )
750 USER_REFERENCE_ENTRY Ref
;
751 UserRefObjectCo(Child
, &Ref
);
753 sx
= x
+ UserGetSystemMetrics(SM_CXBORDER
);
754 sy
= y
- yspacing
- UserGetSystemMetrics(SM_CYBORDER
);
756 Child
->InternalPos
.IconPos
.x
= sx
;
757 Child
->InternalPos
.IconPos
.y
= sy
;
758 Child
->InternalPos
.flags
|= WPF_MININIT
;
760 co_WinPosSetWindowPos( Child
, 0, sx
, sy
, xspacing
, yspacing
, SWP_NOZORDER
| SWP_NOACTIVATE
| SWP_NOCOPYBITS
| SWP_ASYNCWINDOWPOS
);
762 UserDerefObjectCo(Child
);
764 if (x
<= rectParent
.right
- xspacing
)
772 Child
= Child
->spwndNext
;
778 WinPosFindIconPos(PWND Window
, POINT
*Pos
)
781 PWND pwndChild
, pwndParent
;
782 int x
, y
, xspacing
, yspacing
;
784 pwndParent
= Window
->spwndParent
;
785 if (UserIsDesktopWindow(pwndParent
))
787 ERR("FIXME: Parent is Desktop, Min off screen!\n");
788 /* FIXME: ReactOS doesn't support iconic minimize to desktop */
789 Pos
->x
= Pos
->y
= -32000;
790 Window
->InternalPos
.flags
|= WPF_MININIT
;
791 Window
->InternalPos
.IconPos
.x
= Pos
->x
;
792 Window
->InternalPos
.IconPos
.y
= Pos
->y
;
796 IntGetClientRect( pwndParent
, &rectParent
);
797 // FIXME: Support Minimize Metrics gspv.mm.iArrange.
798 // Default: ARW_BOTTOMLEFT
800 y
= rectParent
.bottom
;
802 xspacing
= UserGetSystemMetrics(SM_CXMINIMIZED
);
803 yspacing
= UserGetSystemMetrics(SM_CYMINIMIZED
);
805 // Set to default position when minimized.
806 Pos
->x
= x
+ UserGetSystemMetrics(SM_CXBORDER
);
807 Pos
->y
= y
- yspacing
- UserGetSystemMetrics(SM_CYBORDER
);
809 for (pwndChild
= pwndParent
->spwndChild
; pwndChild
; pwndChild
= pwndChild
->spwndNext
)
811 if (pwndChild
== Window
) continue;
813 if ((pwndChild
->style
& (WS_VISIBLE
|WS_MINIMIZE
)) != (WS_VISIBLE
|WS_MINIMIZE
) )
818 if ( pwndChild
->InternalPos
.IconPos
.x
!= Pos
->x
&& pwndChild
->InternalPos
.IconPos
.y
!= Pos
->y
)
822 if (x
<= rectParent
.right
- xspacing
)
829 Pos
->x
= x
+ UserGetSystemMetrics(SM_CXBORDER
);
830 Pos
->y
= y
- yspacing
- UserGetSystemMetrics(SM_CYBORDER
);
833 Window
->InternalPos
.IconPos
.x
= Pos
->x
;
834 Window
->InternalPos
.IconPos
.y
= Pos
->y
;
835 Window
->InternalPos
.flags
|= WPF_MININIT
;
836 TRACE("Position is set! X:%d Y:%d\n",Pos
->x
,Pos
->y
);
841 UserHasWindowEdge(DWORD Style
, DWORD ExStyle
)
843 if (Style
& WS_MINIMIZE
)
845 if (ExStyle
& WS_EX_DLGMODALFRAME
)
847 if (ExStyle
& WS_EX_STATICEDGE
)
849 if (Style
& WS_THICKFRAME
)
852 if (Style
== WS_DLGFRAME
|| Style
== WS_CAPTION
)
858 IntGetWindowBorderMeasures(PWND Wnd
, UINT
*cx
, UINT
*cy
)
860 if(HAS_DLGFRAME(Wnd
->style
, Wnd
->ExStyle
) && !(Wnd
->style
& WS_MINIMIZE
))
862 *cx
= UserGetSystemMetrics(SM_CXDLGFRAME
);
863 *cy
= UserGetSystemMetrics(SM_CYDLGFRAME
);
867 if(HAS_THICKFRAME(Wnd
->style
, Wnd
->ExStyle
)&& !(Wnd
->style
& WS_MINIMIZE
))
869 *cx
= UserGetSystemMetrics(SM_CXFRAME
);
870 *cy
= UserGetSystemMetrics(SM_CYFRAME
);
872 else if(HAS_THINFRAME(Wnd
->style
, Wnd
->ExStyle
))
874 *cx
= UserGetSystemMetrics(SM_CXBORDER
);
875 *cy
= UserGetSystemMetrics(SM_CYBORDER
);
885 UserGetWindowBorders(DWORD Style
, DWORD ExStyle
, SIZE
*Size
, BOOL WithClient
)
889 if (UserHasWindowEdge(Style
, ExStyle
))
891 else if (ExStyle
& WS_EX_STATICEDGE
)
893 if ((ExStyle
& WS_EX_CLIENTEDGE
) && WithClient
)
895 if (Style
& WS_CAPTION
|| ExStyle
& WS_EX_DLGMODALFRAME
)
897 Size
->cx
= Size
->cy
= Border
;
898 if ((Style
& WS_THICKFRAME
) && !(Style
& WS_MINIMIZE
))
900 Size
->cx
+= UserGetSystemMetrics(SM_CXFRAME
) - UserGetSystemMetrics(SM_CXDLGFRAME
);
901 Size
->cy
+= UserGetSystemMetrics(SM_CYFRAME
) - UserGetSystemMetrics(SM_CYDLGFRAME
);
903 Size
->cx
*= UserGetSystemMetrics(SM_CXBORDER
);
904 Size
->cy
*= UserGetSystemMetrics(SM_CYBORDER
);
908 UserAdjustWindowRectEx(LPRECT lpRect
,
917 lpRect
->top
-= UserGetSystemMetrics(SM_CYMENU
);
919 if ((dwStyle
& WS_CAPTION
) == WS_CAPTION
)
921 if (dwExStyle
& WS_EX_TOOLWINDOW
)
922 lpRect
->top
-= UserGetSystemMetrics(SM_CYSMCAPTION
);
924 lpRect
->top
-= UserGetSystemMetrics(SM_CYCAPTION
);
926 UserGetWindowBorders(dwStyle
, dwExStyle
, &BorderSize
, TRUE
);
936 co_WinPosGetMinMaxInfo(PWND Window
, POINT
* MaxSize
, POINT
* MaxPos
,
937 POINT
* MinTrack
, POINT
* MaxTrack
)
942 LONG style
= Window
->style
;
944 LONG exstyle
= Window
->ExStyle
;
947 ASSERT_REFS_CO(Window
);
949 /* Compute default values */
951 rc
= Window
->rcWindow
;
952 MinMax
.ptReserved
.x
= rc
.left
;
953 MinMax
.ptReserved
.y
= rc
.top
;
955 if ((style
& WS_CAPTION
) == WS_CAPTION
)
956 adjustedStyle
= style
& ~WS_BORDER
; /* WS_CAPTION = WS_DLGFRAME | WS_BORDER */
958 adjustedStyle
= style
;
960 if(Window
->spwndParent
)
961 IntGetClientRect(Window
->spwndParent
, &rc
);
962 UserAdjustWindowRectEx(&rc
, adjustedStyle
, ((style
& WS_POPUP
) && Window
->IDMenu
), exstyle
);
967 MinMax
.ptMaxSize
.x
= rc
.right
- rc
.left
;
968 MinMax
.ptMaxSize
.y
= rc
.bottom
- rc
.top
;
969 if (style
& (WS_DLGFRAME
| WS_BORDER
))
971 MinMax
.ptMinTrackSize
.x
= UserGetSystemMetrics(SM_CXMINTRACK
);
972 MinMax
.ptMinTrackSize
.y
= UserGetSystemMetrics(SM_CYMINTRACK
);
976 MinMax
.ptMinTrackSize
.x
= 2 * xinc
;
977 MinMax
.ptMinTrackSize
.y
= 2 * yinc
;
979 MinMax
.ptMaxTrackSize
.x
= UserGetSystemMetrics(SM_CXMAXTRACK
);
980 MinMax
.ptMaxTrackSize
.y
= UserGetSystemMetrics(SM_CYMAXTRACK
);
981 MinMax
.ptMaxPosition
.x
= -xinc
;
982 MinMax
.ptMaxPosition
.y
= -yinc
;
984 if (!EMPTYPOINT(Window
->InternalPos
.MaxPos
)) MinMax
.ptMaxPosition
= Window
->InternalPos
.MaxPos
;
986 co_IntSendMessage(Window
->head
.h
, WM_GETMINMAXINFO
, 0, (LPARAM
)&MinMax
);
988 /* if the app didn't change the values, adapt them for the current monitor */
989 if ((monitor
= UserGetPrimaryMonitor()))
993 rc_work
= monitor
->rcMonitor
;
995 if (style
& WS_MAXIMIZEBOX
)
997 if ((style
& WS_CAPTION
) == WS_CAPTION
|| !(style
& (WS_CHILD
| WS_POPUP
)))
998 rc_work
= monitor
->rcWork
;
1001 if (MinMax
.ptMaxSize
.x
== UserGetSystemMetrics(SM_CXSCREEN
) + 2 * xinc
&&
1002 MinMax
.ptMaxSize
.y
== UserGetSystemMetrics(SM_CYSCREEN
) + 2 * yinc
)
1004 MinMax
.ptMaxSize
.x
= (rc_work
.right
- rc_work
.left
) + 2 * xinc
;
1005 MinMax
.ptMaxSize
.y
= (rc_work
.bottom
- rc_work
.top
) + 2 * yinc
;
1007 if (MinMax
.ptMaxPosition
.x
== -xinc
&& MinMax
.ptMaxPosition
.y
== -yinc
)
1009 MinMax
.ptMaxPosition
.x
= rc_work
.left
- xinc
;
1010 MinMax
.ptMaxPosition
.y
= rc_work
.top
- yinc
;
1012 if (MinMax
.ptMaxSize
.x
>= (monitor
->rcMonitor
.right
- monitor
->rcMonitor
.left
) &&
1013 MinMax
.ptMaxSize
.y
>= (monitor
->rcMonitor
.bottom
- monitor
->rcMonitor
.top
) )
1014 Window
->state
|= WNDS_MAXIMIZESTOMONITOR
;
1016 Window
->state
&= ~WNDS_MAXIMIZESTOMONITOR
;
1020 MinMax
.ptMaxTrackSize
.x
= max(MinMax
.ptMaxTrackSize
.x
,
1021 MinMax
.ptMinTrackSize
.x
);
1022 MinMax
.ptMaxTrackSize
.y
= max(MinMax
.ptMaxTrackSize
.y
,
1023 MinMax
.ptMinTrackSize
.y
);
1026 *MaxSize
= MinMax
.ptMaxSize
;
1028 *MaxPos
= MinMax
.ptMaxPosition
;
1030 *MinTrack
= MinMax
.ptMinTrackSize
;
1032 *MaxTrack
= MinMax
.ptMaxTrackSize
;
1034 return 0; // FIXME: What does it return?
1039 IntValidateParent(PWND Child
, PREGION ValidateRgn
)
1041 PWND ParentWnd
= Child
;
1043 if (ParentWnd
->style
& WS_CHILD
)
1046 ParentWnd
= ParentWnd
->spwndParent
;
1047 while (ParentWnd
->style
& WS_CHILD
);
1050 ParentWnd
= Child
->spwndParent
;
1053 if (ParentWnd
->style
& WS_CLIPCHILDREN
)
1056 if (ParentWnd
->hrgnUpdate
!= 0)
1058 IntInvalidateWindows( ParentWnd
,
1060 RDW_VALIDATE
| RDW_NOCHILDREN
);
1063 ParentWnd
= ParentWnd
->spwndParent
;
1071 FixClientRect(PRECTL ClientRect
, PRECTL WindowRect
)
1073 if (ClientRect
->left
< WindowRect
->left
)
1075 ClientRect
->left
= WindowRect
->left
;
1077 else if (WindowRect
->right
< ClientRect
->left
)
1079 ClientRect
->left
= WindowRect
->right
;
1081 if (ClientRect
->right
< WindowRect
->left
)
1083 ClientRect
->right
= WindowRect
->left
;
1085 else if (WindowRect
->right
< ClientRect
->right
)
1087 ClientRect
->right
= WindowRect
->right
;
1089 if (ClientRect
->top
< WindowRect
->top
)
1091 ClientRect
->top
= WindowRect
->top
;
1093 else if (WindowRect
->bottom
< ClientRect
->top
)
1095 ClientRect
->top
= WindowRect
->bottom
;
1097 if (ClientRect
->bottom
< WindowRect
->top
)
1099 ClientRect
->bottom
= WindowRect
->top
;
1101 else if (WindowRect
->bottom
< ClientRect
->bottom
)
1103 ClientRect
->bottom
= WindowRect
->bottom
;
1106 /***********************************************************************
1109 * Compute the valid rects from the old and new client rect and WVR_* flags.
1110 * Helper for WM_NCCALCSIZE handling.
1114 get_valid_rects( RECTL
*old_client
, RECTL
*new_client
, UINT flags
, RECTL
*valid
)
1118 if (flags
& WVR_REDRAW
)
1120 RECTL_vSetEmptyRect( &valid
[0] );
1121 RECTL_vSetEmptyRect( &valid
[1] );
1125 if (flags
& WVR_VALIDRECTS
)
1127 if (!RECTL_bIntersectRect( &valid
[0], &valid
[0], new_client
) ||
1128 !RECTL_bIntersectRect( &valid
[1], &valid
[1], old_client
))
1130 RECTL_vSetEmptyRect( &valid
[0] );
1131 RECTL_vSetEmptyRect( &valid
[1] );
1134 flags
= WVR_ALIGNLEFT
| WVR_ALIGNTOP
;
1138 valid
[0] = *new_client
;
1139 valid
[1] = *old_client
;
1142 /* make sure the rectangles have the same size */
1143 cx
= min( valid
[0].right
- valid
[0].left
, valid
[1].right
- valid
[1].left
);
1144 cy
= min( valid
[0].bottom
- valid
[0].top
, valid
[1].bottom
- valid
[1].top
);
1146 if (flags
& WVR_ALIGNBOTTOM
)
1148 valid
[0].top
= valid
[0].bottom
- cy
;
1149 valid
[1].top
= valid
[1].bottom
- cy
;
1153 valid
[0].bottom
= valid
[0].top
+ cy
;
1154 valid
[1].bottom
= valid
[1].top
+ cy
;
1156 if (flags
& WVR_ALIGNRIGHT
)
1158 valid
[0].left
= valid
[0].right
- cx
;
1159 valid
[1].left
= valid
[1].right
- cx
;
1163 valid
[0].right
= valid
[0].left
+ cx
;
1164 valid
[1].right
= valid
[1].left
+ cx
;
1170 co_WinPosDoNCCALCSize(PWND Window
, PWINDOWPOS WinPos
, RECTL
* WindowRect
, RECTL
* ClientRect
, RECTL
* validRects
)
1175 ASSERT_REFS_CO(Window
);
1177 /* Send WM_NCCALCSIZE message to get new client area */
1178 if ((WinPos
->flags
& (SWP_FRAMECHANGED
| SWP_NOSIZE
)) != SWP_NOSIZE
)
1180 NCCALCSIZE_PARAMS params
;
1181 WINDOWPOS winposCopy
;
1183 params
.rgrc
[0] = *WindowRect
; // new coordinates of a window that has been moved or resized
1184 params
.rgrc
[1] = Window
->rcWindow
; // window before it was moved or resized
1185 params
.rgrc
[2] = Window
->rcClient
; // client area before the window was moved or resized
1187 Parent
= Window
->spwndParent
;
1188 if (0 != (Window
->style
& WS_CHILD
) && Parent
)
1190 RECTL_vOffsetRect(&(params
.rgrc
[0]), - Parent
->rcClient
.left
, - Parent
->rcClient
.top
);
1191 RECTL_vOffsetRect(&(params
.rgrc
[1]), - Parent
->rcClient
.left
, - Parent
->rcClient
.top
);
1192 RECTL_vOffsetRect(&(params
.rgrc
[2]), - Parent
->rcClient
.left
, - Parent
->rcClient
.top
);
1195 params
.lppos
= &winposCopy
;
1196 winposCopy
= *WinPos
;
1198 wvrFlags
= co_IntSendMessage(Window
->head
.h
, WM_NCCALCSIZE
, TRUE
, (LPARAM
) ¶ms
);
1200 /* If the application send back garbage, ignore it */
1201 if (params
.rgrc
[0].left
<= params
.rgrc
[0].right
&&
1202 params
.rgrc
[0].top
<= params
.rgrc
[0].bottom
)
1204 *ClientRect
= params
.rgrc
[0]; // First rectangle contains the coordinates of the new client rectangle resulting from the move or resize
1205 if ((Window
->style
& WS_CHILD
) && Parent
)
1207 RECTL_vOffsetRect(ClientRect
, Parent
->rcClient
.left
, Parent
->rcClient
.top
);
1209 FixClientRect(ClientRect
, WindowRect
);
1212 if (ClientRect
->left
!= Window
->rcClient
.left
||
1213 ClientRect
->top
!= Window
->rcClient
.top
)
1215 WinPos
->flags
&= ~SWP_NOCLIENTMOVE
;
1218 if (ClientRect
->right
- ClientRect
->left
!= Window
->rcClient
.right
- Window
->rcClient
.left
)
1220 WinPos
->flags
&= ~SWP_NOCLIENTSIZE
;
1223 wvrFlags
&= ~WVR_HREDRAW
;
1225 if (ClientRect
->bottom
- ClientRect
->top
!= Window
->rcClient
.bottom
- Window
->rcClient
.top
)
1227 WinPos
->flags
&= ~SWP_NOCLIENTSIZE
;
1230 wvrFlags
&= ~WVR_VREDRAW
;
1232 validRects
[0] = params
.rgrc
[1]; // second rectangle contains the valid destination rectangle
1233 validRects
[1] = params
.rgrc
[2]; // third rectangle contains the valid source rectangle
1237 if (!(WinPos
->flags
& SWP_NOMOVE
) &&
1238 (ClientRect
->left
!= Window
->rcClient
.left
||
1239 ClientRect
->top
!= Window
->rcClient
.top
))
1241 WinPos
->flags
&= ~SWP_NOCLIENTMOVE
;
1245 if (WinPos
->flags
& (SWP_NOCOPYBITS
| SWP_NOREDRAW
| SWP_SHOWWINDOW
| SWP_HIDEWINDOW
))
1247 RECTL_vSetEmptyRect( &validRects
[0] );
1248 RECTL_vSetEmptyRect( &validRects
[1] );
1250 else get_valid_rects( &Window
->rcClient
, ClientRect
, wvrFlags
, validRects
);
1257 co_WinPosDoWinPosChanging(PWND Window
,
1262 ASSERT_REFS_CO(Window
);
1264 /* Send WM_WINDOWPOSCHANGING message */
1266 if (!(WinPos
->flags
& SWP_NOSENDCHANGING
))
1268 TRACE("Sending WM_WINDOWPOSCHANGING to hwnd %p flags %04x.\n", Window
->head
.h
,WinPos
->flags
);
1269 co_IntSendMessage(Window
->head
.h
, WM_WINDOWPOSCHANGING
, 0, (LPARAM
) WinPos
);
1272 /* Calculate new position and size */
1274 *WindowRect
= Window
->rcWindow
;
1275 *ClientRect
= (Window
->style
& WS_MINIMIZE
) ? Window
->rcWindow
: Window
->rcClient
;
1277 if (!(WinPos
->flags
& SWP_NOSIZE
))
1279 if (Window
->style
& WS_MINIMIZE
)
1281 WindowRect
->right
= WindowRect
->left
+ UserGetSystemMetrics(SM_CXMINIMIZED
);
1282 WindowRect
->bottom
= WindowRect
->top
+ UserGetSystemMetrics(SM_CYMINIMIZED
);
1286 WindowRect
->right
= WindowRect
->left
+ WinPos
->cx
;
1287 WindowRect
->bottom
= WindowRect
->top
+ WinPos
->cy
;
1291 if (!(WinPos
->flags
& SWP_NOMOVE
))
1298 Parent
= Window
->spwndParent
;
1300 // Parent child position issue is in here. SetParent_W7 test CORE-6651.
1301 if (//((Window->style & WS_CHILD) != 0) && <- Fixes wine msg test_SetParent: "rects do not match", the last test.
1303 Parent
!= Window
->head
.rpdesk
->pDeskInfo
->spwnd
)
1305 TRACE("Not SWP_NOMOVE 1 Parent client offset X %d Y %d\n",X
,Y
);
1306 X
+= Parent
->rcClient
.left
;
1307 Y
+= Parent
->rcClient
.top
;
1308 TRACE("Not SWP_NOMOVE 2 Parent client offset X %d Y %d\n",X
,Y
);
1311 WindowRect
->left
= X
;
1312 WindowRect
->top
= Y
;
1313 WindowRect
->right
+= X
- Window
->rcWindow
.left
;
1314 WindowRect
->bottom
+= Y
- Window
->rcWindow
.top
;
1316 RECTL_vOffsetRect(ClientRect
, X
- Window
->rcWindow
.left
,
1317 Y
- Window
->rcWindow
.top
);
1319 WinPos
->flags
|= SWP_NOCLIENTMOVE
| SWP_NOCLIENTSIZE
;
1321 TRACE( "hwnd %p, after %p, swp %d,%d %dx%d flags %08x\n",
1322 WinPos
->hwnd
, WinPos
->hwndInsertAfter
, WinPos
->x
, WinPos
->y
,
1323 WinPos
->cx
, WinPos
->cy
, WinPos
->flags
);
1324 TRACE("WindowRect: %d %d %d %d\n", WindowRect
->left
,WindowRect
->top
,WindowRect
->right
,WindowRect
->bottom
);
1325 TRACE("ClientRect: %d %d %d %d\n", ClientRect
->left
,ClientRect
->top
,ClientRect
->right
,ClientRect
->bottom
);
1331 * Fix Z order taking into account owned popups -
1332 * basically we need to maintain them above the window that owns them
1334 * FIXME: hide/show owned popups when owner visibility changes.
1336 * ReactOS: See bug CORE-6129 and CORE-6554.
1340 // Pass all the win:test_children/popup_zorder tests except "move hwnd_F and its popups down" which is if'ed out.
1341 // Side effect, breaks more of the DeferWindowPos api tests, but wine breaks more!!!!
1344 WinPosDoOwnedPopups(PWND Window
, HWND hWndInsertAfter
)
1349 PWND DesktopWindow
, ChildObject
;
1352 TRACE("(%p) hInsertAfter = %p\n", Window
, hWndInsertAfter
);
1354 Style
= Window
->style
;
1356 if (Style
& WS_CHILD
)
1358 TRACE("Window is child\n");
1359 return hWndInsertAfter
;
1362 Owner
= Window
->spwndOwner
? Window
->spwndOwner
->head
.h
: NULL
;
1366 /* Make sure this popup stays above the owner */
1368 if (hWndInsertAfter
!= HWND_TOPMOST
)
1370 DesktopWindow
= UserGetDesktopWindow();
1371 List
= IntWinListChildren(DesktopWindow
);
1375 for (i
= 0; List
[i
]; i
++)
1377 BOOL topmost
= FALSE
;
1379 ChildObject
= ValidateHwndNoErr(List
[i
]);
1382 topmost
= (ChildObject
->ExStyle
& WS_EX_TOPMOST
) != 0;
1385 if (List
[i
] == Owner
)
1387 if (i
> 0) hWndInsertAfter
= List
[i
-1];
1388 else hWndInsertAfter
= topmost
? HWND_TOPMOST
: HWND_TOP
;
1392 if (hWndInsertAfter
== HWND_TOP
|| hWndInsertAfter
== HWND_NOTOPMOST
)
1394 if (!topmost
) break;
1396 else if (List
[i
] == hWndInsertAfter
) break;
1400 return hWndInsertAfter
;
1404 if (hWndInsertAfter
== HWND_BOTTOM
)
1406 ERR("Window is HWND_BOTTOM hwnd %p\n",hWndInsertAfter
);
1407 if (List
) ExFreePoolWithTag(List
, USERTAG_WINDOWLIST
);
1413 DesktopWindow
= UserGetDesktopWindow();
1414 List
= IntWinListChildren(DesktopWindow
);
1421 if (hWndInsertAfter
== HWND_TOP
|| hWndInsertAfter
== HWND_NOTOPMOST
)
1423 if (hWndInsertAfter
== HWND_NOTOPMOST
|| !(Window
->ExStyle
& WS_EX_TOPMOST
))
1425 TRACE("skip all the topmost windows\n");
1426 /* skip all the topmost windows */
1428 (ChildObject
= ValidateHwndNoErr(List
[i
])) &&
1429 (ChildObject
->ExStyle
& WS_EX_TOPMOST
)) i
++;
1432 else if (hWndInsertAfter
!= HWND_TOPMOST
)
1434 /* skip windows that are already placed correctly */
1435 for (i
= 0; List
[i
]; i
++)
1437 if (List
[i
] == hWndInsertAfter
) break;
1438 if (List
[i
] == UserHMGetHandle(Window
))
1440 ExFreePoolWithTag(List
, USERTAG_WINDOWLIST
);
1441 goto done
; /* nothing to do if window is moving backwards in z-order */
1446 for (; List
[i
]; i
++)
1449 USER_REFERENCE_ENTRY Ref
;
1451 if (List
[i
] == UserHMGetHandle(Window
))
1454 if (!(Wnd
= ValidateHwndNoErr(List
[i
])))
1457 Owner
= Wnd
->spwndOwner
? Wnd
->spwndOwner
->head
.h
: NULL
;
1459 if (Owner
!= UserHMGetHandle(Window
)) continue;
1461 UserRefObjectCo(Wnd
, &Ref
);
1462 TRACE( "moving %p owned by %p after %p\n", List
[i
], UserHMGetHandle(Window
), hWndInsertAfter
);
1463 co_WinPosSetWindowPos(Wnd
, hWndInsertAfter
, 0, 0, 0, 0,
1464 SWP_NOMOVE
| SWP_NOSIZE
| SWP_NOACTIVATE
| SWP_NOSENDCHANGING
| SWP_DEFERERASE
);
1466 UserDerefObjectCo(Wnd
);
1467 hWndInsertAfter
= List
[i
];
1469 ExFreePoolWithTag(List
, USERTAG_WINDOWLIST
);
1472 return hWndInsertAfter
;
1476 /***********************************************************************
1477 * WinPosInternalMoveWindow
1479 * Update WindowRect and ClientRect of Window and all of its children
1480 * We keep both WindowRect and ClientRect in screen coordinates internally
1484 WinPosInternalMoveWindow(PWND Window
, INT MoveX
, INT MoveY
)
1488 ASSERT(Window
!= Window
->spwndChild
);
1489 TRACE("InternalMoveWin X %d Y %d\n", MoveX
, MoveY
);
1491 Window
->rcWindow
.left
+= MoveX
;
1492 Window
->rcWindow
.right
+= MoveX
;
1493 Window
->rcWindow
.top
+= MoveY
;
1494 Window
->rcWindow
.bottom
+= MoveY
;
1496 Window
->rcClient
.left
+= MoveX
;
1497 Window
->rcClient
.right
+= MoveX
;
1498 Window
->rcClient
.top
+= MoveY
;
1499 Window
->rcClient
.bottom
+= MoveY
;
1501 for(Child
= Window
->spwndChild
; Child
; Child
= Child
->spwndNext
)
1503 WinPosInternalMoveWindow(Child
, MoveX
, MoveY
);
1508 * WinPosFixupSWPFlags
1510 * Fix redundant flags and values in the WINDOWPOS structure.
1514 WinPosFixupFlags(WINDOWPOS
*WinPos
, PWND Wnd
)
1519 /* Finally make sure that all coordinates are valid */
1520 if (WinPos
->x
< -32768) WinPos
->x
= -32768;
1521 else if (WinPos
->x
> 32767) WinPos
->x
= 32767;
1522 if (WinPos
->y
< -32768) WinPos
->y
= -32768;
1523 else if (WinPos
->y
> 32767) WinPos
->y
= 32767;
1525 WinPos
->cx
= max(WinPos
->cx
, 0);
1526 WinPos
->cy
= max(WinPos
->cy
, 0);
1528 Parent
= UserGetAncestor( Wnd
, GA_PARENT
);
1529 if (!IntIsWindowVisible( Parent
) &&
1530 /* Fix B : wine msg test_SetParent:WmSetParentSeq_2:25 wParam bits! */
1531 (WinPos
->flags
& SWP_AGG_STATUSFLAGS
) == SWP_AGG_NOPOSCHANGE
) WinPos
->flags
|= SWP_NOREDRAW
;
1533 if (Wnd
->style
& WS_VISIBLE
) WinPos
->flags
&= ~SWP_SHOWWINDOW
;
1536 WinPos
->flags
&= ~SWP_HIDEWINDOW
;
1537 if (!(WinPos
->flags
& SWP_SHOWWINDOW
)) WinPos
->flags
|= SWP_NOREDRAW
;
1540 /* Check for right size */
1541 if (Wnd
->rcWindow
.right
- Wnd
->rcWindow
.left
== WinPos
->cx
&&
1542 Wnd
->rcWindow
.bottom
- Wnd
->rcWindow
.top
== WinPos
->cy
)
1544 WinPos
->flags
|= SWP_NOSIZE
;
1549 IntClientToScreen( Parent
, &pt
);
1550 TRACE("WPFU C2S wpx %d wpy %d ptx %d pty %d\n",WinPos
->x
,WinPos
->y
,pt
.x
,pt
.y
);
1551 /* Check for right position */
1552 if (Wnd
->rcWindow
.left
== pt
.x
&& Wnd
->rcWindow
.top
== pt
.y
)
1554 //ERR("In right pos\n");
1555 WinPos
->flags
|= SWP_NOMOVE
;
1558 if ( WinPos
->hwnd
!= UserGetForegroundWindow() && (Wnd
->style
& (WS_POPUP
| WS_CHILD
)) != WS_CHILD
)
1560 /* Bring to the top when activating */
1561 if (!(WinPos
->flags
& (SWP_NOACTIVATE
|SWP_HIDEWINDOW
)) &&
1562 (WinPos
->flags
& SWP_NOZORDER
||
1563 (WinPos
->hwndInsertAfter
!= HWND_TOPMOST
&& WinPos
->hwndInsertAfter
!= HWND_NOTOPMOST
)))
1565 WinPos
->flags
&= ~SWP_NOZORDER
;
1566 WinPos
->hwndInsertAfter
= (0 != (Wnd
->ExStyle
& WS_EX_TOPMOST
) ? HWND_TOPMOST
: HWND_TOP
);
1570 /* Check hwndInsertAfter */
1571 if (!(WinPos
->flags
& SWP_NOZORDER
))
1573 /* Fix sign extension */
1574 if (WinPos
->hwndInsertAfter
== (HWND
)0xffff)
1576 WinPos
->hwndInsertAfter
= HWND_TOPMOST
;
1578 else if (WinPos
->hwndInsertAfter
== (HWND
)0xfffe)
1580 WinPos
->hwndInsertAfter
= HWND_NOTOPMOST
;
1583 if (WinPos
->hwndInsertAfter
== HWND_TOP
)
1585 /* Keep it topmost when it's already topmost */
1586 if ((Wnd
->ExStyle
& WS_EX_TOPMOST
) != 0)
1587 WinPos
->hwndInsertAfter
= HWND_TOPMOST
;
1589 if (IntGetWindow(WinPos
->hwnd
, GW_HWNDFIRST
) == WinPos
->hwnd
)
1591 WinPos
->flags
|= SWP_NOZORDER
;
1594 else if (WinPos
->hwndInsertAfter
== HWND_BOTTOM
)
1596 if (!(Wnd
->ExStyle
& WS_EX_TOPMOST
) && IntGetWindow(WinPos
->hwnd
, GW_HWNDLAST
) == WinPos
->hwnd
)
1597 WinPos
->flags
|= SWP_NOZORDER
;
1599 else if (WinPos
->hwndInsertAfter
== HWND_TOPMOST
)
1601 if ((Wnd
->ExStyle
& WS_EX_TOPMOST
) && IntGetWindow(WinPos
->hwnd
, GW_HWNDFIRST
) == WinPos
->hwnd
)
1602 WinPos
->flags
|= SWP_NOZORDER
;
1604 else if (WinPos
->hwndInsertAfter
== HWND_NOTOPMOST
)
1606 if (!(Wnd
->ExStyle
& WS_EX_TOPMOST
))
1607 WinPos
->flags
|= SWP_NOZORDER
;
1609 else /* hwndInsertAfter must be a sibling of the window */
1613 InsAfterWnd
= ValidateHwndNoErr(WinPos
->hwndInsertAfter
);
1619 if (InsAfterWnd
->spwndParent
!= Wnd
->spwndParent
)
1621 /* Note from wine User32 Win test_SetWindowPos:
1622 "Returns TRUE also for windows that are not siblings"
1623 "Does not seem to do anything even without passing flags, still returns TRUE"
1624 "Same thing the other way around."
1625 ".. and with these windows."
1632 * We don't need to change the Z order of hwnd if it's already
1633 * inserted after hwndInsertAfter or when inserting hwnd after
1636 if ((WinPos
->hwnd
== WinPos
->hwndInsertAfter
) ||
1637 ((InsAfterWnd
->spwndNext
) && (WinPos
->hwnd
== InsAfterWnd
->spwndNext
->head
.h
)))
1639 WinPos
->flags
|= SWP_NOZORDER
;
1648 /* x and y are always screen relative */
1650 co_WinPosSetWindowPos(
1652 HWND WndInsertAfter
,
1661 RECTL NewWindowRect
;
1662 RECTL NewClientRect
;
1663 RECTL valid_rects
[2];
1664 PREGION VisBefore
= NULL
;
1665 PREGION VisBeforeJustClient
= NULL
;
1666 PREGION VisAfter
= NULL
;
1667 PREGION CopyRgn
= NULL
;
1669 RECTL OldWindowRect
, OldClientRect
;
1674 BOOL bPointerInWindow
, PosChanged
= FALSE
;
1675 PTHREADINFO pti
= PsGetCurrentThreadWin32Thread();
1677 ASSERT_REFS_CO(Window
);
1679 TRACE("pwnd %p, after %p, %d,%d (%dx%d), flags %s",
1680 Window
, WndInsertAfter
, x
, y
, cx
, cy
, flags
);
1682 dump_winpos_flags(flags
);
1685 /* FIXME: Get current active window from active queue. Why? since r2915. */
1687 bPointerInWindow
= IntPtInWindow(Window
, gpsi
->ptCursor
.x
, gpsi
->ptCursor
.y
);
1689 WinPos
.hwnd
= Window
->head
.h
;
1690 WinPos
.hwndInsertAfter
= WndInsertAfter
;
1695 WinPos
.flags
= flags
;
1697 if ( flags
& SWP_ASYNCWINDOWPOS
)
1700 PWINDOWPOS ppos
= ExAllocatePoolWithTag(PagedPool
, sizeof(WINDOWPOS
), USERTAG_SWP
);
1703 WinPos
.flags
&= ~SWP_ASYNCWINDOWPOS
; // Clear flag.
1705 /* Yes it's a pointer inside Win32k! */
1706 lRes
= co_IntSendMessageNoWait( WinPos
.hwnd
, WM_ASYNC_SETWINDOWPOS
, 0, (LPARAM
)ppos
);
1707 /* We handle this the same way as Event Hooks and Hooks. */
1710 ExFreePoolWithTag(ppos
, USERTAG_SWP
);
1718 co_WinPosDoWinPosChanging(Window
, &WinPos
, &NewWindowRect
, &NewClientRect
);
1720 /* Does the window still exist? */
1721 if (!IntIsWindow(WinPos
.hwnd
))
1723 TRACE("WinPosSetWindowPos: Invalid handle 0x%p!\n",WinPos
.hwnd
);
1724 EngSetLastError(ERROR_INVALID_WINDOW_HANDLE
);
1728 /* Fix up the flags. */
1729 if (!WinPosFixupFlags(&WinPos
, Window
))
1735 Ancestor
= UserGetAncestor(Window
, GA_PARENT
);
1736 if ( (WinPos
.flags
& (SWP_NOZORDER
| SWP_HIDEWINDOW
| SWP_SHOWWINDOW
)) != SWP_NOZORDER
&&
1737 Ancestor
&& Ancestor
->head
.h
== IntGetDesktopWindow() )
1739 WinPos
.hwndInsertAfter
= WinPosDoOwnedPopups(Window
, WinPos
.hwndInsertAfter
);
1742 if (!(WinPos
.flags
& SWP_NOREDRAW
))
1744 /* Compute the visible region before the window position is changed */
1745 if (!(WinPos
.flags
& SWP_SHOWWINDOW
) &&
1746 (WinPos
.flags
& (SWP_NOMOVE
| SWP_NOSIZE
| SWP_NOZORDER
|
1747 SWP_HIDEWINDOW
| SWP_FRAMECHANGED
)) !=
1748 (SWP_NOMOVE
| SWP_NOSIZE
| SWP_NOZORDER
))
1750 VisBefore
= VIS_ComputeVisibleRegion(Window
, FALSE
, FALSE
,
1751 (Window
->style
& WS_CLIPSIBLINGS
) ? TRUE
: FALSE
);
1753 if ( VisBefore
!= NULL
&&
1754 REGION_Complexity(VisBefore
) == NULLREGION
)
1756 REGION_Delete(VisBefore
);
1761 REGION_bOffsetRgn(VisBefore
, -Window
->rcWindow
.left
, -Window
->rcWindow
.top
);
1764 /* Calculate the non client area for resizes, as this is used in the copy region */
1765 if (!(WinPos
.flags
& SWP_NOSIZE
))
1767 VisBeforeJustClient
= VIS_ComputeVisibleRegion(Window
, TRUE
, FALSE
,
1768 (Window
->style
& WS_CLIPSIBLINGS
) ? TRUE
: FALSE
);
1770 if ( VisBeforeJustClient
!= NULL
&&
1771 REGION_Complexity(VisBeforeJustClient
) == NULLREGION
)
1773 REGION_Delete(VisBeforeJustClient
);
1774 VisBeforeJustClient
= NULL
;
1776 else if(VisBeforeJustClient
)
1778 REGION_bOffsetRgn(VisBeforeJustClient
, -Window
->rcWindow
.left
, -Window
->rcWindow
.top
);
1785 if (Window
->hrgnNewFrame
)
1787 SelectWindowRgn( Window
, Window
->hrgnNewFrame
); // Should be PSMWP->acvr->hrgnClip
1788 Window
->hrgnNewFrame
= NULL
;
1791 WvrFlags
= co_WinPosDoNCCALCSize(Window
, &WinPos
, &NewWindowRect
, &NewClientRect
, valid_rects
);
1793 // ERR("co_WinPosDoNCCALCSize returned 0x%x\n valid dest: %d %d %d %d\n valid src : %d %d %d %d\n", WvrFlags,
1794 // valid_rects[0].left,valid_rects[0].top,valid_rects[0].right,valid_rects[0].bottom,
1795 // valid_rects[1].left,valid_rects[1].top,valid_rects[1].right,valid_rects[1].bottom);
1797 /* Validate link windows. (also take into account shell window in hwndShellWindow) */
1798 if (!(WinPos
.flags
& SWP_NOZORDER
) && WinPos
.hwnd
!= UserGetShellWindow())
1800 IntLinkHwnd(Window
, WinPos
.hwndInsertAfter
);
1803 OldWindowRect
= Window
->rcWindow
;
1804 OldClientRect
= Window
->rcClient
;
1806 if (NewClientRect
.left
!= OldClientRect
.left
||
1807 NewClientRect
.top
!= OldClientRect
.top
)
1809 // Move child window if their parent is moved. Keep Child window relative to Parent...
1810 WinPosInternalMoveWindow(Window
,
1811 NewClientRect
.left
- OldClientRect
.left
,
1812 NewClientRect
.top
- OldClientRect
.top
);
1816 Window
->rcWindow
= NewWindowRect
;
1817 Window
->rcClient
= NewClientRect
;
1819 /* erase parent when hiding or resizing child */
1820 if (WinPos
.flags
& SWP_HIDEWINDOW
)
1822 /* Clear the update region */
1823 co_UserRedrawWindow( Window
,
1826 RDW_VALIDATE
| RDW_NOFRAME
| RDW_NOERASE
| RDW_NOINTERNALPAINT
| RDW_ALLCHILDREN
);
1828 if (UserIsDesktopWindow(Window
->spwndParent
))
1829 co_IntShellHookNotify(HSHELL_WINDOWDESTROYED
, (WPARAM
)Window
->head
.h
, 0);
1831 Window
->style
&= ~WS_VISIBLE
; //IntSetStyle( Window, 0, WS_VISIBLE );
1832 Window
->head
.pti
->cVisWindows
--;
1833 IntNotifyWinEvent(EVENT_OBJECT_HIDE
, Window
, OBJID_WINDOW
, CHILDID_SELF
, WEF_SETBYWNDPTI
);
1835 else if (WinPos
.flags
& SWP_SHOWWINDOW
)
1837 if (UserIsDesktopWindow(Window
->spwndParent
) &&
1838 Window
->spwndOwner
== NULL
&&
1839 (!(Window
->ExStyle
& WS_EX_TOOLWINDOW
) ||
1840 (Window
->ExStyle
& WS_EX_APPWINDOW
)))
1841 co_IntShellHookNotify(HSHELL_WINDOWCREATED
, (WPARAM
)Window
->head
.h
, 0);
1843 Window
->style
|= WS_VISIBLE
; //IntSetStyle( Window, WS_VISIBLE, 0 );
1844 Window
->head
.pti
->cVisWindows
++;
1845 IntNotifyWinEvent(EVENT_OBJECT_SHOW
, Window
, OBJID_WINDOW
, CHILDID_SELF
, WEF_SETBYWNDPTI
);
1848 if (Window
->hrgnUpdate
!= NULL
&& Window
->hrgnUpdate
!= HRGN_WINDOW
)
1850 NtGdiOffsetRgn(Window
->hrgnUpdate
,
1851 NewWindowRect
.left
- OldWindowRect
.left
,
1852 NewWindowRect
.top
- OldWindowRect
.top
);
1855 DceResetActiveDCEs(Window
); // For WS_VISIBLE changes.
1857 if (!(WinPos
.flags
& SWP_NOREDRAW
))
1859 /* Determine the new visible region */
1860 VisAfter
= VIS_ComputeVisibleRegion(Window
, FALSE
, FALSE
,
1861 (Window
->style
& WS_CLIPSIBLINGS
) ? TRUE
: FALSE
);
1863 if ( VisAfter
!= NULL
&&
1864 REGION_Complexity(VisAfter
) == NULLREGION
)
1866 REGION_Delete(VisAfter
);
1871 REGION_bOffsetRgn(VisAfter
, -Window
->rcWindow
.left
, -Window
->rcWindow
.top
);
1875 * Determine which pixels can be copied from the old window position
1876 * to the new. Those pixels must be visible in both the old and new
1877 * position. Also, check the class style to see if the windows of this
1878 * class need to be completely repainted on (horizontal/vertical) size
1881 if ( ( VisBefore
!= NULL
&&
1883 !(WinPos
.flags
& SWP_NOCOPYBITS
) &&
1884 ((WinPos
.flags
& SWP_NOSIZE
) || !(WvrFlags
& WVR_REDRAW
)) &&
1885 !(Window
->ExStyle
& WS_EX_TRANSPARENT
) ) ||
1886 ( !PosChanged
&& (WinPos
.flags
& SWP_FRAMECHANGED
) && VisBefore
) )
1890 * If this is (also) a window resize, the whole nonclient area
1891 * needs to be repainted. So we limit the copy to the client area,
1892 * 'cause there is no use in copying it (would possibly cause
1893 * "flashing" too). However, if the copy region is already empty,
1894 * we don't have to crop (can't take anything away from an empty
1898 CopyRgn
= IntSysCreateRectpRgn(0, 0, 0, 0);
1899 if (WinPos
.flags
& SWP_NOSIZE
)
1900 RgnType
= IntGdiCombineRgn(CopyRgn
, VisAfter
, VisBefore
, RGN_AND
);
1901 else if (VisBeforeJustClient
!= NULL
)
1903 RgnType
= IntGdiCombineRgn(CopyRgn
, VisAfter
, VisBeforeJustClient
, RGN_AND
);
1904 REGION_Delete(VisBeforeJustClient
);
1907 /* Now use in copying bits which are in the update region. */
1908 if (Window
->hrgnUpdate
!= NULL
)
1910 PREGION RgnUpdate
= REGION_LockRgn(Window
->hrgnUpdate
);
1913 REGION_bOffsetRgn(CopyRgn
, NewWindowRect
.left
, NewWindowRect
.top
);
1914 IntGdiCombineRgn(CopyRgn
, CopyRgn
, RgnUpdate
, RGN_DIFF
);
1915 REGION_bOffsetRgn(CopyRgn
, -NewWindowRect
.left
, -NewWindowRect
.top
);
1916 REGION_UnlockRgn(RgnUpdate
);
1921 * Now, get the bounding box of the copy region. If it's empty
1922 * there's nothing to copy. Also, it's no use copying bits onto
1925 if (REGION_GetRgnBox(CopyRgn
, &CopyRect
) == NULLREGION
)
1927 /* Nothing to copy, clean up */
1928 REGION_Delete(CopyRgn
);
1931 else if ( OldWindowRect
.left
!= NewWindowRect
.left
||
1932 OldWindowRect
.top
!= NewWindowRect
.top
||
1933 (WinPos
.flags
& SWP_FRAMECHANGED
) )
1935 HRGN DcRgn
= NtGdiCreateRectRgn(0, 0, 0, 0);
1936 PREGION DcRgnObj
= REGION_LockRgn(DcRgn
);
1939 * Small trick here: there is no function to bitblt a region. So
1940 * we set the region as the clipping region, take the bounding box
1941 * of the region and bitblt that. Since nothing outside the clipping
1942 * region is copied, this has the effect of bitblt'ing the region.
1944 * Since NtUserGetDCEx takes ownership of the clip region, we need
1945 * to create a copy of CopyRgn and pass that. We need CopyRgn later
1947 IntGdiCombineRgn(DcRgnObj
, CopyRgn
, NULL
, RGN_COPY
);
1948 REGION_bOffsetRgn(DcRgnObj
, NewWindowRect
.left
, NewWindowRect
.top
);
1949 REGION_UnlockRgn(DcRgnObj
);
1950 Dc
= UserGetDCEx( Window
,
1952 DCX_WINDOW
|DCX_CACHE
|DCX_INTERSECTRGN
|DCX_CLIPSIBLINGS
|DCX_KEEPCLIPRGN
);
1954 CopyRect
.left
, CopyRect
.top
,
1955 CopyRect
.right
- CopyRect
.left
,
1956 CopyRect
.bottom
- CopyRect
.top
,
1958 CopyRect
.left
+ (OldWindowRect
.left
- NewWindowRect
.left
),
1959 CopyRect
.top
+ (OldWindowRect
.top
- NewWindowRect
.top
),
1964 UserReleaseDC(Window
, Dc
, FALSE
);
1965 IntValidateParent(Window
, CopyRgn
);
1966 GreDeleteObject(DcRgn
);
1974 /////// Fixes NoPopup tests but breaks msg_paint tests.
1975 if ( !PosChanged
&& (WinPos
.flags
& SWP_FRAMECHANGED
) && VisBefore
)
1977 PWND Parent
= Window
->spwndParent
;
1978 ERR("SWP_FRAMECHANGED no chg\n");
1979 if ( !(Window
->style
& WS_CHILD
) && (Parent
) && (Parent
->style
& WS_CLIPCHILDREN
))
1981 ERR("SWP_FRAMECHANGED Parent WS_CLIPCHILDREN\n");
1982 //IntInvalidateWindows( Window, VisBefore, /*RDW_ERASE |*/ RDW_FRAME | RDW_INVALIDATE | RDW_ALLCHILDREN);
1986 /* We need to redraw what wasn't visible before */
1987 if (VisAfter
!= NULL
)
1989 PREGION DirtyRgn
= IntSysCreateRectpRgn(0, 0, 0, 0);
1992 if (CopyRgn
!= NULL
)
1994 RgnType
= IntGdiCombineRgn(DirtyRgn
, VisAfter
, CopyRgn
, RGN_DIFF
);
1998 RgnType
= IntGdiCombineRgn(DirtyRgn
, VisAfter
, 0, RGN_COPY
);
2001 if (RgnType
!= ERROR
&& RgnType
!= NULLREGION
)
2004 NtGdiOffsetRgn(DirtyRgn, Window->rcWindow.left, Window->rcWindow.top);
2005 IntInvalidateWindows( Window,
2007 RDW_ERASE | RDW_FRAME | RDW_INVALIDATE | RDW_ALLCHILDREN);
2009 GreDeleteObject(DirtyRgn);
2012 PWND Parent
= Window
->spwndParent
;
2014 REGION_bOffsetRgn( DirtyRgn
, Window
->rcWindow
.left
, Window
->rcWindow
.top
);
2016 if ( (Window
->style
& WS_CHILD
) && (Parent
) && !(Parent
->style
& WS_CLIPCHILDREN
))
2018 IntInvalidateWindows( Parent
, DirtyRgn
, RDW_ERASE
| RDW_INVALIDATE
);
2019 co_IntPaintWindows(Parent
, RDW_NOCHILDREN
, FALSE
);
2023 IntInvalidateWindows( Window
, DirtyRgn
, RDW_ERASE
| RDW_FRAME
| RDW_INVALIDATE
| RDW_ALLCHILDREN
);
2026 REGION_Delete(DirtyRgn
);
2030 if (CopyRgn
!= NULL
)
2032 REGION_Delete(CopyRgn
);
2035 /* Expose what was covered before but not covered anymore */
2036 if (VisBefore
!= NULL
)
2038 PREGION ExposedRgn
= IntSysCreateRectpRgn(0, 0, 0, 0);
2041 RgnType
= IntGdiCombineRgn(ExposedRgn
, VisBefore
, NULL
, RGN_COPY
);
2042 REGION_bOffsetRgn(ExposedRgn
,
2043 OldWindowRect
.left
- NewWindowRect
.left
,
2044 OldWindowRect
.top
- NewWindowRect
.top
);
2046 if (VisAfter
!= NULL
)
2047 RgnType
= IntGdiCombineRgn(ExposedRgn
, ExposedRgn
, VisAfter
, RGN_DIFF
);
2049 if (RgnType
!= ERROR
&& RgnType
!= NULLREGION
)
2051 co_VIS_WindowLayoutChanged(Window
, ExposedRgn
);
2053 REGION_Delete(ExposedRgn
);
2055 REGION_Delete(VisBefore
);
2058 if (VisAfter
!= NULL
)
2060 REGION_Delete(VisAfter
);
2064 if (!(WinPos
.flags
& (SWP_NOACTIVATE
|SWP_HIDEWINDOW
)))
2066 if ((Window
->style
& (WS_CHILD
| WS_POPUP
)) == WS_CHILD
)
2068 co_IntSendMessageNoWait(WinPos
.hwnd
, WM_CHILDACTIVATE
, 0, 0);
2072 //ERR("SetWindowPos Set FG Window!\n");
2073 if ( pti
->MessageQueue
->spwndActive
!= Window
||
2074 pti
->MessageQueue
!= gpqForeground
)
2076 //ERR("WPSWP : set active window\n");
2077 if (!(Window
->state
& WNDS_BEINGACTIVATED
)) // Inside SAW?
2079 co_IntSetForegroundWindow(Window
); // Fixes SW_HIDE issues. Wine win test_SetActiveWindow & test_SetForegroundWindow.
2086 (WinPos
.flags
& SWP_FRAMECHANGED
) &&
2087 !(WinPos
.flags
& SWP_DEFERERASE
) && // Prevent sending WM_SYNCPAINT message.
2090 PWND Parent
= Window
->spwndParent
;
2091 if ( !(Window
->style
& WS_CHILD
) && (Parent
) && (Parent
->style
& WS_CLIPCHILDREN
))
2093 TRACE("SWP_FRAMECHANGED Parent WS_CLIPCHILDREN\n");
2094 UserSyncAndPaintWindows( Parent
, RDW_CLIPCHILDREN
);
2098 // Fix wine msg test_SetFocus, prevents sending WM_WINDOWPOSCHANGED.
2099 if ( VisBefore
== NULL
&&
2100 VisBeforeJustClient
== NULL
&&
2101 !(Window
->ExStyle
& WS_EX_TOPMOST
) &&
2102 (WinPos
.flags
& SWP_AGG_STATUSFLAGS
) == (SWP_AGG_NOPOSCHANGE
& ~SWP_NOZORDER
))
2104 TRACE("No drawing, set no Z order and no redraw!\n");
2105 WinPos
.flags
|= SWP_NOZORDER
|SWP_NOREDRAW
;
2108 /* And last, send the WM_WINDOWPOSCHANGED message */
2110 TRACE("\tstatus hwnd %p flags = %04x\n",Window
?Window
->head
.h
:NULL
,WinPos
.flags
& SWP_AGG_STATUSFLAGS
);
2112 if ((WinPos
.flags
& SWP_AGG_STATUSFLAGS
) != SWP_AGG_NOPOSCHANGE
)
2114 /* WM_WINDOWPOSCHANGED is sent even if SWP_NOSENDCHANGING is set
2115 and always contains final window position.
2117 WinPos
.x
= NewWindowRect
.left
;
2118 WinPos
.y
= NewWindowRect
.top
;
2119 WinPos
.cx
= NewWindowRect
.right
- NewWindowRect
.left
;
2120 WinPos
.cy
= NewWindowRect
.bottom
- NewWindowRect
.top
;
2121 TRACE("WM_WINDOWPOSCHANGED hwnd %p Flags %04x\n",WinPos
.hwnd
,WinPos
.flags
);
2122 co_IntSendMessageNoWait(WinPos
.hwnd
, WM_WINDOWPOSCHANGED
, 0, (LPARAM
) &WinPos
);
2125 if ( WinPos
.flags
& SWP_FRAMECHANGED
|| WinPos
.flags
& SWP_STATECHANGED
||
2126 !(WinPos
.flags
& SWP_NOCLIENTSIZE
) || !(WinPos
.flags
& SWP_NOCLIENTMOVE
) )
2128 PWND pWnd
= ValidateHwndNoErr(WinPos
.hwnd
);
2130 IntNotifyWinEvent(EVENT_OBJECT_LOCATIONCHANGE
, pWnd
, OBJID_WINDOW
, CHILDID_SELF
, WEF_SETBYWNDPTI
);
2133 if(bPointerInWindow
!= IntPtInWindow(Window
, gpsi
->ptCursor
.x
, gpsi
->ptCursor
.y
))
2135 /* Generate mouse move message */
2137 msg
.message
= WM_MOUSEMOVE
;
2138 msg
.wParam
= UserGetMouseButtonsState();
2139 msg
.lParam
= MAKELPARAM(gpsi
->ptCursor
.x
, gpsi
->ptCursor
.y
);
2140 msg
.pt
= gpsi
->ptCursor
;
2141 co_MsqInsertMouseMessage(&msg
, 0, 0, TRUE
);
2148 co_WinPosGetNonClientSize(PWND Window
, RECT
* WindowRect
, RECT
* ClientRect
)
2152 ASSERT_REFS_CO(Window
);
2154 *ClientRect
= *WindowRect
;
2155 Result
= co_IntSendMessageNoWait(Window
->head
.h
, WM_NCCALCSIZE
, FALSE
, (LPARAM
) ClientRect
);
2157 FixClientRect(ClientRect
, WindowRect
);
2163 co_WinPosSendSizeMove(PWND Wnd
)
2167 WPARAM wParam
= SIZE_RESTORED
;
2169 IntGetClientRect(Wnd
, &Rect
);
2170 lParam
= MAKELONG(Rect
.right
-Rect
.left
, Rect
.bottom
-Rect
.top
);
2172 Wnd
->state
&= ~WNDS_SENDSIZEMOVEMSGS
;
2174 if (Wnd
->style
& WS_MAXIMIZE
)
2176 wParam
= SIZE_MAXIMIZED
;
2178 else if (Wnd
->style
& WS_MINIMIZE
)
2180 wParam
= SIZE_MINIMIZED
;
2184 co_IntSendMessageNoWait(UserHMGetHandle(Wnd
), WM_SIZE
, wParam
, lParam
);
2186 if (UserIsDesktopWindow(Wnd
->spwndParent
))
2187 lParam
= MAKELONG(Wnd
->rcClient
.left
, Wnd
->rcClient
.top
);
2189 lParam
= MAKELONG(Wnd
->rcClient
.left
-Wnd
->spwndParent
->rcClient
.left
, Wnd
->rcClient
.top
-Wnd
->spwndParent
->rcClient
.top
);
2191 co_IntSendMessageNoWait(UserHMGetHandle(Wnd
), WM_MOVE
, 0, lParam
);
2193 IntEngWindowChanged(Wnd
, WOC_RGN_CLIENT
);
2197 co_WinPosMinMaximize(PWND Wnd
, UINT ShowFlag
, RECT
* NewPos
)
2200 WINDOWPLACEMENT wpl
;
2204 ASSERT_REFS_CO(Wnd
);
2206 wpl
.length
= sizeof(wpl
);
2207 IntGetWindowPlacement( Wnd
, &wpl
);
2209 if (co_HOOK_CallHooks( WH_CBT
, HCBT_MINMAX
, (WPARAM
)Wnd
->head
.h
, ShowFlag
))
2211 ERR("WinPosMinMaximize WH_CBT Call Hook return!\n");
2212 return SWP_NOSIZE
| SWP_NOMOVE
;
2214 if (Wnd
->style
& WS_MINIMIZE
)
2219 case SW_SHOWMINNOACTIVE
:
2220 case SW_SHOWMINIMIZED
:
2221 case SW_FORCEMINIMIZE
:
2222 return SWP_NOSIZE
| SWP_NOMOVE
;
2224 if (!co_IntSendMessageNoWait(Wnd
->head
.h
, WM_QUERYOPEN
, 0, 0))
2226 return(SWP_NOSIZE
| SWP_NOMOVE
);
2228 SwpFlags
|= SWP_NOCOPYBITS
;
2233 case SW_SHOWMINNOACTIVE
:
2234 case SW_SHOWMINIMIZED
:
2235 case SW_FORCEMINIMIZE
:
2237 //ERR("MinMaximize Minimize\n");
2238 if (Wnd
->style
& WS_MAXIMIZE
)
2240 Wnd
->InternalPos
.flags
|= WPF_RESTORETOMAXIMIZED
;
2244 Wnd
->InternalPos
.flags
&= ~WPF_RESTORETOMAXIMIZED
;
2247 old_style
= IntSetStyle( Wnd
, WS_MINIMIZE
, WS_MAXIMIZE
);
2249 co_UserRedrawWindow(Wnd
, NULL
, 0, RDW_VALIDATE
| RDW_NOERASE
| RDW_NOINTERNALPAINT
);
2251 if (!(Wnd
->InternalPos
.flags
& WPF_SETMINPOSITION
))
2252 Wnd
->InternalPos
.flags
&= ~WPF_MININIT
;
2254 WinPosFindIconPos(Wnd
, &wpl
.ptMinPosition
);
2256 /*if (!(old_style & WS_MINIMIZE))
2258 SwpFlags |= SWP_STATECHANGED;
2259 IntShowOwnedPopups(Wnd, FALSE);
2262 RECTL_vSetRect(NewPos
, wpl
.ptMinPosition
.x
, wpl
.ptMinPosition
.y
,
2263 wpl
.ptMinPosition
.x
+ UserGetSystemMetrics(SM_CXMINIMIZED
),
2264 wpl
.ptMinPosition
.y
+ UserGetSystemMetrics(SM_CYMINIMIZED
));
2265 SwpFlags
|= SWP_NOCOPYBITS
;
2271 //ERR("MinMaximize Maximize\n");
2272 if ((Wnd
->style
& WS_MAXIMIZE
) && (Wnd
->style
& WS_VISIBLE
))
2274 SwpFlags
= SWP_NOSIZE
| SWP_NOMOVE
;
2277 co_WinPosGetMinMaxInfo(Wnd
, &Size
, &wpl
.ptMaxPosition
, NULL
, NULL
);
2279 /*ERR("Maximize: %d,%d %dx%d\n",
2280 wpl.ptMaxPosition.x, wpl.ptMaxPosition.y, Size.x, Size.y);
2282 old_style
= IntSetStyle( Wnd
, WS_MAXIMIZE
, WS_MINIMIZE
);
2283 /*if (old_style & WS_MINIMIZE)
2285 IntShowOwnedPopups(Wnd, TRUE);
2288 if (!(old_style
& WS_MAXIMIZE
)) SwpFlags
|= SWP_STATECHANGED
;
2289 RECTL_vSetRect(NewPos
, wpl
.ptMaxPosition
.x
, wpl
.ptMaxPosition
.y
,
2290 //wpl.ptMaxPosition.x + Size.x, wpl.ptMaxPosition.y + Size.y);
2295 case SW_SHOWNOACTIVATE
:
2296 Wnd
->InternalPos
.flags
&= ~WPF_RESTORETOMAXIMIZED
;
2300 case SW_SHOWDEFAULT
: /* FIXME: should have its own handler */
2302 //ERR("MinMaximize Restore\n");
2303 old_style
= IntSetStyle( Wnd
, 0, WS_MINIMIZE
| WS_MAXIMIZE
);
2304 if (old_style
& WS_MINIMIZE
)
2306 //IntShowOwnedPopups(Wnd, TRUE);
2308 if (Wnd
->InternalPos
.flags
& WPF_RESTORETOMAXIMIZED
)
2310 co_WinPosGetMinMaxInfo(Wnd
, &Size
, &wpl
.ptMaxPosition
, NULL
, NULL
);
2311 IntSetStyle( Wnd
, WS_MAXIMIZE
, 0 );
2312 SwpFlags
|= SWP_STATECHANGED
;
2313 RECTL_vSetRect(NewPos
, wpl
.ptMaxPosition
.x
, wpl
.ptMaxPosition
.y
,
2314 wpl
.ptMaxPosition
.x
+ Size
.x
, wpl
.ptMaxPosition
.y
+ Size
.y
);
2319 *NewPos
= wpl
.rcNormalPosition
;
2320 NewPos
->right
-= NewPos
->left
;
2321 NewPos
->bottom
-= NewPos
->top
;
2327 if (!(old_style
& WS_MAXIMIZE
))
2331 SwpFlags
|= SWP_STATECHANGED
;
2332 Wnd
->InternalPos
.flags
&= ~WPF_RESTORETOMAXIMIZED
;
2333 *NewPos
= wpl
.rcNormalPosition
;
2334 NewPos
->right
-= NewPos
->left
;
2335 NewPos
->bottom
-= NewPos
->top
;
2344 ShowWindow does not set SWP_FRAMECHANGED!!! Fix wine msg test_SetParent:WmSetParentSeq_2:23 wParam bits!
2347 co_WinPosShowWindow(PWND Wnd
, INT Cmd
)
2350 UINT Swp
= 0, EventMsg
= 0;
2351 RECTL NewPos
= {0, 0, 0, 0};
2357 BOOL ShowOwned
= FALSE
;
2358 BOOL FirstTime
= FALSE
;
2359 ASSERT_REFS_CO(Wnd
);
2360 //KeRosDumpStackFrames(NULL, 20);
2361 pti
= PsGetCurrentThreadWin32Thread();
2362 WasVisible
= (Wnd
->style
& WS_VISIBLE
) != 0;
2365 TRACE("co_WinPosShowWindow START hwnd %p Cmd %d usicmd %u\n",
2366 Wnd
->head
.h
, Cmd
, pti
->ppi
->usi
.wShowWindow
);
2368 if ( pti
->ppi
->usi
.dwFlags
& STARTF_USESHOWWINDOW
)
2370 if ((Wnd
->style
& (WS_POPUP
|WS_CHILD
)) != WS_CHILD
)
2372 if ((Wnd
->style
& WS_CAPTION
) == WS_CAPTION
)
2374 if (Wnd
->spwndOwner
== NULL
)
2376 if ( Cmd
== SW_SHOWNORMAL
|| Cmd
== SW_SHOW
)
2378 Cmd
= SW_SHOWDEFAULT
;
2381 TRACE("co_WPSW FT 1\n");
2387 if ( Cmd
== SW_SHOWDEFAULT
)
2389 if ( pti
->ppi
->usi
.dwFlags
& STARTF_USESHOWWINDOW
)
2391 Cmd
= pti
->ppi
->usi
.wShowWindow
;
2393 TRACE("co_WPSW FT 2\n");
2399 pti
->ppi
->usi
.dwFlags
&= ~(STARTF_USEPOSITION
|STARTF_USESIZE
|STARTF_USESHOWWINDOW
);
2408 //ERR("co_WinPosShowWindow Exit Bad\n");
2411 Swp
|= SWP_HIDEWINDOW
| SWP_NOSIZE
| SWP_NOMOVE
;
2412 if (Wnd
!= pti
->MessageQueue
->spwndActive
)
2413 Swp
|= SWP_NOACTIVATE
| SWP_NOZORDER
;
2417 case SW_FORCEMINIMIZE
: /* FIXME: Does not work if thread is hung. */
2418 case SW_SHOWMINNOACTIVE
:
2419 Swp
|= SWP_NOACTIVATE
| SWP_NOZORDER
;
2421 case SW_SHOWMINIMIZED
:
2422 Swp
|= SWP_SHOWWINDOW
;
2426 Swp
|= SWP_NOACTIVATE
;
2427 if (!(style
& WS_MINIMIZE
))
2429 IntShowOwnedPopups(Wnd
, FALSE
);
2430 // Fix wine Win test_SetFocus todo #1 & #2,
2431 if (Cmd
== SW_SHOWMINIMIZED
)
2433 //ERR("co_WinPosShowWindow Set focus 1\n");
2434 if ((style
& (WS_CHILD
| WS_POPUP
)) == WS_CHILD
)
2435 co_UserSetFocus(Wnd
->spwndParent
);
2440 Swp
|= co_WinPosMinMaximize(Wnd
, Cmd
, &NewPos
);
2442 EventMsg
= EVENT_SYSTEM_MINIMIZESTART
;
2448 //ERR("co_WinPosShowWindow Exit Good\n");
2451 Swp
|= SWP_NOSIZE
| SWP_NOMOVE
;
2456 case SW_SHOWMAXIMIZED
:
2458 Swp
|= SWP_SHOWWINDOW
;
2459 if (!(style
& WS_MAXIMIZE
))
2463 Swp
|= co_WinPosMinMaximize(Wnd
, SW_MAXIMIZE
, &NewPos
);
2465 EventMsg
= EVENT_SYSTEM_MINIMIZEEND
;
2471 //ERR("co_WinPosShowWindow Exit Good 1\n");
2474 Swp
|= SWP_NOSIZE
| SWP_NOMOVE
;
2480 Swp
|= SWP_NOACTIVATE
| SWP_SHOWWINDOW
| SWP_NOSIZE
| SWP_NOMOVE
;
2481 if (style
& WS_CHILD
&& !(Wnd
->ExStyle
& WS_EX_MDICHILD
)) Swp
|= SWP_NOZORDER
;
2484 if (WasVisible
) return(TRUE
); // Nothing to do!
2485 Swp
|= SWP_SHOWWINDOW
| SWP_NOSIZE
| SWP_NOMOVE
;
2486 /* Don't activate the topmost window. */
2487 if (style
& WS_CHILD
&& !(Wnd
->ExStyle
& WS_EX_MDICHILD
)) Swp
|= SWP_NOACTIVATE
| SWP_NOZORDER
;
2490 case SW_SHOWNOACTIVATE
:
2491 Swp
|= SWP_NOACTIVATE
| SWP_NOZORDER
;
2494 case SW_SHOWDEFAULT
:
2496 if (!WasVisible
) Swp
|= SWP_SHOWWINDOW
;
2497 if (style
& (WS_MINIMIZE
| WS_MAXIMIZE
))
2499 Swp
|= co_WinPosMinMaximize(Wnd
, Cmd
, &NewPos
);
2500 if (style
& WS_MINIMIZE
) EventMsg
= EVENT_SYSTEM_MINIMIZEEND
;
2506 //ERR("co_WinPosShowWindow Exit Good 3\n");
2509 Swp
|= SWP_NOSIZE
| SWP_NOMOVE
;
2511 if ( style
& WS_CHILD
&&
2512 !(Wnd
->ExStyle
& WS_EX_MDICHILD
) &&
2513 !(Swp
& SWP_STATECHANGED
))
2514 Swp
|= SWP_NOACTIVATE
| SWP_NOZORDER
;
2518 //ERR("co_WinPosShowWindow Exit Good 4\n");
2522 ShowFlag
= (Cmd
!= SW_HIDE
);
2524 if ((ShowFlag
!= WasVisible
|| Cmd
== SW_SHOWNA
) && Cmd
!= SW_SHOWMAXIMIZED
&& !(Swp
& SWP_STATECHANGED
))
2526 co_IntSendMessageNoWait(Wnd
->head
.h
, WM_SHOWWINDOW
, ShowFlag
, 0);
2527 #if 0 // Fix wine msg test_SetParent:WmSetParentSeq_1:2
2528 if (!(Wnd
->state2
& WNDS2_WIN31COMPAT
)) // <------------- XP sets this bit!
2529 co_IntSendMessageNoWait(Wnd
->head
.h
, WM_SETVISIBLE
, ShowFlag
, 0);
2531 if (!VerifyWnd(Wnd
)) return WasVisible
;
2534 /* We can't activate a child window */
2535 if ((Wnd
->style
& WS_CHILD
) &&
2536 !(Wnd
->ExStyle
& WS_EX_MDICHILD
) &&
2539 //ERR("SWP Child No active and ZOrder\n");
2540 Swp
|= SWP_NOACTIVATE
| SWP_NOZORDER
;
2543 #if 0 // Explorer issues with common controls? Someone does not know how CS_SAVEBITS works.
2544 // Breaks startup and shutdown active window...
2545 if ((Wnd
->style
& (WS_POPUP
|WS_CHILD
)) != WS_CHILD
&&
2546 Wnd
->pcls
->style
& CS_SAVEBITS
&&
2547 ((Cmd
== SW_SHOW
) || (Cmd
== SW_NORMAL
)))
2549 ERR("WinPosShowWindow Set active\n");
2550 //UserSetActiveWindow(Wnd);
2551 co_IntSetForegroundWindow(Wnd
); // HACK
2552 Swp
|= SWP_NOACTIVATE
| SWP_NOZORDER
;
2556 if (IsChildVisible(Wnd
) || Swp
& SWP_STATECHANGED
)
2558 TRACE("Child is Vis %s or State changed %s. ShowFlag %s Swp %04x\n",
2559 (IsChildVisible(Wnd
) ? "TRUE" : "FALSE"), (Swp
& SWP_STATECHANGED
? "TRUE" : "FALSE"),
2560 (ShowFlag
? "TRUE" : "FALSE"),LOWORD(Swp
));
2561 co_WinPosSetWindowPos( Wnd
,
2562 0 != (Wnd
->ExStyle
& WS_EX_TOPMOST
) ? HWND_TOPMOST
: HWND_TOP
,
2565 NewPos
.right
, // NewPos.right - NewPos.left, when minimized and restore, the window becomes smaller.
2566 NewPos
.bottom
,// NewPos.bottom - NewPos.top,
2571 TRACE("Parent Vis?\n");
2572 /* if parent is not visible simply toggle WS_VISIBLE and return */
2573 if (ShowFlag
) IntSetStyle( Wnd
, WS_VISIBLE
, 0 );
2574 else IntSetStyle( Wnd
, 0, WS_VISIBLE
);
2577 if ( EventMsg
) IntNotifyWinEvent(EventMsg
, Wnd
, OBJID_WINDOW
, CHILDID_SELF
, WEF_SETBYWNDPTI
);
2579 if ( ShowOwned
) IntShowOwnedPopups(Wnd
, TRUE
);
2581 if ((Cmd
== SW_HIDE
) || (Cmd
== SW_MINIMIZE
))
2583 if ( Wnd
== pti
->MessageQueue
->spwndActive
&& pti
->MessageQueue
== IntGetFocusMessageQueue() )
2585 if (UserIsDesktopWindow(Wnd
->spwndParent
))
2587 if (!ActivateOtherWindowMin(Wnd
))
2589 co_WinPosActivateOtherWindow(Wnd
);
2594 co_WinPosActivateOtherWindow(Wnd
);
2598 /* Revert focus to parent */
2599 if (Wnd
== pti
->MessageQueue
->spwndFocus
)
2601 Parent
= Wnd
->spwndParent
;
2602 if (UserIsDesktopWindow(Wnd
->spwndParent
))
2604 co_UserSetFocus(Parent
);
2606 // Hide, just return.
2607 if (Cmd
== SW_HIDE
) return WasVisible
;
2610 /* FIXME: Check for window destruction. */
2612 if ((Wnd
->state
& WNDS_SENDSIZEMOVEMSGS
) &&
2613 !(Wnd
->state2
& WNDS2_INDESTROY
))
2615 co_WinPosSendSizeMove(Wnd
);
2618 /* if previous state was minimized Windows sets focus to the window */
2619 if (style
& WS_MINIMIZE
)
2621 co_UserSetFocus(Wnd
);
2622 // Fix wine Win test_SetFocus todo #3,
2623 if (!(style
& WS_CHILD
)) co_IntSendMessage(UserHMGetHandle(Wnd
), WM_ACTIVATE
, WA_ACTIVE
, 0);
2625 //ERR("co_WinPosShowWindow EXIT\n");
2630 co_WinPosSearchChildren(
2633 IN OUT USHORT
*HitTest
,
2638 PWND pwndChild
= NULL
;
2641 if (!(ScopeWin
->style
& WS_VISIBLE
))
2646 /* not in window or in window region */
2647 if (!IntPtInWindow(ScopeWin
, Point
->x
, Point
->y
))
2653 if ((ScopeWin
->ExStyle
& (WS_EX_LAYERED
|WS_EX_TRANSPARENT
)) == (WS_EX_LAYERED
|WS_EX_TRANSPARENT
))
2658 if (!Ignore
&& (ScopeWin
->style
& WS_DISABLED
))
2659 { /* disabled child */
2660 if ((ScopeWin
->style
& (WS_POPUP
|WS_CHILD
)) == WS_CHILD
) return NULL
;
2661 /* process the hit error */
2666 /* not minimized and check if point is inside the window */
2667 if (!(ScopeWin
->style
& WS_MINIMIZE
) &&
2668 RECTL_bPointInRect(&ScopeWin
->rcClient
, Point
->x
, Point
->y
) )
2670 UserReferenceObject(ScopeWin
);
2672 List
= IntWinListChildren(ScopeWin
);
2675 for (phWnd
= List
; *phWnd
; ++phWnd
)
2677 if (!(pwndChild
= ValidateHwndNoErr(*phWnd
)))
2682 pwndChild
= co_WinPosSearchChildren(pwndChild
, Point
, HitTest
, Ignore
);
2684 if (pwndChild
!= NULL
)
2686 /* We found a window. Don't send any more WM_NCHITTEST messages */
2687 ExFreePoolWithTag(List
, USERTAG_WINDOWLIST
);
2688 UserDereferenceObject(ScopeWin
);
2692 ExFreePoolWithTag(List
, USERTAG_WINDOWLIST
);
2694 UserDereferenceObject(ScopeWin
);
2697 if (ScopeWin
->head
.pti
== PsGetCurrentThreadWin32Thread())
2699 *HitTest
= (USHORT
)co_IntSendMessage(ScopeWin
->head
.h
, WM_NCHITTEST
, 0, MAKELONG(Point
->x
, Point
->y
));
2701 if ((*HitTest
) == (USHORT
)HTTRANSPARENT
)
2708 if (*HitTest
== HTNOWHERE
&& pwndChild
== NULL
) *HitTest
= HTCLIENT
;
2715 co_WinPosWindowFromPoint(
2718 IN OUT USHORT
* HitTest
,
2722 POINT Point
= *WinPoint
;
2723 USER_REFERENCE_ENTRY Ref
;
2725 if( ScopeWin
== NULL
)
2727 ScopeWin
= UserGetDesktopWindow();
2728 if(ScopeWin
== NULL
)
2732 *HitTest
= HTNOWHERE
;
2734 ASSERT_REFS_CO(ScopeWin
);
2735 UserRefObjectCo(ScopeWin
, &Ref
);
2737 Window
= co_WinPosSearchChildren(ScopeWin
, &Point
, HitTest
, Ignore
);
2739 UserDerefObjectCo(ScopeWin
);
2741 ASSERT_REFS_CO(Window
);
2742 ASSERT_REFS_CO(ScopeWin
);
2748 IntRealChildWindowFromPoint(PWND Parent
, LONG x
, LONG y
)
2752 PWND pwndHit
= NULL
;
2757 if (!UserIsDesktopWindow(Parent
))
2759 Pt
.x
+= Parent
->rcClient
.left
;
2760 Pt
.y
+= Parent
->rcClient
.top
;
2763 if (!IntPtInWindow(Parent
, Pt
.x
, Pt
.y
)) return NULL
;
2765 if ((List
= IntWinListChildren(Parent
)))
2767 for (phWnd
= List
; *phWnd
; phWnd
++)
2770 if ((Child
= ValidateHwndNoErr(*phWnd
)))
2772 if ( Child
->style
& WS_VISIBLE
&& IntPtInWindow(Child
, Pt
.x
, Pt
.y
) )
2774 if ( Child
->pcls
->atomClassName
!= gpsi
->atomSysClass
[ICLS_BUTTON
] ||
2775 (Child
->style
& BS_TYPEMASK
) != BS_GROUPBOX
)
2777 ExFreePoolWithTag(List
, USERTAG_WINDOWLIST
);
2784 ExFreePoolWithTag(List
, USERTAG_WINDOWLIST
);
2786 return pwndHit
? pwndHit
: Parent
;
2790 IntChildWindowFromPointEx(PWND Parent
, LONG x
, LONG y
, UINT uiFlags
)
2794 PWND pwndHit
= NULL
;
2799 if (!UserIsDesktopWindow(Parent
))
2801 if (Parent
->ExStyle
& WS_EX_LAYOUTRTL
)
2802 Pt
.x
= Parent
->rcClient
.right
- Pt
.x
;
2804 Pt
.x
+= Parent
->rcClient
.left
;
2805 Pt
.y
+= Parent
->rcClient
.top
;
2808 if (!IntPtInWindow(Parent
, Pt
.x
, Pt
.y
)) return NULL
;
2810 if ((List
= IntWinListChildren(Parent
)))
2812 for (phWnd
= List
; *phWnd
; phWnd
++)
2815 if ((Child
= ValidateHwndNoErr(*phWnd
)))
2817 if (uiFlags
& (CWP_SKIPINVISIBLE
|CWP_SKIPDISABLED
))
2819 if (!(Child
->style
& WS_VISIBLE
) && (uiFlags
& CWP_SKIPINVISIBLE
)) continue;
2820 if ((Child
->style
& WS_DISABLED
) && (uiFlags
& CWP_SKIPDISABLED
)) continue;
2823 if (uiFlags
& CWP_SKIPTRANSPARENT
)
2825 if (Child
->ExStyle
& WS_EX_TRANSPARENT
) continue;
2828 if (IntPtInWindow(Child
, Pt
.x
, Pt
.y
))
2835 ExFreePoolWithTag(List
, USERTAG_WINDOWLIST
);
2837 return pwndHit
? pwndHit
: Parent
;
2842 IntDeferWindowPos( HDWP hdwp
,
2853 HDWP retvalue
= hdwp
;
2855 TRACE("hdwp %p, hwnd %p, after %p, %d,%d (%dx%d), flags %08x\n",
2856 hdwp
, hwnd
, hwndAfter
, x
, y
, cx
, cy
, flags
);
2858 if (flags
& ~(SWP_NOSIZE
| SWP_NOMOVE
|
2859 SWP_NOZORDER
| SWP_NOREDRAW
|
2860 SWP_NOACTIVATE
| SWP_NOCOPYBITS
|
2861 SWP_NOOWNERZORDER
|SWP_SHOWWINDOW
|
2862 SWP_HIDEWINDOW
| SWP_FRAMECHANGED
))
2864 EngSetLastError(ERROR_INVALID_PARAMETER
);
2868 if (!(pDWP
= (PSMWP
)UserGetObject(gHandleTable
, hdwp
, TYPE_SETWINDOWPOS
)))
2870 EngSetLastError(ERROR_INVALID_DWP_HANDLE
);
2874 for (i
= 0; i
< pDWP
->ccvr
; i
++)
2876 if (pDWP
->acvr
[i
].pos
.hwnd
== hwnd
)
2878 /* Merge with the other changes */
2879 if (!(flags
& SWP_NOZORDER
))
2881 pDWP
->acvr
[i
].pos
.hwndInsertAfter
= hwndAfter
;
2883 if (!(flags
& SWP_NOMOVE
))
2885 pDWP
->acvr
[i
].pos
.x
= x
;
2886 pDWP
->acvr
[i
].pos
.y
= y
;
2888 if (!(flags
& SWP_NOSIZE
))
2890 pDWP
->acvr
[i
].pos
.cx
= cx
;
2891 pDWP
->acvr
[i
].pos
.cy
= cy
;
2893 pDWP
->acvr
[i
].pos
.flags
&= flags
| ~(SWP_NOSIZE
| SWP_NOMOVE
|
2894 SWP_NOZORDER
| SWP_NOREDRAW
|
2895 SWP_NOACTIVATE
| SWP_NOCOPYBITS
|
2897 pDWP
->acvr
[i
].pos
.flags
|= flags
& (SWP_SHOWWINDOW
| SWP_HIDEWINDOW
|
2902 if (pDWP
->ccvr
>= pDWP
->ccvrAlloc
)
2904 PCVR newpos
= ExAllocatePoolWithTag(PagedPool
, pDWP
->ccvrAlloc
* 2 * sizeof(CVR
), USERTAG_SWP
);
2910 RtlZeroMemory(newpos
, pDWP
->ccvrAlloc
* 2 * sizeof(CVR
));
2911 RtlCopyMemory(newpos
, pDWP
->acvr
, pDWP
->ccvrAlloc
* sizeof(CVR
));
2912 ExFreePoolWithTag(pDWP
->acvr
, USERTAG_SWP
);
2913 pDWP
->ccvrAlloc
*= 2;
2914 pDWP
->acvr
= newpos
;
2916 pDWP
->acvr
[pDWP
->ccvr
].pos
.hwnd
= hwnd
;
2917 pDWP
->acvr
[pDWP
->ccvr
].pos
.hwndInsertAfter
= hwndAfter
;
2918 pDWP
->acvr
[pDWP
->ccvr
].pos
.x
= x
;
2919 pDWP
->acvr
[pDWP
->ccvr
].pos
.y
= y
;
2920 pDWP
->acvr
[pDWP
->ccvr
].pos
.cx
= cx
;
2921 pDWP
->acvr
[pDWP
->ccvr
].pos
.cy
= cy
;
2922 pDWP
->acvr
[pDWP
->ccvr
].pos
.flags
= flags
;
2923 pDWP
->acvr
[pDWP
->ccvr
].hrgnClip
= NULL
;
2924 pDWP
->acvr
[pDWP
->ccvr
].hrgnInterMonitor
= NULL
;
2930 BOOL FASTCALL
IntEndDeferWindowPosEx( HDWP hdwp
, BOOL sAsync
)
2937 TRACE("%p\n", hdwp
);
2939 if (!(pDWP
= (PSMWP
)UserGetObject(gHandleTable
, hdwp
, TYPE_SETWINDOWPOS
)))
2941 EngSetLastError(ERROR_INVALID_DWP_HANDLE
);
2945 for (i
= 0, winpos
= pDWP
->acvr
; res
&& i
< pDWP
->ccvr
; i
++, winpos
++)
2948 USER_REFERENCE_ENTRY Ref
;
2950 TRACE("hwnd %p, after %p, %d,%d (%dx%d), flags %08x\n",
2951 winpos
->pos
.hwnd
, winpos
->pos
.hwndInsertAfter
, winpos
->pos
.x
, winpos
->pos
.y
,
2952 winpos
->pos
.cx
, winpos
->pos
.cy
, winpos
->pos
.flags
);
2954 pwnd
= ValidateHwndNoErr(winpos
->pos
.hwnd
);
2958 UserRefObjectCo(pwnd
, &Ref
);
2963 PWINDOWPOS ppos
= ExAllocatePoolWithTag(PagedPool
, sizeof(WINDOWPOS
), USERTAG_SWP
);
2966 *ppos
= winpos
->pos
;
2967 /* Yes it's a pointer inside Win32k! */
2968 lRes
= co_IntSendMessageNoWait( winpos
->pos
.hwnd
, WM_ASYNC_SETWINDOWPOS
, 0, (LPARAM
)ppos
);
2969 /* We handle this the same way as Event Hooks and Hooks. */
2972 ExFreePoolWithTag(ppos
, USERTAG_SWP
);
2977 res
= co_WinPosSetWindowPos( pwnd
,
2978 winpos
->pos
.hwndInsertAfter
,
2985 // Hack to pass tests.... Must have some work to do so clear the error.
2986 if (res
&& (winpos
->pos
.flags
& (SWP_NOMOVE
|SWP_NOSIZE
|SWP_NOZORDER
)) == SWP_NOZORDER
)
2987 EngSetLastError(ERROR_SUCCESS
);
2989 UserDerefObjectCo(pwnd
);
2991 ExFreePoolWithTag(pDWP
->acvr
, USERTAG_SWP
);
2992 UserDereferenceObject(pDWP
);
2993 UserDeleteObject(hdwp
, TYPE_SETWINDOWPOS
);
3001 NtUserChildWindowFromPointEx(HWND hwndParent
,
3007 TRACE("Enter NtUserChildWindowFromPointEx\n");
3008 UserEnterExclusive();
3009 if ((pwndParent
= UserGetWindowObject(hwndParent
)))
3011 pwndParent
= IntChildWindowFromPointEx(pwndParent
, x
, y
, uiFlags
);
3014 TRACE("Leave NtUserChildWindowFromPointEx\n");
3015 return pwndParent
? UserHMGetHandle(pwndParent
) : NULL
;
3022 NtUserEndDeferWindowPosEx(HDWP WinPosInfo
,
3026 TRACE("Enter NtUserEndDeferWindowPosEx\n");
3027 UserEnterExclusive();
3028 Ret
= IntEndDeferWindowPosEx(WinPosInfo
, (BOOL
)Unknown1
);
3029 TRACE("Leave NtUserEndDeferWindowPosEx, ret=%i\n", Ret
);
3038 NtUserDeferWindowPos(HDWP WinPosInfo
,
3040 HWND WndInsertAfter
,
3049 UINT Tmp
= ~(SWP_ASYNCWINDOWPOS
|SWP_DEFERERASE
|SWP_NOSENDCHANGING
|SWP_NOREPOSITION
|
3050 SWP_NOCOPYBITS
|SWP_HIDEWINDOW
|SWP_SHOWWINDOW
|SWP_FRAMECHANGED
|
3051 SWP_NOACTIVATE
|SWP_NOREDRAW
|SWP_NOZORDER
|SWP_NOMOVE
|SWP_NOSIZE
);
3053 TRACE("Enter NtUserDeferWindowPos\n");
3054 UserEnterExclusive();
3058 EngSetLastError(ERROR_INVALID_FLAGS
);
3062 pWnd
= UserGetWindowObject(Wnd
);
3063 if (!pWnd
|| UserIsDesktopWindow(pWnd
) || UserIsMessageWindow(pWnd
))
3068 if ( WndInsertAfter
&&
3069 WndInsertAfter
!= HWND_BOTTOM
&&
3070 WndInsertAfter
!= HWND_TOPMOST
&&
3071 WndInsertAfter
!= HWND_NOTOPMOST
)
3073 pWndIA
= UserGetWindowObject(WndInsertAfter
);
3074 if (!pWndIA
|| UserIsDesktopWindow(pWndIA
) || UserIsMessageWindow(pWndIA
))
3080 Ret
= IntDeferWindowPos(WinPosInfo
, Wnd
, WndInsertAfter
, x
, y
, cx
, cy
, Flags
);
3083 TRACE("Leave NtUserDeferWindowPos, ret=%p\n", Ret
);
3092 NtUserGetInternalWindowPos( HWND hWnd
,
3099 WINDOWPLACEMENT wndpl
;
3103 if (!(Window
= UserGetWindowObject(hWnd
)))
3113 ProbeForWrite(rectWnd
,
3119 ProbeForWrite(ptIcon
,
3125 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
3127 SetLastNtError(_SEH2_GetExceptionCode());
3132 wndpl
.length
= sizeof(WINDOWPLACEMENT
);
3134 if (IntGetWindowPlacement(Window
, &wndpl
) && !Hit
)
3140 RtlCopyMemory(rectWnd
, &wndpl
.rcNormalPosition
, sizeof(RECT
));
3144 RtlCopyMemory(ptIcon
, &wndpl
.ptMinPosition
, sizeof(POINT
));
3148 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
3150 SetLastNtError(_SEH2_GetExceptionCode());
3155 if (!Hit
) Ret
= wndpl
.showCmd
;
3166 NtUserGetWindowPlacement(HWND hWnd
,
3167 WINDOWPLACEMENT
*lpwndpl
)
3170 WINDOWPLACEMENT Safepl
;
3172 DECLARE_RETURN(BOOL
);
3174 TRACE("Enter NtUserGetWindowPlacement\n");
3177 if (!(Wnd
= UserGetWindowObject(hWnd
)))
3182 Status
= MmCopyFromCaller(&Safepl
, lpwndpl
, sizeof(WINDOWPLACEMENT
));
3183 if (!NT_SUCCESS(Status
))
3185 SetLastNtError(Status
);
3189 Safepl
.length
= sizeof(WINDOWPLACEMENT
);
3191 IntGetWindowPlacement(Wnd
, &Safepl
);
3193 Status
= MmCopyToCaller(lpwndpl
, &Safepl
, sizeof(WINDOWPLACEMENT
));
3194 if (!NT_SUCCESS(Status
))
3196 SetLastNtError(Status
);
3203 TRACE("Leave NtUserGetWindowPlacement, ret=%i\n",_ret_
);
3212 UINT cmd
, // Wine SW_ commands
3217 TRACE("Enter NtUserMinMaximize\n");
3218 UserEnterExclusive();
3220 pWnd
= UserGetWindowObject(hWnd
);
3221 if (!pWnd
|| UserIsDesktopWindow(pWnd
) || UserIsMessageWindow(pWnd
))
3226 if ( cmd
> SW_MAX
|| pWnd
->state2
& WNDS2_INDESTROY
)
3228 EngSetLastError(ERROR_INVALID_PARAMETER
);
3232 cmd
|= Hide
? SW_HIDE
: 0;
3234 co_WinPosShowWindow(pWnd
, cmd
);
3237 TRACE("Leave NtUserMinMaximize\n");
3239 return 0; // Always NULL?
3254 return NtUserSetWindowPos(hWnd
, 0, X
, Y
, nWidth
, nHeight
,
3255 (bRepaint
? SWP_NOZORDER
| SWP_NOACTIVATE
:
3256 SWP_NOZORDER
| SWP_NOACTIVATE
| SWP_NOREDRAW
));
3263 NtUserRealChildWindowFromPoint(HWND Parent
,
3268 TRACE("Enter NtUserRealChildWindowFromPoint\n");
3270 if ((pwndParent
= UserGetWindowObject(Parent
)))
3272 pwndParent
= IntRealChildWindowFromPoint(pwndParent
, x
, y
);
3275 TRACE("Leave NtUserRealChildWindowFromPoint\n");
3276 return pwndParent
? UserHMGetHandle(pwndParent
) : NULL
;
3285 HWND hWndInsertAfter
,
3292 DECLARE_RETURN(BOOL
);
3293 PWND Window
, pWndIA
;
3295 USER_REFERENCE_ENTRY Ref
;
3297 TRACE("Enter NtUserSetWindowPos\n");
3298 UserEnterExclusive();
3300 if (!(Window
= UserGetWindowObject(hWnd
)) ||
3301 UserIsDesktopWindow(Window
) || UserIsMessageWindow(Window
))
3303 ERR("NtUserSetWindowPos bad window handle!\n");
3307 if ( hWndInsertAfter
&&
3308 hWndInsertAfter
!= HWND_BOTTOM
&&
3309 hWndInsertAfter
!= HWND_TOPMOST
&&
3310 hWndInsertAfter
!= HWND_NOTOPMOST
)
3312 if (!(pWndIA
= UserGetWindowObject(hWndInsertAfter
)) ||
3313 UserIsDesktopWindow(pWndIA
) || UserIsMessageWindow(pWndIA
))
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
)) ||
3367 UserIsDesktopWindow(Window
) || UserIsMessageWindow(Window
))
3372 if (hRgn
) // The region will be deleted in user32.
3374 if (GreIsHandleValid(hRgn
))
3376 hrgnCopy
= NtGdiCreateRectRgn(0, 0, 0, 0);
3377 /* The coordinates of a window's window region are relative to the
3378 upper-left corner of the window, not the client area of the window. */
3379 NtGdiCombineRgn( hrgnCopy
, hRgn
, 0, RGN_COPY
);
3385 //// HACK 1 : Work around the lack of supporting DeferWindowPos.
3388 Window
->hrgnNewFrame
= hrgnCopy
; // Should be PSMWP->acvr->hrgnClip
3392 Window
->hrgnNewFrame
= HRGN_WINDOW
;
3395 Ret
= co_WinPosSetWindowPos(Window
, HWND_TOP
, 0, 0, 0, 0, bRedraw
? flags
: (flags
|SWP_NOREDRAW
) );
3400 TRACE("Leave NtUserSetWindowRgn, ret=%i\n",_ret_
);
3409 NtUserSetInternalWindowPos(
3415 WINDOWPLACEMENT wndpl
;
3420 DECLARE_RETURN(BOOL
);
3421 USER_REFERENCE_ENTRY Ref
;
3423 TRACE("Enter NtUserSetWindowPlacement\n");
3424 UserEnterExclusive();
3426 if (!(Wnd
= UserGetWindowObject(hwnd
)) || // FIXME:
3427 UserIsDesktopWindow(Wnd
) || UserIsMessageWindow(Wnd
))
3436 ProbeForRead(lppt
, sizeof(POINT
), 1);
3437 RtlCopyMemory(&pt
, lppt
, sizeof(POINT
));
3441 ProbeForRead(lprect
, sizeof(RECT
), 1);
3442 RtlCopyMemory(&rect
, lprect
, sizeof(RECT
));
3445 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
3447 SetLastNtError(_SEH2_GetExceptionCode());
3448 _SEH2_YIELD(RETURN( FALSE
));
3452 wndpl
.length
= sizeof(wndpl
);
3453 wndpl
.showCmd
= showCmd
;
3454 wndpl
.flags
= flags
= 0;
3459 wndpl
.flags
|= WPF_SETMINPOSITION
;
3460 wndpl
.ptMinPosition
= pt
;
3464 flags
|= PLACE_RECT
;
3465 wndpl
.rcNormalPosition
= rect
;
3468 UserRefObjectCo(Wnd
, &Ref
);
3469 IntSetWindowPlacement(Wnd
, &wndpl
, flags
);
3470 UserDerefObjectCo(Wnd
);
3474 TRACE("Leave NtUserSetWindowPlacement, ret=%i\n",_ret_
);
3483 NtUserSetWindowPlacement(HWND hWnd
,
3484 WINDOWPLACEMENT
*lpwndpl
)
3487 WINDOWPLACEMENT Safepl
;
3489 DECLARE_RETURN(BOOL
);
3490 USER_REFERENCE_ENTRY Ref
;
3492 TRACE("Enter NtUserSetWindowPlacement\n");
3493 UserEnterExclusive();
3495 if (!(Wnd
= UserGetWindowObject(hWnd
)) ||
3496 UserIsDesktopWindow(Wnd
) || UserIsMessageWindow(Wnd
))
3503 ProbeForRead(lpwndpl
, sizeof(WINDOWPLACEMENT
), 1);
3504 RtlCopyMemory(&Safepl
, lpwndpl
, sizeof(WINDOWPLACEMENT
));
3506 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
3508 SetLastNtError(_SEH2_GetExceptionCode());
3509 _SEH2_YIELD(RETURN( FALSE
));
3513 if(Safepl
.length
!= sizeof(WINDOWPLACEMENT
))
3518 Flags
= PLACE_MAX
| PLACE_RECT
;
3519 if (Safepl
.flags
& WPF_SETMINPOSITION
) Flags
|= PLACE_MIN
;
3520 UserRefObjectCo(Wnd
, &Ref
);
3521 IntSetWindowPlacement(Wnd
, &Safepl
, Flags
);
3522 UserDerefObjectCo(Wnd
);
3526 TRACE("Leave NtUserSetWindowPlacement, ret=%i\n",_ret_
);
3535 NtUserShowWindowAsync(HWND hWnd
, LONG nCmdShow
)
3539 DECLARE_RETURN(BOOL
);
3540 USER_REFERENCE_ENTRY Ref
;
3542 TRACE("Enter NtUserShowWindowAsync\n");
3543 UserEnterExclusive();
3545 if (!(Window
= UserGetWindowObject(hWnd
)) ||
3546 UserIsDesktopWindow(Window
) || UserIsMessageWindow(Window
))
3551 if ( nCmdShow
> SW_MAX
)
3553 EngSetLastError(ERROR_INVALID_PARAMETER
);
3557 UserRefObjectCo(Window
, &Ref
);
3558 ret
= co_IntSendMessageNoWait( hWnd
, WM_ASYNC_SHOWWINDOW
, nCmdShow
, 0 );
3559 UserDerefObjectCo(Window
);
3560 if (-1 == (int) ret
|| !ret
) ret
= FALSE
;
3565 TRACE("Leave NtUserShowWindowAsync, ret=%i\n",_ret_
);
3574 NtUserShowWindow(HWND hWnd
, LONG nCmdShow
)
3578 DECLARE_RETURN(BOOL
);
3579 USER_REFERENCE_ENTRY Ref
;
3581 TRACE("Enter NtUserShowWindow hWnd %p SW_ %d\n",hWnd
, nCmdShow
);
3582 UserEnterExclusive();
3584 if (!(Window
= UserGetWindowObject(hWnd
)) ||
3585 UserIsDesktopWindow(Window
) || UserIsMessageWindow(Window
))
3590 if ( nCmdShow
> SW_MAX
|| Window
->state2
& WNDS2_INDESTROY
)
3592 EngSetLastError(ERROR_INVALID_PARAMETER
);
3596 UserRefObjectCo(Window
, &Ref
);
3597 ret
= co_WinPosShowWindow(Window
, nCmdShow
);
3598 UserDerefObjectCo(Window
);
3603 TRACE("Leave NtUserShowWindow, ret=%i\n",_ret_
);
3613 NtUserWindowFromPoint(LONG X
, LONG Y
)
3617 PWND DesktopWindow
= NULL
, Window
= NULL
;
3619 DECLARE_RETURN(HWND
);
3620 USER_REFERENCE_ENTRY Ref
;
3622 TRACE("Enter NtUserWindowFromPoint\n");
3623 UserEnterExclusive();
3625 if ((DesktopWindow
= UserGetWindowObject(IntGetDesktopWindow())))
3632 // Hmm... Threads live on desktops thus we have a reference on the desktop and indirectly the desktop window.
3633 // It is possible this referencing is useless, though it should not hurt...
3634 UserRefObjectCo(DesktopWindow
, &Ref
);
3636 //pti = PsGetCurrentThreadWin32Thread();
3637 Window
= co_WinPosWindowFromPoint(DesktopWindow
, &pt
, &hittest
, FALSE
);
3641 Ret
= UserHMGetHandle(Window
);
3650 if (DesktopWindow
) UserDerefObjectCo(DesktopWindow
);
3652 TRACE("Leave NtUserWindowFromPoint, ret=%p\n", _ret_
);