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 /* FUNCTIONS *****************************************************************/
34 IntGetClientOrigin(PWND Window OPTIONAL
, LPPOINT Point
)
36 Window
= Window
? Window
: UserGetWindowObject(IntGetDesktopWindow());
39 Point
->x
= Point
->y
= 0;
42 Point
->x
= Window
->rcClient
.left
;
43 Point
->y
= Window
->rcClient
.top
;
50 * Returns client window rectangle relative to the upper-left corner of client area.
52 * \note Does not check the validity of the parameters
55 IntGetClientRect(PWND Wnd
, RECTL
*Rect
)
59 if (Wnd
->style
& WS_MINIMIZED
)
61 Rect
->left
= Rect
->top
= 0;
62 Rect
->right
= UserGetSystemMetrics(SM_CXMINIMIZED
);
63 Rect
->bottom
= UserGetSystemMetrics(SM_CYMINIMIZED
);
66 if ( Wnd
!= UserGetDesktopWindow()) // Wnd->fnid != FNID_DESKTOP )
68 *Rect
= Wnd
->rcClient
;
69 RECTL_vOffsetRect(Rect
, -Wnd
->rcClient
.left
, -Wnd
->rcClient
.top
);
73 Rect
->left
= Rect
->top
= 0;
74 Rect
->right
= Wnd
->rcClient
.right
;
75 Rect
->bottom
= Wnd
->rcClient
.bottom
;
76 /* Do this until Init bug is fixed. This sets 640x480, see InitMetrics.
77 Rect->right = UserGetSystemMetrics(SM_CXSCREEN);
78 Rect->bottom = UserGetSystemMetrics(SM_CYSCREEN);
84 IntMapWindowPoints(PWND FromWnd
, PWND ToWnd
, LPPOINT lpPoints
, UINT cPoints
)
86 BOOL mirror_from
, mirror_to
;
91 /* Note: Desktop Top and Left is always 0! */
92 Delta
.x
= Delta
.y
= 0;
93 mirror_from
= mirror_to
= FALSE
;
95 if (FromWnd
&& FromWnd
!= UserGetDesktopWindow()) // FromWnd->fnid != FNID_DESKTOP)
97 if (FromWnd
->ExStyle
& WS_EX_LAYOUTRTL
)
101 Delta
.x
= -FromWnd
->rcClient
.right
;
104 Delta
.x
= FromWnd
->rcClient
.left
;
105 Delta
.y
= FromWnd
->rcClient
.top
;
108 if (ToWnd
&& ToWnd
!= UserGetDesktopWindow()) // ToWnd->fnid != FNID_DESKTOP)
110 if (ToWnd
->ExStyle
& WS_EX_LAYOUTRTL
)
114 Delta
.x
+= Change
* ToWnd
->rcClient
.right
;
117 Delta
.x
-= Change
* ToWnd
->rcClient
.left
;
118 Delta
.y
-= ToWnd
->rcClient
.top
;
121 if (mirror_from
) Delta
.x
= -Delta
.x
;
123 for (i
= 0; i
!= cPoints
; i
++)
125 lpPoints
[i
].x
+= Delta
.x
;
126 lpPoints
[i
].x
*= Change
;
127 lpPoints
[i
].y
+= Delta
.y
;
130 if ((mirror_from
|| mirror_to
) && cPoints
== 2) /* special case for rectangle */
132 int tmp
= min(lpPoints
[0].x
, lpPoints
[1].x
);
133 lpPoints
[1].x
= max(lpPoints
[0].x
, lpPoints
[1].x
);
137 return MAKELONG(LOWORD(Delta
.x
), LOWORD(Delta
.y
));
140 /*******************************************************************
141 * can_activate_window
143 * Check if we can activate the specified window.
146 BOOL FASTCALL
can_activate_window( PWND Wnd OPTIONAL
)
150 if (!Wnd
) return FALSE
;
153 if (!(style
& WS_VISIBLE
)) return FALSE
;
154 if (style
& WS_MINIMIZE
) return FALSE
;
155 if ((style
& (WS_POPUP
|WS_CHILD
)) == WS_CHILD
) return FALSE
;
157 /* FIXME: This window could be disable because the child that closed
159 //return !(style & WS_DISABLED);
163 /*******************************************************************
164 * WinPosActivateOtherWindow
166 * Activates window other than pWnd.
169 co_WinPosActivateOtherWindow(PWND Wnd
)
173 USER_REFERENCE_ENTRY Ref
;
177 if (IntIsDesktopWindow(Wnd
))
179 IntSetFocusMessageQueue(NULL
);
183 /* If this is popup window, try to activate the owner first. */
184 if ((Wnd
->style
& WS_POPUP
) && (WndTo
= Wnd
->spwndOwner
))
186 WndTo
= UserGetAncestor( WndTo
, GA_ROOT
);
187 if (can_activate_window(WndTo
)) goto done
;
190 /* Pick a next top-level window. */
191 /* FIXME: Search for non-tooltip windows first. */
195 if (!(WndTo
= WndTo
->spwndNext
)) break;
196 if (can_activate_window( WndTo
)) break;
201 if (WndTo
) UserRefObjectCo(WndTo
, &Ref
);
203 Fg
= UserGetForegroundWindow();
204 if ((!Fg
|| Wnd
->head
.h
== Fg
) && WndTo
) // FIXME: Ok if WndTo is NULL??
206 /* FIXME: Wine can pass WndTo = NULL to co_IntSetForegroundWindow. Hmm... */
207 if (co_IntSetForegroundWindow(WndTo
))
209 UserDerefObjectCo(WndTo
);
214 if (!co_IntSetActiveWindow(WndTo
,&previous
,FALSE
,TRUE
) || /* Ok for WndTo to be NULL here */
216 co_IntSetActiveWindow(0,NULL
,FALSE
,TRUE
);
218 if (WndTo
) UserDerefObjectCo(WndTo
);
223 co_WinPosArrangeIconicWindows(PWND parent
)
226 INT i
, x
, y
, xspacing
, yspacing
, sx
, sy
;
227 HWND
*List
= IntWinListChildren(parent
);
229 ASSERT_REFS_CO(parent
);
231 /* Check if we found any children */
237 IntGetClientRect( parent
, &rectParent
);
238 // FIXME: Support gspv.mm.iArrange.
240 y
= rectParent
.bottom
;
242 xspacing
= (UserGetSystemMetrics(SM_CXMINSPACING
)/2)+UserGetSystemMetrics(SM_CXBORDER
);
243 yspacing
= (UserGetSystemMetrics(SM_CYMINSPACING
)/2)+UserGetSystemMetrics(SM_CYBORDER
);
245 //ERR("X:%d Y:%d XS:%d YS:%d\n",x,y,xspacing,yspacing);
247 for(i
= 0; List
[i
]; i
++)
251 if (!(Child
= UserGetWindowObject(List
[i
])))
254 if((Child
->style
& WS_MINIMIZE
) != 0 )
256 USER_REFERENCE_ENTRY Ref
;
257 UserRefObjectCo(Child
, &Ref
);
259 sx
= x
+ UserGetSystemMetrics(SM_CXBORDER
);
260 sy
= y
- yspacing
- UserGetSystemMetrics(SM_CYBORDER
);
262 co_WinPosSetWindowPos( Child
, 0, sx
, sy
, 0, 0,
263 SWP_NOSIZE
| SWP_NOZORDER
| SWP_NOACTIVATE
);
265 Child
->InternalPos
.IconPos
.x
= sx
;
266 Child
->InternalPos
.IconPos
.y
= sy
;
267 Child
->InternalPos
.flags
|= WPF_MININIT
;
268 Child
->InternalPos
.flags
&= ~WPF_SETMINPOSITION
;
270 UserDerefObjectCo(Child
);
272 if (x
<= (rectParent
.right
- UserGetSystemMetrics(SM_CXMINSPACING
)))
279 //ERR("X:%d Y:%d\n",x,y);
287 WinPosFindIconPos(PWND Window
, POINT
*Pos
)
290 PWND pwndChild
, pwndParent
;
291 int x
, y
, xspacing
, yspacing
;
293 pwndParent
= Window
->spwndParent
;
294 if (pwndParent
== UserGetDesktopWindow())
296 /* ReactOS doesn't support iconic minimize to desktop */
297 Pos
->x
= Pos
->y
= -32000;
298 Window
->InternalPos
.flags
|= WPF_MININIT
;
299 Window
->InternalPos
.IconPos
.x
= Pos
->x
;
300 Window
->InternalPos
.IconPos
.y
= Pos
->y
;
304 IntGetClientRect( pwndParent
, &rectParent
);
305 // FIXME: Support gspv.mm.iArrange.
307 y
= rectParent
.bottom
;
309 xspacing
= (UserGetSystemMetrics(SM_CXMINSPACING
)/2)+UserGetSystemMetrics(SM_CXBORDER
);
310 yspacing
= (UserGetSystemMetrics(SM_CYMINSPACING
)/2)+UserGetSystemMetrics(SM_CYBORDER
);
312 //ERR("X:%d Y:%d XS:%d YS:%d\n",Pos->x,Pos->y,xspacing,yspacing);
314 // Set to default position when minimized.
315 Pos
->x
= x
+ UserGetSystemMetrics(SM_CXBORDER
);
316 Pos
->y
= y
- yspacing
- UserGetSystemMetrics(SM_CYBORDER
);
318 for (pwndChild
= pwndParent
->spwndChild
; pwndChild
; pwndChild
= pwndChild
->spwndNext
)
320 if (pwndChild
== Window
) continue;
322 if (pwndChild
->style
& WS_VISIBLE
)
327 //ERR("Pos Child X %d Y %d!\n", pwndChild->InternalPos.IconPos.x, pwndChild->InternalPos.IconPos.y);
328 if ( pwndChild
->InternalPos
.IconPos
.x
== Pos
->x
&&
329 pwndChild
->InternalPos
.IconPos
.y
== Pos
->y
)
331 if (x
<= rectParent
.right
- UserGetSystemMetrics(SM_CXMINSPACING
))
338 Pos
->x
= x
+ UserGetSystemMetrics(SM_CXBORDER
);
339 Pos
->y
= y
- yspacing
- UserGetSystemMetrics(SM_CYBORDER
);
342 Window
->InternalPos
.IconPos
.x
= Pos
->x
;
343 Window
->InternalPos
.IconPos
.y
= Pos
->y
;
344 Window
->InternalPos
.flags
|= WPF_MININIT
;
345 //ERR("Position is set! X:%d Y:%d\n",Pos->x,Pos->y);
350 WinPosInitInternalPos(PWND Wnd
, RECTL
*RestoreRect
)
353 RECTL Rect
= *RestoreRect
;
355 if (Wnd
->spwndParent
!= UserGetDesktopWindow())
357 RECTL_vOffsetRect(&Rect
,
358 -Wnd
->spwndParent
->rcClient
.left
,
359 -Wnd
->spwndParent
->rcClient
.top
);
365 if (!Wnd
->InternalPosInitialized
)
367 // FIXME: Use check point Atom..
368 Wnd
->InternalPos
.flags
= 0;
369 Wnd
->InternalPos
.MaxPos
.x
= Wnd
->InternalPos
.MaxPos
.y
= -1;
370 Wnd
->InternalPos
.IconPos
.x
= Wnd
->InternalPos
.IconPos
.y
= -1;
371 Wnd
->InternalPos
.NormalRect
= Rect
;
372 Wnd
->InternalPosInitialized
= TRUE
;
375 if (Wnd
->style
& WS_MINIMIZE
)
377 Wnd
->InternalPos
.IconPos
= Size
;
378 Wnd
->InternalPos
.flags
|= WPF_MININIT
;
380 else if (Wnd
->style
& WS_MAXIMIZE
)
382 Wnd
->InternalPos
.flags
|= WPF_MAXINIT
;
384 if ( Wnd
->spwndParent
== Wnd
->head
.rpdesk
->pDeskInfo
->spwnd
)
386 if (Wnd
->state
& WNDS_MAXIMIZESTOMONITOR
)
388 Wnd
->InternalPos
.flags
&= ~WPF_MAXINIT
;
389 Wnd
->InternalPos
.MaxPos
.x
= Wnd
->InternalPos
.MaxPos
.y
= -1;
394 PMONITOR pmonitor
= UserMonitorFromRect(&Rect
, MONITOR_DEFAULTTOPRIMARY
);
395 // FIXME: support DPI aware, rcWorkDPI/Real etc..
396 WorkArea
= pmonitor
->rcMonitor
;
398 if (Wnd
->style
& WS_MAXIMIZEBOX
)
399 { // Support (Wnd->state & WNDS_HASCAPTION) || pmonitor->cFullScreen too.
400 if ((Wnd
->style
& WS_CAPTION
) == WS_CAPTION
|| !(Wnd
->style
& (WS_CHILD
| WS_POPUP
)))
402 WorkArea
= pmonitor
->rcWork
;
407 Wnd
->InternalPos
.MaxPos
.x
= Rect
.left
- WorkArea
.left
;
408 Wnd
->InternalPos
.MaxPos
.y
= Rect
.top
- WorkArea
.top
;
410 /*ERR("WinPosIP 2 X %d = R.l %d - W.l %d | Y %d = R.t %d - W.t %d\n",
411 Wnd->InternalPos.MaxPos.x,
412 Rect.left, WorkArea.left,
413 Wnd->InternalPos.MaxPos.y,
414 Rect.top, WorkArea.top);
419 Wnd
->InternalPos
.MaxPos
= Size
;
423 Wnd
->InternalPos
.NormalRect
= Rect
;
429 IntGetWindowPlacement(PWND Wnd
, WINDOWPLACEMENT
*lpwndpl
)
431 if (!Wnd
) return FALSE
;
433 if(lpwndpl
->length
!= sizeof(WINDOWPLACEMENT
))
440 WinPosInitInternalPos(Wnd
, &Wnd
->rcWindow
);
442 lpwndpl
->showCmd
= SW_HIDE
;
444 if ( Wnd
->style
& WS_MINIMIZE
)
445 lpwndpl
->showCmd
= SW_SHOWMINIMIZED
;
447 lpwndpl
->showCmd
= ( Wnd
->style
& WS_MAXIMIZE
) ? SW_SHOWMAXIMIZED
: SW_SHOWNORMAL
;
449 lpwndpl
->rcNormalPosition
= Wnd
->InternalPos
.NormalRect
;
451 if (Wnd
->InternalPos
.flags
& WPF_MININIT
) // Return if it was set!
453 lpwndpl
->ptMinPosition
.x
= Wnd
->InternalPos
.IconPos
.x
;
454 lpwndpl
->ptMinPosition
.y
= Wnd
->InternalPos
.IconPos
.y
;
457 lpwndpl
->ptMinPosition
.x
= lpwndpl
->ptMinPosition
.y
= -1;
459 if ( Wnd
->InternalPos
.flags
& WPF_MAXINIT
&& // Return if set and not maximized to monitor!
460 !(Wnd
->state
& WNDS_MAXIMIZESTOMONITOR
))
462 lpwndpl
->ptMaxPosition
.x
= Wnd
->InternalPos
.MaxPos
.x
;
463 lpwndpl
->ptMaxPosition
.y
= Wnd
->InternalPos
.MaxPos
.y
;
466 lpwndpl
->ptMaxPosition
.x
= lpwndpl
->ptMaxPosition
.y
= -1;
468 if ( Wnd
->spwndParent
== Wnd
->head
.rpdesk
->pDeskInfo
->spwnd
&&
469 !(Wnd
->ExStyle
& WS_EX_TOOLWINDOW
))
471 PMONITOR pmonitor
= UserMonitorFromRect(&lpwndpl
->rcNormalPosition
, MONITOR_DEFAULTTOPRIMARY
);
473 // FIXME: support DPI aware, rcWorkDPI/Real etc..
474 if (Wnd
->InternalPos
.flags
& WPF_MININIT
)
476 lpwndpl
->ptMinPosition
.x
-= (pmonitor
->rcWork
.left
- pmonitor
->rcMonitor
.left
);
477 lpwndpl
->ptMinPosition
.y
-= (pmonitor
->rcWork
.top
- pmonitor
->rcMonitor
.top
);
479 RECTL_vOffsetRect(&lpwndpl
->rcNormalPosition
,
480 pmonitor
->rcMonitor
.left
- pmonitor
->rcWork
.left
,
481 pmonitor
->rcMonitor
.top
- pmonitor
->rcWork
.top
);
484 if ( Wnd
->InternalPos
.flags
& WPF_RESTORETOMAXIMIZED
|| Wnd
->style
& WS_MAXIMIZE
)
485 lpwndpl
->flags
|= WPF_RESTORETOMAXIMIZED
;
487 if ( ((Wnd
->style
& (WS_CHILD
|WS_POPUP
)) == WS_CHILD
) && Wnd
->InternalPos
.flags
& WPF_SETMINPOSITION
)
488 lpwndpl
->flags
|= WPF_SETMINPOSITION
;
493 /* make sure the specified rect is visible on screen */
494 static void make_rect_onscreen( RECT
*rect
)
496 PMONITOR pmonitor
= UserMonitorFromRect( rect
, MONITOR_DEFAULTTONEAREST
); // Wine uses this.
498 // FIXME: support DPI aware, rcWorkDPI/Real etc..
499 if (!pmonitor
) return;
500 /* FIXME: map coordinates from rcWork to rcMonitor */
501 if (rect
->right
<= pmonitor
->rcWork
.left
)
503 rect
->right
+= pmonitor
->rcWork
.left
- rect
->left
;
504 rect
->left
= pmonitor
->rcWork
.left
;
506 else if (rect
->left
>= pmonitor
->rcWork
.right
)
508 rect
->left
+= pmonitor
->rcWork
.right
- rect
->right
;
509 rect
->right
= pmonitor
->rcWork
.right
;
511 if (rect
->bottom
<= pmonitor
->rcWork
.top
)
513 rect
->bottom
+= pmonitor
->rcWork
.top
- rect
->top
;
514 rect
->top
= pmonitor
->rcWork
.top
;
516 else if (rect
->top
>= pmonitor
->rcWork
.bottom
)
518 rect
->top
+= pmonitor
->rcWork
.bottom
- rect
->bottom
;
519 rect
->bottom
= pmonitor
->rcWork
.bottom
;
523 /* make sure the specified point is visible on screen */
524 static void make_point_onscreen( POINT
*pt
)
528 RECTL_vSetRect( &rect
, pt
->x
, pt
->y
, pt
->x
+ 1, pt
->y
+ 1 );
529 make_rect_onscreen( &rect
);
535 IntSetWindowPlacement(PWND Wnd
, WINDOWPLACEMENT
*wpl
, UINT Flags
)
540 if ( Flags
& PLACE_MIN
) make_point_onscreen( &wpl
->ptMinPosition
);
541 if ( Flags
& PLACE_MAX
) make_point_onscreen( &wpl
->ptMaxPosition
);
542 if ( Flags
& PLACE_RECT
) make_rect_onscreen( &wpl
->rcNormalPosition
);
544 if (!Wnd
|| Wnd
== Wnd
->head
.rpdesk
->pDeskInfo
->spwnd
) return FALSE
;
546 if ( Flags
& PLACE_MIN
) Wnd
->InternalPos
.IconPos
= wpl
->ptMinPosition
;
547 if ( Flags
& PLACE_MAX
) Wnd
->InternalPos
.MaxPos
= wpl
->ptMaxPosition
;
548 if ( Flags
& PLACE_RECT
) Wnd
->InternalPos
.NormalRect
= wpl
->rcNormalPosition
;
550 SWP_Flags
= SWP_NOZORDER
| SWP_NOACTIVATE
| ((wpl
->flags
& WPF_ASYNCWINDOWPLACEMENT
) ? SWP_ASYNCWINDOWPOS
: 0);
552 if (Wnd
->style
& WS_MINIMIZE
)
554 if (Flags
& PLACE_MIN
|| Wnd
->InternalPos
.flags
& WPF_SETMINPOSITION
)
556 co_WinPosSetWindowPos(Wnd
, HWND_TOP
,
557 wpl
->ptMinPosition
.x
, wpl
->ptMinPosition
.y
, 0, 0,
558 SWP_NOSIZE
| SWP_Flags
);
559 Wnd
->InternalPos
.flags
|= WPF_MININIT
;
562 else if (Wnd
->style
& WS_MAXIMIZE
)
564 if (Flags
& PLACE_MAX
)
566 co_WinPosSetWindowPos(Wnd
, HWND_TOP
,
567 wpl
->ptMaxPosition
.x
, wpl
->ptMaxPosition
.y
, 0, 0,
568 SWP_NOSIZE
| SWP_Flags
);
569 Wnd
->InternalPos
.flags
|= WPF_MAXINIT
;
572 else if (Flags
& PLACE_RECT
)
574 co_WinPosSetWindowPos(Wnd
, HWND_TOP
,
575 wpl
->rcNormalPosition
.left
, wpl
->rcNormalPosition
.top
,
576 wpl
->rcNormalPosition
.right
- wpl
->rcNormalPosition
.left
,
577 wpl
->rcNormalPosition
.bottom
- wpl
->rcNormalPosition
.top
,
581 sAsync
= (Wnd
->head
.pti
->MessageQueue
!= gptiCurrent
->MessageQueue
&& wpl
->flags
& WPF_ASYNCWINDOWPLACEMENT
);
584 co_IntSendMessageNoWait( UserHMGetHandle(Wnd
), WM_ASYNC_SHOWWINDOW
, wpl
->showCmd
, 0 );
586 co_WinPosShowWindow(Wnd
, wpl
->showCmd
);
588 if ( Wnd
->style
& WS_MINIMIZE
&& !sAsync
)
590 if ( wpl
->flags
& WPF_SETMINPOSITION
)
591 Wnd
->InternalPos
.flags
|= WPF_SETMINPOSITION
;
593 if ( wpl
->flags
& WPF_RESTORETOMAXIMIZED
)
594 Wnd
->InternalPos
.flags
|= WPF_RESTORETOMAXIMIZED
;
600 co_WinPosMinMaximize(PWND Wnd
, UINT ShowFlag
, RECT
* NewPos
)
608 wpl
.length
= sizeof(wpl
);
609 IntGetWindowPlacement( Wnd
, &wpl
);
611 if (co_HOOK_CallHooks( WH_CBT
, HCBT_MINMAX
, (WPARAM
)Wnd
->head
.h
, ShowFlag
))
613 ERR("WinPosMinMaximize WH_CBT Call Hook return!\n");
614 return SWP_NOSIZE
| SWP_NOMOVE
;
616 if (Wnd
->style
& WS_MINIMIZE
)
618 if (ShowFlag
== SW_MINIMIZE
) return SWP_NOSIZE
| SWP_NOMOVE
;
620 if (!co_IntSendMessageNoWait(Wnd
->head
.h
, WM_QUERYOPEN
, 0, 0))
622 return(SWP_NOSIZE
| SWP_NOMOVE
);
624 SwpFlags
|= SWP_NOCOPYBITS
;
630 if (Wnd
->style
& WS_MAXIMIZE
)
632 Wnd
->InternalPos
.flags
|= WPF_RESTORETOMAXIMIZED
;
633 Wnd
->style
&= ~WS_MAXIMIZE
;
634 SwpFlags
|= SWP_STATECHANGED
;
638 Wnd
->InternalPos
.flags
&= ~WPF_RESTORETOMAXIMIZED
;
640 co_UserRedrawWindow(Wnd
, NULL
, 0, RDW_VALIDATE
| RDW_NOERASE
|
641 RDW_NOINTERNALPAINT
);
642 Wnd
->style
|= WS_MINIMIZE
;
643 if (!(Wnd
->InternalPos
.flags
& WPF_SETMINPOSITION
))
644 Wnd
->InternalPos
.flags
&= ~WPF_MININIT
;
645 WinPosFindIconPos(Wnd
, &wpl
.ptMinPosition
);
646 /*ERR("Minimize: %d,%d %dx%d\n",
647 wpl.ptMinPosition.x, wpl.ptMinPosition.y, UserGetSystemMetrics(SM_CXMINIMIZED),
648 UserGetSystemMetrics(SM_CYMINIMIZED));
650 RECTL_vSetRect(NewPos
, wpl
.ptMinPosition
.x
, wpl
.ptMinPosition
.y
,
651 // wpl.ptMinPosition.x + UserGetSystemMetrics(SM_CXMINIMIZED),
652 // wpl.ptMinPosition.y + UserGetSystemMetrics(SM_CYMINIMIZED));
653 UserGetSystemMetrics(SM_CXMINIMIZED
),
654 UserGetSystemMetrics(SM_CYMINIMIZED
));
655 SwpFlags
|= SWP_NOCOPYBITS
;
661 co_WinPosGetMinMaxInfo(Wnd
, &Size
, &wpl
.ptMaxPosition
, NULL
, NULL
);
663 /*ERR("Maximize: %d,%d %dx%d\n",
664 wpl.ptMaxPosition.x, wpl.ptMaxPosition.y, Size.x, Size.y);
666 if (Wnd
->style
& WS_MINIMIZE
)
668 SwpFlags
|= SWP_STATECHANGED
;
669 Wnd
->style
&= ~WS_MINIMIZE
;
671 Wnd
->style
|= WS_MAXIMIZE
;
672 RECTL_vSetRect(NewPos
, wpl
.ptMaxPosition
.x
, wpl
.ptMaxPosition
.y
,
673 // wpl.ptMaxPosition.x + Size.x, wpl.ptMaxPosition.y + Size.y);
680 if (Wnd
->style
& WS_MINIMIZE
)
682 Wnd
->style
&= ~WS_MINIMIZE
;
683 if (Wnd
->InternalPos
.flags
& WPF_RESTORETOMAXIMIZED
)
685 co_WinPosGetMinMaxInfo(Wnd
, &Size
, &wpl
.ptMaxPosition
, NULL
, NULL
);
686 SwpFlags
|= SWP_STATECHANGED
;
687 Wnd
->style
|= WS_MAXIMIZE
;
688 /*ERR("Restore to Max: %d,%d %dx%d\n",
689 wpl.ptMaxPosition.x, wpl.ptMaxPosition.y, Size.x, Size.y);
691 RECTL_vSetRect(NewPos
, wpl
.ptMaxPosition
.x
, wpl
.ptMaxPosition
.y
,
692 // wpl.ptMaxPosition.x + Size.x, wpl.ptMaxPosition.y + Size.y);
698 *NewPos
= wpl
.rcNormalPosition
;
699 /*ERR("Restore Max: %d,%d %dx%d\n",
700 NewPos->left, NewPos->top, NewPos->right - NewPos->left, NewPos->bottom - NewPos->top);
702 NewPos
->right
-= NewPos
->left
;
703 NewPos
->bottom
-= NewPos
->top
;
709 if (!(Wnd
->style
& WS_MAXIMIZE
))
713 Wnd
->style
&= ~WS_MAXIMIZE
;
714 SwpFlags
|= SWP_STATECHANGED
;
715 Wnd
->InternalPos
.flags
&= ~WPF_RESTORETOMAXIMIZED
;
716 *NewPos
= wpl
.rcNormalPosition
;
717 /*ERR("Restore Min: %d,%d %dx%d\n",
718 NewPos->left, NewPos->top, NewPos->right - NewPos->left, NewPos->bottom - NewPos->top);
720 NewPos
->right
-= NewPos
->left
;
721 NewPos
->bottom
-= NewPos
->top
;
730 UserHasWindowEdge(DWORD Style
, DWORD ExStyle
)
732 if (Style
& WS_MINIMIZE
)
734 if (ExStyle
& WS_EX_DLGMODALFRAME
)
736 if (ExStyle
& WS_EX_STATICEDGE
)
738 if (Style
& WS_THICKFRAME
)
741 if (Style
== WS_DLGFRAME
|| Style
== WS_CAPTION
)
747 IntGetWindowBorderMeasures(PWND Wnd
, UINT
*cx
, UINT
*cy
)
749 if(HAS_DLGFRAME(Wnd
->style
, Wnd
->ExStyle
) && !(Wnd
->style
& WS_MINIMIZE
))
751 *cx
= UserGetSystemMetrics(SM_CXDLGFRAME
);
752 *cy
= UserGetSystemMetrics(SM_CYDLGFRAME
);
756 if(HAS_THICKFRAME(Wnd
->style
, Wnd
->ExStyle
)&& !(Wnd
->style
& WS_MINIMIZE
))
758 *cx
= UserGetSystemMetrics(SM_CXFRAME
);
759 *cy
= UserGetSystemMetrics(SM_CYFRAME
);
761 else if(HAS_THINFRAME(Wnd
->style
, Wnd
->ExStyle
))
763 *cx
= UserGetSystemMetrics(SM_CXBORDER
);
764 *cy
= UserGetSystemMetrics(SM_CYBORDER
);
774 UserGetWindowBorders(DWORD Style
, DWORD ExStyle
, SIZE
*Size
, BOOL WithClient
)
778 if (UserHasWindowEdge(Style
, ExStyle
))
780 else if (ExStyle
& WS_EX_STATICEDGE
)
782 if ((ExStyle
& WS_EX_CLIENTEDGE
) && WithClient
)
784 if (Style
& WS_CAPTION
|| ExStyle
& WS_EX_DLGMODALFRAME
)
786 Size
->cx
= Size
->cy
= Border
;
787 if ((Style
& WS_THICKFRAME
) && !(Style
& WS_MINIMIZE
))
789 Size
->cx
+= UserGetSystemMetrics(SM_CXFRAME
) - UserGetSystemMetrics(SM_CXDLGFRAME
);
790 Size
->cy
+= UserGetSystemMetrics(SM_CYFRAME
) - UserGetSystemMetrics(SM_CYDLGFRAME
);
792 Size
->cx
*= UserGetSystemMetrics(SM_CXBORDER
);
793 Size
->cy
*= UserGetSystemMetrics(SM_CYBORDER
);
797 UserAdjustWindowRectEx(LPRECT lpRect
,
806 lpRect
->top
-= UserGetSystemMetrics(SM_CYMENU
);
808 if ((dwStyle
& WS_CAPTION
) == WS_CAPTION
)
810 if (dwExStyle
& WS_EX_TOOLWINDOW
)
811 lpRect
->top
-= UserGetSystemMetrics(SM_CYSMCAPTION
);
813 lpRect
->top
-= UserGetSystemMetrics(SM_CYCAPTION
);
815 UserGetWindowBorders(dwStyle
, dwExStyle
, &BorderSize
, TRUE
);
825 co_WinPosGetMinMaxInfo(PWND Window
, POINT
* MaxSize
, POINT
* MaxPos
,
826 POINT
* MinTrack
, POINT
* MaxTrack
)
831 LONG style
= Window
->style
;
833 LONG exstyle
= Window
->ExStyle
;
836 ASSERT_REFS_CO(Window
);
838 /* Compute default values */
840 rc
= Window
->rcWindow
;
841 MinMax
.ptReserved
.x
= rc
.left
;
842 MinMax
.ptReserved
.y
= rc
.top
;
844 if ((style
& WS_CAPTION
) == WS_CAPTION
)
845 adjustedStyle
= style
& ~WS_BORDER
; /* WS_CAPTION = WS_DLGFRAME | WS_BORDER */
847 adjustedStyle
= style
;
849 if(Window
->spwndParent
)
850 IntGetClientRect(Window
->spwndParent
, &rc
);
851 UserAdjustWindowRectEx(&rc
, adjustedStyle
, ((style
& WS_POPUP
) && Window
->IDMenu
), exstyle
);
856 MinMax
.ptMaxSize
.x
= rc
.right
- rc
.left
;
857 MinMax
.ptMaxSize
.y
= rc
.bottom
- rc
.top
;
858 if (style
& (WS_DLGFRAME
| WS_BORDER
))
860 MinMax
.ptMinTrackSize
.x
= UserGetSystemMetrics(SM_CXMINTRACK
);
861 MinMax
.ptMinTrackSize
.y
= UserGetSystemMetrics(SM_CYMINTRACK
);
865 MinMax
.ptMinTrackSize
.x
= 2 * xinc
;
866 MinMax
.ptMinTrackSize
.y
= 2 * yinc
;
868 MinMax
.ptMaxTrackSize
.x
= UserGetSystemMetrics(SM_CXMAXTRACK
);
869 MinMax
.ptMaxTrackSize
.y
= UserGetSystemMetrics(SM_CYMAXTRACK
);
870 MinMax
.ptMaxPosition
.x
= -xinc
;
871 MinMax
.ptMaxPosition
.y
= -yinc
;
873 if (!EMPTYPOINT(Window
->InternalPos
.MaxPos
)) MinMax
.ptMaxPosition
= Window
->InternalPos
.MaxPos
;
875 co_IntSendMessage(Window
->head
.h
, WM_GETMINMAXINFO
, 0, (LPARAM
)&MinMax
);
877 /* if the app didn't change the values, adapt them for the current monitor */
878 if ((monitor
= UserGetPrimaryMonitor()))
882 rc_work
= monitor
->rcMonitor
;
884 if (style
& WS_MAXIMIZEBOX
)
886 if ((style
& WS_CAPTION
) == WS_CAPTION
|| !(style
& (WS_CHILD
| WS_POPUP
)))
887 rc_work
= monitor
->rcWork
;
890 if (MinMax
.ptMaxSize
.x
== UserGetSystemMetrics(SM_CXSCREEN
) + 2 * xinc
&&
891 MinMax
.ptMaxSize
.y
== UserGetSystemMetrics(SM_CYSCREEN
) + 2 * yinc
)
893 MinMax
.ptMaxSize
.x
= (rc_work
.right
- rc_work
.left
) + 2 * xinc
;
894 MinMax
.ptMaxSize
.y
= (rc_work
.bottom
- rc_work
.top
) + 2 * yinc
;
896 if (MinMax
.ptMaxPosition
.x
== -xinc
&& MinMax
.ptMaxPosition
.y
== -yinc
)
898 MinMax
.ptMaxPosition
.x
= rc_work
.left
- xinc
;
899 MinMax
.ptMaxPosition
.y
= rc_work
.top
- yinc
;
901 if (MinMax
.ptMaxSize
.x
>= (monitor
->rcMonitor
.right
- monitor
->rcMonitor
.left
) &&
902 MinMax
.ptMaxSize
.y
>= (monitor
->rcMonitor
.bottom
- monitor
->rcMonitor
.top
) )
903 Window
->state
|= WNDS_MAXIMIZESTOMONITOR
;
905 Window
->state
&= ~WNDS_MAXIMIZESTOMONITOR
;
909 MinMax
.ptMaxTrackSize
.x
= max(MinMax
.ptMaxTrackSize
.x
,
910 MinMax
.ptMinTrackSize
.x
);
911 MinMax
.ptMaxTrackSize
.y
= max(MinMax
.ptMaxTrackSize
.y
,
912 MinMax
.ptMinTrackSize
.y
);
915 *MaxSize
= MinMax
.ptMaxSize
;
917 *MaxPos
= MinMax
.ptMaxPosition
;
919 *MinTrack
= MinMax
.ptMinTrackSize
;
921 *MaxTrack
= MinMax
.ptMaxTrackSize
;
923 return 0; // FIXME: What does it return?
928 FixClientRect(PRECTL ClientRect
, PRECTL WindowRect
)
930 if (ClientRect
->left
< WindowRect
->left
)
932 ClientRect
->left
= WindowRect
->left
;
934 else if (WindowRect
->right
< ClientRect
->left
)
936 ClientRect
->left
= WindowRect
->right
;
938 if (ClientRect
->right
< WindowRect
->left
)
940 ClientRect
->right
= WindowRect
->left
;
942 else if (WindowRect
->right
< ClientRect
->right
)
944 ClientRect
->right
= WindowRect
->right
;
946 if (ClientRect
->top
< WindowRect
->top
)
948 ClientRect
->top
= WindowRect
->top
;
950 else if (WindowRect
->bottom
< ClientRect
->top
)
952 ClientRect
->top
= WindowRect
->bottom
;
954 if (ClientRect
->bottom
< WindowRect
->top
)
956 ClientRect
->bottom
= WindowRect
->top
;
958 else if (WindowRect
->bottom
< ClientRect
->bottom
)
960 ClientRect
->bottom
= WindowRect
->bottom
;
966 co_WinPosDoNCCALCSize(PWND Window
, PWINDOWPOS WinPos
,
967 RECT
* WindowRect
, RECT
* ClientRect
)
972 ASSERT_REFS_CO(Window
);
974 /* Send WM_NCCALCSIZE message to get new client area */
975 if ((WinPos
->flags
& (SWP_FRAMECHANGED
| SWP_NOSIZE
)) != SWP_NOSIZE
)
977 NCCALCSIZE_PARAMS params
;
978 WINDOWPOS winposCopy
;
980 params
.rgrc
[0] = *WindowRect
;
981 params
.rgrc
[1] = Window
->rcWindow
;
982 params
.rgrc
[2] = Window
->rcClient
;
983 Parent
= Window
->spwndParent
;
984 if (0 != (Window
->style
& WS_CHILD
) && Parent
)
986 RECTL_vOffsetRect(&(params
.rgrc
[0]), - Parent
->rcClient
.left
,
987 - Parent
->rcClient
.top
);
988 RECTL_vOffsetRect(&(params
.rgrc
[1]), - Parent
->rcClient
.left
,
989 - Parent
->rcClient
.top
);
990 RECTL_vOffsetRect(&(params
.rgrc
[2]), - Parent
->rcClient
.left
,
991 - Parent
->rcClient
.top
);
993 params
.lppos
= &winposCopy
;
994 winposCopy
= *WinPos
;
996 wvrFlags
= co_IntSendMessage(Window
->head
.h
, WM_NCCALCSIZE
, TRUE
, (LPARAM
) ¶ms
);
998 /* If the application send back garbage, ignore it */
999 if (params
.rgrc
[0].left
<= params
.rgrc
[0].right
&&
1000 params
.rgrc
[0].top
<= params
.rgrc
[0].bottom
)
1002 *ClientRect
= params
.rgrc
[0];
1003 if ((Window
->style
& WS_CHILD
) && Parent
)
1005 RECTL_vOffsetRect(ClientRect
, Parent
->rcClient
.left
,
1006 Parent
->rcClient
.top
);
1008 FixClientRect(ClientRect
, WindowRect
);
1011 /* FIXME: WVR_ALIGNxxx */
1013 if (ClientRect
->left
!= Window
->rcClient
.left
||
1014 ClientRect
->top
!= Window
->rcClient
.top
)
1016 WinPos
->flags
&= ~SWP_NOCLIENTMOVE
;
1019 if ((ClientRect
->right
- ClientRect
->left
!=
1020 Window
->rcClient
.right
- Window
->rcClient
.left
) ||
1021 (ClientRect
->bottom
- ClientRect
->top
!=
1022 Window
->rcClient
.bottom
- Window
->rcClient
.top
))
1024 WinPos
->flags
&= ~SWP_NOCLIENTSIZE
;
1029 if (! (WinPos
->flags
& SWP_NOMOVE
)
1030 && (ClientRect
->left
!= Window
->rcClient
.left
||
1031 ClientRect
->top
!= Window
->rcClient
.top
))
1033 WinPos
->flags
&= ~SWP_NOCLIENTMOVE
;
1042 co_WinPosDoWinPosChanging(PWND Window
,
1049 ASSERT_REFS_CO(Window
);
1051 if (!(WinPos
->flags
& SWP_NOSENDCHANGING
))
1053 co_IntSendMessageNoWait(Window
->head
.h
, WM_WINDOWPOSCHANGING
, 0, (LPARAM
) WinPos
);
1056 *WindowRect
= Window
->rcWindow
;
1057 *ClientRect
= Window
->rcClient
;
1059 if (!(WinPos
->flags
& SWP_NOSIZE
))
1061 WindowRect
->right
= WindowRect
->left
+ WinPos
->cx
;
1062 WindowRect
->bottom
= WindowRect
->top
+ WinPos
->cy
;
1065 if (!(WinPos
->flags
& SWP_NOMOVE
))
1070 Parent
= Window
->spwndParent
;
1071 if ((0 != (Window
->style
& WS_CHILD
)) && Parent
)
1073 X
+= Parent
->rcClient
.left
;
1074 Y
+= Parent
->rcClient
.top
;
1077 WindowRect
->left
= X
;
1078 WindowRect
->top
= Y
;
1079 WindowRect
->right
+= X
- Window
->rcWindow
.left
;
1080 WindowRect
->bottom
+= Y
- Window
->rcWindow
.top
;
1081 RECTL_vOffsetRect(ClientRect
,
1082 X
- Window
->rcWindow
.left
,
1083 Y
- Window
->rcWindow
.top
);
1086 WinPos
->flags
|= SWP_NOCLIENTMOVE
| SWP_NOCLIENTSIZE
;
1092 * Fix Z order taking into account owned popups -
1093 * basically we need to maintain them above the window that owns them
1097 WinPosDoOwnedPopups(PWND Window
, HWND hWndInsertAfter
)
1102 PWND DesktopWindow
, ChildObject
;
1105 Owner
= Window
->spwndOwner
? Window
->spwndOwner
->head
.h
: NULL
;
1106 Style
= Window
->style
;
1108 if ((Style
& WS_POPUP
) && Owner
)
1110 /* Make sure this popup stays above the owner */
1111 HWND hWndLocalPrev
= HWND_TOPMOST
;
1113 if (hWndInsertAfter
!= HWND_TOPMOST
)
1115 DesktopWindow
= UserGetWindowObject(IntGetDesktopWindow());
1116 List
= IntWinListChildren(DesktopWindow
);
1120 for (i
= 0; List
[i
]; i
++)
1122 if (List
[i
] == Owner
)
1124 if (HWND_TOP
== hWndInsertAfter
)
1126 ChildObject
= UserGetWindowObject(List
[i
]);
1127 if (NULL
!= ChildObject
)
1129 if (0 == (ChildObject
->ExStyle
& WS_EX_TOPMOST
))
1135 if (List
[i
] != Window
->head
.h
)
1136 hWndLocalPrev
= List
[i
];
1137 if (hWndLocalPrev
== hWndInsertAfter
)
1140 hWndInsertAfter
= hWndLocalPrev
;
1144 else if (Style
& WS_CHILD
)
1146 return hWndInsertAfter
;
1151 DesktopWindow
= UserGetWindowObject(IntGetDesktopWindow());
1152 List
= IntWinListChildren(DesktopWindow
);
1156 for (i
= 0; List
[i
]; i
++)
1160 if (List
[i
] == Window
->head
.h
)
1163 if (!(Wnd
= UserGetWindowObject(List
[i
])))
1166 if (Wnd
->style
& WS_POPUP
&& Wnd
->spwndOwner
== Window
)
1168 USER_REFERENCE_ENTRY Ref
;
1169 UserRefObjectCo(Wnd
, &Ref
);
1171 co_WinPosSetWindowPos(Wnd
, hWndInsertAfter
, 0, 0, 0, 0,
1172 SWP_NOMOVE
| SWP_NOSIZE
| SWP_NOACTIVATE
| SWP_NOSENDCHANGING
);
1174 UserDerefObjectCo(Wnd
);
1176 hWndInsertAfter
= List
[i
];
1182 return hWndInsertAfter
;
1185 /***********************************************************************
1186 * WinPosInternalMoveWindow
1188 * Update WindowRect and ClientRect of Window and all of its children
1189 * We keep both WindowRect and ClientRect in screen coordinates internally
1193 WinPosInternalMoveWindow(PWND Window
, INT MoveX
, INT MoveY
)
1197 ASSERT(Window
!= Window
->spwndChild
);
1199 Window
->rcWindow
.left
+= MoveX
;
1200 Window
->rcWindow
.right
+= MoveX
;
1201 Window
->rcWindow
.top
+= MoveY
;
1202 Window
->rcWindow
.bottom
+= MoveY
;
1204 Window
->rcClient
.left
+= MoveX
;
1205 Window
->rcClient
.right
+= MoveX
;
1206 Window
->rcClient
.top
+= MoveY
;
1207 Window
->rcClient
.bottom
+= MoveY
;
1209 for(Child
= Window
->spwndChild
; Child
; Child
= Child
->spwndNext
)
1211 WinPosInternalMoveWindow(Child
, MoveX
, MoveY
);
1216 * WinPosFixupSWPFlags
1218 * Fix redundant flags and values in the WINDOWPOS structure.
1222 WinPosFixupFlags(WINDOWPOS
*WinPos
, PWND Wnd
)
1224 if (Wnd
->style
& WS_VISIBLE
)
1226 WinPos
->flags
&= ~SWP_SHOWWINDOW
;
1230 WinPos
->flags
&= ~SWP_HIDEWINDOW
;
1231 if (!(WinPos
->flags
& SWP_SHOWWINDOW
))
1232 WinPos
->flags
|= SWP_NOREDRAW
;
1235 WinPos
->cx
= max(WinPos
->cx
, 0);
1236 WinPos
->cy
= max(WinPos
->cy
, 0);
1238 /* Check for right size */
1239 if (Wnd
->rcWindow
.right
- Wnd
->rcWindow
.left
== WinPos
->cx
&&
1240 Wnd
->rcWindow
.bottom
- Wnd
->rcWindow
.top
== WinPos
->cy
)
1242 WinPos
->flags
|= SWP_NOSIZE
;
1245 /* Check for right position */
1246 if (Wnd
->rcWindow
.left
== WinPos
->x
&&
1247 Wnd
->rcWindow
.top
== WinPos
->y
)
1249 WinPos
->flags
|= SWP_NOMOVE
;
1252 if (WinPos
->hwnd
== UserGetForegroundWindow())
1254 WinPos
->flags
|= SWP_NOACTIVATE
; /* Already active */
1257 if ((Wnd
->style
& (WS_POPUP
| WS_CHILD
)) != WS_CHILD
)
1259 /* Bring to the top when activating */
1260 if (!(WinPos
->flags
& SWP_NOACTIVATE
))
1262 WinPos
->flags
&= ~SWP_NOZORDER
;
1263 WinPos
->hwndInsertAfter
= (0 != (Wnd
->ExStyle
& WS_EX_TOPMOST
) ?
1264 HWND_TOPMOST
: HWND_TOP
);
1269 /* Check hwndInsertAfter */
1270 if (!(WinPos
->flags
& SWP_NOZORDER
))
1272 /* Fix sign extension */
1273 if (WinPos
->hwndInsertAfter
== (HWND
)0xffff)
1275 WinPos
->hwndInsertAfter
= HWND_TOPMOST
;
1277 else if (WinPos
->hwndInsertAfter
== (HWND
)0xfffe)
1279 WinPos
->hwndInsertAfter
= HWND_NOTOPMOST
;
1282 if (WinPos
->hwndInsertAfter
== HWND_NOTOPMOST
)
1284 WinPos
->hwndInsertAfter
= HWND_TOP
;
1286 else if (HWND_TOP
== WinPos
->hwndInsertAfter
1287 && 0 != (Wnd
->ExStyle
& WS_EX_TOPMOST
))
1289 /* Keep it topmost when it's already topmost */
1290 WinPos
->hwndInsertAfter
= HWND_TOPMOST
;
1293 /* hwndInsertAfter must be a sibling of the window */
1294 if (HWND_TOPMOST
!= WinPos
->hwndInsertAfter
1295 && HWND_TOP
!= WinPos
->hwndInsertAfter
1296 && HWND_NOTOPMOST
!= WinPos
->hwndInsertAfter
1297 && HWND_BOTTOM
!= WinPos
->hwndInsertAfter
)
1301 InsAfterWnd
= UserGetWindowObject(WinPos
->hwndInsertAfter
);
1307 if (InsAfterWnd
->spwndParent
!= Wnd
->spwndParent
)
1309 /* Note from wine User32 Win test_SetWindowPos:
1310 "Returns TRUE also for windows that are not siblings"
1311 "Does not seem to do anything even without passing flags, still returns TRUE"
1312 "Same thing the other way around."
1313 ".. and with these windows."
1320 * We don't need to change the Z order of hwnd if it's already
1321 * inserted after hwndInsertAfter or when inserting hwnd after
1324 if ((WinPos
->hwnd
== WinPos
->hwndInsertAfter
) ||
1325 ((InsAfterWnd
->spwndNext
) && (WinPos
->hwnd
== InsAfterWnd
->spwndNext
->head
.h
)))
1327 WinPos
->flags
|= SWP_NOZORDER
;
1336 /* x and y are always screen relative */
1338 co_WinPosSetWindowPos(
1340 HWND WndInsertAfter
,
1349 RECTL NewWindowRect
;
1350 RECTL NewClientRect
;
1352 HRGN VisBefore
= NULL
;
1353 HRGN VisAfter
= NULL
;
1354 HRGN DirtyRgn
= NULL
;
1355 HRGN ExposedRgn
= NULL
;
1356 HRGN CopyRgn
= NULL
;
1358 RECTL OldWindowRect
, OldClientRect
;
1363 BOOL bPointerInWindow
;
1365 ASSERT_REFS_CO(Window
);
1367 /* FIXME: Get current active window from active queue. */
1369 * Only allow CSRSS to mess with the desktop window
1372 if ( Window
->head
.h
== IntGetDesktopWindow() &&
1373 Window
->head
.pti
->ppi
!= PsGetCurrentProcessWin32Process())
1375 ERR("Desktop Window...\n");
1379 bPointerInWindow
= IntPtInWindow(Window
, gpsi
->ptCursor
.x
, gpsi
->ptCursor
.y
);
1381 WinPos
.hwnd
= Window
->head
.h
;
1382 WinPos
.hwndInsertAfter
= WndInsertAfter
;
1387 WinPos
.flags
= flags
;
1389 co_WinPosDoWinPosChanging(Window
, &WinPos
, &NewWindowRect
, &NewClientRect
);
1391 /* Does the window still exist? */
1392 if (!IntIsWindow(WinPos
.hwnd
))
1394 EngSetLastError(ERROR_INVALID_WINDOW_HANDLE
);
1398 /* Fix up the flags. */
1399 if (!WinPosFixupFlags(&WinPos
, Window
))
1405 Ancestor
= UserGetAncestor(Window
, GA_PARENT
);
1406 if ( (WinPos
.flags
& (SWP_NOZORDER
| SWP_HIDEWINDOW
| SWP_SHOWWINDOW
)) !=
1408 Ancestor
&& Ancestor
->head
.h
== IntGetDesktopWindow() )
1410 WinPos
.hwndInsertAfter
= WinPosDoOwnedPopups(Window
, WinPos
.hwndInsertAfter
);
1413 if (!(WinPos
.flags
& SWP_NOREDRAW
))
1415 /* Compute the visible region before the window position is changed */
1416 if (!(WinPos
.flags
& SWP_SHOWWINDOW
) &&
1417 (WinPos
.flags
& (SWP_NOMOVE
| SWP_NOSIZE
| SWP_NOZORDER
|
1418 SWP_HIDEWINDOW
| SWP_FRAMECHANGED
)) !=
1419 (SWP_NOMOVE
| SWP_NOSIZE
| SWP_NOZORDER
))
1421 VisBefore
= VIS_ComputeVisibleRegion(Window
, FALSE
, FALSE
,
1422 (Window
->style
& WS_CLIPSIBLINGS
) ? TRUE
: FALSE
);
1425 if ( VisBefore
!= NULL
&&
1426 (VisRgn
= (PROSRGNDATA
)RGNOBJAPI_Lock(VisBefore
, NULL
)) &&
1427 REGION_Complexity(VisRgn
) == NULLREGION
)
1429 RGNOBJAPI_Unlock(VisRgn
);
1430 GreDeleteObject(VisBefore
);
1435 RGNOBJAPI_Unlock(VisRgn
);
1436 NtGdiOffsetRgn(VisBefore
, -Window
->rcWindow
.left
, -Window
->rcWindow
.top
);
1441 WvrFlags
= co_WinPosDoNCCALCSize(Window
, &WinPos
, &NewWindowRect
, &NewClientRect
);
1443 TRACE("co_WinPosDoNCCALCSize returned %d\n", WvrFlags
);
1445 /* Relink windows. (also take into account shell window in hwndShellWindow) */
1446 if (!(WinPos
.flags
& SWP_NOZORDER
) && WinPos
.hwnd
!= UserGetShellWindow())
1448 IntLinkHwnd(Window
, WndInsertAfter
);
1451 OldWindowRect
= Window
->rcWindow
;
1452 OldClientRect
= Window
->rcClient
;
1454 if (OldClientRect
.bottom
- OldClientRect
.top
==
1455 NewClientRect
.bottom
- NewClientRect
.top
)
1457 WvrFlags
&= ~WVR_VREDRAW
;
1460 if (OldClientRect
.right
- OldClientRect
.left
==
1461 NewClientRect
.right
- NewClientRect
.left
)
1463 WvrFlags
&= ~WVR_HREDRAW
;
1466 /* FIXME: Actually do something with WVR_VALIDRECTS */
1468 if (NewClientRect
.left
!= OldClientRect
.left
||
1469 NewClientRect
.top
!= OldClientRect
.top
)
1471 WinPosInternalMoveWindow(Window
,
1472 NewClientRect
.left
- OldClientRect
.left
,
1473 NewClientRect
.top
- OldClientRect
.top
);
1476 Window
->rcWindow
= NewWindowRect
;
1477 Window
->rcClient
= NewClientRect
;
1479 if (WinPos
.flags
& SWP_HIDEWINDOW
)
1481 /* Clear the update region */
1482 co_UserRedrawWindow( Window
,
1485 RDW_VALIDATE
| RDW_NOFRAME
| RDW_NOERASE
| RDW_NOINTERNALPAINT
| RDW_ALLCHILDREN
);
1487 if (Window
->spwndParent
== UserGetDesktopWindow())
1488 co_IntShellHookNotify(HSHELL_WINDOWDESTROYED
, (LPARAM
)Window
->head
.h
);
1490 Window
->style
&= ~WS_VISIBLE
;
1492 else if (WinPos
.flags
& SWP_SHOWWINDOW
)
1494 if (Window
->spwndParent
== UserGetDesktopWindow())
1495 co_IntShellHookNotify(HSHELL_WINDOWCREATED
, (LPARAM
)Window
->head
.h
);
1497 Window
->style
|= WS_VISIBLE
;
1500 if (Window
->hrgnUpdate
!= NULL
&& Window
->hrgnUpdate
!= HRGN_WINDOW
)
1502 NtGdiOffsetRgn(Window
->hrgnUpdate
,
1503 NewWindowRect
.left
- OldWindowRect
.left
,
1504 NewWindowRect
.top
- OldWindowRect
.top
);
1507 DceResetActiveDCEs(Window
);
1509 if (!(WinPos
.flags
& SWP_NOREDRAW
))
1511 /* Determine the new visible region */
1512 VisAfter
= VIS_ComputeVisibleRegion(Window
, FALSE
, FALSE
,
1513 (Window
->style
& WS_CLIPSIBLINGS
) ? TRUE
: FALSE
);
1516 if ( VisAfter
!= NULL
&&
1517 (VisRgn
= (PROSRGNDATA
)RGNOBJAPI_Lock(VisAfter
, NULL
)) &&
1518 REGION_Complexity(VisRgn
) == NULLREGION
)
1520 RGNOBJAPI_Unlock(VisRgn
);
1521 GreDeleteObject(VisAfter
);
1526 RGNOBJAPI_Unlock(VisRgn
);
1527 NtGdiOffsetRgn(VisAfter
, -Window
->rcWindow
.left
, -Window
->rcWindow
.top
);
1531 * Determine which pixels can be copied from the old window position
1532 * to the new. Those pixels must be visible in both the old and new
1533 * position. Also, check the class style to see if the windows of this
1534 * class need to be completely repainted on (horizontal/vertical) size
1537 if ( VisBefore
!= NULL
&&
1539 !(WinPos
.flags
& SWP_NOCOPYBITS
) &&
1540 ((WinPos
.flags
& SWP_NOSIZE
) || !(WvrFlags
& WVR_REDRAW
)) &&
1541 !(Window
->ExStyle
& WS_EX_TRANSPARENT
) )
1543 CopyRgn
= IntSysCreateRectRgn(0, 0, 0, 0);
1544 RgnType
= NtGdiCombineRgn(CopyRgn
, VisAfter
, VisBefore
, RGN_AND
);
1547 * If this is (also) a window resize, the whole nonclient area
1548 * needs to be repainted. So we limit the copy to the client area,
1549 * 'cause there is no use in copying it (would possibly cause
1550 * "flashing" too). However, if the copy region is already empty,
1551 * we don't have to crop (can't take anything away from an empty
1554 if (!(WinPos
.flags
& SWP_NOSIZE
) &&
1556 RgnType
!= NULLREGION
)
1558 PROSRGNDATA pCopyRgn
;
1559 RECTL ORect
= OldClientRect
;
1560 RECTL NRect
= NewClientRect
;
1561 RECTL_vOffsetRect(&ORect
, - OldWindowRect
.left
, - OldWindowRect
.top
);
1562 RECTL_vOffsetRect(&NRect
, - NewWindowRect
.left
, - NewWindowRect
.top
);
1563 RECTL_bIntersectRect(&CopyRect
, &ORect
, &NRect
);
1564 pCopyRgn
= RGNOBJAPI_Lock(CopyRgn
, NULL
);
1565 REGION_CropAndOffsetRegion(pCopyRgn
, pCopyRgn
, &CopyRect
, NULL
);
1566 RGNOBJAPI_Unlock(pCopyRgn
);
1569 /* No use in copying bits which are in the update region. */
1570 if (Window
->hrgnUpdate
!= NULL
)
1572 NtGdiOffsetRgn(CopyRgn
, NewWindowRect
.left
, NewWindowRect
.top
);
1573 NtGdiCombineRgn(CopyRgn
, CopyRgn
, Window
->hrgnUpdate
, RGN_DIFF
);
1574 NtGdiOffsetRgn(CopyRgn
, -NewWindowRect
.left
, -NewWindowRect
.top
);
1578 * Now, get the bounding box of the copy region. If it's empty
1579 * there's nothing to copy. Also, it's no use copying bits onto
1582 if ( (VisRgn
= (PROSRGNDATA
)RGNOBJAPI_Lock(CopyRgn
, NULL
)) &&
1583 REGION_GetRgnBox(VisRgn
, &CopyRect
) == NULLREGION
)
1585 /* Nothing to copy, clean up */
1586 RGNOBJAPI_Unlock(VisRgn
);
1587 GreDeleteObject(CopyRgn
);
1590 else if (OldWindowRect
.left
!= NewWindowRect
.left
||
1591 OldWindowRect
.top
!= NewWindowRect
.top
)
1595 RGNOBJAPI_Unlock(VisRgn
);
1599 * Small trick here: there is no function to bitblt a region. So
1600 * we set the region as the clipping region, take the bounding box
1601 * of the region and bitblt that. Since nothing outside the clipping
1602 * region is copied, this has the effect of bitblt'ing the region.
1604 * Since NtUserGetDCEx takes ownership of the clip region, we need
1605 * to create a copy of CopyRgn and pass that. We need CopyRgn later
1607 NtGdiOffsetRgn(CopyRgn
, NewWindowRect
.left
, NewWindowRect
.top
);
1608 Dc
= UserGetDCEx( Window
,
1610 DCX_WINDOW
|DCX_CACHE
|DCX_INTERSECTRGN
|DCX_CLIPSIBLINGS
|DCX_KEEPCLIPRGN
);
1612 CopyRect
.left
, CopyRect
.top
,
1613 CopyRect
.right
- CopyRect
.left
,
1614 CopyRect
.bottom
- CopyRect
.top
,
1616 CopyRect
.left
+ (OldWindowRect
.left
- NewWindowRect
.left
),
1617 CopyRect
.top
+ (OldWindowRect
.top
- NewWindowRect
.top
),
1622 UserReleaseDC(Window
, Dc
, FALSE
);
1623 IntValidateParent(Window
, CopyRgn
, FALSE
);
1624 NtGdiOffsetRgn(CopyRgn
, -NewWindowRect
.left
, -NewWindowRect
.top
);
1628 RGNOBJAPI_Unlock(VisRgn
);
1636 /* We need to redraw what wasn't visible before */
1637 if (VisAfter
!= NULL
)
1639 DirtyRgn
= IntSysCreateRectRgn(0, 0, 0, 0);
1640 if (CopyRgn
!= NULL
)
1642 RgnType
= NtGdiCombineRgn(DirtyRgn
, VisAfter
, CopyRgn
, RGN_DIFF
);
1646 RgnType
= NtGdiCombineRgn(DirtyRgn
, VisAfter
, 0, RGN_COPY
);
1648 if (RgnType
!= ERROR
&& RgnType
!= NULLREGION
)
1651 NtGdiOffsetRgn(DirtyRgn, Window->rcWindow.left, Window->rcWindow.top);
1652 IntInvalidateWindows( Window,
1654 RDW_ERASE | RDW_FRAME | RDW_INVALIDATE | RDW_ALLCHILDREN);
1656 GreDeleteObject(DirtyRgn);
1659 PWND Parent
= Window
->spwndParent
;
1661 NtGdiOffsetRgn( DirtyRgn
,
1662 Window
->rcWindow
.left
,
1663 Window
->rcWindow
.top
);
1664 if ( (Window
->style
& WS_CHILD
) &&
1666 !(Parent
->style
& WS_CLIPCHILDREN
))
1668 IntInvalidateWindows( Parent
,
1670 RDW_ERASE
| RDW_INVALIDATE
);
1671 co_IntPaintWindows(Parent
, RDW_ERASENOW
, FALSE
);
1675 IntInvalidateWindows( Window
,
1677 RDW_ERASE
| RDW_FRAME
| RDW_INVALIDATE
| RDW_ALLCHILDREN
);
1680 GreDeleteObject(DirtyRgn
);
1683 if (CopyRgn
!= NULL
)
1685 GreDeleteObject(CopyRgn
);
1688 /* Expose what was covered before but not covered anymore */
1689 if (VisBefore
!= NULL
)
1691 ExposedRgn
= IntSysCreateRectRgn(0, 0, 0, 0);
1692 RgnType
= NtGdiCombineRgn(ExposedRgn
, VisBefore
, NULL
, RGN_COPY
);
1693 NtGdiOffsetRgn( ExposedRgn
,
1694 OldWindowRect
.left
- NewWindowRect
.left
,
1695 OldWindowRect
.top
- NewWindowRect
.top
);
1697 if (VisAfter
!= NULL
)
1698 RgnType
= NtGdiCombineRgn(ExposedRgn
, ExposedRgn
, VisAfter
, RGN_DIFF
);
1700 if (RgnType
!= ERROR
&& RgnType
!= NULLREGION
)
1702 co_VIS_WindowLayoutChanged(Window
, ExposedRgn
);
1704 GreDeleteObject(ExposedRgn
);
1705 GreDeleteObject(VisBefore
);
1708 if (VisAfter
!= NULL
)
1710 GreDeleteObject(VisAfter
);
1714 if (!(WinPos
.flags
& SWP_NOACTIVATE
))//(SWP_NOACTIVATE|SWP_HIDEWINDOW)))
1716 if ((Window
->style
& (WS_CHILD
| WS_POPUP
)) == WS_CHILD
)
1718 co_IntSendMessageNoWait(WinPos
.hwnd
, WM_CHILDACTIVATE
, 0, 0);
1722 TRACE("SetWindowPos Set FG Window!\n");
1723 co_IntSetForegroundWindow(Window
);
1727 if ((WinPos
.flags
& SWP_AGG_STATUSFLAGS
) != SWP_AGG_NOPOSCHANGE
)
1729 /* WM_WINDOWPOSCHANGED is sent even if SWP_NOSENDCHANGING is set
1730 and always contains final window position.
1732 WinPos
.x
= NewWindowRect
.left
;
1733 WinPos
.y
= NewWindowRect
.top
;
1734 WinPos
.cx
= NewWindowRect
.right
- NewWindowRect
.left
;
1735 WinPos
.cy
= NewWindowRect
.bottom
- NewWindowRect
.top
;
1736 co_IntSendMessageNoWait(WinPos
.hwnd
, WM_WINDOWPOSCHANGED
, 0, (LPARAM
) &WinPos
);
1739 if ( WinPos
.flags
& SWP_FRAMECHANGED
|| WinPos
.flags
& SWP_STATECHANGED
||
1740 !(WinPos
.flags
& SWP_NOCLIENTSIZE
) || !(WinPos
.flags
& SWP_NOCLIENTMOVE
) )
1742 PWND pWnd
= UserGetWindowObject(WinPos
.hwnd
);
1744 IntNotifyWinEvent(EVENT_OBJECT_LOCATIONCHANGE
, pWnd
, OBJID_WINDOW
, CHILDID_SELF
, WEF_SETBYWNDPTI
);
1747 if(bPointerInWindow
!= IntPtInWindow(Window
, gpsi
->ptCursor
.x
, gpsi
->ptCursor
.y
))
1749 /* Generate mouse move message */
1751 msg
.message
= WM_MOUSEMOVE
;
1752 msg
.wParam
= UserGetMouseButtonsState();
1753 msg
.lParam
= MAKELPARAM(gpsi
->ptCursor
.x
, gpsi
->ptCursor
.y
);
1754 msg
.pt
= gpsi
->ptCursor
;
1755 co_MsqInsertMouseMessage(&msg
, 0, 0, TRUE
);
1762 co_WinPosGetNonClientSize(PWND Window
, RECT
* WindowRect
, RECT
* ClientRect
)
1766 ASSERT_REFS_CO(Window
);
1768 *ClientRect
= *WindowRect
;
1769 Result
= co_IntSendMessageNoWait(Window
->head
.h
, WM_NCCALCSIZE
, FALSE
, (LPARAM
) ClientRect
);
1771 FixClientRect(ClientRect
, WindowRect
);
1777 co_WinPosSendSizeMove(PWND Wnd
)
1781 WPARAM wParam
= SIZE_RESTORED
;
1783 IntGetClientRect(Wnd
, &Rect
);
1784 lParam
= MAKELONG(Rect
.right
-Rect
.left
, Rect
.bottom
-Rect
.top
);
1786 Wnd
->state
&= ~WNDS_SENDSIZEMOVEMSGS
;
1788 if (Wnd
->style
& WS_MAXIMIZE
)
1790 wParam
= SIZE_MAXIMIZED
;
1792 else if (Wnd
->style
& WS_MINIMIZE
)
1794 wParam
= SIZE_MINIMIZED
;
1798 co_IntSendMessageNoWait(UserHMGetHandle(Wnd
), WM_SIZE
, wParam
, lParam
);
1800 if (Wnd
->spwndParent
== UserGetDesktopWindow()) // Wnd->spwndParent->fnid != FNID_DESKTOP )
1801 lParam
= MAKELONG(Wnd
->rcClient
.left
, Wnd
->rcClient
.top
);
1803 lParam
= MAKELONG(Wnd
->rcClient
.left
-Wnd
->spwndParent
->rcClient
.left
, Wnd
->rcClient
.top
-Wnd
->spwndParent
->rcClient
.top
);
1805 co_IntSendMessageNoWait(UserHMGetHandle(Wnd
), WM_MOVE
, 0, lParam
);
1807 IntEngWindowChanged(Wnd
, WOC_RGN_CLIENT
);
1811 co_WinPosShowWindow(PWND Wnd
, INT Cmd
)
1821 ASSERT_REFS_CO(Wnd
);
1823 WasVisible
= (Wnd
->style
& WS_VISIBLE
) != 0;
1834 Swp
|= SWP_HIDEWINDOW
| SWP_NOSIZE
| SWP_NOMOVE
;
1835 if (Wnd
->head
.h
!= UserGetActiveWindow())
1836 Swp
|= SWP_NOACTIVATE
| SWP_NOZORDER
;
1840 case SW_SHOWMINNOACTIVE
:
1841 Swp
|= SWP_NOACTIVATE
| SWP_NOZORDER
;
1843 case SW_SHOWMINIMIZED
:
1844 Swp
|= SWP_SHOWWINDOW
;
1848 Swp
|= SWP_NOACTIVATE
;
1849 if (!(style
& WS_MINIMIZE
))
1851 Swp
|= co_WinPosMinMaximize(Wnd
, SW_MINIMIZE
, &NewPos
) |
1856 Swp
|= SWP_NOSIZE
| SWP_NOMOVE
;
1859 Swp
|= SWP_FRAMECHANGED
;
1865 case SW_SHOWMAXIMIZED
:
1867 Swp
|= SWP_SHOWWINDOW
;
1868 if (!(style
& WS_MAXIMIZE
))
1870 Swp
|= co_WinPosMinMaximize(Wnd
, SW_MAXIMIZE
, &NewPos
) |
1875 Swp
|= SWP_NOSIZE
| SWP_NOMOVE
;
1878 Swp
|= SWP_FRAMECHANGED
;
1885 Swp
|= SWP_NOACTIVATE
| SWP_NOZORDER
;
1888 if (WasVisible
) return(TRUE
); // Nothing to do!
1889 Swp
|= SWP_SHOWWINDOW
| SWP_NOSIZE
| SWP_NOMOVE
;
1890 /* Don't activate the topmost window. */
1891 if (style
& WS_CHILD
) Swp
|= SWP_NOACTIVATE
| SWP_NOZORDER
;
1894 case SW_SHOWNOACTIVATE
:
1895 Wnd
->InternalPos
.flags
&= ~WPF_RESTORETOMAXIMIZED
;
1896 //Swp |= SWP_NOZORDER;
1897 Swp
|= SWP_NOACTIVATE
| SWP_NOZORDER
;
1900 case SW_SHOWDEFAULT
:
1902 Swp
|= SWP_SHOWWINDOW
;
1903 if (style
& (WS_MINIMIZE
| WS_MAXIMIZE
))
1905 Swp
|= co_WinPosMinMaximize(Wnd
, SW_RESTORE
, &NewPos
) |
1910 Swp
|= SWP_NOSIZE
| SWP_NOMOVE
;
1913 Swp
|= SWP_FRAMECHANGED
;
1919 ShowFlag
= (Cmd
!= SW_HIDE
);
1921 if (ShowFlag
!= WasVisible
)
1923 co_IntSendMessageNoWait(Wnd
->head
.h
, WM_SHOWWINDOW
, ShowFlag
, 0);
1924 if (!(Wnd
->state2
& WNDS2_WIN31COMPAT
))
1925 co_IntSendMessageNoWait(Wnd
->head
.h
, WM_SETVISIBLE
, ShowFlag
, 0);
1928 /* We can't activate a child window */
1929 if ((Wnd
->style
& WS_CHILD
) &&
1930 !(Wnd
->ExStyle
& WS_EX_MDICHILD
))
1932 Swp
|= SWP_NOACTIVATE
| SWP_NOZORDER
;
1935 #if 0 // Explorer issues with common controls. Someone does not know how CS_SAVEBITS works.
1936 if ((Wnd
->style
& (WS_POPUP
|WS_CHILD
)) != WS_CHILD
&&
1937 Wnd
->pcls
->style
& CS_SAVEBITS
&&
1938 ((Cmd
== SW_SHOW
) || (Cmd
== SW_NORMAL
)))
1940 co_IntSetActiveWindow(Wnd
,NULL
,FALSE
,TRUE
);
1941 Swp
|= SWP_NOACTIVATE
| SWP_NOZORDER
;
1945 co_WinPosSetWindowPos( Wnd
,
1946 0 != (Wnd
->ExStyle
& WS_EX_TOPMOST
) ? HWND_TOPMOST
: HWND_TOP
,
1949 NewPos
.right
, //NewPos.right - NewPos.left,
1950 NewPos
.bottom
, //NewPos.bottom - NewPos.top,
1953 if ((Cmd
== SW_HIDE
) || (Cmd
== SW_MINIMIZE
))
1955 PTHREADINFO pti
= PsGetCurrentThreadWin32Thread();
1958 if (Wnd
== pti
->MessageQueue
->spwndActive
&& pti
->MessageQueue
== IntGetFocusMessageQueue())
1960 co_WinPosActivateOtherWindow(Wnd
);
1963 /* Revert focus to parent */
1964 if (Wnd
== pti
->MessageQueue
->spwndFocus
)
1966 Parent
= Wnd
->spwndParent
;
1967 if (Wnd
->spwndParent
== UserGetDesktopWindow()) Parent
= 0;
1968 co_UserSetFocus(Parent
);
1972 /* FIXME: Check for window destruction. */
1974 if ((Wnd
->state
& WNDS_SENDSIZEMOVEMSGS
) &&
1975 !(Wnd
->state2
& WNDS2_INDESTROY
))
1977 co_WinPosSendSizeMove(Wnd
);
1980 /* if previous state was minimized Windows sets focus to the window */
1981 if (style
& WS_MINIMIZE
) co_UserSetFocus(Wnd
);
1988 co_WinPosSearchChildren(
1997 if (!(ScopeWin
->style
& WS_VISIBLE
))
2002 if ((ScopeWin
->style
& WS_DISABLED
))
2007 if (!IntPtInWindow(ScopeWin
, Point
->x
, Point
->y
))
2012 UserReferenceObject(ScopeWin
);
2014 if ( RECTL_bPointInRect(&ScopeWin
->rcClient
, Point
->x
, Point
->y
) )
2016 List
= IntWinListChildren(ScopeWin
);
2019 for (phWnd
= List
; *phWnd
; ++phWnd
)
2021 if (!(pwndChild
= UserGetWindowObject(*phWnd
)))
2026 pwndChild
= co_WinPosSearchChildren(pwndChild
, Point
, HitTest
);
2028 if(pwndChild
!= NULL
)
2030 /* We found a window. Don't send any more WM_NCHITTEST messages */
2032 UserDereferenceObject(ScopeWin
);
2040 *HitTest
= (USHORT
)co_IntSendMessage(ScopeWin
->head
.h
, WM_NCHITTEST
, 0,
2041 MAKELONG(Point
->x
, Point
->y
));
2042 if ((*HitTest
) == (USHORT
)HTTRANSPARENT
)
2044 UserDereferenceObject(ScopeWin
);
2052 co_WinPosWindowFromPoint(PWND ScopeWin
, POINT
*WinPoint
, USHORT
* HitTest
)
2055 POINT Point
= *WinPoint
;
2056 USER_REFERENCE_ENTRY Ref
;
2058 if( ScopeWin
== NULL
)
2060 ScopeWin
= UserGetDesktopWindow();
2061 if(ScopeWin
== NULL
)
2065 *HitTest
= HTNOWHERE
;
2067 ASSERT_REFS_CO(ScopeWin
);
2068 UserRefObjectCo(ScopeWin
, &Ref
);
2070 Window
= co_WinPosSearchChildren(ScopeWin
, &Point
, HitTest
);
2072 UserDerefObjectCo(ScopeWin
);
2074 ASSERT_REFS_CO(Window
);
2075 ASSERT_REFS_CO(ScopeWin
);
2081 IntRealChildWindowFromPoint(PWND Parent
, LONG x
, LONG y
)
2085 PWND pwndHit
= NULL
;
2090 if (Parent
!= UserGetDesktopWindow())
2092 Pt
.x
+= Parent
->rcClient
.left
;
2093 Pt
.y
+= Parent
->rcClient
.top
;
2096 if (!IntPtInWindow(Parent
, Pt
.x
, Pt
.y
)) return NULL
;
2098 if ((List
= IntWinListChildren(Parent
)))
2100 for (phWnd
= List
; *phWnd
; phWnd
++)
2103 if ((Child
= UserGetWindowObject(*phWnd
)))
2105 if ( Child
->style
& WS_VISIBLE
&& IntPtInWindow(Child
, Pt
.x
, Pt
.y
) )
2107 if ( Child
->pcls
->atomClassName
!= gpsi
->atomSysClass
[ICLS_BUTTON
] ||
2108 (Child
->style
& BS_TYPEMASK
) != BS_GROUPBOX
)
2119 return pwndHit
? pwndHit
: Parent
;
2123 IntChildWindowFromPointEx(PWND Parent
, LONG x
, LONG y
, UINT uiFlags
)
2127 PWND pwndHit
= NULL
;
2132 if (Parent
!= UserGetDesktopWindow())
2134 if (Parent
->ExStyle
& WS_EX_LAYOUTRTL
)
2135 Pt
.x
= Parent
->rcClient
.right
- Pt
.x
;
2137 Pt
.x
+= Parent
->rcClient
.left
;
2138 Pt
.y
+= Parent
->rcClient
.top
;
2141 if (!IntPtInWindow(Parent
, Pt
.x
, Pt
.y
)) return NULL
;
2143 if ((List
= IntWinListChildren(Parent
)))
2145 for (phWnd
= List
; *phWnd
; phWnd
++)
2148 if ((Child
= UserGetWindowObject(*phWnd
)))
2150 if (uiFlags
& (CWP_SKIPINVISIBLE
|CWP_SKIPDISABLED
))
2152 if (!(Child
->style
& WS_VISIBLE
) && (uiFlags
& CWP_SKIPINVISIBLE
)) continue;
2153 if ((Child
->style
& WS_DISABLED
) && (uiFlags
& CWP_SKIPDISABLED
)) continue;
2156 if (uiFlags
& CWP_SKIPTRANSPARENT
)
2158 if (Child
->ExStyle
& WS_EX_TRANSPARENT
) continue;
2161 if (IntPtInWindow(Child
, Pt
.x
, Pt
.y
))
2170 return pwndHit
? pwndHit
: Parent
;
2175 IntDeferWindowPos( HDWP hdwp
,
2186 HDWP retvalue
= hdwp
;
2188 TRACE("hdwp %p, hwnd %p, after %p, %d,%d (%dx%d), flags %08x\n",
2189 hdwp
, hwnd
, hwndAfter
, x
, y
, cx
, cy
, flags
);
2191 if (flags
& ~(SWP_NOSIZE
| SWP_NOMOVE
|
2192 SWP_NOZORDER
| SWP_NOREDRAW
|
2193 SWP_NOACTIVATE
| SWP_NOCOPYBITS
|
2194 SWP_NOOWNERZORDER
|SWP_SHOWWINDOW
|
2195 SWP_HIDEWINDOW
| SWP_FRAMECHANGED
))
2197 EngSetLastError(ERROR_INVALID_PARAMETER
);
2201 if (!(pDWP
= (PSMWP
)UserGetObject(gHandleTable
, hdwp
, otSMWP
)))
2203 EngSetLastError(ERROR_INVALID_DWP_HANDLE
);
2207 for (i
= 0; i
< pDWP
->ccvr
; i
++)
2209 if (pDWP
->acvr
[i
].pos
.hwnd
== hwnd
)
2211 /* Merge with the other changes */
2212 if (!(flags
& SWP_NOZORDER
))
2214 pDWP
->acvr
[i
].pos
.hwndInsertAfter
= hwndAfter
;
2216 if (!(flags
& SWP_NOMOVE
))
2218 pDWP
->acvr
[i
].pos
.x
= x
;
2219 pDWP
->acvr
[i
].pos
.y
= y
;
2221 if (!(flags
& SWP_NOSIZE
))
2223 pDWP
->acvr
[i
].pos
.cx
= cx
;
2224 pDWP
->acvr
[i
].pos
.cy
= cy
;
2226 pDWP
->acvr
[i
].pos
.flags
&= flags
| ~(SWP_NOSIZE
| SWP_NOMOVE
|
2227 SWP_NOZORDER
| SWP_NOREDRAW
|
2228 SWP_NOACTIVATE
| SWP_NOCOPYBITS
|
2230 pDWP
->acvr
[i
].pos
.flags
|= flags
& (SWP_SHOWWINDOW
| SWP_HIDEWINDOW
|
2235 if (pDWP
->ccvr
>= pDWP
->ccvrAlloc
)
2237 PCVR newpos
= ExAllocatePoolWithTag(PagedPool
, pDWP
->ccvrAlloc
* 2 * sizeof(CVR
), USERTAG_SWP
);
2243 RtlZeroMemory(newpos
, pDWP
->ccvrAlloc
* 2 * sizeof(CVR
));
2244 RtlCopyMemory(newpos
, pDWP
->acvr
, pDWP
->ccvrAlloc
* sizeof(CVR
));
2245 ExFreePoolWithTag(pDWP
->acvr
, USERTAG_SWP
);
2246 pDWP
->ccvrAlloc
*= 2;
2247 pDWP
->acvr
= newpos
;
2249 pDWP
->acvr
[pDWP
->ccvr
].pos
.hwnd
= hwnd
;
2250 pDWP
->acvr
[pDWP
->ccvr
].pos
.hwndInsertAfter
= hwndAfter
;
2251 pDWP
->acvr
[pDWP
->ccvr
].pos
.x
= x
;
2252 pDWP
->acvr
[pDWP
->ccvr
].pos
.y
= y
;
2253 pDWP
->acvr
[pDWP
->ccvr
].pos
.cx
= cx
;
2254 pDWP
->acvr
[pDWP
->ccvr
].pos
.cy
= cy
;
2255 pDWP
->acvr
[pDWP
->ccvr
].pos
.flags
= flags
;
2256 pDWP
->acvr
[pDWP
->ccvr
].hrgnClip
= NULL
;
2257 pDWP
->acvr
[pDWP
->ccvr
].hrgnInterMonitor
= NULL
;
2263 BOOL FASTCALL
IntEndDeferWindowPosEx( HDWP hdwp
, BOOL sAsync
)
2270 TRACE("%p\n", hdwp
);
2272 if (!(pDWP
= (PSMWP
)UserGetObject(gHandleTable
, hdwp
, otSMWP
)))
2274 EngSetLastError(ERROR_INVALID_DWP_HANDLE
);
2278 for (i
= 0, winpos
= pDWP
->acvr
; res
&& i
< pDWP
->ccvr
; i
++, winpos
++)
2281 USER_REFERENCE_ENTRY Ref
;
2283 TRACE("hwnd %p, after %p, %d,%d (%dx%d), flags %08x\n",
2284 winpos
->pos
.hwnd
, winpos
->pos
.hwndInsertAfter
, winpos
->pos
.x
, winpos
->pos
.y
,
2285 winpos
->pos
.cx
, winpos
->pos
.cy
, winpos
->pos
.flags
);
2287 pwnd
= (PWND
)UserGetObject(gHandleTable
, winpos
->pos
.hwnd
, otWindow
);
2291 UserRefObjectCo(pwnd
, &Ref
);
2296 PWINDOWPOS ppos
= ExAllocatePoolWithTag(PagedPool
, sizeof(WINDOWPOS
), USERTAG_SWP
);
2299 *ppos
= winpos
->pos
;
2300 /* Yes it's a pointer inside Win32k! */
2301 lRes
= co_IntSendMessageNoWait( winpos
->pos
.hwnd
, WM_ASYNC_SETWINDOWPOS
, 0, (LPARAM
)ppos
);
2302 /* We handle this the same way as Event Hooks and Hooks. */
2305 ExFreePoolWithTag(ppos
, USERTAG_SWP
);
2310 res
= co_WinPosSetWindowPos( pwnd
,
2311 winpos
->pos
.hwndInsertAfter
,
2318 UserDerefObjectCo(pwnd
);
2320 ExFreePoolWithTag(pDWP
->acvr
, USERTAG_SWP
);
2321 UserDereferenceObject(pDWP
);
2322 UserDeleteObject(hdwp
, otSMWP
);
2331 NtUserChildWindowFromPointEx(HWND hwndParent
,
2337 TRACE("Enter NtUserChildWindowFromPointEx\n");
2338 UserEnterExclusive();
2339 if ((pwndParent
= UserGetWindowObject(hwndParent
)))
2341 pwndParent
= IntChildWindowFromPointEx(pwndParent
, x
, y
, uiFlags
);
2344 TRACE("Leave NtUserChildWindowFromPointEx\n");
2345 return pwndParent
? UserHMGetHandle(pwndParent
) : NULL
;
2352 NtUserEndDeferWindowPosEx(HDWP WinPosInfo
,
2356 TRACE("Enter NtUserEndDeferWindowPosEx\n");
2357 UserEnterExclusive();
2358 Ret
= IntEndDeferWindowPosEx(WinPosInfo
, (BOOL
)Unknown1
);
2359 TRACE("Leave NtUserEndDeferWindowPosEx, ret=%i\n", Ret
);
2368 NtUserDeferWindowPos(HDWP WinPosInfo
,
2370 HWND WndInsertAfter
,
2379 UINT Tmp
= ~(SWP_ASYNCWINDOWPOS
|SWP_DEFERERASE
|SWP_NOSENDCHANGING
|SWP_NOREPOSITION
|
2380 SWP_NOCOPYBITS
|SWP_HIDEWINDOW
|SWP_SHOWWINDOW
|SWP_FRAMECHANGED
|
2381 SWP_NOACTIVATE
|SWP_NOREDRAW
|SWP_NOZORDER
|SWP_NOMOVE
|SWP_NOSIZE
);
2383 TRACE("Enter NtUserDeferWindowPos\n");
2384 UserEnterExclusive();
2388 EngSetLastError(ERROR_INVALID_FLAGS
);
2392 pWnd
= UserGetWindowObject(Wnd
);
2393 if ( !pWnd
|| // FIXME:
2394 pWnd
== UserGetDesktopWindow() || // pWnd->fnid == FNID_DESKTOP
2395 pWnd
== UserGetMessageWindow() ) // pWnd->fnid == FNID_MESSAGEWND
2400 if ( WndInsertAfter
&&
2401 WndInsertAfter
!= HWND_BOTTOM
&&
2402 WndInsertAfter
!= HWND_TOPMOST
&&
2403 WndInsertAfter
!= HWND_NOTOPMOST
)
2405 pWndIA
= UserGetWindowObject(WndInsertAfter
);
2407 pWndIA
== UserGetDesktopWindow() ||
2408 pWndIA
== UserGetMessageWindow() )
2414 Ret
= IntDeferWindowPos(WinPosInfo
, Wnd
, WndInsertAfter
, x
, y
, cx
, cy
, Flags
);
2417 TRACE("Leave NtUserDeferWindowPos, ret=%i\n", Ret
);
2426 NtUserGetInternalWindowPos( HWND hWnd
,
2433 WINDOWPLACEMENT wndpl
;
2437 if (!(Window
= UserGetWindowObject(hWnd
)))
2447 ProbeForWrite(rectWnd
,
2453 ProbeForWrite(ptIcon
,
2459 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
2461 SetLastNtError(_SEH2_GetExceptionCode());
2466 wndpl
.length
= sizeof(WINDOWPLACEMENT
);
2468 if (IntGetWindowPlacement(Window
, &wndpl
) && !Hit
)
2474 RtlCopyMemory(rectWnd
, &wndpl
.rcNormalPosition
, sizeof(RECT
));
2478 RtlCopyMemory(ptIcon
, &wndpl
.ptMinPosition
, sizeof(POINT
));
2482 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
2484 SetLastNtError(_SEH2_GetExceptionCode());
2489 if (!Hit
) Ret
= wndpl
.showCmd
;
2500 NtUserGetWindowPlacement(HWND hWnd
,
2501 WINDOWPLACEMENT
*lpwndpl
)
2504 WINDOWPLACEMENT Safepl
;
2506 DECLARE_RETURN(BOOL
);
2508 TRACE("Enter NtUserGetWindowPlacement\n");
2511 if (!(Wnd
= UserGetWindowObject(hWnd
)))
2516 Status
= MmCopyFromCaller(&Safepl
, lpwndpl
, sizeof(WINDOWPLACEMENT
));
2517 if(!NT_SUCCESS(Status
))
2519 SetLastNtError(Status
);
2522 if(Safepl
.length
!= sizeof(WINDOWPLACEMENT
))
2527 IntGetWindowPlacement(Wnd
, &Safepl
);
2529 Status
= MmCopyToCaller(lpwndpl
, &Safepl
, sizeof(WINDOWPLACEMENT
));
2530 if(!NT_SUCCESS(Status
))
2532 SetLastNtError(Status
);
2539 TRACE("Leave NtUserGetWindowPlacement, ret=%i\n",_ret_
);
2548 UINT cmd
, // Wine SW_ commands
2555 TRACE("Enter NtUserMinMaximize\n");
2556 UserEnterExclusive();
2558 pWnd
= UserGetWindowObject(hWnd
);
2559 if ( !pWnd
|| // FIXME:
2560 pWnd
== UserGetDesktopWindow() || // pWnd->fnid == FNID_DESKTOP
2561 pWnd
== UserGetMessageWindow() ) // pWnd->fnid == FNID_MESSAGEWND
2566 if ( cmd
> SW_MAX
|| pWnd
->state2
& WNDS2_INDESTROY
)
2568 EngSetLastError(ERROR_INVALID_PARAMETER
);
2572 SwFlags
= co_WinPosMinMaximize(pWnd
, cmd
, &NewPos
);
2574 SwFlags
|= Hide
? SWP_NOACTIVATE
: 0;
2576 co_WinPosSetWindowPos( pWnd
,
2580 NewPos
.right
, //NewPos.right - NewPos.left,
2581 NewPos
.bottom
, //NewPos.bottom - NewPos.top,
2584 co_WinPosShowWindow(pWnd
, cmd
);
2587 TRACE("Leave NtUserMinMaximize\n");
2589 return 0; // Always NULL?
2604 return NtUserSetWindowPos(hWnd
, 0, X
, Y
, nWidth
, nHeight
,
2605 (bRepaint
? SWP_NOZORDER
| SWP_NOACTIVATE
:
2606 SWP_NOZORDER
| SWP_NOACTIVATE
| SWP_NOREDRAW
));
2613 NtUserRealChildWindowFromPoint(HWND Parent
,
2618 TRACE("Enter NtUserRealChildWindowFromPoint\n");
2620 if ((pwndParent
= UserGetWindowObject(Parent
)))
2622 pwndParent
= IntRealChildWindowFromPoint(pwndParent
, x
, y
);
2625 TRACE("Leave NtUserRealChildWindowFromPoint\n");
2626 return pwndParent
? UserHMGetHandle(pwndParent
) : NULL
;
2635 HWND hWndInsertAfter
,
2642 DECLARE_RETURN(BOOL
);
2643 PWND Window
, pWndIA
;
2645 USER_REFERENCE_ENTRY Ref
;
2647 TRACE("Enter NtUserSetWindowPos\n");
2648 UserEnterExclusive();
2650 if (!(Window
= UserGetWindowObject(hWnd
)) || // FIXME:
2651 // Due to desktopbg.c
2652 // Window == UserGetDesktopWindow() || // pWnd->fnid == FNID_DESKTOP
2653 Window
== UserGetMessageWindow() ) // pWnd->fnid == FNID_MESSAGEWND
2655 ERR("NtUserSetWindowPos bad window handle!\n");
2659 if ( hWndInsertAfter
&&
2660 hWndInsertAfter
!= HWND_BOTTOM
&&
2661 hWndInsertAfter
!= HWND_TOPMOST
&&
2662 hWndInsertAfter
!= HWND_NOTOPMOST
)
2664 if (!(pWndIA
= UserGetWindowObject(hWndInsertAfter
)) ||
2665 pWndIA
== UserGetDesktopWindow() ||
2666 pWndIA
== UserGetMessageWindow() )
2668 ERR("NtUserSetWindowPos bad insert window handle!\n");
2673 /* First make sure that coordinates are valid for WM_WINDOWPOSCHANGING */
2674 if (!(uFlags
& SWP_NOMOVE
))
2676 if (X
< -32768) X
= -32768;
2677 else if (X
> 32767) X
= 32767;
2678 if (Y
< -32768) Y
= -32768;
2679 else if (Y
> 32767) Y
= 32767;
2681 if (!(uFlags
& SWP_NOSIZE
))
2684 else if (cx
> 32767) cx
= 32767;
2686 else if (cy
> 32767) cy
= 32767;
2689 UserRefObjectCo(Window
, &Ref
);
2690 ret
= co_WinPosSetWindowPos(Window
, hWndInsertAfter
, X
, Y
, cx
, cy
, uFlags
);
2691 UserDerefObjectCo(Window
);
2696 TRACE("Leave NtUserSetWindowPos, ret=%i\n",_ret_
);
2712 INT flags
= (SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
|SWP_NOACTIVATE
|SWP_FRAMECHANGED
|SWP_NOSIZE
|SWP_NOMOVE
);
2713 BOOLEAN Ret
= FALSE
;
2714 DECLARE_RETURN(INT
);
2716 TRACE("Enter NtUserSetWindowRgn\n");
2717 UserEnterExclusive();
2719 if (!(Window
= UserGetWindowObject(hWnd
)) || // FIXME:
2720 Window
== UserGetDesktopWindow() || // pWnd->fnid == FNID_DESKTOP
2721 Window
== UserGetMessageWindow() ) // pWnd->fnid == FNID_MESSAGEWND
2726 if (hRgn
) // The region will be deleted in user32.
2728 if (GreIsHandleValid(hRgn
))
2730 hrgnCopy
= IntSysCreateRectRgn(0, 0, 0, 0);
2731 /* The coordinates of a window's window region are relative to the
2732 upper-left corner of the window, not the client area of the window. */
2733 NtGdiCombineRgn( hrgnCopy
, hRgn
, 0, RGN_COPY
);
2743 if (Window
->hrgnClip
)
2745 /* Delete no longer needed region handle */
2746 IntGdiSetRegionOwner(Window
->hrgnClip
, GDI_OBJ_HMGR_POWNED
);
2747 GreDeleteObject(Window
->hrgnClip
);
2752 /* Set public ownership */
2753 IntGdiSetRegionOwner(hrgnCopy
, GDI_OBJ_HMGR_PUBLIC
);
2755 Window
->hrgnClip
= hrgnCopy
;
2757 Ret
= co_WinPosSetWindowPos(Window
, HWND_TOP
, 0, 0, 0, 0, bRedraw
? flags
: (flags
|SWP_NOREDRAW
) );
2762 TRACE("Leave NtUserSetWindowRgn, ret=%i\n",_ret_
);
2771 NtUserSetInternalWindowPos(
2777 WINDOWPLACEMENT wndpl
;
2782 DECLARE_RETURN(BOOL
);
2783 USER_REFERENCE_ENTRY Ref
;
2785 TRACE("Enter NtUserSetWindowPlacement\n");
2786 UserEnterExclusive();
2788 if (!(Wnd
= UserGetWindowObject(hwnd
)) || // FIXME:
2789 Wnd
== UserGetDesktopWindow() || // pWnd->fnid == FNID_DESKTOP
2790 Wnd
== UserGetMessageWindow() ) // pWnd->fnid == FNID_MESSAGEWND
2799 ProbeForRead(lppt
, sizeof(POINT
), 1);
2800 RtlCopyMemory(&pt
, lppt
, sizeof(POINT
));
2804 ProbeForRead(lprect
, sizeof(RECT
), 1);
2805 RtlCopyMemory(&rect
, lprect
, sizeof(RECT
));
2808 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
2810 SetLastNtError(_SEH2_GetExceptionCode());
2811 _SEH2_YIELD(RETURN( FALSE
));
2815 wndpl
.length
= sizeof(wndpl
);
2816 wndpl
.showCmd
= showCmd
;
2817 wndpl
.flags
= flags
= 0;
2822 wndpl
.flags
|= WPF_SETMINPOSITION
;
2823 wndpl
.ptMinPosition
= pt
;
2827 flags
|= PLACE_RECT
;
2828 wndpl
.rcNormalPosition
= rect
;
2831 UserRefObjectCo(Wnd
, &Ref
);
2832 IntSetWindowPlacement(Wnd
, &wndpl
, flags
);
2833 UserDerefObjectCo(Wnd
);
2837 TRACE("Leave NtUserSetWindowPlacement, ret=%i\n",_ret_
);
2846 NtUserSetWindowPlacement(HWND hWnd
,
2847 WINDOWPLACEMENT
*lpwndpl
)
2850 WINDOWPLACEMENT Safepl
;
2852 DECLARE_RETURN(BOOL
);
2853 USER_REFERENCE_ENTRY Ref
;
2855 TRACE("Enter NtUserSetWindowPlacement\n");
2856 UserEnterExclusive();
2858 if (!(Wnd
= UserGetWindowObject(hWnd
)) || // FIXME:
2859 Wnd
== UserGetDesktopWindow() || // pWnd->fnid == FNID_DESKTOP
2860 Wnd
== UserGetMessageWindow() ) // pWnd->fnid == FNID_MESSAGEWND
2867 ProbeForRead(lpwndpl
, sizeof(WINDOWPLACEMENT
), 1);
2868 RtlCopyMemory(&Safepl
, lpwndpl
, sizeof(WINDOWPLACEMENT
));
2870 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
2872 SetLastNtError(_SEH2_GetExceptionCode());
2873 _SEH2_YIELD(RETURN( FALSE
));
2877 if(Safepl
.length
!= sizeof(WINDOWPLACEMENT
))
2882 Flags
= PLACE_MAX
| PLACE_RECT
;
2883 if (Safepl
.flags
& WPF_SETMINPOSITION
) Flags
|= PLACE_MIN
;
2884 UserRefObjectCo(Wnd
, &Ref
);
2885 IntSetWindowPlacement(Wnd
, &Safepl
, Flags
);
2886 UserDerefObjectCo(Wnd
);
2890 TRACE("Leave NtUserSetWindowPlacement, ret=%i\n",_ret_
);
2899 NtUserShowWindowAsync(HWND hWnd
, LONG nCmdShow
)
2903 DECLARE_RETURN(BOOL
);
2904 USER_REFERENCE_ENTRY Ref
;
2906 TRACE("Enter NtUserShowWindowAsync\n");
2907 UserEnterExclusive();
2909 if (!(Window
= UserGetWindowObject(hWnd
)) || // FIXME:
2910 Window
== UserGetDesktopWindow() || // pWnd->fnid == FNID_DESKTOP
2911 Window
== UserGetMessageWindow() ) // pWnd->fnid == FNID_MESSAGEWND
2916 if ( nCmdShow
> SW_MAX
)
2918 EngSetLastError(ERROR_INVALID_PARAMETER
);
2922 UserRefObjectCo(Window
, &Ref
);
2923 ret
= co_IntSendMessageNoWait( hWnd
, WM_ASYNC_SHOWWINDOW
, nCmdShow
, 0 );
2924 UserDerefObjectCo(Window
);
2925 if (-1 == (int) ret
|| !ret
) ret
= FALSE
;
2930 TRACE("Leave NtUserShowWindowAsync, ret=%i\n",_ret_
);
2939 NtUserShowWindow(HWND hWnd
, LONG nCmdShow
)
2943 DECLARE_RETURN(BOOL
);
2944 USER_REFERENCE_ENTRY Ref
;
2946 TRACE("Enter NtUserShowWindow\n");
2947 UserEnterExclusive();
2949 if (!(Window
= UserGetWindowObject(hWnd
)) || // FIXME:
2950 Window
== UserGetDesktopWindow() || // pWnd->fnid == FNID_DESKTOP
2951 Window
== UserGetMessageWindow() ) // pWnd->fnid == FNID_MESSAGEWND
2956 if ( nCmdShow
> SW_MAX
|| Window
->state2
& WNDS2_INDESTROY
)
2958 EngSetLastError(ERROR_INVALID_PARAMETER
);
2962 UserRefObjectCo(Window
, &Ref
);
2963 ret
= co_WinPosShowWindow(Window
, nCmdShow
);
2964 UserDerefObjectCo(Window
);
2969 TRACE("Leave NtUserShowWindow, ret=%i\n",_ret_
);
2979 NtUserWindowFromPoint(LONG X
, LONG Y
)
2983 PWND DesktopWindow
= NULL
, Window
= NULL
;
2985 DECLARE_RETURN(HWND
);
2986 USER_REFERENCE_ENTRY Ref
;
2988 TRACE("Enter NtUserWindowFromPoint\n");
2989 UserEnterExclusive();
2991 if ((DesktopWindow
= UserGetWindowObject(IntGetDesktopWindow())))
2998 // Hmm... Threads live on desktops thus we have a reference on the desktop and indirectly the desktop window.
2999 // It is possible this referencing is useless, though it should not hurt...
3000 UserRefObjectCo(DesktopWindow
, &Ref
);
3002 //pti = PsGetCurrentThreadWin32Thread();
3003 Window
= co_WinPosWindowFromPoint(DesktopWindow
, &pt
, &hittest
);
3007 Ret
= Window
->head
.h
;
3016 if (Window
) UserDereferenceObject(Window
);
3017 if (DesktopWindow
) UserDerefObjectCo(DesktopWindow
);
3019 TRACE("Leave NtUserWindowFromPoint, ret=%i\n",_ret_
);