2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS kernel
5 * FILE: subsystems/win32/win32k/ntuser/window.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_NOMOVE | SWP_NOCLIENTSIZE | SWP_NOCLIENTMOVE)
21 #define SWP_AGG_NOPOSCHANGE \
22 (SWP_AGG_NOGEOMETRYCHANGE | 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 IntGetClientOrigin(PWND Window OPTIONAL
, LPPOINT Point
)
38 Window
= Window
? Window
: UserGetDesktopWindow();
41 Point
->x
= Point
->y
= 0;
44 Point
->x
= Window
->rcClient
.left
;
45 Point
->y
= Window
->rcClient
.top
;
52 * Returns client window rectangle relative to the upper-left corner of client area.
54 * \note Does not check the validity of the parameters
57 IntGetClientRect(PWND Wnd
, RECTL
*Rect
)
61 if (Wnd
->style
& WS_MINIMIZED
)
63 Rect
->left
= Rect
->top
= 0;
64 Rect
->right
= UserGetSystemMetrics(SM_CXMINIMIZED
);
65 Rect
->bottom
= UserGetSystemMetrics(SM_CYMINIMIZED
);
68 if ( Wnd
!= UserGetDesktopWindow()) // Wnd->fnid != FNID_DESKTOP )
70 *Rect
= Wnd
->rcClient
;
71 RECTL_vOffsetRect(Rect
, -Wnd
->rcClient
.left
, -Wnd
->rcClient
.top
);
75 Rect
->left
= Rect
->top
= 0;
76 Rect
->right
= Wnd
->rcClient
.right
;
77 Rect
->bottom
= Wnd
->rcClient
.bottom
;
78 /* Do this until Init bug is fixed. This sets 640x480, see InitMetrics.
79 Rect->right = UserGetSystemMetrics(SM_CXSCREEN);
80 Rect->bottom = UserGetSystemMetrics(SM_CYSCREEN);
86 IntMapWindowPoints(PWND FromWnd
, PWND ToWnd
, LPPOINT lpPoints
, UINT cPoints
)
88 BOOL mirror_from
, mirror_to
;
93 /* Note: Desktop Top and Left is always 0! */
94 Delta
.x
= Delta
.y
= 0;
95 mirror_from
= mirror_to
= FALSE
;
97 if (FromWnd
&& FromWnd
!= UserGetDesktopWindow()) // FromWnd->fnid != FNID_DESKTOP)
99 if (FromWnd
->ExStyle
& WS_EX_LAYOUTRTL
)
103 Delta
.x
= -FromWnd
->rcClient
.right
;
106 Delta
.x
= FromWnd
->rcClient
.left
;
107 Delta
.y
= FromWnd
->rcClient
.top
;
110 if (ToWnd
&& ToWnd
!= UserGetDesktopWindow()) // ToWnd->fnid != FNID_DESKTOP)
112 if (ToWnd
->ExStyle
& WS_EX_LAYOUTRTL
)
116 Delta
.x
+= Change
* ToWnd
->rcClient
.right
;
119 Delta
.x
-= Change
* ToWnd
->rcClient
.left
;
120 Delta
.y
-= ToWnd
->rcClient
.top
;
123 if (mirror_from
) Delta
.x
= -Delta
.x
;
125 for (i
= 0; i
!= cPoints
; i
++)
127 lpPoints
[i
].x
+= Delta
.x
;
128 lpPoints
[i
].x
*= Change
;
129 lpPoints
[i
].y
+= Delta
.y
;
132 if ((mirror_from
|| mirror_to
) && cPoints
== 2) /* special case for rectangle */
134 int tmp
= min(lpPoints
[0].x
, lpPoints
[1].x
);
135 lpPoints
[1].x
= max(lpPoints
[0].x
, lpPoints
[1].x
);
139 return MAKELONG(LOWORD(Delta
.x
), LOWORD(Delta
.y
));
143 IntClientToScreen(PWND Wnd
, LPPOINT lpPoint
)
145 if (Wnd
&& Wnd
->fnid
!= FNID_DESKTOP
)
147 if (Wnd
->ExStyle
& WS_EX_LAYOUTRTL
)
148 lpPoint
->x
= Wnd
->rcClient
.right
- lpPoint
->x
;
150 lpPoint
->x
+= Wnd
->rcClient
.left
;
151 lpPoint
->y
+= Wnd
->rcClient
.top
;
157 IntScreenToClient(PWND Wnd
, LPPOINT lpPoint
)
159 if (Wnd
&& Wnd
->fnid
!= FNID_DESKTOP
)
161 if (Wnd
->ExStyle
& WS_EX_LAYOUTRTL
)
162 lpPoint
->x
= Wnd
->rcClient
.right
- lpPoint
->x
;
164 lpPoint
->x
-= Wnd
->rcClient
.left
;
165 lpPoint
->y
-= Wnd
->rcClient
.top
;
170 BOOL FASTCALL
IsChildVisible(PWND pWnd
)
174 if ( (pWnd
->style
& (WS_POPUP
|WS_CHILD
)) != WS_CHILD
||
175 !(pWnd
= pWnd
->spwndParent
) )
178 while (pWnd
->style
& WS_VISIBLE
);
182 PWND FASTCALL
IntGetLastTopMostWindow(VOID
)
185 PDESKTOP rpdesk
= gptiCurrent
->rpdesk
;
188 (pWnd
= rpdesk
->pDeskInfo
->spwnd
->spwndChild
) &&
189 pWnd
->ExStyle
& WS_EX_TOPMOST
)
193 if (!pWnd
->spwndNext
) break;
194 if (!(pWnd
->spwndNext
->ExStyle
& WS_EX_TOPMOST
)) break;
195 pWnd
= pWnd
->spwndNext
;
203 // This helps with bug 6751 forcing modal dialog active when another app is minimized or closed.
205 BOOL FASTCALL
ActivateOtherWindowMin(PWND Wnd
)
207 BOOL ActivePrev
, FindTopWnd
;
208 PWND pWndTopMost
, pWndChild
, pWndSetActive
, pWndTemp
, pWndDesk
;
209 USER_REFERENCE_ENTRY Ref
;
210 PTHREADINFO pti
= gptiCurrent
;
213 ActivePrev
= (pti
->MessageQueue
->spwndActivePrev
!= NULL
);
216 if ((pWndTopMost
= IntGetLastTopMostWindow()))
217 pWndChild
= pWndTopMost
->spwndNext
;
219 pWndChild
= Wnd
->spwndParent
->spwndChild
;
224 pWndSetActive
= pti
->MessageQueue
->spwndActivePrev
;
226 pWndSetActive
= pWndChild
;
232 if ( VerifyWnd(pWndSetActive
) &&
233 !(pWndSetActive
->ExStyle
& WS_EX_NOACTIVATE
) &&
234 (pWndSetActive
->style
& (WS_VISIBLE
|WS_DISABLED
)) == WS_VISIBLE
&&
235 (!(pWndSetActive
->style
& WS_ICONIC
) /* FIXME MinMax pos? */ ) )
237 if (!(pWndSetActive
->ExStyle
& WS_EX_TOOLWINDOW
) )
239 UserRefObjectCo(pWndSetActive
, &Ref
);
240 //ERR("ActivateOtherWindowMin Set FG 1\n");
241 co_IntSetForegroundWindow(pWndSetActive
);
242 UserDerefObjectCo(pWndSetActive
);
243 //ERR("AOWM 2 Exit Good\n");
246 if (!pWndTemp
) pWndTemp
= pWndSetActive
;
251 pWndSetActive
= pWndChild
;
254 pWndSetActive
= pWndSetActive
->spwndNext
;
257 if ( !FindTopWnd
) break;
262 pWndChild
= pWndChild
->spwndParent
->spwndChild
;
266 if (!(pWndDesk
= IntGetThreadDesktopWindow(pti
)))
271 pWndChild
= pWndDesk
->spwndChild
;
274 if ((pWndSetActive
= pWndTemp
))
276 UserRefObjectCo(pWndSetActive
, &Ref
);
277 //ERR("ActivateOtherWindowMin Set FG 2\n");
278 co_IntSetForegroundWindow(pWndSetActive
);
279 UserDerefObjectCo(pWndSetActive
);
280 //ERR("AOWM 3 Exit Good\n");
283 //ERR("AOWM 4 Bad\n");
287 /*******************************************************************
288 * can_activate_window
290 * Check if we can activate the specified window.
293 BOOL FASTCALL
can_activate_window( PWND Wnd OPTIONAL
)
297 if (!Wnd
) return FALSE
;
300 if (!(style
& WS_VISIBLE
)) return FALSE
;
301 if (style
& WS_MINIMIZE
) return FALSE
;
302 if ((style
& (WS_POPUP
|WS_CHILD
)) == WS_CHILD
) return FALSE
;
304 /* FIXME: This window could be disable because the child that closed
306 //return !(style & WS_DISABLED);
310 /*******************************************************************
311 * WinPosActivateOtherWindow
313 * Activates window other than pWnd.
316 co_WinPosActivateOtherWindow(PWND Wnd
)
319 USER_REFERENCE_ENTRY Ref
;
323 if (IntIsDesktopWindow(Wnd
))
325 IntSetFocusMessageQueue(NULL
);
329 /* If this is popup window, try to activate the owner first. */
330 if ((Wnd
->style
& WS_POPUP
) && (WndTo
= Wnd
->spwndOwner
))
332 WndTo
= UserGetAncestor( WndTo
, GA_ROOT
);
333 if (can_activate_window(WndTo
)) goto done
;
336 /* Pick a next top-level window. */
337 /* FIXME: Search for non-tooltip windows first. */
341 if (!(WndTo
= WndTo
->spwndNext
)) break;
342 if (can_activate_window( WndTo
)) break;
347 if (WndTo
) UserRefObjectCo(WndTo
, &Ref
);
349 if (!gpqForeground
|| Wnd
== gpqForeground
->spwndActive
)
351 /* ReactOS can pass WndTo = NULL to co_IntSetForegroundWindow and returns FALSE. */
352 //ERR("WinPosActivateOtherWindow Set FG 0x%p\n",WndTo);
353 if (co_IntSetForegroundWindow(WndTo
))
355 if (WndTo
) UserDerefObjectCo(WndTo
);
359 //ERR("WinPosActivateOtherWindow Set Active 0x%p\n",WndTo);
360 if (!co_IntSetActiveWindow(WndTo
,FALSE
,TRUE
,FALSE
)) /* Ok for WndTo to be NULL here */
362 co_IntSetActiveWindow(NULL
,FALSE
,TRUE
,FALSE
);
364 if (WndTo
) UserDerefObjectCo(WndTo
);
369 co_WinPosArrangeIconicWindows(PWND parent
)
372 INT i
, x
, y
, xspacing
, yspacing
, sx
, sy
;
373 HWND
*List
= IntWinListChildren(parent
);
375 ASSERT_REFS_CO(parent
);
377 /* Check if we found any children */
383 IntGetClientRect( parent
, &rectParent
);
384 // FIXME: Support gspv.mm.iArrange.
386 y
= rectParent
.bottom
;
388 xspacing
= (UserGetSystemMetrics(SM_CXMINSPACING
)/2)+UserGetSystemMetrics(SM_CXBORDER
);
389 yspacing
= (UserGetSystemMetrics(SM_CYMINSPACING
)/2)+UserGetSystemMetrics(SM_CYBORDER
);
391 //ERR("X:%d Y:%d XS:%d YS:%d\n",x,y,xspacing,yspacing);
393 for(i
= 0; List
[i
]; i
++)
397 if (!(Child
= ValidateHwndNoErr(List
[i
])))
400 if((Child
->style
& WS_MINIMIZE
) != 0 )
402 USER_REFERENCE_ENTRY Ref
;
403 UserRefObjectCo(Child
, &Ref
);
405 sx
= x
+ UserGetSystemMetrics(SM_CXBORDER
);
406 sy
= y
- yspacing
- UserGetSystemMetrics(SM_CYBORDER
);
408 co_WinPosSetWindowPos( Child
, 0, sx
, sy
, 0, 0,
409 SWP_NOSIZE
| SWP_NOZORDER
| SWP_NOACTIVATE
);
411 Child
->InternalPos
.IconPos
.x
= sx
;
412 Child
->InternalPos
.IconPos
.y
= sy
;
413 Child
->InternalPos
.flags
|= WPF_MININIT
;
414 Child
->InternalPos
.flags
&= ~WPF_SETMINPOSITION
;
416 UserDerefObjectCo(Child
);
418 if (x
<= (rectParent
.right
- UserGetSystemMetrics(SM_CXMINSPACING
)))
425 //ERR("X:%d Y:%d\n",x,y);
428 ExFreePoolWithTag(List
, USERTAG_WINDOWLIST
);
433 WinPosFindIconPos(PWND Window
, POINT
*Pos
)
436 PWND pwndChild
, pwndParent
;
437 int x
, y
, xspacing
, yspacing
;
439 pwndParent
= Window
->spwndParent
;
440 if (pwndParent
== UserGetDesktopWindow())
442 //ERR("Parent is Desktop, Min off screen!\n");
443 /* ReactOS doesn't support iconic minimize to desktop */
444 Pos
->x
= Pos
->y
= -32000;
445 Window
->InternalPos
.flags
|= WPF_MININIT
;
446 Window
->InternalPos
.IconPos
.x
= Pos
->x
;
447 Window
->InternalPos
.IconPos
.y
= Pos
->y
;
451 IntGetClientRect( pwndParent
, &rectParent
);
452 // FIXME: Support gspv.mm.iArrange.
454 y
= rectParent
.bottom
;
456 xspacing
= (UserGetSystemMetrics(SM_CXMINSPACING
)/2)+UserGetSystemMetrics(SM_CXBORDER
);
457 yspacing
= (UserGetSystemMetrics(SM_CYMINSPACING
)/2)+UserGetSystemMetrics(SM_CYBORDER
);
459 //ERR("X:%d Y:%d XS:%d YS:%d\n",Pos->x,Pos->y,xspacing,yspacing);
461 // Set to default position when minimized.
462 Pos
->x
= x
+ UserGetSystemMetrics(SM_CXBORDER
);
463 Pos
->y
= y
- yspacing
- UserGetSystemMetrics(SM_CYBORDER
);
465 for (pwndChild
= pwndParent
->spwndChild
; pwndChild
; pwndChild
= pwndChild
->spwndNext
)
467 if (pwndChild
== Window
) continue;
469 if (pwndChild
->style
& WS_VISIBLE
)
474 //ERR("Pos Child X %d Y %d!\n", pwndChild->InternalPos.IconPos.x, pwndChild->InternalPos.IconPos.y);
475 if ( pwndChild
->InternalPos
.IconPos
.x
== Pos
->x
&&
476 pwndChild
->InternalPos
.IconPos
.y
== Pos
->y
)
478 if (x
<= rectParent
.right
- UserGetSystemMetrics(SM_CXMINSPACING
))
485 Pos
->x
= x
+ UserGetSystemMetrics(SM_CXBORDER
);
486 Pos
->y
= y
- yspacing
- UserGetSystemMetrics(SM_CYBORDER
);
489 Window
->InternalPos
.IconPos
.x
= Pos
->x
;
490 Window
->InternalPos
.IconPos
.y
= Pos
->y
;
491 Window
->InternalPos
.flags
|= WPF_MININIT
;
492 //ERR("Position is set! X:%d Y:%d\n",Pos->x,Pos->y);
497 WinPosInitInternalPos(PWND Wnd
, RECTL
*RestoreRect
)
500 RECTL Rect
= *RestoreRect
;
502 if (Wnd
->spwndParent
!= UserGetDesktopWindow())
504 RECTL_vOffsetRect(&Rect
,
505 -Wnd
->spwndParent
->rcClient
.left
,
506 -Wnd
->spwndParent
->rcClient
.top
);
512 if (!Wnd
->InternalPosInitialized
)
514 // FIXME: Use check point Atom..
515 Wnd
->InternalPos
.flags
= 0;
516 Wnd
->InternalPos
.MaxPos
.x
= Wnd
->InternalPos
.MaxPos
.y
= -1;
517 Wnd
->InternalPos
.IconPos
.x
= Wnd
->InternalPos
.IconPos
.y
= -1;
518 Wnd
->InternalPos
.NormalRect
= Rect
;
519 Wnd
->InternalPosInitialized
= TRUE
;
522 if (Wnd
->style
& WS_MINIMIZE
)
524 Wnd
->InternalPos
.IconPos
= Size
;
525 Wnd
->InternalPos
.flags
|= WPF_MININIT
;
527 else if (Wnd
->style
& WS_MAXIMIZE
)
529 Wnd
->InternalPos
.flags
|= WPF_MAXINIT
;
531 if ( Wnd
->spwndParent
== Wnd
->head
.rpdesk
->pDeskInfo
->spwnd
)
533 if (Wnd
->state
& WNDS_MAXIMIZESTOMONITOR
)
535 Wnd
->InternalPos
.flags
&= ~WPF_MAXINIT
;
536 Wnd
->InternalPos
.MaxPos
.x
= Wnd
->InternalPos
.MaxPos
.y
= -1;
541 PMONITOR pmonitor
= UserMonitorFromRect(&Rect
, MONITOR_DEFAULTTOPRIMARY
);
542 // FIXME: support DPI aware, rcWorkDPI/Real etc..
543 WorkArea
= pmonitor
->rcMonitor
;
545 if (Wnd
->style
& WS_MAXIMIZEBOX
)
546 { // Support (Wnd->state & WNDS_HASCAPTION) || pmonitor->cFullScreen too.
547 if ((Wnd
->style
& WS_CAPTION
) == WS_CAPTION
|| !(Wnd
->style
& (WS_CHILD
| WS_POPUP
)))
549 WorkArea
= pmonitor
->rcWork
;
554 Wnd
->InternalPos
.MaxPos
.x
= Rect
.left
- WorkArea
.left
;
555 Wnd
->InternalPos
.MaxPos
.y
= Rect
.top
- WorkArea
.top
;
557 /*ERR("WinPosIP 2 X %d = R.l %d - W.l %d | Y %d = R.t %d - W.t %d\n",
558 Wnd->InternalPos.MaxPos.x,
559 Rect.left, WorkArea.left,
560 Wnd->InternalPos.MaxPos.y,
561 Rect.top, WorkArea.top);*/
565 Wnd
->InternalPos
.MaxPos
= Size
;
569 Wnd
->InternalPos
.NormalRect
= Rect
;
575 IntGetWindowPlacement(PWND Wnd
, WINDOWPLACEMENT
*lpwndpl
)
577 if (!Wnd
) return FALSE
;
579 if(lpwndpl
->length
!= sizeof(WINDOWPLACEMENT
))
586 WinPosInitInternalPos(Wnd
, &Wnd
->rcWindow
);
588 lpwndpl
->showCmd
= SW_HIDE
;
590 if ( Wnd
->style
& WS_MINIMIZE
)
591 lpwndpl
->showCmd
= SW_SHOWMINIMIZED
;
593 lpwndpl
->showCmd
= ( Wnd
->style
& WS_MAXIMIZE
) ? SW_SHOWMAXIMIZED
: SW_SHOWNORMAL
;
595 lpwndpl
->rcNormalPosition
= Wnd
->InternalPos
.NormalRect
;
597 if (Wnd
->InternalPos
.flags
& WPF_MININIT
) // Return if it was set!
599 lpwndpl
->ptMinPosition
.x
= Wnd
->InternalPos
.IconPos
.x
;
600 lpwndpl
->ptMinPosition
.y
= Wnd
->InternalPos
.IconPos
.y
;
603 lpwndpl
->ptMinPosition
.x
= lpwndpl
->ptMinPosition
.y
= -1;
605 if ( Wnd
->InternalPos
.flags
& WPF_MAXINIT
&& // Return if set and not maximized to monitor!
606 !(Wnd
->state
& WNDS_MAXIMIZESTOMONITOR
))
608 lpwndpl
->ptMaxPosition
.x
= Wnd
->InternalPos
.MaxPos
.x
;
609 lpwndpl
->ptMaxPosition
.y
= Wnd
->InternalPos
.MaxPos
.y
;
612 lpwndpl
->ptMaxPosition
.x
= lpwndpl
->ptMaxPosition
.y
= -1;
614 if ( Wnd
->spwndParent
== Wnd
->head
.rpdesk
->pDeskInfo
->spwnd
&&
615 !(Wnd
->ExStyle
& WS_EX_TOOLWINDOW
))
617 PMONITOR pmonitor
= UserMonitorFromRect(&lpwndpl
->rcNormalPosition
, MONITOR_DEFAULTTOPRIMARY
);
619 // FIXME: support DPI aware, rcWorkDPI/Real etc..
620 if (Wnd
->InternalPos
.flags
& WPF_MININIT
)
622 lpwndpl
->ptMinPosition
.x
-= (pmonitor
->rcWork
.left
- pmonitor
->rcMonitor
.left
);
623 lpwndpl
->ptMinPosition
.y
-= (pmonitor
->rcWork
.top
- pmonitor
->rcMonitor
.top
);
625 RECTL_vOffsetRect(&lpwndpl
->rcNormalPosition
,
626 pmonitor
->rcMonitor
.left
- pmonitor
->rcWork
.left
,
627 pmonitor
->rcMonitor
.top
- pmonitor
->rcWork
.top
);
630 if ( Wnd
->InternalPos
.flags
& WPF_RESTORETOMAXIMIZED
|| Wnd
->style
& WS_MAXIMIZE
)
631 lpwndpl
->flags
|= WPF_RESTORETOMAXIMIZED
;
633 if ( ((Wnd
->style
& (WS_CHILD
|WS_POPUP
)) == WS_CHILD
) && Wnd
->InternalPos
.flags
& WPF_SETMINPOSITION
)
634 lpwndpl
->flags
|= WPF_SETMINPOSITION
;
639 /* make sure the specified rect is visible on screen */
640 static void make_rect_onscreen( RECT
*rect
)
642 PMONITOR pmonitor
= UserMonitorFromRect( rect
, MONITOR_DEFAULTTONEAREST
); // Wine uses this.
644 // FIXME: support DPI aware, rcWorkDPI/Real etc..
645 if (!pmonitor
) return;
646 /* FIXME: map coordinates from rcWork to rcMonitor */
647 if (rect
->right
<= pmonitor
->rcWork
.left
)
649 rect
->right
+= pmonitor
->rcWork
.left
- rect
->left
;
650 rect
->left
= pmonitor
->rcWork
.left
;
652 else if (rect
->left
>= pmonitor
->rcWork
.right
)
654 rect
->left
+= pmonitor
->rcWork
.right
- rect
->right
;
655 rect
->right
= pmonitor
->rcWork
.right
;
657 if (rect
->bottom
<= pmonitor
->rcWork
.top
)
659 rect
->bottom
+= pmonitor
->rcWork
.top
- rect
->top
;
660 rect
->top
= pmonitor
->rcWork
.top
;
662 else if (rect
->top
>= pmonitor
->rcWork
.bottom
)
664 rect
->top
+= pmonitor
->rcWork
.bottom
- rect
->bottom
;
665 rect
->bottom
= pmonitor
->rcWork
.bottom
;
669 /* make sure the specified point is visible on screen */
670 static void make_point_onscreen( POINT
*pt
)
674 RECTL_vSetRect( &rect
, pt
->x
, pt
->y
, pt
->x
+ 1, pt
->y
+ 1 );
675 make_rect_onscreen( &rect
);
681 IntSetWindowPlacement(PWND Wnd
, WINDOWPLACEMENT
*wpl
, UINT Flags
)
686 if ( Flags
& PLACE_MIN
) make_point_onscreen( &wpl
->ptMinPosition
);
687 if ( Flags
& PLACE_MAX
) make_point_onscreen( &wpl
->ptMaxPosition
);
688 if ( Flags
& PLACE_RECT
) make_rect_onscreen( &wpl
->rcNormalPosition
);
690 if (!Wnd
|| Wnd
== Wnd
->head
.rpdesk
->pDeskInfo
->spwnd
) return FALSE
;
692 if ( Flags
& PLACE_MIN
) Wnd
->InternalPos
.IconPos
= wpl
->ptMinPosition
;
693 if ( Flags
& PLACE_MAX
) Wnd
->InternalPos
.MaxPos
= wpl
->ptMaxPosition
;
694 if ( Flags
& PLACE_RECT
) Wnd
->InternalPos
.NormalRect
= wpl
->rcNormalPosition
;
696 SWP_Flags
= SWP_NOZORDER
| SWP_NOACTIVATE
| ((wpl
->flags
& WPF_ASYNCWINDOWPLACEMENT
) ? SWP_ASYNCWINDOWPOS
: 0);
698 if (Wnd
->style
& WS_MINIMIZE
)
700 if (Flags
& PLACE_MIN
|| Wnd
->InternalPos
.flags
& WPF_SETMINPOSITION
)
702 co_WinPosSetWindowPos(Wnd
, HWND_TOP
,
703 wpl
->ptMinPosition
.x
, wpl
->ptMinPosition
.y
, 0, 0,
704 SWP_NOSIZE
| SWP_Flags
);
705 Wnd
->InternalPos
.flags
|= WPF_MININIT
;
708 else if (Wnd
->style
& WS_MAXIMIZE
)
710 if (Flags
& PLACE_MAX
)
712 co_WinPosSetWindowPos(Wnd
, HWND_TOP
,
713 wpl
->ptMaxPosition
.x
, wpl
->ptMaxPosition
.y
, 0, 0,
714 SWP_NOSIZE
| SWP_Flags
);
715 Wnd
->InternalPos
.flags
|= WPF_MAXINIT
;
718 else if (Flags
& PLACE_RECT
)
720 co_WinPosSetWindowPos(Wnd
, HWND_TOP
,
721 wpl
->rcNormalPosition
.left
, wpl
->rcNormalPosition
.top
,
722 wpl
->rcNormalPosition
.right
- wpl
->rcNormalPosition
.left
,
723 wpl
->rcNormalPosition
.bottom
- wpl
->rcNormalPosition
.top
,
727 sAsync
= (Wnd
->head
.pti
->MessageQueue
!= gptiCurrent
->MessageQueue
&& wpl
->flags
& WPF_ASYNCWINDOWPLACEMENT
);
730 co_IntSendMessageNoWait( UserHMGetHandle(Wnd
), WM_ASYNC_SHOWWINDOW
, wpl
->showCmd
, 0 );
732 co_WinPosShowWindow(Wnd
, wpl
->showCmd
);
734 if ( Wnd
->style
& WS_MINIMIZE
&& !sAsync
)
736 if ( wpl
->flags
& WPF_SETMINPOSITION
)
737 Wnd
->InternalPos
.flags
|= WPF_SETMINPOSITION
;
739 if ( wpl
->flags
& WPF_RESTORETOMAXIMIZED
)
740 Wnd
->InternalPos
.flags
|= WPF_RESTORETOMAXIMIZED
;
746 co_WinPosMinMaximize(PWND Wnd
, UINT ShowFlag
, RECT
* NewPos
)
755 wpl
.length
= sizeof(wpl
);
756 IntGetWindowPlacement( Wnd
, &wpl
);
758 if (co_HOOK_CallHooks( WH_CBT
, HCBT_MINMAX
, (WPARAM
)Wnd
->head
.h
, ShowFlag
))
760 ERR("WinPosMinMaximize WH_CBT Call Hook return!\n");
761 return SWP_NOSIZE
| SWP_NOMOVE
;
763 if (Wnd
->style
& WS_MINIMIZE
)
767 case SW_SHOWMINNOACTIVE
:
768 case SW_SHOWMINIMIZED
:
769 case SW_FORCEMINIMIZE
:
771 return SWP_NOSIZE
| SWP_NOMOVE
;
773 if (!co_IntSendMessageNoWait(Wnd
->head
.h
, WM_QUERYOPEN
, 0, 0))
775 return(SWP_NOSIZE
| SWP_NOMOVE
);
777 SwpFlags
|= SWP_NOCOPYBITS
;
781 case SW_SHOWMINNOACTIVE
:
782 case SW_SHOWMINIMIZED
:
783 case SW_FORCEMINIMIZE
:
786 //ERR("MinMaximize Minimize\n");
787 if (Wnd
->style
& WS_MAXIMIZE
)
789 Wnd
->InternalPos
.flags
|= WPF_RESTORETOMAXIMIZED
;
793 Wnd
->InternalPos
.flags
&= ~WPF_RESTORETOMAXIMIZED
;
796 old_style
= IntSetStyle( Wnd
, WS_MINIMIZE
, WS_MAXIMIZE
);
798 co_UserRedrawWindow(Wnd
, NULL
, 0, RDW_VALIDATE
| RDW_NOERASE
|
799 RDW_NOINTERNALPAINT
);
801 if (!(Wnd
->InternalPos
.flags
& WPF_SETMINPOSITION
))
802 Wnd
->InternalPos
.flags
&= ~WPF_MININIT
;
804 WinPosFindIconPos(Wnd
, &wpl
.ptMinPosition
);
806 if (!(old_style
& WS_MINIMIZE
)) SwpFlags
|= SWP_STATECHANGED
;
808 /*ERR("Minimize: %d,%d %dx%d\n",
809 wpl.ptMinPosition.x, wpl.ptMinPosition.y, UserGetSystemMetrics(SM_CXMINIMIZED),
810 UserGetSystemMetrics(SM_CYMINIMIZED));
812 RECTL_vSetRect(NewPos
, wpl
.ptMinPosition
.x
, wpl
.ptMinPosition
.y
,
813 // wpl.ptMinPosition.x + UserGetSystemMetrics(SM_CXMINIMIZED),
814 // wpl.ptMinPosition.y + UserGetSystemMetrics(SM_CYMINIMIZED));
815 UserGetSystemMetrics(SM_CXMINIMIZED
),
816 UserGetSystemMetrics(SM_CYMINIMIZED
));
817 SwpFlags
|= SWP_NOCOPYBITS
;
823 //ERR("MinMaximize Maximize\n");
824 if ((Wnd
->style
& WS_MAXIMIZE
) && (Wnd
->style
& WS_VISIBLE
))
826 SwpFlags
= SWP_NOSIZE
| SWP_NOMOVE
;
829 co_WinPosGetMinMaxInfo(Wnd
, &Size
, &wpl
.ptMaxPosition
, NULL
, NULL
);
831 /*ERR("Maximize: %d,%d %dx%d\n",
832 wpl.ptMaxPosition.x, wpl.ptMaxPosition.y, Size.x, Size.y);
834 old_style
= IntSetStyle( Wnd
, WS_MAXIMIZE
, WS_MINIMIZE
);
836 if (!(old_style
& WS_MAXIMIZE
)) SwpFlags
|= SWP_STATECHANGED
;
837 RECTL_vSetRect(NewPos
, wpl
.ptMaxPosition
.x
, wpl
.ptMaxPosition
.y
,
838 // wpl.ptMaxPosition.x + Size.x, wpl.ptMaxPosition.y + Size.y);
843 case SW_SHOWNOACTIVATE
:
844 Wnd
->InternalPos
.flags
&= ~WPF_RESTORETOMAXIMIZED
;
848 case SW_SHOWDEFAULT
: /* FIXME: should have its own handler */
850 //ERR("MinMaximize Restore\n");
851 old_style
= IntSetStyle( Wnd
, 0, WS_MINIMIZE
| WS_MAXIMIZE
);
852 if (old_style
& WS_MINIMIZE
)
854 if (Wnd
->InternalPos
.flags
& WPF_RESTORETOMAXIMIZED
)
856 co_WinPosGetMinMaxInfo(Wnd
, &Size
, &wpl
.ptMaxPosition
, NULL
, NULL
);
857 IntSetStyle( Wnd
, WS_MAXIMIZE
, 0 );
858 SwpFlags
|= SWP_STATECHANGED
;
859 /*ERR("Restore to Max: %d,%d %dx%d\n",
860 wpl.ptMaxPosition.x, wpl.ptMaxPosition.y, Size.x, Size.y);
862 RECTL_vSetRect(NewPos
, wpl
.ptMaxPosition
.x
, wpl
.ptMaxPosition
.y
,
863 // wpl.ptMaxPosition.x + Size.x, wpl.ptMaxPosition.y + Size.y);
869 *NewPos
= wpl
.rcNormalPosition
;
870 /*ERR("Restore Max: %d,%d %dx%d\n",
871 NewPos->left, NewPos->top, NewPos->right - NewPos->left, NewPos->bottom - NewPos->top);
873 NewPos
->right
-= NewPos
->left
;
874 NewPos
->bottom
-= NewPos
->top
;
880 if (!(old_style
& WS_MAXIMIZE
))
884 SwpFlags
|= SWP_STATECHANGED
;
885 Wnd
->InternalPos
.flags
&= ~WPF_RESTORETOMAXIMIZED
;
886 *NewPos
= wpl
.rcNormalPosition
;
887 /*ERR("Restore Min: %d,%d %dx%d\n",
888 NewPos->left, NewPos->top, NewPos->right - NewPos->left, NewPos->bottom - NewPos->top);
890 NewPos
->right
-= NewPos
->left
;
891 NewPos
->bottom
-= NewPos
->top
;
900 UserHasWindowEdge(DWORD Style
, DWORD ExStyle
)
902 if (Style
& WS_MINIMIZE
)
904 if (ExStyle
& WS_EX_DLGMODALFRAME
)
906 if (ExStyle
& WS_EX_STATICEDGE
)
908 if (Style
& WS_THICKFRAME
)
911 if (Style
== WS_DLGFRAME
|| Style
== WS_CAPTION
)
917 IntGetWindowBorderMeasures(PWND Wnd
, UINT
*cx
, UINT
*cy
)
919 if(HAS_DLGFRAME(Wnd
->style
, Wnd
->ExStyle
) && !(Wnd
->style
& WS_MINIMIZE
))
921 *cx
= UserGetSystemMetrics(SM_CXDLGFRAME
);
922 *cy
= UserGetSystemMetrics(SM_CYDLGFRAME
);
926 if(HAS_THICKFRAME(Wnd
->style
, Wnd
->ExStyle
)&& !(Wnd
->style
& WS_MINIMIZE
))
928 *cx
= UserGetSystemMetrics(SM_CXFRAME
);
929 *cy
= UserGetSystemMetrics(SM_CYFRAME
);
931 else if(HAS_THINFRAME(Wnd
->style
, Wnd
->ExStyle
))
933 *cx
= UserGetSystemMetrics(SM_CXBORDER
);
934 *cy
= UserGetSystemMetrics(SM_CYBORDER
);
944 UserGetWindowBorders(DWORD Style
, DWORD ExStyle
, SIZE
*Size
, BOOL WithClient
)
948 if (UserHasWindowEdge(Style
, ExStyle
))
950 else if (ExStyle
& WS_EX_STATICEDGE
)
952 if ((ExStyle
& WS_EX_CLIENTEDGE
) && WithClient
)
954 if (Style
& WS_CAPTION
|| ExStyle
& WS_EX_DLGMODALFRAME
)
956 Size
->cx
= Size
->cy
= Border
;
957 if ((Style
& WS_THICKFRAME
) && !(Style
& WS_MINIMIZE
))
959 Size
->cx
+= UserGetSystemMetrics(SM_CXFRAME
) - UserGetSystemMetrics(SM_CXDLGFRAME
);
960 Size
->cy
+= UserGetSystemMetrics(SM_CYFRAME
) - UserGetSystemMetrics(SM_CYDLGFRAME
);
962 Size
->cx
*= UserGetSystemMetrics(SM_CXBORDER
);
963 Size
->cy
*= UserGetSystemMetrics(SM_CYBORDER
);
967 UserAdjustWindowRectEx(LPRECT lpRect
,
976 lpRect
->top
-= UserGetSystemMetrics(SM_CYMENU
);
978 if ((dwStyle
& WS_CAPTION
) == WS_CAPTION
)
980 if (dwExStyle
& WS_EX_TOOLWINDOW
)
981 lpRect
->top
-= UserGetSystemMetrics(SM_CYSMCAPTION
);
983 lpRect
->top
-= UserGetSystemMetrics(SM_CYCAPTION
);
985 UserGetWindowBorders(dwStyle
, dwExStyle
, &BorderSize
, TRUE
);
995 co_WinPosGetMinMaxInfo(PWND Window
, POINT
* MaxSize
, POINT
* MaxPos
,
996 POINT
* MinTrack
, POINT
* MaxTrack
)
1001 LONG style
= Window
->style
;
1003 LONG exstyle
= Window
->ExStyle
;
1006 ASSERT_REFS_CO(Window
);
1008 /* Compute default values */
1010 rc
= Window
->rcWindow
;
1011 MinMax
.ptReserved
.x
= rc
.left
;
1012 MinMax
.ptReserved
.y
= rc
.top
;
1014 if ((style
& WS_CAPTION
) == WS_CAPTION
)
1015 adjustedStyle
= style
& ~WS_BORDER
; /* WS_CAPTION = WS_DLGFRAME | WS_BORDER */
1017 adjustedStyle
= style
;
1019 if(Window
->spwndParent
)
1020 IntGetClientRect(Window
->spwndParent
, &rc
);
1021 UserAdjustWindowRectEx(&rc
, adjustedStyle
, ((style
& WS_POPUP
) && Window
->IDMenu
), exstyle
);
1026 MinMax
.ptMaxSize
.x
= rc
.right
- rc
.left
;
1027 MinMax
.ptMaxSize
.y
= rc
.bottom
- rc
.top
;
1028 if (style
& (WS_DLGFRAME
| WS_BORDER
))
1030 MinMax
.ptMinTrackSize
.x
= UserGetSystemMetrics(SM_CXMINTRACK
);
1031 MinMax
.ptMinTrackSize
.y
= UserGetSystemMetrics(SM_CYMINTRACK
);
1035 MinMax
.ptMinTrackSize
.x
= 2 * xinc
;
1036 MinMax
.ptMinTrackSize
.y
= 2 * yinc
;
1038 MinMax
.ptMaxTrackSize
.x
= UserGetSystemMetrics(SM_CXMAXTRACK
);
1039 MinMax
.ptMaxTrackSize
.y
= UserGetSystemMetrics(SM_CYMAXTRACK
);
1040 MinMax
.ptMaxPosition
.x
= -xinc
;
1041 MinMax
.ptMaxPosition
.y
= -yinc
;
1043 if (!EMPTYPOINT(Window
->InternalPos
.MaxPos
)) MinMax
.ptMaxPosition
= Window
->InternalPos
.MaxPos
;
1045 co_IntSendMessage(Window
->head
.h
, WM_GETMINMAXINFO
, 0, (LPARAM
)&MinMax
);
1047 /* if the app didn't change the values, adapt them for the current monitor */
1048 if ((monitor
= UserGetPrimaryMonitor()))
1052 rc_work
= monitor
->rcMonitor
;
1054 if (style
& WS_MAXIMIZEBOX
)
1056 if ((style
& WS_CAPTION
) == WS_CAPTION
|| !(style
& (WS_CHILD
| WS_POPUP
)))
1057 rc_work
= monitor
->rcWork
;
1060 if (MinMax
.ptMaxSize
.x
== UserGetSystemMetrics(SM_CXSCREEN
) + 2 * xinc
&&
1061 MinMax
.ptMaxSize
.y
== UserGetSystemMetrics(SM_CYSCREEN
) + 2 * yinc
)
1063 MinMax
.ptMaxSize
.x
= (rc_work
.right
- rc_work
.left
) + 2 * xinc
;
1064 MinMax
.ptMaxSize
.y
= (rc_work
.bottom
- rc_work
.top
) + 2 * yinc
;
1066 if (MinMax
.ptMaxPosition
.x
== -xinc
&& MinMax
.ptMaxPosition
.y
== -yinc
)
1068 MinMax
.ptMaxPosition
.x
= rc_work
.left
- xinc
;
1069 MinMax
.ptMaxPosition
.y
= rc_work
.top
- yinc
;
1071 if (MinMax
.ptMaxSize
.x
>= (monitor
->rcMonitor
.right
- monitor
->rcMonitor
.left
) &&
1072 MinMax
.ptMaxSize
.y
>= (monitor
->rcMonitor
.bottom
- monitor
->rcMonitor
.top
) )
1073 Window
->state
|= WNDS_MAXIMIZESTOMONITOR
;
1075 Window
->state
&= ~WNDS_MAXIMIZESTOMONITOR
;
1079 MinMax
.ptMaxTrackSize
.x
= max(MinMax
.ptMaxTrackSize
.x
,
1080 MinMax
.ptMinTrackSize
.x
);
1081 MinMax
.ptMaxTrackSize
.y
= max(MinMax
.ptMaxTrackSize
.y
,
1082 MinMax
.ptMinTrackSize
.y
);
1085 *MaxSize
= MinMax
.ptMaxSize
;
1087 *MaxPos
= MinMax
.ptMaxPosition
;
1089 *MinTrack
= MinMax
.ptMinTrackSize
;
1091 *MaxTrack
= MinMax
.ptMaxTrackSize
;
1093 return 0; // FIXME: What does it return?
1098 FixClientRect(PRECTL ClientRect
, PRECTL WindowRect
)
1100 if (ClientRect
->left
< WindowRect
->left
)
1102 ClientRect
->left
= WindowRect
->left
;
1104 else if (WindowRect
->right
< ClientRect
->left
)
1106 ClientRect
->left
= WindowRect
->right
;
1108 if (ClientRect
->right
< WindowRect
->left
)
1110 ClientRect
->right
= WindowRect
->left
;
1112 else if (WindowRect
->right
< ClientRect
->right
)
1114 ClientRect
->right
= WindowRect
->right
;
1116 if (ClientRect
->top
< WindowRect
->top
)
1118 ClientRect
->top
= WindowRect
->top
;
1120 else if (WindowRect
->bottom
< ClientRect
->top
)
1122 ClientRect
->top
= WindowRect
->bottom
;
1124 if (ClientRect
->bottom
< WindowRect
->top
)
1126 ClientRect
->bottom
= WindowRect
->top
;
1128 else if (WindowRect
->bottom
< ClientRect
->bottom
)
1130 ClientRect
->bottom
= WindowRect
->bottom
;
1133 /***********************************************************************
1136 * Compute the valid rects from the old and new client rect and WVR_* flags.
1137 * Helper for WM_NCCALCSIZE handling.
1141 get_valid_rects( RECTL
*old_client
, RECTL
*new_client
, UINT flags
, RECTL
*valid
)
1145 if (flags
& WVR_REDRAW
)
1147 RECTL_vSetEmptyRect( &valid
[0] );
1148 RECTL_vSetEmptyRect( &valid
[1] );
1152 if (flags
& WVR_VALIDRECTS
)
1154 if (!RECTL_bIntersectRect( &valid
[0], &valid
[0], new_client
) ||
1155 !RECTL_bIntersectRect( &valid
[1], &valid
[1], old_client
))
1157 RECTL_vSetEmptyRect( &valid
[0] );
1158 RECTL_vSetEmptyRect( &valid
[1] );
1161 flags
= WVR_ALIGNLEFT
| WVR_ALIGNTOP
;
1165 valid
[0] = *new_client
;
1166 valid
[1] = *old_client
;
1169 /* make sure the rectangles have the same size */
1170 cx
= min( valid
[0].right
- valid
[0].left
, valid
[1].right
- valid
[1].left
);
1171 cy
= min( valid
[0].bottom
- valid
[0].top
, valid
[1].bottom
- valid
[1].top
);
1173 if (flags
& WVR_ALIGNBOTTOM
)
1175 valid
[0].top
= valid
[0].bottom
- cy
;
1176 valid
[1].top
= valid
[1].bottom
- cy
;
1180 valid
[0].bottom
= valid
[0].top
+ cy
;
1181 valid
[1].bottom
= valid
[1].top
+ cy
;
1183 if (flags
& WVR_ALIGNRIGHT
)
1185 valid
[0].left
= valid
[0].right
- cx
;
1186 valid
[1].left
= valid
[1].right
- cx
;
1190 valid
[0].right
= valid
[0].left
+ cx
;
1191 valid
[1].right
= valid
[1].left
+ cx
;
1197 co_WinPosDoNCCALCSize(PWND Window
, PWINDOWPOS WinPos
, RECTL
* WindowRect
, RECTL
* ClientRect
, RECTL
* validRects
)
1202 ASSERT_REFS_CO(Window
);
1204 /* Send WM_NCCALCSIZE message to get new client area */
1205 if ((WinPos
->flags
& (SWP_FRAMECHANGED
| SWP_NOSIZE
)) != SWP_NOSIZE
)
1207 NCCALCSIZE_PARAMS params
;
1208 WINDOWPOS winposCopy
;
1210 params
.rgrc
[0] = *WindowRect
; // new coordinates of a window that has been moved or resized
1211 params
.rgrc
[1] = Window
->rcWindow
; // window before it was moved or resized
1212 params
.rgrc
[2] = Window
->rcClient
; // client area before the window was moved or resized
1214 Parent
= Window
->spwndParent
;
1215 if (0 != (Window
->style
& WS_CHILD
) && Parent
)
1217 RECTL_vOffsetRect(&(params
.rgrc
[0]), - Parent
->rcClient
.left
,
1218 - Parent
->rcClient
.top
);
1219 RECTL_vOffsetRect(&(params
.rgrc
[1]), - Parent
->rcClient
.left
,
1220 - Parent
->rcClient
.top
);
1221 RECTL_vOffsetRect(&(params
.rgrc
[2]), - Parent
->rcClient
.left
,
1222 - Parent
->rcClient
.top
);
1225 params
.lppos
= &winposCopy
;
1226 winposCopy
= *WinPos
;
1228 wvrFlags
= co_IntSendMessage(Window
->head
.h
, WM_NCCALCSIZE
, TRUE
, (LPARAM
) ¶ms
);
1230 /* If the application send back garbage, ignore it */
1231 if (params
.rgrc
[0].left
<= params
.rgrc
[0].right
&&
1232 params
.rgrc
[0].top
<= params
.rgrc
[0].bottom
)
1234 *ClientRect
= params
.rgrc
[0]; // First rectangle contains the coordinates of the new client rectangle resulting from the move or resize
1235 if ((Window
->style
& WS_CHILD
) && Parent
)
1237 RECTL_vOffsetRect(ClientRect
, Parent
->rcClient
.left
,
1238 Parent
->rcClient
.top
);
1240 FixClientRect(ClientRect
, WindowRect
);
1243 if (ClientRect
->left
!= Window
->rcClient
.left
||
1244 ClientRect
->top
!= Window
->rcClient
.top
)
1246 WinPos
->flags
&= ~SWP_NOCLIENTMOVE
;
1249 if (ClientRect
->right
- ClientRect
->left
!=
1250 Window
->rcClient
.right
- Window
->rcClient
.left
)
1252 WinPos
->flags
&= ~SWP_NOCLIENTSIZE
;
1255 wvrFlags
&= ~WVR_HREDRAW
;
1257 if (ClientRect
->bottom
- ClientRect
->top
!=
1258 Window
->rcClient
.bottom
- Window
->rcClient
.top
)
1260 WinPos
->flags
&= ~SWP_NOCLIENTSIZE
;
1263 wvrFlags
&= ~WVR_VREDRAW
;
1265 validRects
[0] = params
.rgrc
[1]; // second rectangle contains the valid destination rectangle
1266 validRects
[1] = params
.rgrc
[2]; // third rectangle contains the valid source rectangle
1270 if (!(WinPos
->flags
& SWP_NOMOVE
) &&
1271 (ClientRect
->left
!= Window
->rcClient
.left
||
1272 ClientRect
->top
!= Window
->rcClient
.top
))
1274 WinPos
->flags
&= ~SWP_NOCLIENTMOVE
;
1278 if (WinPos
->flags
& (SWP_NOCOPYBITS
| SWP_NOREDRAW
| SWP_SHOWWINDOW
| SWP_HIDEWINDOW
))
1280 RECTL_vSetEmptyRect( &validRects
[0] );
1281 RECTL_vSetEmptyRect( &validRects
[1] );
1283 else get_valid_rects( &Window
->rcClient
, ClientRect
, wvrFlags
, validRects
);
1290 co_WinPosDoWinPosChanging(PWND Window
,
1295 ASSERT_REFS_CO(Window
);
1297 /* Send WM_WINDOWPOSCHANGING message */
1299 if (!(WinPos
->flags
& SWP_NOSENDCHANGING
))
1301 co_IntSendMessageNoWait(Window
->head
.h
, WM_WINDOWPOSCHANGING
, 0, (LPARAM
) WinPos
);
1304 /* Calculate new position and size */
1306 *WindowRect
= Window
->rcWindow
;
1307 *ClientRect
= (Window
->style
& WS_MINIMIZE
) ? Window
->rcWindow
: Window
->rcClient
;
1309 if (!(WinPos
->flags
& SWP_NOSIZE
))
1311 if (Window
->style
& WS_MINIMIZE
)
1313 WindowRect
->right
= WindowRect
->left
+ UserGetSystemMetrics(SM_CXICON
);
1314 WindowRect
->bottom
= WindowRect
->top
+ UserGetSystemMetrics(SM_CYICON
);
1318 WindowRect
->right
= WindowRect
->left
+ WinPos
->cx
;
1319 WindowRect
->bottom
= WindowRect
->top
+ WinPos
->cy
;
1323 if (!(WinPos
->flags
& SWP_NOMOVE
))
1325 WindowRect
->left
= WinPos
->x
;
1326 WindowRect
->top
= WinPos
->y
;
1327 WindowRect
->right
+= WinPos
->x
- Window
->rcWindow
.left
;
1328 WindowRect
->bottom
+= WinPos
->y
- Window
->rcWindow
.top
;
1329 RECTL_vOffsetRect(ClientRect
,
1330 WinPos
->x
- Window
->rcWindow
.left
,
1331 WinPos
->y
- Window
->rcWindow
.top
);
1335 *WindowRect
= Window
->rcWindow
;
1336 *ClientRect
= Window
->rcClient
;
1338 if (!(WinPos
->flags
& SWP_NOSIZE
))
1340 WindowRect
->right
= WindowRect
->left
+ WinPos
->cx
;
1341 WindowRect
->bottom
= WindowRect
->top
+ WinPos
->cy
;
1344 if (!(WinPos
->flags
& SWP_NOMOVE
))
1350 //ERR("Not SWP_NOMOVE\n");
1351 Parent
= Window
->spwndParent
;
1352 if (((Window
->style
& WS_CHILD
) != 0) &&
1354 Parent
!= Window
->head
.rpdesk
->pDeskInfo
->spwnd
)
1356 //ERR("Not SWP_NOMOVE 1 Parent client offset X %d Y %d\n",X,Y);
1357 X
+= Parent
->rcClient
.left
;
1358 Y
+= Parent
->rcClient
.top
;
1359 //ERR("Not SWP_NOMOVE 2 Parent client offset X %d Y %d\n",X,Y);
1362 WindowRect
->left
= X
;
1363 WindowRect
->top
= Y
;
1364 WindowRect
->right
+= X
- Window
->rcWindow
.left
;
1365 WindowRect
->bottom
+= Y
- Window
->rcWindow
.top
;
1367 RECTL_vOffsetRect(ClientRect
, X
- Window
->rcWindow
.left
,
1368 Y
- Window
->rcWindow
.top
);
1371 WinPos
->flags
|= SWP_NOCLIENTMOVE
| SWP_NOCLIENTSIZE
;
1373 TRACE( "hwnd %p, after %p, swp %d,%d %dx%d flags %08x\n",
1374 WinPos
->hwnd
, WinPos
->hwndInsertAfter
, WinPos
->x
, WinPos
->y
,
1375 WinPos
->cx
, WinPos
->cy
, WinPos
->flags
);
1381 * Fix Z order taking into account owned popups -
1382 * basically we need to maintain them above the window that owns them
1384 * FIXME: hide/show owned popups when owner visibility changes.
1386 * ReactOS: See bug 6751 and 7228.
1390 // Pass all the win:test_children/popup_zorder tests except "move hwnd_F and its popups down" which is if'ed out.
1391 // Side effect, breaks more of the DeferWindowPos api tests, but wine breaks more!!!!
1394 WinPosDoOwnedPopups(PWND Window
, HWND hWndInsertAfter
)
1399 PWND DesktopWindow
, ChildObject
;
1402 TRACE("(%p) hInsertAfter = %p\n", Window
, hWndInsertAfter
);
1404 Owner
= Window
->spwndOwner
? Window
->spwndOwner
->head
.h
: NULL
;
1405 Style
= Window
->style
;
1407 if (Style
& WS_CHILD
)
1409 TRACE("Window is child\n");
1410 return hWndInsertAfter
;
1415 /* Make sure this popup stays above the owner */
1417 if (hWndInsertAfter
!= HWND_TOPMOST
)
1419 DesktopWindow
= UserGetDesktopWindow();
1420 List
= IntWinListChildren(DesktopWindow
);
1424 for (i
= 0; List
[i
]; i
++)
1426 BOOL topmost
= FALSE
;
1428 ChildObject
= ValidateHwndNoErr(List
[i
]);
1431 topmost
= (ChildObject
->ExStyle
& WS_EX_TOPMOST
) != 0;
1434 if (List
[i
] == Owner
)
1436 if (i
> 0) hWndInsertAfter
= List
[i
-1];
1437 else hWndInsertAfter
= topmost
? HWND_TOPMOST
: HWND_TOP
;
1441 if (hWndInsertAfter
== HWND_TOP
|| hWndInsertAfter
== HWND_NOTOPMOST
)
1443 if (!topmost
) break;
1445 else if (List
[i
] == hWndInsertAfter
) break;
1449 return hWndInsertAfter
;
1453 if (hWndInsertAfter
== HWND_BOTTOM
)
1455 TRACE("Window is HWND_BOTTOM\n");
1456 if (List
) ExFreePoolWithTag(List
, USERTAG_WINDOWLIST
);
1462 DesktopWindow
= UserGetDesktopWindow();
1463 List
= IntWinListChildren(DesktopWindow
);
1470 if (hWndInsertAfter
== HWND_TOP
|| hWndInsertAfter
== HWND_NOTOPMOST
)
1472 if (hWndInsertAfter
== HWND_NOTOPMOST
|| !(Window
->ExStyle
& WS_EX_TOPMOST
))
1474 TRACE("skip all the topmost windows\n");
1475 /* skip all the topmost windows */
1477 (ChildObject
= ValidateHwndNoErr(List
[i
])) &&
1478 (ChildObject
->ExStyle
& WS_EX_TOPMOST
)) i
++;
1481 else if (hWndInsertAfter
!= HWND_TOPMOST
)
1483 /* skip windows that are already placed correctly */
1484 for (i
= 0; List
[i
]; i
++)
1486 if (List
[i
] == hWndInsertAfter
) break;
1487 if (List
[i
] == UserHMGetHandle(Window
))
1489 ExFreePoolWithTag(List
, USERTAG_WINDOWLIST
);
1490 goto done
; /* nothing to do if window is moving backwards in z-order */
1495 for (; List
[i
]; i
++)
1498 USER_REFERENCE_ENTRY Ref
;
1500 if (List
[i
] == UserHMGetHandle(Window
))
1503 if (!(Wnd
= ValidateHwndNoErr(List
[i
])))
1506 Owner
= Wnd
->spwndOwner
? Wnd
->spwndOwner
->head
.h
: NULL
;
1508 if (Owner
!= UserHMGetHandle(Window
)) continue;
1510 UserRefObjectCo(Wnd
, &Ref
);
1511 TRACE( "moving %p owned by %p after %p\n", List
[i
], UserHMGetHandle(Window
), hWndInsertAfter
);
1512 co_WinPosSetWindowPos(Wnd
, hWndInsertAfter
, 0, 0, 0, 0,
1513 SWP_NOMOVE
| SWP_NOSIZE
| SWP_NOACTIVATE
| SWP_NOSENDCHANGING
| SWP_DEFERERASE
);
1515 UserDerefObjectCo(Wnd
);
1516 hWndInsertAfter
= List
[i
];
1518 ExFreePoolWithTag(List
, USERTAG_WINDOWLIST
);
1521 return hWndInsertAfter
;
1525 /***********************************************************************
1526 * WinPosInternalMoveWindow
1528 * Update WindowRect and ClientRect of Window and all of its children
1529 * We keep both WindowRect and ClientRect in screen coordinates internally
1533 WinPosInternalMoveWindow(PWND Window
, INT MoveX
, INT MoveY
)
1537 ASSERT(Window
!= Window
->spwndChild
);
1539 Window
->rcWindow
.left
+= MoveX
;
1540 Window
->rcWindow
.right
+= MoveX
;
1541 Window
->rcWindow
.top
+= MoveY
;
1542 Window
->rcWindow
.bottom
+= MoveY
;
1544 Window
->rcClient
.left
+= MoveX
;
1545 Window
->rcClient
.right
+= MoveX
;
1546 Window
->rcClient
.top
+= MoveY
;
1547 Window
->rcClient
.bottom
+= MoveY
;
1549 for(Child
= Window
->spwndChild
; Child
; Child
= Child
->spwndNext
)
1551 WinPosInternalMoveWindow(Child
, MoveX
, MoveY
);
1556 * WinPosFixupSWPFlags
1558 * Fix redundant flags and values in the WINDOWPOS structure.
1562 WinPosFixupFlags(WINDOWPOS
*WinPos
, PWND Wnd
)
1567 /* Finally make sure that all coordinates are valid */
1568 if (WinPos
->x
< -32768) WinPos
->x
= -32768;
1569 else if (WinPos
->x
> 32767) WinPos
->x
= 32767;
1570 if (WinPos
->y
< -32768) WinPos
->y
= -32768;
1571 else if (WinPos
->y
> 32767) WinPos
->y
= 32767;
1573 WinPos
->cx
= max(WinPos
->cx
, 0);
1574 WinPos
->cy
= max(WinPos
->cy
, 0);
1576 Parent
= UserGetAncestor( Wnd
, GA_PARENT
);
1577 if (!IntIsWindowVisible( Parent
)) WinPos
->flags
|= SWP_NOREDRAW
;
1579 if (Wnd
->style
& WS_VISIBLE
) WinPos
->flags
&= ~SWP_SHOWWINDOW
;
1582 WinPos
->flags
&= ~SWP_HIDEWINDOW
;
1583 if (!(WinPos
->flags
& SWP_SHOWWINDOW
)) WinPos
->flags
|= SWP_NOREDRAW
;
1586 /* Check for right size */
1587 if (Wnd
->rcWindow
.right
- Wnd
->rcWindow
.left
== WinPos
->cx
&&
1588 Wnd
->rcWindow
.bottom
- Wnd
->rcWindow
.top
== WinPos
->cy
)
1590 WinPos
->flags
|= SWP_NOSIZE
;
1595 IntClientToScreen( Parent
, &pt
);
1596 //ERR("WPFU C2S wpx %d wpy %d ptx %d pty %d\n",WinPos->x,WinPos->y,pt.x,pt.y);
1597 /* Check for right position */
1598 if (Wnd
->rcWindow
.left
== pt
.x
&& Wnd
->rcWindow
.top
== pt
.y
)
1600 //ERR("In right pos\n");
1601 WinPos
->flags
|= SWP_NOMOVE
;
1604 if (WinPos
->hwnd
== UserGetForegroundWindow())
1606 WinPos
->flags
|= SWP_NOACTIVATE
; /* Already active */
1609 if ((Wnd
->style
& (WS_POPUP
| WS_CHILD
)) != WS_CHILD
)
1611 /* Bring to the top when activating */
1612 if (!(WinPos
->flags
& (SWP_NOACTIVATE
|SWP_HIDEWINDOW
)) &&
1613 (WinPos
->flags
& SWP_NOZORDER
||
1614 (WinPos
->hwndInsertAfter
!= HWND_TOPMOST
&& WinPos
->hwndInsertAfter
!= HWND_NOTOPMOST
)))
1616 WinPos
->flags
&= ~SWP_NOZORDER
;
1617 WinPos
->hwndInsertAfter
= (0 != (Wnd
->ExStyle
& WS_EX_TOPMOST
) ? HWND_TOPMOST
: HWND_TOP
);
1621 /* Check hwndInsertAfter */
1622 if (!(WinPos
->flags
& SWP_NOZORDER
))
1624 /* Fix sign extension */
1625 if (WinPos
->hwndInsertAfter
== (HWND
)0xffff)
1627 WinPos
->hwndInsertAfter
= HWND_TOPMOST
;
1629 else if (WinPos
->hwndInsertAfter
== (HWND
)0xfffe)
1631 WinPos
->hwndInsertAfter
= HWND_NOTOPMOST
;
1634 if (WinPos
->hwndInsertAfter
== HWND_TOP
)
1636 /* Keep it topmost when it's already topmost */
1637 if ((Wnd
->ExStyle
& WS_EX_TOPMOST
) != 0)
1638 WinPos
->hwndInsertAfter
= HWND_TOPMOST
;
1640 if (IntGetWindow(WinPos
->hwnd
, GW_HWNDFIRST
) == WinPos
->hwnd
)
1641 WinPos
->flags
|= SWP_NOZORDER
;
1643 else if (WinPos
->hwndInsertAfter
== HWND_BOTTOM
)
1645 if (!(Wnd
->ExStyle
& WS_EX_TOPMOST
) && IntGetWindow(WinPos
->hwnd
, GW_HWNDLAST
) == WinPos
->hwnd
)
1646 WinPos
->flags
|= SWP_NOZORDER
;
1648 else if (WinPos
->hwndInsertAfter
== HWND_TOPMOST
)
1650 if ((Wnd
->ExStyle
& WS_EX_TOPMOST
) && IntGetWindow(WinPos
->hwnd
, GW_HWNDFIRST
) == WinPos
->hwnd
)
1651 WinPos
->flags
|= SWP_NOZORDER
;
1653 else if (WinPos
->hwndInsertAfter
== HWND_NOTOPMOST
)
1655 if (!(Wnd
->ExStyle
& WS_EX_TOPMOST
))
1656 WinPos
->flags
|= SWP_NOZORDER
;
1658 else /* hwndInsertAfter must be a sibling of the window */
1662 InsAfterWnd
= ValidateHwndNoErr(WinPos
->hwndInsertAfter
);
1668 if (InsAfterWnd
->spwndParent
!= Wnd
->spwndParent
)
1670 /* Note from wine User32 Win test_SetWindowPos:
1671 "Returns TRUE also for windows that are not siblings"
1672 "Does not seem to do anything even without passing flags, still returns TRUE"
1673 "Same thing the other way around."
1674 ".. and with these windows."
1681 * We don't need to change the Z order of hwnd if it's already
1682 * inserted after hwndInsertAfter or when inserting hwnd after
1685 if ((WinPos
->hwnd
== WinPos
->hwndInsertAfter
) ||
1686 ((InsAfterWnd
->spwndNext
) && (WinPos
->hwnd
== InsAfterWnd
->spwndNext
->head
.h
)))
1688 WinPos
->flags
|= SWP_NOZORDER
;
1697 /* x and y are always screen relative */
1699 co_WinPosSetWindowPos(
1701 HWND WndInsertAfter
,
1710 RECTL NewWindowRect
;
1711 RECTL NewClientRect
;
1712 RECTL valid_rects
[2];
1714 HRGN VisBefore
= NULL
;
1715 HRGN VisAfter
= NULL
;
1716 HRGN DirtyRgn
= NULL
;
1717 HRGN ExposedRgn
= NULL
;
1718 HRGN CopyRgn
= NULL
;
1720 RECTL OldWindowRect
, OldClientRect
;
1725 BOOL bPointerInWindow
;
1728 ASSERT_REFS_CO(Window
);
1730 /* FIXME: Get current active window from active queue. Why? since r2915. */
1732 bPointerInWindow
= IntPtInWindow(Window
, gpsi
->ptCursor
.x
, gpsi
->ptCursor
.y
);
1734 WinPos
.hwnd
= Window
->head
.h
;
1735 WinPos
.hwndInsertAfter
= WndInsertAfter
;
1740 WinPos
.flags
= flags
;
1742 if ( flags
& SWP_ASYNCWINDOWPOS
)
1745 PWINDOWPOS ppos
= ExAllocatePoolWithTag(PagedPool
, sizeof(WINDOWPOS
), USERTAG_SWP
);
1748 WinPos
.flags
&= ~SWP_ASYNCWINDOWPOS
; // Clear flag.
1750 /* Yes it's a pointer inside Win32k! */
1751 lRes
= co_IntSendMessageNoWait( WinPos
.hwnd
, WM_ASYNC_SETWINDOWPOS
, 0, (LPARAM
)ppos
);
1752 /* We handle this the same way as Event Hooks and Hooks. */
1755 ExFreePoolWithTag(ppos
, USERTAG_SWP
);
1763 co_WinPosDoWinPosChanging(Window
, &WinPos
, &NewWindowRect
, &NewClientRect
);
1765 // HWND_NOTOPMOST is redirected in WinPosFixupFlags.
1766 //bNoTopMost = WndInsertAfter == HWND_NOTOPMOST;
1768 /* Does the window still exist? */
1769 if (!IntIsWindow(WinPos
.hwnd
))
1771 TRACE("WinPosSetWindowPos: Invalid handle 0x%p!\n",WinPos
.hwnd
);
1772 EngSetLastError(ERROR_INVALID_WINDOW_HANDLE
);
1776 /* Fix up the flags. */
1777 if (!WinPosFixupFlags(&WinPos
, Window
))
1783 Ancestor
= UserGetAncestor(Window
, GA_PARENT
);
1784 if ( (WinPos
.flags
& (SWP_NOZORDER
| SWP_HIDEWINDOW
| SWP_SHOWWINDOW
)) != SWP_NOZORDER
&&
1785 Ancestor
&& Ancestor
->head
.h
== IntGetDesktopWindow() )
1787 WinPos
.hwndInsertAfter
= WinPosDoOwnedPopups(Window
, WinPos
.hwndInsertAfter
);
1790 if (!(WinPos
.flags
& SWP_NOREDRAW
))
1792 /* Compute the visible region before the window position is changed */
1793 if (!(WinPos
.flags
& SWP_SHOWWINDOW
) &&
1794 (WinPos
.flags
& (SWP_NOMOVE
| SWP_NOSIZE
| SWP_NOZORDER
|
1795 SWP_HIDEWINDOW
| SWP_FRAMECHANGED
)) !=
1796 (SWP_NOMOVE
| SWP_NOSIZE
| SWP_NOZORDER
))
1798 VisBefore
= VIS_ComputeVisibleRegion(Window
, FALSE
, FALSE
,
1799 (Window
->style
& WS_CLIPSIBLINGS
) ? TRUE
: FALSE
);
1802 if ( VisBefore
!= NULL
&&
1803 (VisRgn
= (PROSRGNDATA
)RGNOBJAPI_Lock(VisBefore
, NULL
)) &&
1804 REGION_Complexity(VisRgn
) == NULLREGION
)
1806 RGNOBJAPI_Unlock(VisRgn
);
1807 GreDeleteObject(VisBefore
);
1812 RGNOBJAPI_Unlock(VisRgn
);
1813 NtGdiOffsetRgn(VisBefore
, -Window
->rcWindow
.left
, -Window
->rcWindow
.top
);
1818 WvrFlags
= co_WinPosDoNCCALCSize(Window
, &WinPos
, &NewWindowRect
, &NewClientRect
, valid_rects
);
1820 // ERR("co_WinPosDoNCCALCSize returned 0x%x\n valid dest: %d %d %d %d\n valid src : %d %d %d %d\n", WvrFlags,
1821 // valid_rects[0].left,valid_rects[0].top,valid_rects[0].right,valid_rects[0].bottom,
1822 // valid_rects[1].left,valid_rects[1].top,valid_rects[1].right,valid_rects[1].bottom);
1824 /* Validate link windows. (also take into account shell window in hwndShellWindow) */
1825 if (!(WinPos
.flags
& SWP_NOZORDER
) && WinPos
.hwnd
!= UserGetShellWindow())
1827 IntLinkHwnd(Window
, WinPos
.hwndInsertAfter
);
1829 //// Fix bug 6751 & 7228 see WinPosDoOwnedPopups wine Fixme.
1832 PWND InsertAfterWindow
;
1834 if ((ParentWindow
= Window
->spwndParent
)) // Must have a Parent window!
1836 //ERR("SetWindowPos has parent window.\n");
1837 if (WinPos
.hwndInsertAfter
== HWND_TOPMOST
)
1839 InsertAfterWindow
= NULL
;
1841 else if ( WinPos
.hwndInsertAfter
== HWND_TOP
)
1843 InsertAfterWindow
= NULL
;
1845 Sibling
= ParentWindow
->spwndChild
;
1847 while ( Sibling
&& Sibling
->ExStyle
& WS_EX_TOPMOST
)
1849 InsertAfterWindow
= Sibling
;
1850 Sibling
= Sibling
->spwndNext
;
1853 else if (WinPos
.hwndInsertAfter
== HWND_BOTTOM
)
1855 if (ParentWindow
->spwndChild
)
1857 InsertAfterWindow
= ParentWindow
->spwndChild
;
1859 if(InsertAfterWindow
)
1861 while (InsertAfterWindow
->spwndNext
)
1862 InsertAfterWindow
= InsertAfterWindow
->spwndNext
;
1866 InsertAfterWindow
= NULL
;
1869 InsertAfterWindow
= IntGetWindowObject(WinPos
.hwndInsertAfter
);
1870 /* Do nothing if hwndInsertAfter is HWND_BOTTOM and Window is already
1872 if (InsertAfterWindow
!= Window
)
1874 IntUnlinkWindow(Window
);
1875 IntLinkWindow(Window
, InsertAfterWindow
);
1878 if ( ( WinPos
.hwndInsertAfter
== HWND_TOPMOST
||
1879 ( Window
->ExStyle
& WS_EX_TOPMOST
&& Window
->spwndPrev
&& Window
->spwndPrev
->ExStyle
& WS_EX_TOPMOST
) ||
1880 ( Window
->spwndNext
&& Window
->spwndNext
->ExStyle
& WS_EX_TOPMOST
) ) &&
1883 Window
->ExStyle
|= WS_EX_TOPMOST
;
1887 Window
->ExStyle
&= ~ WS_EX_TOPMOST
;
1894 OldWindowRect
= Window
->rcWindow
;
1895 OldClientRect
= Window
->rcClient
;
1896 //ERR("SetWindowPos OldWindowRect: %d %d %d %d\n", OldWindowRect.left,OldWindowRect.top,OldWindowRect.right,OldWindowRect.bottom);
1897 //ERR("SetWindowPos OldClientRect: %d %d %d %d\n", OldClientRect.left,OldClientRect.top,OldClientRect.right,OldClientRect.bottom);
1899 if (NewClientRect
.left
!= OldClientRect
.left
||
1900 NewClientRect
.top
!= OldClientRect
.top
)
1902 WinPosInternalMoveWindow(Window
,
1903 NewClientRect
.left
- OldClientRect
.left
,
1904 NewClientRect
.top
- OldClientRect
.top
);
1907 Window
->rcWindow
= NewWindowRect
;
1908 Window
->rcClient
= NewClientRect
;
1910 //ERR("SetWindowPos NewWindowRect: %d %d %d %d\n", NewWindowRect.left,NewWindowRect.top,NewWindowRect.right,NewWindowRect.bottom);
1911 //ERR("SetWindowPos NewClientRect: %d %d %d %d\n", NewClientRect.left,NewClientRect.top,NewClientRect.right,NewClientRect.bottom);
1913 /* erase parent when hiding or resizing child */
1914 if (WinPos
.flags
& SWP_HIDEWINDOW
)
1916 /* Clear the update region */
1917 co_UserRedrawWindow( Window
,
1920 RDW_VALIDATE
| RDW_NOFRAME
| RDW_NOERASE
| RDW_NOINTERNALPAINT
| RDW_ALLCHILDREN
);
1922 if (Window
->spwndParent
== UserGetDesktopWindow())
1923 co_IntShellHookNotify(HSHELL_WINDOWDESTROYED
, (WPARAM
)Window
->head
.h
, 0);
1925 Window
->style
&= ~WS_VISIBLE
; //IntSetStyle( Window, 0, WS_VISIBLE );
1926 Window
->head
.pti
->cVisWindows
--;
1927 IntNotifyWinEvent(EVENT_OBJECT_HIDE
, Window
, OBJID_WINDOW
, CHILDID_SELF
, WEF_SETBYWNDPTI
);
1929 else if (WinPos
.flags
& SWP_SHOWWINDOW
)
1931 if (Window
->spwndParent
== UserGetDesktopWindow())
1932 co_IntShellHookNotify(HSHELL_WINDOWCREATED
, (WPARAM
)Window
->head
.h
, 0);
1934 Window
->style
|= WS_VISIBLE
; //IntSetStyle( Window, WS_VISIBLE, 0 );
1935 Window
->head
.pti
->cVisWindows
++;
1936 IntNotifyWinEvent(EVENT_OBJECT_SHOW
, Window
, OBJID_WINDOW
, CHILDID_SELF
, WEF_SETBYWNDPTI
);
1939 if (Window
->hrgnUpdate
!= NULL
&& Window
->hrgnUpdate
!= HRGN_WINDOW
)
1941 NtGdiOffsetRgn(Window
->hrgnUpdate
,
1942 NewWindowRect
.left
- OldWindowRect
.left
,
1943 NewWindowRect
.top
- OldWindowRect
.top
);
1946 DceResetActiveDCEs(Window
); // For WS_VISIBLE changes.
1948 if (!(WinPos
.flags
& SWP_NOREDRAW
))
1950 /* Determine the new visible region */
1951 VisAfter
= VIS_ComputeVisibleRegion(Window
, FALSE
, FALSE
,
1952 (Window
->style
& WS_CLIPSIBLINGS
) ? TRUE
: FALSE
);
1955 if ( VisAfter
!= NULL
&&
1956 (VisRgn
= (PROSRGNDATA
)RGNOBJAPI_Lock(VisAfter
, NULL
)) &&
1957 REGION_Complexity(VisRgn
) == NULLREGION
)
1959 RGNOBJAPI_Unlock(VisRgn
);
1960 GreDeleteObject(VisAfter
);
1965 RGNOBJAPI_Unlock(VisRgn
);
1966 NtGdiOffsetRgn(VisAfter
, -Window
->rcWindow
.left
, -Window
->rcWindow
.top
);
1970 * Determine which pixels can be copied from the old window position
1971 * to the new. Those pixels must be visible in both the old and new
1972 * position. Also, check the class style to see if the windows of this
1973 * class need to be completely repainted on (horizontal/vertical) size
1976 if ( VisBefore
!= NULL
&&
1978 !(WinPos
.flags
& SWP_NOCOPYBITS
) &&
1979 ((WinPos
.flags
& SWP_NOSIZE
) || !(WvrFlags
& WVR_REDRAW
)) &&
1980 !(Window
->ExStyle
& WS_EX_TRANSPARENT
) )
1982 CopyRgn
= IntSysCreateRectRgn(0, 0, 0, 0);
1983 RgnType
= NtGdiCombineRgn(CopyRgn
, VisAfter
, VisBefore
, RGN_AND
);
1986 * If this is (also) a window resize, the whole nonclient area
1987 * needs to be repainted. So we limit the copy to the client area,
1988 * 'cause there is no use in copying it (would possibly cause
1989 * "flashing" too). However, if the copy region is already empty,
1990 * we don't have to crop (can't take anything away from an empty
1993 if (!(WinPos
.flags
& SWP_NOSIZE
) &&
1995 RgnType
!= NULLREGION
)
1997 PROSRGNDATA pCopyRgn
;
1998 RECTL ORect
= OldClientRect
;
1999 RECTL NRect
= NewClientRect
;
2000 RECTL_vOffsetRect(&ORect
, - OldWindowRect
.left
, - OldWindowRect
.top
);
2001 RECTL_vOffsetRect(&NRect
, - NewWindowRect
.left
, - NewWindowRect
.top
);
2002 RECTL_bIntersectRect(&CopyRect
, &ORect
, &NRect
);
2003 pCopyRgn
= RGNOBJAPI_Lock(CopyRgn
, NULL
);
2004 REGION_CropAndOffsetRegion(pCopyRgn
, pCopyRgn
, &CopyRect
, NULL
);
2005 RGNOBJAPI_Unlock(pCopyRgn
);
2008 /* No use in copying bits which are in the update region. */
2009 if (Window
->hrgnUpdate
!= NULL
)
2011 NtGdiOffsetRgn(CopyRgn
, NewWindowRect
.left
, NewWindowRect
.top
);
2012 NtGdiCombineRgn(CopyRgn
, CopyRgn
, Window
->hrgnUpdate
, RGN_DIFF
);
2013 NtGdiOffsetRgn(CopyRgn
, -NewWindowRect
.left
, -NewWindowRect
.top
);
2017 * Now, get the bounding box of the copy region. If it's empty
2018 * there's nothing to copy. Also, it's no use copying bits onto
2021 if ( (VisRgn
= (PROSRGNDATA
)RGNOBJAPI_Lock(CopyRgn
, NULL
)) &&
2022 REGION_GetRgnBox(VisRgn
, &CopyRect
) == NULLREGION
)
2024 /* Nothing to copy, clean up */
2025 RGNOBJAPI_Unlock(VisRgn
);
2026 GreDeleteObject(CopyRgn
);
2029 else if (OldWindowRect
.left
!= NewWindowRect
.left
||
2030 OldWindowRect
.top
!= NewWindowRect
.top
)
2034 RGNOBJAPI_Unlock(VisRgn
);
2038 * Small trick here: there is no function to bitblt a region. So
2039 * we set the region as the clipping region, take the bounding box
2040 * of the region and bitblt that. Since nothing outside the clipping
2041 * region is copied, this has the effect of bitblt'ing the region.
2043 * Since NtUserGetDCEx takes ownership of the clip region, we need
2044 * to create a copy of CopyRgn and pass that. We need CopyRgn later
2046 NtGdiOffsetRgn(CopyRgn
, NewWindowRect
.left
, NewWindowRect
.top
);
2047 Dc
= UserGetDCEx( Window
,
2049 DCX_WINDOW
|DCX_CACHE
|DCX_INTERSECTRGN
|DCX_CLIPSIBLINGS
|DCX_KEEPCLIPRGN
);
2051 CopyRect
.left
, CopyRect
.top
,
2052 CopyRect
.right
- CopyRect
.left
,
2053 CopyRect
.bottom
- CopyRect
.top
,
2055 CopyRect
.left
+ (OldWindowRect
.left
- NewWindowRect
.left
),
2056 CopyRect
.top
+ (OldWindowRect
.top
- NewWindowRect
.top
),
2061 UserReleaseDC(Window
, Dc
, FALSE
);
2062 IntValidateParent(Window
, CopyRgn
, FALSE
);
2063 NtGdiOffsetRgn(CopyRgn
, -NewWindowRect
.left
, -NewWindowRect
.top
);
2067 RGNOBJAPI_Unlock(VisRgn
);
2075 /* We need to redraw what wasn't visible before */
2076 if (VisAfter
!= NULL
)
2078 DirtyRgn
= IntSysCreateRectRgn(0, 0, 0, 0);
2079 if (CopyRgn
!= NULL
)
2081 RgnType
= NtGdiCombineRgn(DirtyRgn
, VisAfter
, CopyRgn
, RGN_DIFF
);
2085 RgnType
= NtGdiCombineRgn(DirtyRgn
, VisAfter
, 0, RGN_COPY
);
2087 if (RgnType
!= ERROR
&& RgnType
!= NULLREGION
)
2090 NtGdiOffsetRgn(DirtyRgn, Window->rcWindow.left, Window->rcWindow.top);
2091 IntInvalidateWindows( Window,
2093 RDW_ERASE | RDW_FRAME | RDW_INVALIDATE | RDW_ALLCHILDREN);
2095 GreDeleteObject(DirtyRgn);
2098 PWND Parent
= Window
->spwndParent
;
2100 NtGdiOffsetRgn( DirtyRgn
,
2101 Window
->rcWindow
.left
,
2102 Window
->rcWindow
.top
);
2103 if ( (Window
->style
& WS_CHILD
) &&
2105 !(Parent
->style
& WS_CLIPCHILDREN
))
2107 IntInvalidateWindows( Parent
,
2109 RDW_ERASE
| RDW_INVALIDATE
);
2110 co_IntPaintWindows(Parent
, RDW_ERASENOW
, FALSE
);
2114 IntInvalidateWindows( Window
,
2116 RDW_ERASE
| RDW_FRAME
| RDW_INVALIDATE
| RDW_ALLCHILDREN
);
2119 GreDeleteObject(DirtyRgn
);
2122 if (CopyRgn
!= NULL
)
2124 GreDeleteObject(CopyRgn
);
2127 /* Expose what was covered before but not covered anymore */
2128 if (VisBefore
!= NULL
)
2130 ExposedRgn
= IntSysCreateRectRgn(0, 0, 0, 0);
2131 RgnType
= NtGdiCombineRgn(ExposedRgn
, VisBefore
, NULL
, RGN_COPY
);
2132 NtGdiOffsetRgn( ExposedRgn
,
2133 OldWindowRect
.left
- NewWindowRect
.left
,
2134 OldWindowRect
.top
- NewWindowRect
.top
);
2136 if (VisAfter
!= NULL
)
2137 RgnType
= NtGdiCombineRgn(ExposedRgn
, ExposedRgn
, VisAfter
, RGN_DIFF
);
2139 if (RgnType
!= ERROR
&& RgnType
!= NULLREGION
)
2141 co_VIS_WindowLayoutChanged(Window
, ExposedRgn
);
2143 GreDeleteObject(ExposedRgn
);
2144 GreDeleteObject(VisBefore
);
2147 if (VisAfter
!= NULL
)
2149 GreDeleteObject(VisAfter
);
2153 if (!(WinPos
.flags
& (SWP_NOACTIVATE
|SWP_HIDEWINDOW
)))
2155 if ((Window
->style
& (WS_CHILD
| WS_POPUP
)) == WS_CHILD
)
2157 co_IntSendMessageNoWait(WinPos
.hwnd
, WM_CHILDACTIVATE
, 0, 0);
2161 //ERR("SetWindowPos Set FG Window!\n");
2162 if (Window
->state
& WNDS_BEINGACTIVATED
) // Inside SAW?
2163 co_IntSetActiveWindow(Window
, FALSE
, TRUE
, FALSE
); // Fixes Api AttachThreadInput tests.
2165 co_IntSetForegroundWindow(Window
); // Fixes SW_HIDE issues. Wine win test_SetActiveWindow & test_SetForegroundWindow.
2169 /* And last, send the WM_WINDOWPOSCHANGED message */
2171 TRACE("\tstatus flags = %04x\n", WinPos
.flags
& SWP_AGG_STATUSFLAGS
);
2173 if ((WinPos
.flags
& SWP_AGG_STATUSFLAGS
) != SWP_AGG_NOPOSCHANGE
)
2175 /* WM_WINDOWPOSCHANGED is sent even if SWP_NOSENDCHANGING is set
2176 and always contains final window position.
2178 WinPos
.x
= NewWindowRect
.left
;
2179 WinPos
.y
= NewWindowRect
.top
;
2180 WinPos
.cx
= NewWindowRect
.right
- NewWindowRect
.left
;
2181 WinPos
.cy
= NewWindowRect
.bottom
- NewWindowRect
.top
;
2182 co_IntSendMessageNoWait(WinPos
.hwnd
, WM_WINDOWPOSCHANGED
, 0, (LPARAM
) &WinPos
);
2185 if ( WinPos
.flags
& SWP_FRAMECHANGED
|| WinPos
.flags
& SWP_STATECHANGED
||
2186 !(WinPos
.flags
& SWP_NOCLIENTSIZE
) || !(WinPos
.flags
& SWP_NOCLIENTMOVE
) )
2188 PWND pWnd
= ValidateHwndNoErr(WinPos
.hwnd
);
2190 IntNotifyWinEvent(EVENT_OBJECT_LOCATIONCHANGE
, pWnd
, OBJID_WINDOW
, CHILDID_SELF
, WEF_SETBYWNDPTI
);
2193 if(bPointerInWindow
!= IntPtInWindow(Window
, gpsi
->ptCursor
.x
, gpsi
->ptCursor
.y
))
2195 /* Generate mouse move message */
2197 msg
.message
= WM_MOUSEMOVE
;
2198 msg
.wParam
= UserGetMouseButtonsState();
2199 msg
.lParam
= MAKELPARAM(gpsi
->ptCursor
.x
, gpsi
->ptCursor
.y
);
2200 msg
.pt
= gpsi
->ptCursor
;
2201 co_MsqInsertMouseMessage(&msg
, 0, 0, TRUE
);
2208 co_WinPosGetNonClientSize(PWND Window
, RECT
* WindowRect
, RECT
* ClientRect
)
2212 ASSERT_REFS_CO(Window
);
2214 *ClientRect
= *WindowRect
;
2215 Result
= co_IntSendMessageNoWait(Window
->head
.h
, WM_NCCALCSIZE
, FALSE
, (LPARAM
) ClientRect
);
2217 FixClientRect(ClientRect
, WindowRect
);
2223 co_WinPosSendSizeMove(PWND Wnd
)
2227 WPARAM wParam
= SIZE_RESTORED
;
2229 IntGetClientRect(Wnd
, &Rect
);
2230 lParam
= MAKELONG(Rect
.right
-Rect
.left
, Rect
.bottom
-Rect
.top
);
2232 Wnd
->state
&= ~WNDS_SENDSIZEMOVEMSGS
;
2234 if (Wnd
->style
& WS_MAXIMIZE
)
2236 wParam
= SIZE_MAXIMIZED
;
2238 else if (Wnd
->style
& WS_MINIMIZE
)
2240 wParam
= SIZE_MINIMIZED
;
2244 co_IntSendMessageNoWait(UserHMGetHandle(Wnd
), WM_SIZE
, wParam
, lParam
);
2246 if (Wnd
->spwndParent
== UserGetDesktopWindow()) // Wnd->spwndParent->fnid == FNID_DESKTOP )
2247 lParam
= MAKELONG(Wnd
->rcClient
.left
, Wnd
->rcClient
.top
);
2249 lParam
= MAKELONG(Wnd
->rcClient
.left
-Wnd
->spwndParent
->rcClient
.left
, Wnd
->rcClient
.top
-Wnd
->spwndParent
->rcClient
.top
);
2251 co_IntSendMessageNoWait(UserHMGetHandle(Wnd
), WM_MOVE
, 0, lParam
);
2253 IntEngWindowChanged(Wnd
, WOC_RGN_CLIENT
);
2257 co_WinPosShowWindow(PWND Wnd
, INT Cmd
)
2260 UINT Swp
= 0, EventMsg
= 0;
2261 RECTL NewPos
= {0, 0, 0, 0};
2267 //ERR("co_WinPosShowWindow START\n");
2268 BOOL ShowOwned
= FALSE
;
2269 ASSERT_REFS_CO(Wnd
);
2271 pti
= PsGetCurrentThreadWin32Thread();
2272 WasVisible
= (Wnd
->style
& WS_VISIBLE
) != 0;
2281 //ERR("co_WinPosShowWindow Exit Bad\n");
2284 Swp
|= SWP_HIDEWINDOW
| SWP_NOSIZE
| SWP_NOMOVE
;
2285 if (Wnd
!= pti
->MessageQueue
->spwndActive
)
2286 Swp
|= SWP_NOACTIVATE
| SWP_NOZORDER
;
2290 case SW_FORCEMINIMIZE
: /* FIXME: Does not work if thread is hung. */
2291 case SW_SHOWMINNOACTIVE
:
2292 Swp
|= SWP_NOACTIVATE
| SWP_NOZORDER
;
2294 case SW_SHOWMINIMIZED
:
2295 Swp
|= SWP_SHOWWINDOW
;
2299 Swp
|= SWP_NOACTIVATE
;
2300 if (!(style
& WS_MINIMIZE
))
2302 IntShowOwnedPopups(Wnd
, FALSE
);
2304 // Fix wine Win test_SetFocus todo #1 & #2,
2305 if (Cmd
== SW_SHOWMINIMIZED
)
2307 //ERR("co_WinPosShowWindow Set focus 1\n");
2308 if ((style
& (WS_CHILD
| WS_POPUP
)) == WS_CHILD
)
2309 co_UserSetFocus(Wnd
->spwndParent
);
2314 Swp
|= co_WinPosMinMaximize(Wnd
, Cmd
, &NewPos
) |
2317 EventMsg
= EVENT_SYSTEM_MINIMIZESTART
;
2323 Swp
|= SWP_FRAMECHANGED
;
2327 //ERR("co_WinPosShowWindow Exit Good\n");
2330 Swp
|= SWP_NOSIZE
| SWP_NOMOVE
;
2335 case SW_SHOWMAXIMIZED
:
2337 Swp
|= SWP_SHOWWINDOW
;
2338 if (!(style
& WS_MAXIMIZE
))
2342 Swp
|= co_WinPosMinMaximize(Wnd
, SW_MAXIMIZE
, &NewPos
) |
2345 EventMsg
= EVENT_SYSTEM_MINIMIZEEND
;
2351 Swp
|= SWP_FRAMECHANGED
;
2355 //ERR("co_WinPosShowWindow Exit Good 1\n");
2358 Swp
|= SWP_NOSIZE
| SWP_NOMOVE
;
2364 Swp
|= SWP_NOACTIVATE
| SWP_SHOWWINDOW
| SWP_NOSIZE
| SWP_NOMOVE
;
2365 if (style
& WS_CHILD
&& !(Wnd
->ExStyle
& WS_EX_MDICHILD
)) Swp
|= SWP_NOZORDER
;
2368 if (WasVisible
) return(TRUE
); // Nothing to do!
2369 Swp
|= SWP_SHOWWINDOW
| SWP_NOSIZE
| SWP_NOMOVE
;
2370 /* Don't activate the topmost window. */
2371 if (style
& WS_CHILD
&& !(Wnd
->ExStyle
& WS_EX_MDICHILD
)) Swp
|= SWP_NOACTIVATE
| SWP_NOZORDER
;
2374 case SW_SHOWNOACTIVATE
:
2375 Swp
|= SWP_NOACTIVATE
| SWP_NOZORDER
;
2378 case SW_SHOWDEFAULT
:
2380 if (!WasVisible
) Swp
|= SWP_SHOWWINDOW
;
2381 if (style
& (WS_MINIMIZE
| WS_MAXIMIZE
))
2383 Swp
|= co_WinPosMinMaximize(Wnd
, Cmd
, &NewPos
) |
2386 if (style
& WS_MINIMIZE
) EventMsg
= EVENT_SYSTEM_MINIMIZEEND
;
2392 Swp
|= SWP_FRAMECHANGED
;
2396 //ERR("co_WinPosShowWindow Exit Good 3\n");
2399 Swp
|= SWP_NOSIZE
| SWP_NOMOVE
;
2401 if ( style
& WS_CHILD
&&
2402 !(Wnd
->ExStyle
& WS_EX_MDICHILD
) &&
2403 !(Swp
& SWP_STATECHANGED
))
2404 Swp
|= SWP_NOACTIVATE
| SWP_NOZORDER
;
2408 //ERR("co_WinPosShowWindow Exit Good 4\n");
2412 ShowFlag
= (Cmd
!= SW_HIDE
);
2414 if ((ShowFlag
!= WasVisible
|| Cmd
== SW_SHOWNA
) && Cmd
!= SW_SHOWMAXIMIZED
&& !(Swp
& SWP_STATECHANGED
))
2416 co_IntSendMessageNoWait(Wnd
->head
.h
, WM_SHOWWINDOW
, ShowFlag
, 0);
2417 if (!(Wnd
->state2
& WNDS2_WIN31COMPAT
))
2418 co_IntSendMessageNoWait(Wnd
->head
.h
, WM_SETVISIBLE
, ShowFlag
, 0);
2419 if (!VerifyWnd(Wnd
)) return WasVisible
;
2422 /* We can't activate a child window */
2423 if ((Wnd
->style
& WS_CHILD
) &&
2424 !(Wnd
->ExStyle
& WS_EX_MDICHILD
) &&
2427 //ERR("SWP Child No active and ZOrder\n");
2428 Swp
|= SWP_NOACTIVATE
| SWP_NOZORDER
;
2431 #if 0 // Explorer issues with common controls. Someone does not know how CS_SAVEBITS works.
2432 if ((Wnd
->style
& (WS_POPUP
|WS_CHILD
)) != WS_CHILD
&&
2433 Wnd
->pcls
->style
& CS_SAVEBITS
&&
2434 ((Cmd
== SW_SHOW
) || (Cmd
== SW_NORMAL
)))
2436 ERR("WinPosShowWindow Set active\n");
2437 UserSetActiveWindow(Wnd
);
2438 Swp
|= SWP_NOACTIVATE
| SWP_NOZORDER
;
2442 if (IsChildVisible(Wnd
) || Swp
& SWP_STATECHANGED
)
2444 TRACE("Child is Vis %s or State changed %s. ShowFlag %s\n",
2445 (IsChildVisible(Wnd
) ? "TRUE" : "FALSE"), (Swp
& SWP_STATECHANGED
? "TRUE" : "FALSE"),
2446 (ShowFlag
? "TRUE" : "FALSE"));
2447 co_WinPosSetWindowPos( Wnd
,
2448 0 != (Wnd
->ExStyle
& WS_EX_TOPMOST
) ? HWND_TOPMOST
: HWND_TOP
,
2451 NewPos
.right
, //NewPos.right - NewPos.left,
2452 NewPos
.bottom
, //NewPos.bottom - NewPos.top,
2457 TRACE("Parent Vis?\n");
2458 /* if parent is not visible simply toggle WS_VISIBLE and return */
2459 if (ShowFlag
) IntSetStyle( Wnd
, WS_VISIBLE
, 0 );
2460 else IntSetStyle( Wnd
, 0, WS_VISIBLE
);
2463 if ( EventMsg
) IntNotifyWinEvent(EventMsg
, Wnd
, OBJID_WINDOW
, CHILDID_SELF
, WEF_SETBYWNDPTI
);
2465 if ( ShowOwned
) IntShowOwnedPopups(Wnd
, TRUE
);
2467 if ((Cmd
== SW_HIDE
) || (Cmd
== SW_MINIMIZE
))
2469 if ( Wnd
== pti
->MessageQueue
->spwndActive
&& pti
->MessageQueue
== IntGetFocusMessageQueue() )
2471 if ( Wnd
->spwndParent
== UserGetDesktopWindow())
2473 if(!ActivateOtherWindowMin(Wnd
))
2474 co_WinPosActivateOtherWindow(Wnd
);
2477 co_WinPosActivateOtherWindow(Wnd
);
2480 /* Revert focus to parent */
2481 if (Wnd
== pti
->MessageQueue
->spwndFocus
)
2483 Parent
= Wnd
->spwndParent
;
2484 if (Wnd
->spwndParent
== UserGetDesktopWindow()) Parent
= 0;
2485 co_UserSetFocus(Parent
);
2489 /* FIXME: Check for window destruction. */
2491 if ((Wnd
->state
& WNDS_SENDSIZEMOVEMSGS
) &&
2492 !(Wnd
->state2
& WNDS2_INDESTROY
))
2494 co_WinPosSendSizeMove(Wnd
);
2497 /* if previous state was minimized Windows sets focus to the window */
2498 if (style
& WS_MINIMIZE
)
2500 co_UserSetFocus(Wnd
);
2501 // Fix wine Win test_SetFocus todo #3,
2502 if (!(style
& WS_CHILD
)) co_IntSendMessageNoWait(UserHMGetHandle(Wnd
), WM_ACTIVATE
, WA_ACTIVE
, 0);
2504 //ERR("co_WinPosShowWindow EXIT\n");
2510 co_WinPosSearchChildren(
2519 if (!(ScopeWin
->style
& WS_VISIBLE
))
2524 if ((ScopeWin
->style
& WS_DISABLED
))
2529 if (!IntPtInWindow(ScopeWin
, Point
->x
, Point
->y
))
2534 UserReferenceObject(ScopeWin
);
2536 if ( RECTL_bPointInRect(&ScopeWin
->rcClient
, Point
->x
, Point
->y
) )
2538 List
= IntWinListChildren(ScopeWin
);
2541 for (phWnd
= List
; *phWnd
; ++phWnd
)
2543 if (!(pwndChild
= ValidateHwndNoErr(*phWnd
)))
2548 pwndChild
= co_WinPosSearchChildren(pwndChild
, Point
, HitTest
);
2550 if(pwndChild
!= NULL
)
2552 /* We found a window. Don't send any more WM_NCHITTEST messages */
2553 ExFreePoolWithTag(List
, USERTAG_WINDOWLIST
);
2554 UserDereferenceObject(ScopeWin
);
2558 ExFreePoolWithTag(List
, USERTAG_WINDOWLIST
);
2562 if (ScopeWin
->head
.pti
== PsGetCurrentThreadWin32Thread())
2564 *HitTest
= (USHORT
)co_IntSendMessage(ScopeWin
->head
.h
, WM_NCHITTEST
, 0,
2565 MAKELONG(Point
->x
, Point
->y
));
2566 if ((*HitTest
) == (USHORT
)HTTRANSPARENT
)
2568 UserDereferenceObject(ScopeWin
);
2573 *HitTest
= HTCLIENT
;
2579 co_WinPosWindowFromPoint(PWND ScopeWin
, POINT
*WinPoint
, USHORT
* HitTest
)
2582 POINT Point
= *WinPoint
;
2583 USER_REFERENCE_ENTRY Ref
;
2585 if( ScopeWin
== NULL
)
2587 ScopeWin
= UserGetDesktopWindow();
2588 if(ScopeWin
== NULL
)
2592 *HitTest
= HTNOWHERE
;
2594 ASSERT_REFS_CO(ScopeWin
);
2595 UserRefObjectCo(ScopeWin
, &Ref
);
2597 Window
= co_WinPosSearchChildren(ScopeWin
, &Point
, HitTest
);
2599 UserDerefObjectCo(ScopeWin
);
2601 ASSERT_REFS_CO(Window
);
2602 ASSERT_REFS_CO(ScopeWin
);
2608 IntRealChildWindowFromPoint(PWND Parent
, LONG x
, LONG y
)
2612 PWND pwndHit
= NULL
;
2617 if (Parent
!= UserGetDesktopWindow())
2619 Pt
.x
+= Parent
->rcClient
.left
;
2620 Pt
.y
+= Parent
->rcClient
.top
;
2623 if (!IntPtInWindow(Parent
, Pt
.x
, Pt
.y
)) return NULL
;
2625 if ((List
= IntWinListChildren(Parent
)))
2627 for (phWnd
= List
; *phWnd
; phWnd
++)
2630 if ((Child
= ValidateHwndNoErr(*phWnd
)))
2632 if ( Child
->style
& WS_VISIBLE
&& IntPtInWindow(Child
, Pt
.x
, Pt
.y
) )
2634 if ( Child
->pcls
->atomClassName
!= gpsi
->atomSysClass
[ICLS_BUTTON
] ||
2635 (Child
->style
& BS_TYPEMASK
) != BS_GROUPBOX
)
2637 ExFreePoolWithTag(List
, USERTAG_WINDOWLIST
);
2644 ExFreePoolWithTag(List
, USERTAG_WINDOWLIST
);
2646 return pwndHit
? pwndHit
: Parent
;
2650 IntChildWindowFromPointEx(PWND Parent
, LONG x
, LONG y
, UINT uiFlags
)
2654 PWND pwndHit
= NULL
;
2659 if (Parent
!= UserGetDesktopWindow())
2661 if (Parent
->ExStyle
& WS_EX_LAYOUTRTL
)
2662 Pt
.x
= Parent
->rcClient
.right
- Pt
.x
;
2664 Pt
.x
+= Parent
->rcClient
.left
;
2665 Pt
.y
+= Parent
->rcClient
.top
;
2668 if (!IntPtInWindow(Parent
, Pt
.x
, Pt
.y
)) return NULL
;
2670 if ((List
= IntWinListChildren(Parent
)))
2672 for (phWnd
= List
; *phWnd
; phWnd
++)
2675 if ((Child
= ValidateHwndNoErr(*phWnd
)))
2677 if (uiFlags
& (CWP_SKIPINVISIBLE
|CWP_SKIPDISABLED
))
2679 if (!(Child
->style
& WS_VISIBLE
) && (uiFlags
& CWP_SKIPINVISIBLE
)) continue;
2680 if ((Child
->style
& WS_DISABLED
) && (uiFlags
& CWP_SKIPDISABLED
)) continue;
2683 if (uiFlags
& CWP_SKIPTRANSPARENT
)
2685 if (Child
->ExStyle
& WS_EX_TRANSPARENT
) continue;
2688 if (IntPtInWindow(Child
, Pt
.x
, Pt
.y
))
2695 ExFreePoolWithTag(List
, USERTAG_WINDOWLIST
);
2697 return pwndHit
? pwndHit
: Parent
;
2702 IntDeferWindowPos( HDWP hdwp
,
2713 HDWP retvalue
= hdwp
;
2715 TRACE("hdwp %p, hwnd %p, after %p, %d,%d (%dx%d), flags %08x\n",
2716 hdwp
, hwnd
, hwndAfter
, x
, y
, cx
, cy
, flags
);
2718 if (flags
& ~(SWP_NOSIZE
| SWP_NOMOVE
|
2719 SWP_NOZORDER
| SWP_NOREDRAW
|
2720 SWP_NOACTIVATE
| SWP_NOCOPYBITS
|
2721 SWP_NOOWNERZORDER
|SWP_SHOWWINDOW
|
2722 SWP_HIDEWINDOW
| SWP_FRAMECHANGED
))
2724 EngSetLastError(ERROR_INVALID_PARAMETER
);
2728 if (!(pDWP
= (PSMWP
)UserGetObject(gHandleTable
, hdwp
, TYPE_SETWINDOWPOS
)))
2730 EngSetLastError(ERROR_INVALID_DWP_HANDLE
);
2734 for (i
= 0; i
< pDWP
->ccvr
; i
++)
2736 if (pDWP
->acvr
[i
].pos
.hwnd
== hwnd
)
2738 /* Merge with the other changes */
2739 if (!(flags
& SWP_NOZORDER
))
2741 pDWP
->acvr
[i
].pos
.hwndInsertAfter
= hwndAfter
;
2743 if (!(flags
& SWP_NOMOVE
))
2745 pDWP
->acvr
[i
].pos
.x
= x
;
2746 pDWP
->acvr
[i
].pos
.y
= y
;
2748 if (!(flags
& SWP_NOSIZE
))
2750 pDWP
->acvr
[i
].pos
.cx
= cx
;
2751 pDWP
->acvr
[i
].pos
.cy
= cy
;
2753 pDWP
->acvr
[i
].pos
.flags
&= flags
| ~(SWP_NOSIZE
| SWP_NOMOVE
|
2754 SWP_NOZORDER
| SWP_NOREDRAW
|
2755 SWP_NOACTIVATE
| SWP_NOCOPYBITS
|
2757 pDWP
->acvr
[i
].pos
.flags
|= flags
& (SWP_SHOWWINDOW
| SWP_HIDEWINDOW
|
2762 if (pDWP
->ccvr
>= pDWP
->ccvrAlloc
)
2764 PCVR newpos
= ExAllocatePoolWithTag(PagedPool
, pDWP
->ccvrAlloc
* 2 * sizeof(CVR
), USERTAG_SWP
);
2770 RtlZeroMemory(newpos
, pDWP
->ccvrAlloc
* 2 * sizeof(CVR
));
2771 RtlCopyMemory(newpos
, pDWP
->acvr
, pDWP
->ccvrAlloc
* sizeof(CVR
));
2772 ExFreePoolWithTag(pDWP
->acvr
, USERTAG_SWP
);
2773 pDWP
->ccvrAlloc
*= 2;
2774 pDWP
->acvr
= newpos
;
2776 pDWP
->acvr
[pDWP
->ccvr
].pos
.hwnd
= hwnd
;
2777 pDWP
->acvr
[pDWP
->ccvr
].pos
.hwndInsertAfter
= hwndAfter
;
2778 pDWP
->acvr
[pDWP
->ccvr
].pos
.x
= x
;
2779 pDWP
->acvr
[pDWP
->ccvr
].pos
.y
= y
;
2780 pDWP
->acvr
[pDWP
->ccvr
].pos
.cx
= cx
;
2781 pDWP
->acvr
[pDWP
->ccvr
].pos
.cy
= cy
;
2782 pDWP
->acvr
[pDWP
->ccvr
].pos
.flags
= flags
;
2783 pDWP
->acvr
[pDWP
->ccvr
].hrgnClip
= NULL
;
2784 pDWP
->acvr
[pDWP
->ccvr
].hrgnInterMonitor
= NULL
;
2790 BOOL FASTCALL
IntEndDeferWindowPosEx( HDWP hdwp
, BOOL sAsync
)
2797 TRACE("%p\n", hdwp
);
2799 if (!(pDWP
= (PSMWP
)UserGetObject(gHandleTable
, hdwp
, TYPE_SETWINDOWPOS
)))
2801 EngSetLastError(ERROR_INVALID_DWP_HANDLE
);
2805 for (i
= 0, winpos
= pDWP
->acvr
; res
&& i
< pDWP
->ccvr
; i
++, winpos
++)
2808 USER_REFERENCE_ENTRY Ref
;
2810 TRACE("hwnd %p, after %p, %d,%d (%dx%d), flags %08x\n",
2811 winpos
->pos
.hwnd
, winpos
->pos
.hwndInsertAfter
, winpos
->pos
.x
, winpos
->pos
.y
,
2812 winpos
->pos
.cx
, winpos
->pos
.cy
, winpos
->pos
.flags
);
2814 pwnd
= ValidateHwndNoErr(winpos
->pos
.hwnd
);
2818 UserRefObjectCo(pwnd
, &Ref
);
2823 PWINDOWPOS ppos
= ExAllocatePoolWithTag(PagedPool
, sizeof(WINDOWPOS
), USERTAG_SWP
);
2826 *ppos
= winpos
->pos
;
2827 /* Yes it's a pointer inside Win32k! */
2828 lRes
= co_IntSendMessageNoWait( winpos
->pos
.hwnd
, WM_ASYNC_SETWINDOWPOS
, 0, (LPARAM
)ppos
);
2829 /* We handle this the same way as Event Hooks and Hooks. */
2832 ExFreePoolWithTag(ppos
, USERTAG_SWP
);
2837 res
= co_WinPosSetWindowPos( pwnd
,
2838 winpos
->pos
.hwndInsertAfter
,
2845 // Hack to pass tests.... Must have some work to do so clear the error.
2846 if (res
&& (winpos
->pos
.flags
& (SWP_NOMOVE
|SWP_NOSIZE
|SWP_NOZORDER
)) == SWP_NOZORDER
)
2847 EngSetLastError(ERROR_SUCCESS
);
2849 UserDerefObjectCo(pwnd
);
2851 ExFreePoolWithTag(pDWP
->acvr
, USERTAG_SWP
);
2852 UserDereferenceObject(pDWP
);
2853 UserDeleteObject(hdwp
, TYPE_SETWINDOWPOS
);
2861 NtUserChildWindowFromPointEx(HWND hwndParent
,
2867 TRACE("Enter NtUserChildWindowFromPointEx\n");
2868 UserEnterExclusive();
2869 if ((pwndParent
= UserGetWindowObject(hwndParent
)))
2871 pwndParent
= IntChildWindowFromPointEx(pwndParent
, x
, y
, uiFlags
);
2874 TRACE("Leave NtUserChildWindowFromPointEx\n");
2875 return pwndParent
? UserHMGetHandle(pwndParent
) : NULL
;
2882 NtUserEndDeferWindowPosEx(HDWP WinPosInfo
,
2886 TRACE("Enter NtUserEndDeferWindowPosEx\n");
2887 UserEnterExclusive();
2888 Ret
= IntEndDeferWindowPosEx(WinPosInfo
, (BOOL
)Unknown1
);
2889 TRACE("Leave NtUserEndDeferWindowPosEx, ret=%i\n", Ret
);
2898 NtUserDeferWindowPos(HDWP WinPosInfo
,
2900 HWND WndInsertAfter
,
2909 UINT Tmp
= ~(SWP_ASYNCWINDOWPOS
|SWP_DEFERERASE
|SWP_NOSENDCHANGING
|SWP_NOREPOSITION
|
2910 SWP_NOCOPYBITS
|SWP_HIDEWINDOW
|SWP_SHOWWINDOW
|SWP_FRAMECHANGED
|
2911 SWP_NOACTIVATE
|SWP_NOREDRAW
|SWP_NOZORDER
|SWP_NOMOVE
|SWP_NOSIZE
);
2913 TRACE("Enter NtUserDeferWindowPos\n");
2914 UserEnterExclusive();
2918 EngSetLastError(ERROR_INVALID_FLAGS
);
2922 pWnd
= UserGetWindowObject(Wnd
);
2923 if ( !pWnd
|| // FIXME:
2924 pWnd
== UserGetDesktopWindow() || // pWnd->fnid == FNID_DESKTOP
2925 pWnd
== UserGetMessageWindow() ) // pWnd->fnid == FNID_MESSAGEWND
2930 if ( WndInsertAfter
&&
2931 WndInsertAfter
!= HWND_BOTTOM
&&
2932 WndInsertAfter
!= HWND_TOPMOST
&&
2933 WndInsertAfter
!= HWND_NOTOPMOST
)
2935 pWndIA
= UserGetWindowObject(WndInsertAfter
);
2937 pWndIA
== UserGetDesktopWindow() ||
2938 pWndIA
== UserGetMessageWindow() )
2944 Ret
= IntDeferWindowPos(WinPosInfo
, Wnd
, WndInsertAfter
, x
, y
, cx
, cy
, Flags
);
2947 TRACE("Leave NtUserDeferWindowPos, ret=%p\n", Ret
);
2956 NtUserGetInternalWindowPos( HWND hWnd
,
2963 WINDOWPLACEMENT wndpl
;
2967 if (!(Window
= UserGetWindowObject(hWnd
)))
2977 ProbeForWrite(rectWnd
,
2983 ProbeForWrite(ptIcon
,
2989 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
2991 SetLastNtError(_SEH2_GetExceptionCode());
2996 wndpl
.length
= sizeof(WINDOWPLACEMENT
);
2998 if (IntGetWindowPlacement(Window
, &wndpl
) && !Hit
)
3004 RtlCopyMemory(rectWnd
, &wndpl
.rcNormalPosition
, sizeof(RECT
));
3008 RtlCopyMemory(ptIcon
, &wndpl
.ptMinPosition
, sizeof(POINT
));
3012 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
3014 SetLastNtError(_SEH2_GetExceptionCode());
3019 if (!Hit
) Ret
= wndpl
.showCmd
;
3030 NtUserGetWindowPlacement(HWND hWnd
,
3031 WINDOWPLACEMENT
*lpwndpl
)
3034 WINDOWPLACEMENT Safepl
;
3036 DECLARE_RETURN(BOOL
);
3038 TRACE("Enter NtUserGetWindowPlacement\n");
3041 if (!(Wnd
= UserGetWindowObject(hWnd
)))
3046 Status
= MmCopyFromCaller(&Safepl
, lpwndpl
, sizeof(WINDOWPLACEMENT
));
3047 if(!NT_SUCCESS(Status
))
3049 SetLastNtError(Status
);
3052 if(Safepl
.length
!= sizeof(WINDOWPLACEMENT
))
3057 IntGetWindowPlacement(Wnd
, &Safepl
);
3059 Status
= MmCopyToCaller(lpwndpl
, &Safepl
, sizeof(WINDOWPLACEMENT
));
3060 if(!NT_SUCCESS(Status
))
3062 SetLastNtError(Status
);
3069 TRACE("Leave NtUserGetWindowPlacement, ret=%i\n",_ret_
);
3078 UINT cmd
, // Wine SW_ commands
3083 TRACE("Enter NtUserMinMaximize\n");
3084 UserEnterExclusive();
3086 pWnd
= UserGetWindowObject(hWnd
);
3087 if ( !pWnd
|| // FIXME:
3088 pWnd
== UserGetDesktopWindow() || // pWnd->fnid == FNID_DESKTOP
3089 pWnd
== UserGetMessageWindow() ) // pWnd->fnid == FNID_MESSAGEWND
3094 if ( cmd
> SW_MAX
|| pWnd
->state2
& WNDS2_INDESTROY
)
3096 EngSetLastError(ERROR_INVALID_PARAMETER
);
3100 cmd
|= Hide
? SW_HIDE
: 0;
3102 co_WinPosShowWindow(pWnd
, cmd
);
3105 TRACE("Leave NtUserMinMaximize\n");
3107 return 0; // Always NULL?
3122 return NtUserSetWindowPos(hWnd
, 0, X
, Y
, nWidth
, nHeight
,
3123 (bRepaint
? SWP_NOZORDER
| SWP_NOACTIVATE
:
3124 SWP_NOZORDER
| SWP_NOACTIVATE
| SWP_NOREDRAW
));
3131 NtUserRealChildWindowFromPoint(HWND Parent
,
3136 TRACE("Enter NtUserRealChildWindowFromPoint\n");
3138 if ((pwndParent
= UserGetWindowObject(Parent
)))
3140 pwndParent
= IntRealChildWindowFromPoint(pwndParent
, x
, y
);
3143 TRACE("Leave NtUserRealChildWindowFromPoint\n");
3144 return pwndParent
? UserHMGetHandle(pwndParent
) : NULL
;
3153 HWND hWndInsertAfter
,
3160 DECLARE_RETURN(BOOL
);
3161 PWND Window
, pWndIA
;
3163 USER_REFERENCE_ENTRY Ref
;
3165 TRACE("Enter NtUserSetWindowPos\n");
3166 UserEnterExclusive();
3168 if (!(Window
= UserGetWindowObject(hWnd
)) || // FIXME:
3169 Window
== UserGetDesktopWindow() || // pWnd->fnid == FNID_DESKTOP
3170 Window
== UserGetMessageWindow() ) // pWnd->fnid == FNID_MESSAGEWND
3172 ERR("NtUserSetWindowPos bad window handle!\n");
3176 if ( hWndInsertAfter
&&
3177 hWndInsertAfter
!= HWND_BOTTOM
&&
3178 hWndInsertAfter
!= HWND_TOPMOST
&&
3179 hWndInsertAfter
!= HWND_NOTOPMOST
)
3181 if (!(pWndIA
= UserGetWindowObject(hWndInsertAfter
)) ||
3182 pWndIA
== UserGetDesktopWindow() ||
3183 pWndIA
== UserGetMessageWindow() )
3185 ERR("NtUserSetWindowPos bad insert window handle!\n");
3190 /* First make sure that coordinates are valid for WM_WINDOWPOSCHANGING */
3191 if (!(uFlags
& SWP_NOMOVE
))
3193 if (X
< -32768) X
= -32768;
3194 else if (X
> 32767) X
= 32767;
3195 if (Y
< -32768) Y
= -32768;
3196 else if (Y
> 32767) Y
= 32767;
3198 if (!(uFlags
& SWP_NOSIZE
))
3201 else if (cx
> 32767) cx
= 32767;
3203 else if (cy
> 32767) cy
= 32767;
3206 UserRefObjectCo(Window
, &Ref
);
3207 ret
= co_WinPosSetWindowPos(Window
, hWndInsertAfter
, X
, Y
, cx
, cy
, uFlags
);
3208 UserDerefObjectCo(Window
);
3213 TRACE("Leave NtUserSetWindowPos, ret=%i\n",_ret_
);
3229 INT flags
= (SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
|SWP_NOACTIVATE
|SWP_FRAMECHANGED
|SWP_NOSIZE
|SWP_NOMOVE
);
3230 BOOLEAN Ret
= FALSE
;
3231 DECLARE_RETURN(INT
);
3233 TRACE("Enter NtUserSetWindowRgn\n");
3234 UserEnterExclusive();
3236 if (!(Window
= UserGetWindowObject(hWnd
)) || // FIXME:
3237 Window
== UserGetDesktopWindow() || // pWnd->fnid == FNID_DESKTOP
3238 Window
== UserGetMessageWindow() ) // pWnd->fnid == FNID_MESSAGEWND
3243 if (hRgn
) // The region will be deleted in user32.
3245 if (GreIsHandleValid(hRgn
))
3247 hrgnCopy
= IntSysCreateRectRgn(0, 0, 0, 0);
3248 /* The coordinates of a window's window region are relative to the
3249 upper-left corner of the window, not the client area of the window. */
3250 NtGdiCombineRgn( hrgnCopy
, hRgn
, 0, RGN_COPY
);
3260 if (Window
->hrgnClip
)
3262 /* Delete no longer needed region handle */
3263 IntGdiSetRegionOwner(Window
->hrgnClip
, GDI_OBJ_HMGR_POWNED
);
3264 GreDeleteObject(Window
->hrgnClip
);
3269 /* Set public ownership */
3270 IntGdiSetRegionOwner(hrgnCopy
, GDI_OBJ_HMGR_PUBLIC
);
3272 Window
->hrgnClip
= hrgnCopy
;
3274 Ret
= co_WinPosSetWindowPos(Window
, HWND_TOP
, 0, 0, 0, 0, bRedraw
? flags
: (flags
|SWP_NOREDRAW
) );
3279 TRACE("Leave NtUserSetWindowRgn, ret=%i\n",_ret_
);
3288 NtUserSetInternalWindowPos(
3294 WINDOWPLACEMENT wndpl
;
3299 DECLARE_RETURN(BOOL
);
3300 USER_REFERENCE_ENTRY Ref
;
3302 TRACE("Enter NtUserSetWindowPlacement\n");
3303 UserEnterExclusive();
3305 if (!(Wnd
= UserGetWindowObject(hwnd
)) || // FIXME:
3306 Wnd
== UserGetDesktopWindow() || // pWnd->fnid == FNID_DESKTOP
3307 Wnd
== UserGetMessageWindow() ) // pWnd->fnid == FNID_MESSAGEWND
3316 ProbeForRead(lppt
, sizeof(POINT
), 1);
3317 RtlCopyMemory(&pt
, lppt
, sizeof(POINT
));
3321 ProbeForRead(lprect
, sizeof(RECT
), 1);
3322 RtlCopyMemory(&rect
, lprect
, sizeof(RECT
));
3325 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
3327 SetLastNtError(_SEH2_GetExceptionCode());
3328 _SEH2_YIELD(RETURN( FALSE
));
3332 wndpl
.length
= sizeof(wndpl
);
3333 wndpl
.showCmd
= showCmd
;
3334 wndpl
.flags
= flags
= 0;
3339 wndpl
.flags
|= WPF_SETMINPOSITION
;
3340 wndpl
.ptMinPosition
= pt
;
3344 flags
|= PLACE_RECT
;
3345 wndpl
.rcNormalPosition
= rect
;
3348 UserRefObjectCo(Wnd
, &Ref
);
3349 IntSetWindowPlacement(Wnd
, &wndpl
, flags
);
3350 UserDerefObjectCo(Wnd
);
3354 TRACE("Leave NtUserSetWindowPlacement, ret=%i\n",_ret_
);
3363 NtUserSetWindowPlacement(HWND hWnd
,
3364 WINDOWPLACEMENT
*lpwndpl
)
3367 WINDOWPLACEMENT Safepl
;
3369 DECLARE_RETURN(BOOL
);
3370 USER_REFERENCE_ENTRY Ref
;
3372 TRACE("Enter NtUserSetWindowPlacement\n");
3373 UserEnterExclusive();
3375 if (!(Wnd
= UserGetWindowObject(hWnd
)) || // FIXME:
3376 Wnd
== UserGetDesktopWindow() || // pWnd->fnid == FNID_DESKTOP
3377 Wnd
== UserGetMessageWindow() ) // pWnd->fnid == FNID_MESSAGEWND
3384 ProbeForRead(lpwndpl
, sizeof(WINDOWPLACEMENT
), 1);
3385 RtlCopyMemory(&Safepl
, lpwndpl
, sizeof(WINDOWPLACEMENT
));
3387 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
3389 SetLastNtError(_SEH2_GetExceptionCode());
3390 _SEH2_YIELD(RETURN( FALSE
));
3394 if(Safepl
.length
!= sizeof(WINDOWPLACEMENT
))
3399 Flags
= PLACE_MAX
| PLACE_RECT
;
3400 if (Safepl
.flags
& WPF_SETMINPOSITION
) Flags
|= PLACE_MIN
;
3401 UserRefObjectCo(Wnd
, &Ref
);
3402 IntSetWindowPlacement(Wnd
, &Safepl
, Flags
);
3403 UserDerefObjectCo(Wnd
);
3407 TRACE("Leave NtUserSetWindowPlacement, ret=%i\n",_ret_
);
3416 NtUserShowWindowAsync(HWND hWnd
, LONG nCmdShow
)
3420 DECLARE_RETURN(BOOL
);
3421 USER_REFERENCE_ENTRY Ref
;
3423 TRACE("Enter NtUserShowWindowAsync\n");
3424 UserEnterExclusive();
3426 if (!(Window
= UserGetWindowObject(hWnd
)) || // FIXME:
3427 Window
== UserGetDesktopWindow() || // pWnd->fnid == FNID_DESKTOP
3428 Window
== UserGetMessageWindow() ) // pWnd->fnid == FNID_MESSAGEWND
3433 if ( nCmdShow
> SW_MAX
)
3435 EngSetLastError(ERROR_INVALID_PARAMETER
);
3439 UserRefObjectCo(Window
, &Ref
);
3440 ret
= co_IntSendMessageNoWait( hWnd
, WM_ASYNC_SHOWWINDOW
, nCmdShow
, 0 );
3441 UserDerefObjectCo(Window
);
3442 if (-1 == (int) ret
|| !ret
) ret
= FALSE
;
3447 TRACE("Leave NtUserShowWindowAsync, ret=%i\n",_ret_
);
3456 NtUserShowWindow(HWND hWnd
, LONG nCmdShow
)
3460 DECLARE_RETURN(BOOL
);
3461 USER_REFERENCE_ENTRY Ref
;
3463 TRACE("Enter NtUserShowWindow\n");
3464 UserEnterExclusive();
3466 if (!(Window
= UserGetWindowObject(hWnd
)) || // FIXME:
3467 Window
== UserGetDesktopWindow() || // pWnd->fnid == FNID_DESKTOP
3468 Window
== UserGetMessageWindow() ) // pWnd->fnid == FNID_MESSAGEWND
3473 if ( nCmdShow
> SW_MAX
|| Window
->state2
& WNDS2_INDESTROY
)
3475 EngSetLastError(ERROR_INVALID_PARAMETER
);
3479 UserRefObjectCo(Window
, &Ref
);
3480 ret
= co_WinPosShowWindow(Window
, nCmdShow
);
3481 UserDerefObjectCo(Window
);
3486 TRACE("Leave NtUserShowWindow, ret=%i\n",_ret_
);
3496 NtUserWindowFromPoint(LONG X
, LONG Y
)
3500 PWND DesktopWindow
= NULL
, Window
= NULL
;
3502 DECLARE_RETURN(HWND
);
3503 USER_REFERENCE_ENTRY Ref
;
3505 TRACE("Enter NtUserWindowFromPoint\n");
3506 UserEnterExclusive();
3508 if ((DesktopWindow
= UserGetWindowObject(IntGetDesktopWindow())))
3515 // Hmm... Threads live on desktops thus we have a reference on the desktop and indirectly the desktop window.
3516 // It is possible this referencing is useless, though it should not hurt...
3517 UserRefObjectCo(DesktopWindow
, &Ref
);
3519 //pti = PsGetCurrentThreadWin32Thread();
3520 Window
= co_WinPosWindowFromPoint(DesktopWindow
, &pt
, &hittest
);
3524 Ret
= UserHMGetHandle(Window
);
3533 if (Window
) UserDereferenceObject(Window
);
3534 if (DesktopWindow
) UserDerefObjectCo(DesktopWindow
);
3536 TRACE("Leave NtUserWindowFromPoint, ret=%p\n", _ret_
);