2 * Window position related functions.
4 * Copyright 1993, 1994, 1995 Alexandre Julliard
5 * 1995, 1996 Alex Korobka
11 #include <X11/Xatom.h>
12 #include "sysmetrics.h"
23 #include "nonclient.h"
26 #define HAS_DLGFRAME(style,exStyle) \
27 (((exStyle) & WS_EX_DLGMODALFRAME) || \
28 (((style) & WS_DLGFRAME) && !((style) & WS_BORDER)))
30 #define HAS_THICKFRAME(style) \
31 (((style) & WS_THICKFRAME) && \
32 !(((style) & (WS_DLGFRAME|WS_BORDER)) == WS_DLGFRAME))
34 #define SWP_AGG_NOGEOMETRYCHANGE \
35 (SWP_NOSIZE | SWP_NOMOVE | SWP_NOCLIENTSIZE | SWP_NOCLIENTMOVE)
36 #define SWP_AGG_NOPOSCHANGE \
37 (SWP_AGG_NOGEOMETRYCHANGE | SWP_NOZORDER)
38 #define SWP_AGG_STATUSFLAGS \
39 (SWP_AGG_NOPOSCHANGE | SWP_FRAMECHANGED | SWP_HIDEWINDOW | SWP_SHOWWINDOW)
41 #define EMPTYPOINT(pt) ((*(LONG*)&(pt)) == -1)
43 #define PLACE_MIN 0x0001
44 #define PLACE_MAX 0x0002
45 #define PLACE_RECT 0x0004
47 #define SMC_NOCOPY 0x0001
48 #define SMC_NOPARENTERASE 0x0002
49 #define SMC_DRAWFRAME 0x0004
50 #define SMC_SETXPOS 0x0008
52 /* ----- external functions ----- */
54 extern void FOCUS_SwitchFocus( HWND32
, HWND32
);
55 extern HWND32
CARET_GetHwnd();
57 /* ----- internal variables ----- */
59 static HWND32 hwndActive
= 0; /* Currently active window */
60 static HWND32 hwndPrevActive
= 0; /* Previously active window */
62 static LPCSTR atomInternalPos
;
64 extern MESSAGEQUEUE
* pActiveQueue
;
66 /***********************************************************************
67 * WINPOS_CreateInternalPosAtom
69 BOOL32
WINPOS_CreateInternalPosAtom()
72 atomInternalPos
= (LPCSTR
)(DWORD
)GlobalAddAtom32A(str
);
73 return (atomInternalPos
) ? TRUE
: FALSE
;
76 /***********************************************************************
77 * WINPOS_CheckInternalPos
79 * Called when a window is destroyed.
81 void WINPOS_CheckInternalPos( HWND32 hwnd
)
83 LPINTERNALPOS lpPos
= (LPINTERNALPOS
) GetProp32A( hwnd
, atomInternalPos
);
85 if( hwnd
== hwndPrevActive
) hwndPrevActive
= 0;
86 if( hwnd
== hwndActive
)
89 WARN(win
, "\tattempt to activate destroyed window!\n");
94 if( IsWindow32(lpPos
->hwndIconTitle
) )
95 DestroyWindow32( lpPos
->hwndIconTitle
);
96 HeapFree( SystemHeap
, 0, lpPos
);
100 /***********************************************************************
103 * Find a suitable place for an iconic window.
105 static POINT16
WINPOS_FindIconPos( WND
* wndPtr
, POINT16 pt
)
108 short x
, y
, xspacing
, yspacing
;
110 GetClientRect16( wndPtr
->parent
->hwndSelf
, &rectParent
);
111 if ((pt
.x
>= rectParent
.left
) && (pt
.x
+ SYSMETRICS_CXICON
< rectParent
.right
) &&
112 (pt
.y
>= rectParent
.top
) && (pt
.y
+ SYSMETRICS_CYICON
< rectParent
.bottom
))
113 return pt
; /* The icon already has a suitable position */
115 xspacing
= SYSMETRICS_CXICONSPACING
;
116 yspacing
= SYSMETRICS_CYICONSPACING
;
118 y
= rectParent
.bottom
;
121 for (x
= rectParent
.left
; x
<= rectParent
.right
-xspacing
; x
+= xspacing
)
123 /* Check if another icon already occupies this spot */
124 WND
*childPtr
= wndPtr
->parent
->child
;
127 if ((childPtr
->dwStyle
& WS_MINIMIZE
) && (childPtr
!= wndPtr
))
129 if ((childPtr
->rectWindow
.left
< x
+ xspacing
) &&
130 (childPtr
->rectWindow
.right
>= x
) &&
131 (childPtr
->rectWindow
.top
<= y
) &&
132 (childPtr
->rectWindow
.bottom
> y
- yspacing
))
133 break; /* There's a window in there */
135 childPtr
= childPtr
->next
;
137 if (!childPtr
) /* No window was found, so it's OK for us */
139 pt
.x
= x
+ (xspacing
- SYSMETRICS_CXICON
) / 2;
140 pt
.y
= y
- (yspacing
+ SYSMETRICS_CYICON
) / 2;
149 /***********************************************************************
150 * ArrangeIconicWindows16 (USER.170)
152 UINT16 WINAPI
ArrangeIconicWindows16( HWND16 parent
)
154 return ArrangeIconicWindows32(parent
);
156 /***********************************************************************
157 * ArrangeIconicWindows32 (USER32.7)
159 UINT32 WINAPI
ArrangeIconicWindows32( HWND32 parent
)
163 INT32 x
, y
, xspacing
, yspacing
;
165 GetClientRect32( parent
, &rectParent
);
167 y
= rectParent
.bottom
;
168 xspacing
= SYSMETRICS_CXICONSPACING
;
169 yspacing
= SYSMETRICS_CYICONSPACING
;
171 hwndChild
= GetWindow32( parent
, GW_CHILD
);
174 if( IsIconic32( hwndChild
) )
176 WINPOS_ShowIconTitle( WIN_FindWndPtr(hwndChild
), FALSE
);
177 SetWindowPos32( hwndChild
, 0, x
+ (xspacing
- SYSMETRICS_CXICON
) / 2,
178 y
- yspacing
- SYSMETRICS_CYICON
/2, 0, 0,
179 SWP_NOSIZE
| SWP_NOZORDER
| SWP_NOACTIVATE
);
180 if( IsWindow32(hwndChild
) )
181 WINPOS_ShowIconTitle( WIN_FindWndPtr(hwndChild
), TRUE
);
182 if (x
<= rectParent
.right
- xspacing
) x
+= xspacing
;
189 hwndChild
= GetWindow32( hwndChild
, GW_HWNDNEXT
);
195 /***********************************************************************
196 * SwitchToThisWindow16 (USER.172)
198 void WINAPI
SwitchToThisWindow16( HWND16 hwnd
, BOOL16 restore
)
200 SwitchToThisWindow32( hwnd
, restore
);
204 /***********************************************************************
205 * SwitchToThisWindow32 (USER32.539)
207 void WINAPI
SwitchToThisWindow32( HWND32 hwnd
, BOOL32 restore
)
209 ShowWindow32( hwnd
, restore
? SW_RESTORE
: SW_SHOWMINIMIZED
);
213 /***********************************************************************
214 * GetWindowRect16 (USER.32)
216 void WINAPI
GetWindowRect16( HWND16 hwnd
, LPRECT16 rect
)
218 WND
* wndPtr
= WIN_FindWndPtr( hwnd
);
221 CONV_RECT32TO16( &wndPtr
->rectWindow
, rect
);
222 if (wndPtr
->dwStyle
& WS_CHILD
)
223 MapWindowPoints16( wndPtr
->parent
->hwndSelf
, 0, (POINT16
*)rect
, 2 );
227 /***********************************************************************
228 * GetWindowRect32 (USER32.308)
230 void WINAPI
GetWindowRect32( HWND32 hwnd
, LPRECT32 rect
)
232 WND
* wndPtr
= WIN_FindWndPtr( hwnd
);
235 *rect
= wndPtr
->rectWindow
;
236 if (wndPtr
->dwStyle
& WS_CHILD
)
237 MapWindowPoints32( wndPtr
->parent
->hwndSelf
, 0, (POINT32
*)rect
, 2 );
241 /***********************************************************************
244 BOOL32 WINAPI
GetWindowRgn32 ( HWND32 hwnd
, HRGN32 hrgn
)
248 WND
* wndPtr
= WIN_FindWndPtr( hwnd
);
249 if (!wndPtr
) return (ERROR
);
251 FIXME (win
, "GetWindowRgn32: doesn't really do regions\n");
253 memset (&rect
, 0, sizeof(rect
));
255 GetWindowRect32 ( hwnd
, &rect
);
257 FIXME (win
, "Check whether a valid region here\n");
259 SetRectRgn32 ( hrgn
, rect
.left
, rect
.top
, rect
.right
, rect
.bottom
);
261 return (SIMPLEREGION
);
264 /***********************************************************************
267 BOOL32 WINAPI
SetWindowRgn32 ( HWND32 hwnd
, HRGN32 hrgn
,BOOL32 bRedraw
)
271 FIXME (win
, "SetWindowRgn32: stub\n");
276 /***********************************************************************
277 * GetClientRect16 (USER.33)
279 void WINAPI
GetClientRect16( HWND16 hwnd
, LPRECT16 rect
)
281 WND
* wndPtr
= WIN_FindWndPtr( hwnd
);
283 rect
->left
= rect
->top
= rect
->right
= rect
->bottom
= 0;
286 rect
->right
= wndPtr
->rectClient
.right
- wndPtr
->rectClient
.left
;
287 rect
->bottom
= wndPtr
->rectClient
.bottom
- wndPtr
->rectClient
.top
;
292 /***********************************************************************
293 * GetClientRect32 (USER32.220)
295 void WINAPI
GetClientRect32( HWND32 hwnd
, LPRECT32 rect
)
297 WND
* wndPtr
= WIN_FindWndPtr( hwnd
);
299 rect
->left
= rect
->top
= rect
->right
= rect
->bottom
= 0;
302 rect
->right
= wndPtr
->rectClient
.right
- wndPtr
->rectClient
.left
;
303 rect
->bottom
= wndPtr
->rectClient
.bottom
- wndPtr
->rectClient
.top
;
308 /*******************************************************************
309 * ClientToScreen16 (USER.28)
311 void WINAPI
ClientToScreen16( HWND16 hwnd
, LPPOINT16 lppnt
)
313 MapWindowPoints16( hwnd
, 0, lppnt
, 1 );
317 /*******************************************************************
318 * ClientToScreen32 (USER32.52)
320 BOOL32 WINAPI
ClientToScreen32( HWND32 hwnd
, LPPOINT32 lppnt
)
322 MapWindowPoints32( hwnd
, 0, lppnt
, 1 );
327 /*******************************************************************
328 * ScreenToClient16 (USER.29)
330 void WINAPI
ScreenToClient16( HWND16 hwnd
, LPPOINT16 lppnt
)
332 MapWindowPoints16( 0, hwnd
, lppnt
, 1 );
336 /*******************************************************************
337 * ScreenToClient32 (USER32.447)
339 void WINAPI
ScreenToClient32( HWND32 hwnd
, LPPOINT32 lppnt
)
341 MapWindowPoints32( 0, hwnd
, lppnt
, 1 );
345 /***********************************************************************
346 * WINPOS_WindowFromPoint
348 * Find the window and hittest for a given point.
350 INT16
WINPOS_WindowFromPoint( WND
* wndScope
, POINT16 pt
, WND
**ppWnd
)
353 INT16 hittest
= HTERROR
;
357 wndPtr
= wndScope
->child
;
358 MapWindowPoints16( GetDesktopWindow16(), wndScope
->hwndSelf
, &xy
, 1 );
364 /* If point is in window, and window is visible, and it */
365 /* is enabled (or it's a top-level window), then explore */
366 /* its children. Otherwise, go to the next window. */
368 if ((wndPtr
->dwStyle
& WS_VISIBLE
) &&
369 (!(wndPtr
->dwStyle
& WS_DISABLED
) ||
370 ((wndPtr
->dwStyle
& (WS_POPUP
| WS_CHILD
)) != WS_CHILD
)) &&
371 (xy
.x
>= wndPtr
->rectWindow
.left
) &&
372 (xy
.x
< wndPtr
->rectWindow
.right
) &&
373 (xy
.y
>= wndPtr
->rectWindow
.top
) &&
374 (xy
.y
< wndPtr
->rectWindow
.bottom
))
376 *ppWnd
= wndPtr
; /* Got a suitable window */
378 /* If window is minimized or disabled, return at once */
379 if (wndPtr
->dwStyle
& WS_MINIMIZE
) return HTCAPTION
;
380 if (wndPtr
->dwStyle
& WS_DISABLED
) return HTERROR
;
382 /* If point is not in client area, ignore the children */
383 if ((xy
.x
< wndPtr
->rectClient
.left
) ||
384 (xy
.x
>= wndPtr
->rectClient
.right
) ||
385 (xy
.y
< wndPtr
->rectClient
.top
) ||
386 (xy
.y
>= wndPtr
->rectClient
.bottom
)) break;
388 xy
.x
-= wndPtr
->rectClient
.left
;
389 xy
.y
-= wndPtr
->rectClient
.top
;
390 wndPtr
= wndPtr
->child
;
392 else wndPtr
= wndPtr
->next
;
395 /* If nothing found, try the scope window */
396 if (!*ppWnd
) *ppWnd
= wndScope
;
398 /* Send the WM_NCHITTEST message (only if to the same task) */
399 if ((*ppWnd
)->hmemTaskQ
== GetTaskQueue(0))
401 hittest
= (INT16
)SendMessage16( (*ppWnd
)->hwndSelf
, WM_NCHITTEST
,
402 0, MAKELONG( pt
.x
, pt
.y
) );
403 if (hittest
!= HTTRANSPARENT
) return hittest
; /* Found the window */
405 else return HTCLIENT
;
407 /* If no children found in last search, make point relative to parent */
410 xy
.x
+= (*ppWnd
)->rectClient
.left
;
411 xy
.y
+= (*ppWnd
)->rectClient
.top
;
414 /* Restart the search from the next sibling */
415 wndPtr
= (*ppWnd
)->next
;
416 *ppWnd
= (*ppWnd
)->parent
;
421 /*******************************************************************
422 * WindowFromPoint16 (USER.30)
424 HWND16 WINAPI
WindowFromPoint16( POINT16 pt
)
427 WINPOS_WindowFromPoint( WIN_GetDesktop(), pt
, &pWnd
);
428 return pWnd
->hwndSelf
;
432 /*******************************************************************
433 * WindowFromPoint32 (USER32.582)
435 HWND32 WINAPI
WindowFromPoint32( POINT32 pt
)
439 CONV_POINT32TO16( &pt
, &pt16
);
440 WINPOS_WindowFromPoint( WIN_GetDesktop(), pt16
, &pWnd
);
441 return (HWND32
)pWnd
->hwndSelf
;
445 /*******************************************************************
446 * ChildWindowFromPoint16 (USER.191)
448 HWND16 WINAPI
ChildWindowFromPoint16( HWND16 hwndParent
, POINT16 pt
)
451 CONV_POINT16TO32( &pt
, &pt32
);
452 return (HWND16
)ChildWindowFromPoint32( hwndParent
, pt32
);
456 /*******************************************************************
457 * ChildWindowFromPoint32 (USER32.49)
459 HWND32 WINAPI
ChildWindowFromPoint32( HWND32 hwndParent
, POINT32 pt
)
461 /* pt is in the client coordinates */
463 WND
* wnd
= WIN_FindWndPtr(hwndParent
);
468 /* get client rect fast */
469 rect
.top
= rect
.left
= 0;
470 rect
.right
= wnd
->rectClient
.right
- wnd
->rectClient
.left
;
471 rect
.bottom
= wnd
->rectClient
.bottom
- wnd
->rectClient
.top
;
473 if (!PtInRect32( &rect
, pt
)) return 0;
478 if (PtInRect32( &wnd
->rectWindow
, pt
)) return wnd
->hwndSelf
;
485 /*******************************************************************
486 * WINPOS_GetWinOffset
488 * Calculate the offset between the origin of the two windows. Used
489 * to implement MapWindowPoints.
491 static void WINPOS_GetWinOffset( HWND32 hwndFrom
, HWND32 hwndTo
,
496 offset
->x
= offset
->y
= 0;
497 if (hwndFrom
== hwndTo
) return;
499 /* Translate source window origin to screen coords */
502 if (!(wndPtr
= WIN_FindWndPtr( hwndFrom
)))
504 ERR(win
,"bad hwndFrom = %04x\n",hwndFrom
);
507 while (wndPtr
->parent
)
509 offset
->x
+= wndPtr
->rectClient
.left
;
510 offset
->y
+= wndPtr
->rectClient
.top
;
511 wndPtr
= wndPtr
->parent
;
515 /* Translate origin to destination window coords */
518 if (!(wndPtr
= WIN_FindWndPtr( hwndTo
)))
520 ERR(win
,"bad hwndTo = %04x\n", hwndTo
);
523 while (wndPtr
->parent
)
525 offset
->x
-= wndPtr
->rectClient
.left
;
526 offset
->y
-= wndPtr
->rectClient
.top
;
527 wndPtr
= wndPtr
->parent
;
533 /*******************************************************************
534 * MapWindowPoints16 (USER.258)
536 void WINAPI
MapWindowPoints16( HWND16 hwndFrom
, HWND16 hwndTo
,
537 LPPOINT16 lppt
, UINT16 count
)
541 WINPOS_GetWinOffset( hwndFrom
, hwndTo
, &offset
);
551 /*******************************************************************
552 * MapWindowPoints32 (USER32.386)
554 void WINAPI
MapWindowPoints32( HWND32 hwndFrom
, HWND32 hwndTo
,
555 LPPOINT32 lppt
, UINT32 count
)
559 WINPOS_GetWinOffset( hwndFrom
, hwndTo
, &offset
);
569 /***********************************************************************
570 * IsIconic16 (USER.31)
572 BOOL16 WINAPI
IsIconic16(HWND16 hWnd
)
574 return IsIconic32(hWnd
);
578 /***********************************************************************
579 * IsIconic32 (USER32.345)
581 BOOL32 WINAPI
IsIconic32(HWND32 hWnd
)
583 WND
* wndPtr
= WIN_FindWndPtr(hWnd
);
584 if (wndPtr
== NULL
) return FALSE
;
585 return (wndPtr
->dwStyle
& WS_MINIMIZE
) != 0;
589 /***********************************************************************
590 * IsZoomed (USER.272)
592 BOOL16 WINAPI
IsZoomed16(HWND16 hWnd
)
594 return IsZoomed32(hWnd
);
598 /***********************************************************************
599 * IsZoomed (USER32.352)
601 BOOL32 WINAPI
IsZoomed32(HWND32 hWnd
)
603 WND
* wndPtr
= WIN_FindWndPtr(hWnd
);
604 if (wndPtr
== NULL
) return FALSE
;
605 return (wndPtr
->dwStyle
& WS_MAXIMIZE
) != 0;
609 /*******************************************************************
610 * GetActiveWindow (USER.60)
612 HWND16 WINAPI
GetActiveWindow16(void)
614 return (HWND16
)hwndActive
;
617 /*******************************************************************
618 * GetActiveWindow (USER32.205)
620 HWND32 WINAPI
GetActiveWindow32(void)
622 return (HWND32
)hwndActive
;
626 /*******************************************************************
629 static BOOL32
WINPOS_CanActivate(WND
* pWnd
)
631 if( pWnd
&& ((pWnd
->dwStyle
& (WS_DISABLED
| WS_VISIBLE
| WS_CHILD
))
632 == WS_VISIBLE
) ) return TRUE
;
637 /*******************************************************************
638 * SetActiveWindow16 (USER.59)
640 HWND16 WINAPI
SetActiveWindow16( HWND16 hwnd
)
642 return SetActiveWindow32(hwnd
);
646 /*******************************************************************
647 * SetActiveWindow32 (USER32.463)
649 HWND32 WINAPI
SetActiveWindow32( HWND32 hwnd
)
651 HWND32 prev
= hwndActive
;
652 WND
*wndPtr
= WIN_FindWndPtr( hwnd
);
654 if ( !WINPOS_CanActivate(wndPtr
) ) return 0;
656 WINPOS_SetActiveWindow( hwnd
, 0, 0 );
661 /*******************************************************************
662 * GetForegroundWindow16 (USER.608)
664 HWND16 WINAPI
GetForegroundWindow16(void)
666 return (HWND16
)GetForegroundWindow32();
670 /*******************************************************************
671 * SetForegroundWindow16 (USER.609)
673 BOOL16 WINAPI
SetForegroundWindow16( HWND16 hwnd
)
675 return SetForegroundWindow32( hwnd
);
679 /*******************************************************************
680 * GetForegroundWindow32 (USER32.241)
682 HWND32 WINAPI
GetForegroundWindow32(void)
684 return GetActiveWindow32();
688 /*******************************************************************
689 * SetForegroundWindow32 (USER32.482)
691 BOOL32 WINAPI
SetForegroundWindow32( HWND32 hwnd
)
693 SetActiveWindow32( hwnd
);
698 /*******************************************************************
699 * GetShellWindow16 (USER.600)
701 HWND16 WINAPI
GetShellWindow16(void)
703 return GetShellWindow32();
706 /*******************************************************************
707 * SetShellWindow32 (USER32.504)
709 HWND32 WINAPI
SetShellWindow32(HWND32 hwndshell
)
711 FIXME(win
, "(%08x): empty stub\n",hwndshell
);
716 /*******************************************************************
717 * GetShellWindow32 (USER32.287)
719 HWND32 WINAPI
GetShellWindow32(void)
721 FIXME(win
, "(void): empty stub\n" );
726 /***********************************************************************
727 * BringWindowToTop16 (USER.45)
729 BOOL16 WINAPI
BringWindowToTop16( HWND16 hwnd
)
731 return BringWindowToTop32(hwnd
);
735 /***********************************************************************
736 * BringWindowToTop32 (USER32.11)
738 BOOL32 WINAPI
BringWindowToTop32( HWND32 hwnd
)
740 return SetWindowPos32( hwnd
, HWND_TOP
, 0, 0, 0, 0, SWP_NOMOVE
|SWP_NOSIZE
);
744 /***********************************************************************
745 * MoveWindow16 (USER.56)
747 BOOL16 WINAPI
MoveWindow16( HWND16 hwnd
, INT16 x
, INT16 y
, INT16 cx
, INT16 cy
,
750 return MoveWindow32(hwnd
,x
,y
,cx
,cy
,repaint
);
754 /***********************************************************************
755 * MoveWindow32 (USER32.399)
757 BOOL32 WINAPI
MoveWindow32( HWND32 hwnd
, INT32 x
, INT32 y
, INT32 cx
, INT32 cy
,
760 int flags
= SWP_NOZORDER
| SWP_NOACTIVATE
;
761 if (!repaint
) flags
|= SWP_NOREDRAW
;
762 TRACE(win
, "%04x %d,%d %dx%d %d\n",
763 hwnd
, x
, y
, cx
, cy
, repaint
);
764 return SetWindowPos32( hwnd
, 0, x
, y
, cx
, cy
, flags
);
767 /***********************************************************************
768 * WINPOS_InitInternalPos
770 static LPINTERNALPOS
WINPOS_InitInternalPos( WND
* wnd
, POINT32 pt
,
771 LPRECT32 restoreRect
)
773 LPINTERNALPOS lpPos
= (LPINTERNALPOS
) GetProp32A( wnd
->hwndSelf
,
777 /* this happens when the window is minimized/maximized
778 * for the first time (rectWindow is not adjusted yet) */
780 lpPos
= HeapAlloc( SystemHeap
, 0, sizeof(INTERNALPOS
) );
781 if( !lpPos
) return NULL
;
783 SetProp32A( wnd
->hwndSelf
, atomInternalPos
, (HANDLE32
)lpPos
);
784 lpPos
->hwndIconTitle
= 0; /* defer until needs to be shown */
785 CONV_RECT32TO16( &wnd
->rectWindow
, &lpPos
->rectNormal
);
786 *(UINT32
*)&lpPos
->ptIconPos
= *(UINT32
*)&lpPos
->ptMaxPos
= 0xFFFFFFFF;
789 if( wnd
->dwStyle
& WS_MINIMIZE
)
790 CONV_POINT32TO16( &pt
, &lpPos
->ptIconPos
);
791 else if( wnd
->dwStyle
& WS_MAXIMIZE
)
792 CONV_POINT32TO16( &pt
, &lpPos
->ptMaxPos
);
793 else if( restoreRect
)
794 CONV_RECT32TO16( restoreRect
, &lpPos
->rectNormal
);
799 /***********************************************************************
800 * WINPOS_RedrawIconTitle
802 BOOL32
WINPOS_RedrawIconTitle( HWND32 hWnd
)
804 LPINTERNALPOS lpPos
= (LPINTERNALPOS
)GetProp32A( hWnd
, atomInternalPos
);
807 if( lpPos
->hwndIconTitle
)
809 SendMessage32A( lpPos
->hwndIconTitle
, WM_SHOWWINDOW
, TRUE
, 0);
810 InvalidateRect32( lpPos
->hwndIconTitle
, NULL
, TRUE
);
817 /***********************************************************************
818 * WINPOS_ShowIconTitle
820 BOOL32
WINPOS_ShowIconTitle( WND
* pWnd
, BOOL32 bShow
)
822 LPINTERNALPOS lpPos
= (LPINTERNALPOS
)GetProp32A( pWnd
->hwndSelf
, atomInternalPos
);
824 if( lpPos
&& !(pWnd
->flags
& WIN_MANAGED
))
826 HWND16 hWnd
= lpPos
->hwndIconTitle
;
828 TRACE(win
,"0x%04x %i\n", pWnd
->hwndSelf
, (bShow
!= 0) );
831 lpPos
->hwndIconTitle
= hWnd
= ICONTITLE_Create( pWnd
);
834 pWnd
= WIN_FindWndPtr(hWnd
);
836 if( !(pWnd
->dwStyle
& WS_VISIBLE
) )
838 SendMessage32A( hWnd
, WM_SHOWWINDOW
, TRUE
, 0 );
839 SetWindowPos32( hWnd
, 0, 0, 0, 0, 0, SWP_NOSIZE
| SWP_NOMOVE
|
840 SWP_NOACTIVATE
| SWP_NOZORDER
| SWP_SHOWWINDOW
);
843 else ShowWindow32( hWnd
, SW_HIDE
);
848 /*******************************************************************
849 * WINPOS_GetMinMaxInfo
851 * Get the minimized and maximized information for a window.
853 void WINPOS_GetMinMaxInfo( WND
*wndPtr
, POINT32
*maxSize
, POINT32
*maxPos
,
854 POINT32
*minTrack
, POINT32
*maxTrack
)
860 /* Compute default values */
862 MinMax
.ptMaxSize
.x
= SYSMETRICS_CXSCREEN
;
863 MinMax
.ptMaxSize
.y
= SYSMETRICS_CYSCREEN
;
864 MinMax
.ptMinTrackSize
.x
= SYSMETRICS_CXMINTRACK
;
865 MinMax
.ptMinTrackSize
.y
= SYSMETRICS_CYMINTRACK
;
866 MinMax
.ptMaxTrackSize
.x
= SYSMETRICS_CXSCREEN
;
867 MinMax
.ptMaxTrackSize
.y
= SYSMETRICS_CYSCREEN
;
869 if (wndPtr
->flags
& WIN_MANAGED
) xinc
= yinc
= 0;
870 else if (HAS_DLGFRAME( wndPtr
->dwStyle
, wndPtr
->dwExStyle
))
872 xinc
= SYSMETRICS_CXDLGFRAME
;
873 yinc
= SYSMETRICS_CYDLGFRAME
;
878 if (HAS_THICKFRAME(wndPtr
->dwStyle
))
880 xinc
+= SYSMETRICS_CXFRAME
;
881 yinc
+= SYSMETRICS_CYFRAME
;
883 if (wndPtr
->dwStyle
& WS_BORDER
)
885 xinc
+= SYSMETRICS_CXBORDER
;
886 yinc
+= SYSMETRICS_CYBORDER
;
889 MinMax
.ptMaxSize
.x
+= 2 * xinc
;
890 MinMax
.ptMaxSize
.y
+= 2 * yinc
;
892 lpPos
= (LPINTERNALPOS
)GetProp32A( wndPtr
->hwndSelf
, atomInternalPos
);
893 if( lpPos
&& !EMPTYPOINT(lpPos
->ptMaxPos
) )
894 CONV_POINT16TO32( &lpPos
->ptMaxPos
, &MinMax
.ptMaxPosition
);
897 MinMax
.ptMaxPosition
.x
= -xinc
;
898 MinMax
.ptMaxPosition
.y
= -yinc
;
901 SendMessage32A( wndPtr
->hwndSelf
, WM_GETMINMAXINFO
, 0, (LPARAM
)&MinMax
);
903 /* Some sanity checks */
905 TRACE(win
,"%d %d / %d %d / %d %d / %d %d\n",
906 MinMax
.ptMaxSize
.x
, MinMax
.ptMaxSize
.y
,
907 MinMax
.ptMaxPosition
.x
, MinMax
.ptMaxPosition
.y
,
908 MinMax
.ptMaxTrackSize
.x
, MinMax
.ptMaxTrackSize
.y
,
909 MinMax
.ptMinTrackSize
.x
, MinMax
.ptMinTrackSize
.y
);
910 MinMax
.ptMaxTrackSize
.x
= MAX( MinMax
.ptMaxTrackSize
.x
,
911 MinMax
.ptMinTrackSize
.x
);
912 MinMax
.ptMaxTrackSize
.y
= MAX( MinMax
.ptMaxTrackSize
.y
,
913 MinMax
.ptMinTrackSize
.y
);
915 if (maxSize
) *maxSize
= MinMax
.ptMaxSize
;
916 if (maxPos
) *maxPos
= MinMax
.ptMaxPosition
;
917 if (minTrack
) *minTrack
= MinMax
.ptMinTrackSize
;
918 if (maxTrack
) *maxTrack
= MinMax
.ptMaxTrackSize
;
921 /***********************************************************************
924 * Fill in lpRect and return additional flags to be used with SetWindowPos().
925 * This function assumes that 'cmd' is different from the current window
928 UINT16
WINPOS_MinMaximize( WND
* wndPtr
, UINT16 cmd
, LPRECT16 lpRect
)
932 POINT32 size
= { wndPtr
->rectWindow
.left
, wndPtr
->rectWindow
.top
};
933 LPINTERNALPOS lpPos
= WINPOS_InitInternalPos( wndPtr
, size
,
934 &wndPtr
->rectWindow
);
936 TRACE(win
,"0x%04x %u\n", wndPtr
->hwndSelf
, cmd
);
938 if (lpPos
&& !HOOK_CallHooks16(WH_CBT
, HCBT_MINMAX
, wndPtr
->hwndSelf
, cmd
))
940 if( wndPtr
->dwStyle
& WS_MINIMIZE
)
942 if( !SendMessage32A( wndPtr
->hwndSelf
, WM_QUERYOPEN
, 0, 0L ) )
943 return (SWP_NOSIZE
| SWP_NOMOVE
);
944 swpFlags
|= SWP_NOCOPYBITS
;
949 if( wndPtr
->dwStyle
& WS_MAXIMIZE
)
951 wndPtr
->flags
|= WIN_RESTORE_MAX
;
952 wndPtr
->dwStyle
&= ~WS_MAXIMIZE
;
955 wndPtr
->flags
&= ~WIN_RESTORE_MAX
;
956 wndPtr
->dwStyle
|= WS_MINIMIZE
;
958 lpPos
->ptIconPos
= WINPOS_FindIconPos( wndPtr
, lpPos
->ptIconPos
);
960 SetRect16( lpRect
, lpPos
->ptIconPos
.x
, lpPos
->ptIconPos
.y
,
961 SYSMETRICS_CXICON
, SYSMETRICS_CYICON
);
962 swpFlags
|= SWP_NOCOPYBITS
;
966 CONV_POINT16TO32( &lpPos
->ptMaxPos
, &pt
);
967 WINPOS_GetMinMaxInfo( wndPtr
, &size
, &pt
, NULL
, NULL
);
968 CONV_POINT32TO16( &pt
, &lpPos
->ptMaxPos
);
970 if( wndPtr
->dwStyle
& WS_MINIMIZE
)
972 WINPOS_ShowIconTitle( wndPtr
, FALSE
);
973 wndPtr
->dwStyle
&= ~WS_MINIMIZE
;
975 wndPtr
->dwStyle
|= WS_MAXIMIZE
;
977 SetRect16( lpRect
, lpPos
->ptMaxPos
.x
, lpPos
->ptMaxPos
.y
,
982 if( wndPtr
->dwStyle
& WS_MINIMIZE
)
984 wndPtr
->dwStyle
&= ~WS_MINIMIZE
;
985 WINPOS_ShowIconTitle( wndPtr
, FALSE
);
986 if( wndPtr
->flags
& WIN_RESTORE_MAX
)
988 /* Restore to maximized position */
989 CONV_POINT16TO32( &lpPos
->ptMaxPos
, &pt
);
990 WINPOS_GetMinMaxInfo( wndPtr
, &size
, &pt
, NULL
, NULL
);
991 CONV_POINT32TO16( &pt
, &lpPos
->ptMaxPos
);
992 wndPtr
->dwStyle
|= WS_MAXIMIZE
;
993 SetRect16( lpRect
, lpPos
->ptMaxPos
.x
, lpPos
->ptMaxPos
.y
, size
.x
, size
.y
);
998 if( !(wndPtr
->dwStyle
& WS_MAXIMIZE
) ) return (UINT16
)(-1);
999 else wndPtr
->dwStyle
&= ~WS_MAXIMIZE
;
1001 /* Restore to normal position */
1003 *lpRect
= lpPos
->rectNormal
;
1004 lpRect
->right
-= lpRect
->left
;
1005 lpRect
->bottom
-= lpRect
->top
;
1009 } else swpFlags
|= SWP_NOSIZE
| SWP_NOMOVE
;
1013 /***********************************************************************
1014 * ShowWindowAsync32 (USER32.535)
1016 * doesn't wait; returns immediately.
1017 * used by threads to toggle windows in other (possibly hanging) threads
1019 BOOL32 WINAPI
ShowWindowAsync32( HWND32 hwnd
, INT32 cmd
)
1021 /* FIXME: does ShowWindow32() return immediately ? */
1022 return ShowWindow32(hwnd
, cmd
);
1026 /***********************************************************************
1027 * ShowWindow16 (USER.42)
1029 BOOL16 WINAPI
ShowWindow16( HWND16 hwnd
, INT16 cmd
)
1031 return ShowWindow32(hwnd
,cmd
);
1035 /***********************************************************************
1036 * ShowWindow32 (USER32.534)
1038 BOOL32 WINAPI
ShowWindow32( HWND32 hwnd
, INT32 cmd
)
1040 WND
* wndPtr
= WIN_FindWndPtr( hwnd
);
1041 BOOL32 wasVisible
, showFlag
;
1042 RECT16 newPos
= {0, 0, 0, 0};
1045 if (!wndPtr
) return FALSE
;
1047 TRACE(win
,"hwnd=%04x, cmd=%d\n", hwnd
, cmd
);
1049 wasVisible
= (wndPtr
->dwStyle
& WS_VISIBLE
) != 0;
1054 if (!wasVisible
) return FALSE
;
1055 swp
|= SWP_HIDEWINDOW
| SWP_NOSIZE
| SWP_NOMOVE
|
1056 SWP_NOACTIVATE
| SWP_NOZORDER
;
1059 case SW_SHOWMINNOACTIVE
:
1060 swp
|= SWP_NOACTIVATE
| SWP_NOZORDER
;
1062 case SW_SHOWMINIMIZED
:
1063 swp
|= SWP_SHOWWINDOW
;
1066 swp
|= SWP_FRAMECHANGED
;
1067 if( !(wndPtr
->dwStyle
& WS_MINIMIZE
) )
1068 swp
|= WINPOS_MinMaximize( wndPtr
, SW_MINIMIZE
, &newPos
);
1069 else swp
|= SWP_NOSIZE
| SWP_NOMOVE
;
1072 case SW_SHOWMAXIMIZED
: /* same as SW_MAXIMIZE */
1073 swp
|= SWP_SHOWWINDOW
| SWP_FRAMECHANGED
;
1074 if( !(wndPtr
->dwStyle
& WS_MAXIMIZE
) )
1075 swp
|= WINPOS_MinMaximize( wndPtr
, SW_MAXIMIZE
, &newPos
);
1076 else swp
|= SWP_NOSIZE
| SWP_NOMOVE
;
1080 swp
|= SWP_NOACTIVATE
| SWP_NOZORDER
;
1083 swp
|= SWP_SHOWWINDOW
| SWP_NOSIZE
| SWP_NOMOVE
;
1086 case SW_SHOWNOACTIVATE
:
1087 swp
|= SWP_NOZORDER
;
1088 if (GetActiveWindow32()) swp
|= SWP_NOACTIVATE
;
1090 case SW_SHOWNORMAL
: /* same as SW_NORMAL: */
1091 case SW_SHOWDEFAULT
: /* FIXME: should have its own handler */
1093 swp
|= SWP_SHOWWINDOW
| SWP_FRAMECHANGED
;
1095 if( wndPtr
->dwStyle
& (WS_MINIMIZE
| WS_MAXIMIZE
) )
1096 swp
|= WINPOS_MinMaximize( wndPtr
, SW_RESTORE
, &newPos
);
1097 else swp
|= SWP_NOSIZE
| SWP_NOMOVE
;
1101 showFlag
= (cmd
!= SW_HIDE
);
1102 if (showFlag
!= wasVisible
)
1104 SendMessage32A( hwnd
, WM_SHOWWINDOW
, showFlag
, 0 );
1105 if (!IsWindow32( hwnd
)) return wasVisible
;
1108 if ((wndPtr
->dwStyle
& WS_CHILD
) &&
1109 !IsWindowVisible32( wndPtr
->parent
->hwndSelf
) &&
1110 (swp
& (SWP_NOSIZE
| SWP_NOMOVE
)) == (SWP_NOSIZE
| SWP_NOMOVE
) )
1112 /* Don't call SetWindowPos32() on invisible child windows */
1113 if (cmd
== SW_HIDE
) wndPtr
->dwStyle
&= ~WS_VISIBLE
;
1114 else wndPtr
->dwStyle
|= WS_VISIBLE
;
1118 /* We can't activate a child window */
1119 if (wndPtr
->dwStyle
& WS_CHILD
) swp
|= SWP_NOACTIVATE
| SWP_NOZORDER
;
1120 SetWindowPos32( hwnd
, HWND_TOP
,
1121 newPos
.left
, newPos
.top
, newPos
.right
, newPos
.bottom
, swp
);
1122 if (!IsWindow32( hwnd
)) return wasVisible
;
1123 else if( wndPtr
->dwStyle
& WS_MINIMIZE
) WINPOS_ShowIconTitle( wndPtr
, TRUE
);
1126 if (wndPtr
->flags
& WIN_NEED_SIZE
)
1128 /* should happen only in CreateWindowEx() */
1129 int wParam
= SIZE_RESTORED
;
1131 wndPtr
->flags
&= ~WIN_NEED_SIZE
;
1132 if (wndPtr
->dwStyle
& WS_MAXIMIZE
) wParam
= SIZE_MAXIMIZED
;
1133 else if (wndPtr
->dwStyle
& WS_MINIMIZE
) wParam
= SIZE_MINIMIZED
;
1134 SendMessage32A( hwnd
, WM_SIZE
, wParam
,
1135 MAKELONG(wndPtr
->rectClient
.right
-wndPtr
->rectClient
.left
,
1136 wndPtr
->rectClient
.bottom
-wndPtr
->rectClient
.top
));
1137 SendMessage32A( hwnd
, WM_MOVE
, 0,
1138 MAKELONG(wndPtr
->rectClient
.left
, wndPtr
->rectClient
.top
) );
1145 /***********************************************************************
1146 * GetInternalWindowPos16 (USER.460)
1148 UINT16 WINAPI
GetInternalWindowPos16( HWND16 hwnd
, LPRECT16 rectWnd
,
1151 WINDOWPLACEMENT16 wndpl
;
1152 if (GetWindowPlacement16( hwnd
, &wndpl
))
1154 if (rectWnd
) *rectWnd
= wndpl
.rcNormalPosition
;
1155 if (ptIcon
) *ptIcon
= wndpl
.ptMinPosition
;
1156 return wndpl
.showCmd
;
1162 /***********************************************************************
1163 * GetInternalWindowPos32 (USER32.245)
1165 UINT32 WINAPI
GetInternalWindowPos32( HWND32 hwnd
, LPRECT32 rectWnd
,
1168 WINDOWPLACEMENT32 wndpl
;
1169 if (GetWindowPlacement32( hwnd
, &wndpl
))
1171 if (rectWnd
) *rectWnd
= wndpl
.rcNormalPosition
;
1172 if (ptIcon
) *ptIcon
= wndpl
.ptMinPosition
;
1173 return wndpl
.showCmd
;
1178 /***********************************************************************
1179 * GetWindowPlacement16 (USER.370)
1181 BOOL16 WINAPI
GetWindowPlacement16( HWND16 hwnd
, WINDOWPLACEMENT16
*wndpl
)
1183 WND
*pWnd
= WIN_FindWndPtr( hwnd
);
1186 LPINTERNALPOS lpPos
= (LPINTERNALPOS
)WINPOS_InitInternalPos( pWnd
,
1187 *(LPPOINT32
)&pWnd
->rectWindow
.left
, &pWnd
->rectWindow
);
1188 wndpl
->length
= sizeof(*wndpl
);
1189 if( pWnd
->dwStyle
& WS_MINIMIZE
)
1190 wndpl
->showCmd
= SW_SHOWMAXIMIZED
;
1192 wndpl
->showCmd
= ( pWnd
->dwStyle
& WS_MAXIMIZE
)
1193 ? SW_SHOWMINIMIZED
: SW_SHOWNORMAL
;
1194 if( pWnd
->flags
& WIN_RESTORE_MAX
)
1195 wndpl
->flags
= WPF_RESTORETOMAXIMIZED
;
1198 wndpl
->ptMinPosition
= lpPos
->ptIconPos
;
1199 wndpl
->ptMaxPosition
= lpPos
->ptMaxPos
;
1200 wndpl
->rcNormalPosition
= lpPos
->rectNormal
;
1207 /***********************************************************************
1208 * GetWindowPlacement32 (USER32.307)
1210 BOOL32 WINAPI
GetWindowPlacement32( HWND32 hwnd
, WINDOWPLACEMENT32
*pwpl32
)
1214 WINDOWPLACEMENT16 wpl
;
1215 wpl
.length
= sizeof(wpl
);
1216 if( GetWindowPlacement16( hwnd
, &wpl
) )
1218 pwpl32
->length
= sizeof(*pwpl32
);
1219 pwpl32
->flags
= wpl
.flags
;
1220 pwpl32
->showCmd
= wpl
.showCmd
;
1221 CONV_POINT16TO32( &wpl
.ptMinPosition
, &pwpl32
->ptMinPosition
);
1222 CONV_POINT16TO32( &wpl
.ptMaxPosition
, &pwpl32
->ptMaxPosition
);
1223 CONV_RECT16TO32( &wpl
.rcNormalPosition
, &pwpl32
->rcNormalPosition
);
1231 /***********************************************************************
1232 * WINPOS_SetPlacement
1234 static BOOL32
WINPOS_SetPlacement( HWND32 hwnd
, const WINDOWPLACEMENT16
*wndpl
,
1237 WND
*pWnd
= WIN_FindWndPtr( hwnd
);
1240 LPINTERNALPOS lpPos
= (LPINTERNALPOS
)WINPOS_InitInternalPos( pWnd
,
1241 *(LPPOINT32
)&pWnd
->rectWindow
.left
, &pWnd
->rectWindow
);
1243 if( flags
& PLACE_MIN
) lpPos
->ptIconPos
= wndpl
->ptMinPosition
;
1244 if( flags
& PLACE_MAX
) lpPos
->ptMaxPos
= wndpl
->ptMaxPosition
;
1245 if( flags
& PLACE_RECT
) lpPos
->rectNormal
= wndpl
->rcNormalPosition
;
1247 if( pWnd
->dwStyle
& WS_MINIMIZE
)
1249 WINPOS_ShowIconTitle( pWnd
, FALSE
);
1250 if( wndpl
->flags
& WPF_SETMINPOSITION
&& !EMPTYPOINT(lpPos
->ptIconPos
))
1251 SetWindowPos32( hwnd
, 0, lpPos
->ptIconPos
.x
, lpPos
->ptIconPos
.y
,
1252 0, 0, SWP_NOSIZE
| SWP_NOZORDER
| SWP_NOACTIVATE
);
1254 else if( pWnd
->dwStyle
& WS_MAXIMIZE
)
1256 if( !EMPTYPOINT(lpPos
->ptMaxPos
) )
1257 SetWindowPos32( hwnd
, 0, lpPos
->ptMaxPos
.x
, lpPos
->ptMaxPos
.y
,
1258 0, 0, SWP_NOSIZE
| SWP_NOZORDER
| SWP_NOACTIVATE
);
1260 else if( flags
& PLACE_RECT
)
1261 SetWindowPos32( hwnd
, 0, lpPos
->rectNormal
.left
, lpPos
->rectNormal
.top
,
1262 lpPos
->rectNormal
.right
- lpPos
->rectNormal
.left
,
1263 lpPos
->rectNormal
.bottom
- lpPos
->rectNormal
.top
,
1264 SWP_NOZORDER
| SWP_NOACTIVATE
);
1266 ShowWindow32( hwnd
, wndpl
->showCmd
);
1267 if( IsWindow32(hwnd
) && pWnd
->dwStyle
& WS_MINIMIZE
)
1269 if( pWnd
->dwStyle
& WS_VISIBLE
) WINPOS_ShowIconTitle( pWnd
, TRUE
);
1271 /* SDK: ...valid only the next time... */
1272 if( wndpl
->flags
& WPF_RESTORETOMAXIMIZED
) pWnd
->flags
|= WIN_RESTORE_MAX
;
1280 /***********************************************************************
1281 * SetWindowPlacement16 (USER.371)
1283 BOOL16 WINAPI
SetWindowPlacement16(HWND16 hwnd
, const WINDOWPLACEMENT16
*wndpl
)
1285 return WINPOS_SetPlacement( hwnd
, wndpl
,
1286 PLACE_MIN
| PLACE_MAX
| PLACE_RECT
);
1289 /***********************************************************************
1290 * SetWindowPlacement32 (USER32.519)
1292 BOOL32 WINAPI
SetWindowPlacement32( HWND32 hwnd
, const WINDOWPLACEMENT32
*pwpl32
)
1296 WINDOWPLACEMENT16 wpl
= { sizeof(WINDOWPLACEMENT16
),
1297 pwpl32
->flags
, pwpl32
->showCmd
, { pwpl32
->ptMinPosition
.x
,
1298 pwpl32
->ptMinPosition
.y
}, { pwpl32
->ptMaxPosition
.x
,
1299 pwpl32
->ptMaxPosition
.y
}, { pwpl32
->rcNormalPosition
.left
,
1300 pwpl32
->rcNormalPosition
.top
, pwpl32
->rcNormalPosition
.right
,
1301 pwpl32
->rcNormalPosition
.bottom
} };
1303 return WINPOS_SetPlacement( hwnd
, &wpl
, PLACE_MIN
| PLACE_MAX
| PLACE_RECT
);
1309 /***********************************************************************
1310 * SetInternalWindowPos16 (USER.461)
1312 void WINAPI
SetInternalWindowPos16( HWND16 hwnd
, UINT16 showCmd
,
1313 LPRECT16 rect
, LPPOINT16 pt
)
1315 if( IsWindow16(hwnd
) )
1317 WINDOWPLACEMENT16 wndpl
;
1320 wndpl
.length
= sizeof(wndpl
);
1321 wndpl
.showCmd
= showCmd
;
1322 wndpl
.flags
= flags
= 0;
1327 wndpl
.flags
|= WPF_SETMINPOSITION
;
1328 wndpl
.ptMinPosition
= *pt
;
1332 flags
|= PLACE_RECT
;
1333 wndpl
.rcNormalPosition
= *rect
;
1335 WINPOS_SetPlacement( hwnd
, &wndpl
, flags
);
1340 /***********************************************************************
1341 * SetInternalWindowPos32 (USER32.483)
1343 void WINAPI
SetInternalWindowPos32( HWND32 hwnd
, UINT32 showCmd
,
1344 LPRECT32 rect
, LPPOINT32 pt
)
1346 if( IsWindow32(hwnd
) )
1348 WINDOWPLACEMENT16 wndpl
;
1351 wndpl
.length
= sizeof(wndpl
);
1352 wndpl
.showCmd
= showCmd
;
1353 wndpl
.flags
= flags
= 0;
1358 wndpl
.flags
|= WPF_SETMINPOSITION
;
1359 CONV_POINT32TO16( pt
, &wndpl
.ptMinPosition
);
1363 flags
|= PLACE_RECT
;
1364 CONV_RECT32TO16( rect
, &wndpl
.rcNormalPosition
);
1366 WINPOS_SetPlacement( hwnd
, &wndpl
, flags
);
1371 /***********************************************************************
1372 * WINPOS_ForceXWindowRaise
1374 * Raise a window on top of the X stacking order, while preserving
1375 * the correct Windows Z order.
1377 static void WINPOS_ForceXWindowRaise( WND
* pWnd
)
1379 XWindowChanges winChanges
;
1382 /* Raise all windows up to pWnd according to their Z order.
1383 * (it would be easier with sibling-related Below but it doesn't
1384 * work very well with SGI mwm for instance)
1386 winChanges
.stack_mode
= Above
;
1389 if (pWnd
->window
) TSXReconfigureWMWindow( display
, pWnd
->window
, 0,
1390 CWStackMode
, &winChanges
);
1391 wndPrev
= WIN_GetDesktop()->child
;
1392 if (wndPrev
== pWnd
) break;
1393 while (wndPrev
&& (wndPrev
->next
!= pWnd
)) wndPrev
= wndPrev
->next
;
1399 /*******************************************************************
1400 * WINPOS_SetActiveWindow
1402 * SetActiveWindow() back-end. This is the only function that
1403 * can assign active status to a window. It must be called only
1404 * for the top level windows.
1406 BOOL32
WINPOS_SetActiveWindow( HWND32 hWnd
, BOOL32 fMouse
, BOOL32 fChangeFocus
)
1408 CBTACTIVATESTRUCT16
* cbtStruct
;
1409 WND
* wndPtr
, *wndTemp
;
1410 HQUEUE16 hOldActiveQueue
, hNewActiveQueue
;
1413 /* paranoid checks */
1414 if( hWnd
== GetDesktopWindow32() || hWnd
== hwndActive
) return 0;
1416 /* if (wndPtr && (GetTaskQueue(0) != wndPtr->hmemTaskQ))
1419 wndPtr
= WIN_FindWndPtr(hWnd
);
1420 hOldActiveQueue
= (pActiveQueue
)?pActiveQueue
->self
: 0;
1422 if( (wndTemp
= WIN_FindWndPtr(hwndActive
)) )
1423 wIconized
= HIWORD(wndTemp
->dwStyle
& WS_MINIMIZE
);
1425 TRACE(win
,"no current active window.\n");
1427 /* call CBT hook chain */
1428 if ((cbtStruct
= SEGPTR_NEW(CBTACTIVATESTRUCT16
)))
1431 cbtStruct
->fMouse
= fMouse
;
1432 cbtStruct
->hWndActive
= hwndActive
;
1433 wRet
= HOOK_CallHooks16( WH_CBT
, HCBT_ACTIVATE
, (WPARAM16
)hWnd
,
1434 (LPARAM
)SEGPTR_GET(cbtStruct
) );
1435 SEGPTR_FREE(cbtStruct
);
1436 if (wRet
) return wRet
;
1439 /* set prev active wnd to current active wnd and send notification */
1440 if ((hwndPrevActive
= hwndActive
) && IsWindow32(hwndPrevActive
))
1442 if (!SendMessage32A( hwndPrevActive
, WM_NCACTIVATE
, FALSE
, 0 ))
1444 if (GetSysModalWindow16() != hWnd
) return 0;
1445 /* disregard refusal if hWnd is sysmodal */
1449 SendMessage32A( hwndPrevActive
, WM_ACTIVATE
,
1450 MAKEWPARAM( WA_INACTIVE
, wIconized
),
1453 /* FIXME: must be SendMessage16() because 32A doesn't do
1454 * intertask at this time */
1455 SendMessage16( hwndPrevActive
, WM_ACTIVATE
, WA_INACTIVE
,
1456 MAKELPARAM( (HWND16
)hWnd
, wIconized
) );
1459 /* check if something happened during message processing */
1460 if( hwndPrevActive
!= hwndActive
) return 0;
1463 /* set active wnd */
1466 /* send palette messages */
1467 if (hWnd
&& SendMessage16( hWnd
, WM_QUERYNEWPALETTE
, 0, 0L))
1468 SendMessage16((HWND16
)-1, WM_PALETTEISCHANGING
, (WPARAM16
)hWnd
, 0L );
1470 /* if prev wnd is minimized redraw icon title */
1471 if( IsIconic32( hwndPrevActive
) ) WINPOS_RedrawIconTitle(hwndPrevActive
);
1473 /* managed windows will get ConfigureNotify event */
1474 if (wndPtr
&& !(wndPtr
->dwStyle
& WS_CHILD
) && !(wndPtr
->flags
& WIN_MANAGED
))
1476 /* check Z-order and bring hWnd to the top */
1477 for (wndTemp
= WIN_GetDesktop()->child
; wndTemp
; wndTemp
= wndTemp
->next
)
1478 if (wndTemp
->dwStyle
& WS_VISIBLE
) break;
1480 if( wndTemp
!= wndPtr
)
1481 SetWindowPos32(hWnd
, HWND_TOP
, 0,0,0,0,
1482 SWP_NOSIZE
| SWP_NOMOVE
| SWP_NOACTIVATE
);
1483 if (!IsWindow32(hWnd
)) return 0;
1486 hNewActiveQueue
= wndPtr
? wndPtr
->hmemTaskQ
: 0;
1488 /* send WM_ACTIVATEAPP if necessary */
1489 if (hOldActiveQueue
!= hNewActiveQueue
)
1491 WND
**list
, **ppWnd
;
1493 if ((list
= WIN_BuildWinArray( WIN_GetDesktop(), 0, NULL
)))
1495 for (ppWnd
= list
; *ppWnd
; ppWnd
++)
1497 if (!IsWindow32( (*ppWnd
)->hwndSelf
)) continue;
1499 if ((*ppWnd
)->hmemTaskQ
== hOldActiveQueue
)
1500 SendMessage16( (*ppWnd
)->hwndSelf
, WM_ACTIVATEAPP
,
1501 0, QUEUE_GetQueueTask(hNewActiveQueue
) );
1503 HeapFree( SystemHeap
, 0, list
);
1506 pActiveQueue
= (hNewActiveQueue
)
1507 ? (MESSAGEQUEUE
*) GlobalLock16(hNewActiveQueue
) : NULL
;
1509 if ((list
= WIN_BuildWinArray( WIN_GetDesktop(), 0, NULL
)))
1511 for (ppWnd
= list
; *ppWnd
; ppWnd
++)
1513 if (!IsWindow32( (*ppWnd
)->hwndSelf
)) continue;
1515 if ((*ppWnd
)->hmemTaskQ
== hNewActiveQueue
)
1516 SendMessage16( (*ppWnd
)->hwndSelf
, WM_ACTIVATEAPP
,
1517 1, QUEUE_GetQueueTask( hOldActiveQueue
) );
1519 HeapFree( SystemHeap
, 0, list
);
1521 if (!IsWindow32(hWnd
)) return 0;
1526 /* walk up to the first unowned window */
1528 while (wndTemp
->owner
) wndTemp
= wndTemp
->owner
;
1529 /* and set last active owned popup */
1530 wndTemp
->hwndLastActive
= hWnd
;
1532 wIconized
= HIWORD(wndTemp
->dwStyle
& WS_MINIMIZE
);
1533 SendMessage32A( hWnd
, WM_NCACTIVATE
, TRUE
, 0 );
1535 SendMessage32A( hWnd
, WM_ACTIVATE
,
1536 MAKEWPARAM( (fMouse
) ? WA_CLICKACTIVE
: WA_ACTIVE
, wIconized
),
1537 (LPARAM
)hwndPrevActive
);
1539 SendMessage16(hWnd
, WM_ACTIVATE
, (fMouse
) ? WA_CLICKACTIVE
: WA_ACTIVE
,
1540 MAKELPARAM( (HWND16
)hwndPrevActive
, wIconized
) );
1543 if( !IsWindow32(hWnd
) ) return 0;
1546 /* change focus if possible */
1547 if( fChangeFocus
&& GetFocus32() )
1548 if( WIN_GetTopParent(GetFocus32()) != hwndActive
)
1549 FOCUS_SwitchFocus( GetFocus32(),
1550 (wndPtr
->dwStyle
& WS_MINIMIZE
)? 0: hwndActive
);
1552 if( !hwndPrevActive
&& wndPtr
&&
1553 wndPtr
->window
&& !(wndPtr
->flags
& WIN_MANAGED
) )
1554 WINPOS_ForceXWindowRaise(wndPtr
);
1556 /* if active wnd is minimized redraw icon title */
1557 if( IsIconic32(hwndActive
) ) WINPOS_RedrawIconTitle(hwndActive
);
1559 return (hWnd
== hwndActive
);
1562 /*******************************************************************
1563 * WINPOS_ActivateOtherWindow
1565 * Activates window other than pWnd.
1567 BOOL32
WINPOS_ActivateOtherWindow(WND
* pWnd
)
1572 if( pWnd
->hwndSelf
== hwndPrevActive
)
1575 if( hwndActive
!= pWnd
->hwndSelf
&&
1576 ( hwndActive
|| QUEUE_IsExitingQueue(pWnd
->hmemTaskQ
)) )
1579 if( !(pWnd
->dwStyle
& WS_POPUP
) || !(pWnd
->owner
) ||
1580 !WINPOS_CanActivate((pWndTo
= WIN_GetTopParentPtr(pWnd
->owner
))) )
1582 WND
* pWndPtr
= WIN_GetTopParentPtr(pWnd
);
1584 pWndTo
= WIN_FindWndPtr(hwndPrevActive
);
1586 while( !WINPOS_CanActivate(pWndTo
) )
1588 /* by now owned windows should've been taken care of */
1590 pWndTo
= pWndPtr
->next
;
1592 if( !pWndTo
) break;
1596 bRet
= WINPOS_SetActiveWindow( pWndTo
? pWndTo
->hwndSelf
: 0, FALSE
, TRUE
);
1598 /* switch desktop queue to current active */
1599 if( pWndTo
) WIN_GetDesktop()->hmemTaskQ
= pWndTo
->hmemTaskQ
;
1605 /*******************************************************************
1606 * WINPOS_ChangeActiveWindow
1609 BOOL32
WINPOS_ChangeActiveWindow( HWND32 hWnd
, BOOL32 mouseMsg
)
1611 WND
*wndPtr
= WIN_FindWndPtr(hWnd
);
1613 if (!hWnd
) return WINPOS_SetActiveWindow( 0, mouseMsg
, TRUE
);
1615 if( !wndPtr
) return FALSE
;
1617 /* child windows get WM_CHILDACTIVATE message */
1618 if( (wndPtr
->dwStyle
& (WS_CHILD
| WS_POPUP
)) == WS_CHILD
)
1619 return SendMessage32A(hWnd
, WM_CHILDACTIVATE
, 0, 0L);
1621 /* owned popups imply owner activation - not sure */
1622 if ((wndPtr
->dwStyle
& WS_POPUP
) && wndPtr
->owner
&&
1623 !(wndPtr
->owner
->dwStyle
& WS_DISABLED
))
1625 if (!(wndPtr
= wndPtr
->owner
)) return FALSE
;
1626 hWnd
= wndPtr
->hwndSelf
;
1629 if( hWnd
== hwndActive
) return FALSE
;
1631 if( !WINPOS_SetActiveWindow(hWnd
,mouseMsg
,TRUE
) )
1634 /* switch desktop queue to current active */
1635 if( wndPtr
->parent
== WIN_GetDesktop())
1636 WIN_GetDesktop()->hmemTaskQ
= wndPtr
->hmemTaskQ
;
1642 /***********************************************************************
1643 * WINPOS_SendNCCalcSize
1645 * Send a WM_NCCALCSIZE message to a window.
1646 * All parameters are read-only except newClientRect.
1647 * oldWindowRect, oldClientRect and winpos must be non-NULL only
1648 * when calcValidRect is TRUE.
1650 LONG
WINPOS_SendNCCalcSize( HWND32 hwnd
, BOOL32 calcValidRect
,
1651 RECT32
*newWindowRect
, RECT32
*oldWindowRect
,
1652 RECT32
*oldClientRect
, WINDOWPOS32
*winpos
,
1653 RECT32
*newClientRect
)
1655 NCCALCSIZE_PARAMS32 params
;
1658 params
.rgrc
[0] = *newWindowRect
;
1661 params
.rgrc
[1] = *oldWindowRect
;
1662 params
.rgrc
[2] = *oldClientRect
;
1663 params
.lppos
= winpos
;
1665 result
= SendMessage32A( hwnd
, WM_NCCALCSIZE
, calcValidRect
,
1667 TRACE(win
, "%d,%d-%d,%d\n",
1668 params
.rgrc
[0].left
, params
.rgrc
[0].top
,
1669 params
.rgrc
[0].right
, params
.rgrc
[0].bottom
);
1670 *newClientRect
= params
.rgrc
[0];
1675 /***********************************************************************
1676 * WINPOS_HandleWindowPosChanging16
1678 * Default handling for a WM_WINDOWPOSCHANGING. Called from DefWindowProc().
1680 LONG
WINPOS_HandleWindowPosChanging16( WND
*wndPtr
, WINDOWPOS16
*winpos
)
1682 POINT32 maxSize
, minTrack
;
1683 if (winpos
->flags
& SWP_NOSIZE
) return 0;
1684 if ((wndPtr
->dwStyle
& WS_THICKFRAME
) ||
1685 ((wndPtr
->dwStyle
& (WS_POPUP
| WS_CHILD
)) == 0))
1687 WINPOS_GetMinMaxInfo( wndPtr
, &maxSize
, NULL
, &minTrack
, NULL
);
1688 if (maxSize
.x
< winpos
->cx
) winpos
->cx
= maxSize
.x
;
1689 if (maxSize
.y
< winpos
->cy
) winpos
->cy
= maxSize
.y
;
1690 if (!(wndPtr
->dwStyle
& WS_MINIMIZE
))
1692 if (winpos
->cx
< minTrack
.x
) winpos
->cx
= minTrack
.x
;
1693 if (winpos
->cy
< minTrack
.y
) winpos
->cy
= minTrack
.y
;
1700 /***********************************************************************
1701 * WINPOS_HandleWindowPosChanging32
1703 * Default handling for a WM_WINDOWPOSCHANGING. Called from DefWindowProc().
1705 LONG
WINPOS_HandleWindowPosChanging32( WND
*wndPtr
, WINDOWPOS32
*winpos
)
1708 if (winpos
->flags
& SWP_NOSIZE
) return 0;
1709 if ((wndPtr
->dwStyle
& WS_THICKFRAME
) ||
1710 ((wndPtr
->dwStyle
& (WS_POPUP
| WS_CHILD
)) == 0))
1712 WINPOS_GetMinMaxInfo( wndPtr
, &maxSize
, NULL
, NULL
, NULL
);
1713 winpos
->cx
= MIN( winpos
->cx
, maxSize
.x
);
1714 winpos
->cy
= MIN( winpos
->cy
, maxSize
.y
);
1720 /***********************************************************************
1721 * WINPOS_MoveWindowZOrder
1723 * Move a window in Z order, invalidating everything that needs it.
1724 * Only necessary for windows without associated X window.
1726 static void WINPOS_MoveWindowZOrder( HWND32 hwnd
, HWND32 hwndAfter
)
1729 WND
*pWndAfter
, *pWndCur
, *wndPtr
= WIN_FindWndPtr( hwnd
);
1731 /* We have two possible cases:
1732 * - The window is moving up: we have to invalidate all areas
1733 * of the window that were covered by other windows
1734 * - The window is moving down: we have to invalidate areas
1735 * of other windows covered by this one.
1738 if (hwndAfter
== HWND_TOP
)
1742 else if (hwndAfter
== HWND_BOTTOM
)
1744 if (!wndPtr
->next
) return; /* Already at the bottom */
1749 if (!(pWndAfter
= WIN_FindWndPtr( hwndAfter
))) return;
1750 if (wndPtr
->next
== pWndAfter
) return; /* Already placed right */
1752 /* Determine which window we encounter first in Z-order */
1753 pWndCur
= wndPtr
->parent
->child
;
1754 while ((pWndCur
!= wndPtr
) && (pWndCur
!= pWndAfter
))
1755 pWndCur
= pWndCur
->next
;
1756 movingUp
= (pWndCur
== pWndAfter
);
1761 WND
*pWndPrevAfter
= wndPtr
->next
;
1762 WIN_UnlinkWindow( hwnd
);
1763 WIN_LinkWindow( hwnd
, hwndAfter
);
1764 pWndCur
= wndPtr
->next
;
1765 while (pWndCur
!= pWndPrevAfter
)
1767 RECT32 rect
= { pWndCur
->rectWindow
.left
,
1768 pWndCur
->rectWindow
.top
,
1769 pWndCur
->rectWindow
.right
,
1770 pWndCur
->rectWindow
.bottom
};
1771 OffsetRect32( &rect
, -wndPtr
->rectClient
.left
,
1772 -wndPtr
->rectClient
.top
);
1773 PAINT_RedrawWindow( hwnd
, &rect
, 0, RDW_INVALIDATE
| RDW_ALLCHILDREN
|
1774 RDW_FRAME
| RDW_ERASE
, 0 );
1775 pWndCur
= pWndCur
->next
;
1778 else /* Moving down */
1780 pWndCur
= wndPtr
->next
;
1781 WIN_UnlinkWindow( hwnd
);
1782 WIN_LinkWindow( hwnd
, hwndAfter
);
1783 while (pWndCur
!= wndPtr
)
1785 RECT32 rect
= { pWndCur
->rectWindow
.left
,
1786 pWndCur
->rectWindow
.top
,
1787 pWndCur
->rectWindow
.right
,
1788 pWndCur
->rectWindow
.bottom
};
1789 OffsetRect32( &rect
, -pWndCur
->rectClient
.left
,
1790 -pWndCur
->rectClient
.top
);
1791 PAINT_RedrawWindow( pWndCur
->hwndSelf
, &rect
, 0, RDW_INVALIDATE
|
1792 RDW_ALLCHILDREN
| RDW_FRAME
| RDW_ERASE
, 0 );
1793 pWndCur
= pWndCur
->next
;
1798 /***********************************************************************
1799 * WINPOS_ReorderOwnedPopups
1801 * fix Z order taking into account owned popups -
1802 * basically we need to maintain them above owner window
1804 HWND32
WINPOS_ReorderOwnedPopups(HWND32 hwndInsertAfter
,WND
* wndPtr
,WORD flags
)
1806 WND
* w
= WIN_GetDesktop()->child
;
1808 if( wndPtr
->dwStyle
& WS_POPUP
&& wndPtr
->owner
)
1810 /* implement "local z-order" between the top and owner window */
1812 HWND32 hwndLocalPrev
= HWND_TOP
;
1814 if( hwndInsertAfter
!= HWND_TOP
)
1816 while( w
!= wndPtr
->owner
)
1818 if (w
!= wndPtr
) hwndLocalPrev
= w
->hwndSelf
;
1819 if( hwndLocalPrev
== hwndInsertAfter
) break;
1822 hwndInsertAfter
= hwndLocalPrev
;
1826 else if( wndPtr
->dwStyle
& WS_CHILD
) return hwndInsertAfter
;
1828 w
= WIN_GetDesktop()->child
;
1831 if( w
== wndPtr
) break;
1833 if( w
->dwStyle
& WS_POPUP
&& w
->owner
== wndPtr
)
1835 SetWindowPos32(w
->hwndSelf
, hwndInsertAfter
, 0, 0, 0, 0, SWP_NOMOVE
| SWP_NOSIZE
|
1836 SWP_NOACTIVATE
| SWP_NOSENDCHANGING
| SWP_DEFERERASE
);
1837 hwndInsertAfter
= w
->hwndSelf
;
1842 return hwndInsertAfter
;
1845 /***********************************************************************
1846 * WINPOS_SizeMoveClean
1848 * Make window look nice without excessive repainting
1852 * visible regions are in window coordinates
1853 * update regions are in window client coordinates
1854 * client and window rectangles are in parent client coordinates
1856 * FIXME: Move visible and update regions to the same coordinate system
1857 * (either parent client or window). This is a lot of work though.
1859 static UINT32
WINPOS_SizeMoveClean( WND
* Wnd
, HRGN32 oldVisRgn
,
1860 LPRECT32 lpOldWndRect
,
1861 LPRECT32 lpOldClientRect
, UINT32 uFlags
)
1863 HRGN32 newVisRgn
= DCE_GetVisRgn(Wnd
->hwndSelf
,DCX_WINDOW
| DCX_CLIPSIBLINGS
);
1864 HRGN32 dirtyRgn
= CreateRectRgn32(0,0,0,0);
1867 TRACE(win
,"cleaning up...new wnd=(%i %i-%i %i) old wnd=(%i %i-%i %i)\n",
1868 Wnd
->rectWindow
.left
, Wnd
->rectWindow
.top
,
1869 Wnd
->rectWindow
.right
, Wnd
->rectWindow
.bottom
,
1870 lpOldWndRect
->left
, lpOldWndRect
->top
,
1871 lpOldWndRect
->right
, lpOldWndRect
->bottom
);
1872 TRACE(win
,"\tnew client=(%i %i-%i %i) old client=(%i %i-%i %i)\n",
1873 Wnd
->rectClient
.left
, Wnd
->rectClient
.top
,
1874 Wnd
->rectClient
.right
, Wnd
->rectClient
.bottom
,
1875 lpOldClientRect
->left
, lpOldClientRect
->top
,
1876 lpOldClientRect
->right
,lpOldClientRect
->bottom
);
1878 if( (lpOldWndRect
->right
- lpOldWndRect
->left
) != (Wnd
->rectWindow
.right
- Wnd
->rectWindow
.left
) ||
1879 (lpOldWndRect
->bottom
- lpOldWndRect
->top
) != (Wnd
->rectWindow
.bottom
- Wnd
->rectWindow
.top
) )
1880 uFlags
|= SMC_DRAWFRAME
;
1882 CombineRgn32( dirtyRgn
, newVisRgn
, 0, RGN_COPY
);
1884 if( !(uFlags
& SMC_NOCOPY
) )
1885 CombineRgn32( newVisRgn
, newVisRgn
, oldVisRgn
, RGN_AND
);
1887 /* map regions to the parent client area */
1889 OffsetRgn32( dirtyRgn
, Wnd
->rectWindow
.left
, Wnd
->rectWindow
.top
);
1890 OffsetRgn32( oldVisRgn
, lpOldWndRect
->left
, lpOldWndRect
->top
);
1892 /* compute invalidated region outside Wnd - (in client coordinates of the parent window) */
1894 other
= CombineRgn32(dirtyRgn
, oldVisRgn
, dirtyRgn
, RGN_DIFF
);
1896 /* map visible region to the Wnd client area */
1898 OffsetRgn32( newVisRgn
, Wnd
->rectWindow
.left
- Wnd
->rectClient
.left
,
1899 Wnd
->rectWindow
.top
- Wnd
->rectClient
.top
);
1901 /* substract previously invalidated region from the Wnd visible region */
1903 my
= (Wnd
->hrgnUpdate
> 1) ? CombineRgn32( newVisRgn
, newVisRgn
,
1904 Wnd
->hrgnUpdate
, RGN_DIFF
)
1907 if( uFlags
& SMC_NOCOPY
) /* invalidate Wnd visible region */
1909 if (my
!= NULLREGION
)
1910 PAINT_RedrawWindow( Wnd
->hwndSelf
, NULL
, newVisRgn
, RDW_INVALIDATE
|
1911 RDW_FRAME
| RDW_ALLCHILDREN
| RDW_ERASE
, RDW_C_USEHRGN
);
1912 else if(uFlags
& SMC_DRAWFRAME
)
1913 Wnd
->flags
|= WIN_NEEDS_NCPAINT
;
1915 else /* bitblt old client area */
1920 int xfrom
,yfrom
,xto
,yto
,width
,height
;
1922 if( uFlags
& SMC_DRAWFRAME
)
1924 /* copy only client area, frame will be redrawn anyway */
1926 xfrom
= lpOldClientRect
->left
; yfrom
= lpOldClientRect
->top
;
1927 xto
= Wnd
->rectClient
.left
; yto
= Wnd
->rectClient
.top
;
1928 width
= lpOldClientRect
->right
- xfrom
; height
= lpOldClientRect
->bottom
- yfrom
;
1929 updateRgn
= CreateRectRgn32( 0, 0, width
, height
);
1930 CombineRgn32( newVisRgn
, newVisRgn
, updateRgn
, RGN_AND
);
1931 SetRectRgn32( updateRgn
, 0, 0, Wnd
->rectClient
.right
- xto
,
1932 Wnd
->rectClient
.bottom
- yto
);
1936 xfrom
= lpOldWndRect
->left
; yfrom
= lpOldWndRect
->top
;
1937 xto
= Wnd
->rectWindow
.left
; yto
= Wnd
->rectWindow
.top
;
1938 width
= lpOldWndRect
->right
- xfrom
; height
= lpOldWndRect
->bottom
- yfrom
;
1939 updateRgn
= CreateRectRgn32( xto
- Wnd
->rectClient
.left
,
1940 yto
- Wnd
->rectClient
.top
,
1941 Wnd
->rectWindow
.right
- Wnd
->rectClient
.left
,
1942 Wnd
->rectWindow
.bottom
- Wnd
->rectClient
.top
);
1945 CombineRgn32( newVisRgn
, newVisRgn
, updateRgn
, RGN_AND
);
1947 /* substract new visRgn from target rect to get a region that won't be copied */
1949 update
= CombineRgn32( updateRgn
, updateRgn
, newVisRgn
, RGN_DIFF
);
1951 /* Blt valid bits using parent window DC */
1953 if( my
!= NULLREGION
&& (xfrom
!= xto
|| yfrom
!= yto
) )
1956 /* compute clipping region in parent client coordinates */
1958 OffsetRgn32( newVisRgn
, Wnd
->rectClient
.left
, Wnd
->rectClient
.top
);
1959 CombineRgn32( oldVisRgn
, oldVisRgn
, newVisRgn
, RGN_OR
);
1961 hDC
= GetDCEx32( Wnd
->parent
->hwndSelf
, oldVisRgn
,
1962 DCX_KEEPCLIPRGN
| DCX_INTERSECTRGN
|
1963 DCX_CACHE
| DCX_CLIPSIBLINGS
);
1965 BitBlt32( hDC
, xto
, yto
, width
, height
, hDC
, xfrom
, yfrom
, SRCCOPY
);
1966 ReleaseDC32( Wnd
->parent
->hwndSelf
, hDC
);
1969 if( update
!= NULLREGION
)
1970 PAINT_RedrawWindow( Wnd
->hwndSelf
, NULL
, updateRgn
, RDW_INVALIDATE
|
1971 RDW_FRAME
| RDW_ALLCHILDREN
| RDW_ERASE
, RDW_C_USEHRGN
);
1972 else if( uFlags
& SMC_DRAWFRAME
) Wnd
->flags
|= WIN_NEEDS_NCPAINT
;
1973 DeleteObject32( updateRgn
);
1976 /* erase uncovered areas */
1978 if( !(uFlags
& SMC_NOPARENTERASE
) && (other
!= NULLREGION
) )
1979 PAINT_RedrawWindow( Wnd
->parent
->hwndSelf
, NULL
, dirtyRgn
,
1980 RDW_INVALIDATE
| RDW_ALLCHILDREN
| RDW_ERASE
, RDW_C_USEHRGN
);
1981 DeleteObject32(dirtyRgn
);
1982 DeleteObject32(newVisRgn
);
1987 /***********************************************************************
1988 * WINPOS_FindDeskTopXWindow
1990 * Find the actual X window which needs be restacked.
1991 * Used by WINPOS_SetXWindowPos().
1993 static Window
WINPOS_FindDeskTopXWindow( WND
*wndPtr
)
1995 if (!(wndPtr
->flags
& WIN_MANAGED
))
1996 return wndPtr
->window
;
1999 Window window
, root
, parent
, *children
;
2001 window
= wndPtr
->window
;
2004 TSXQueryTree( display
, window
, &root
, &parent
,
2005 &children
, &nchildren
);
2006 TSXFree( children
);
2014 /***********************************************************************
2015 * WINPOS_SetXWindowPos
2017 * SetWindowPos() for an X window. Used by the real SetWindowPos().
2019 static void WINPOS_SetXWindowPos( const WINDOWPOS32
*winpos
)
2021 XWindowChanges winChanges
;
2023 WND
*wndPtr
= WIN_FindWndPtr( winpos
->hwnd
);
2025 if (!(winpos
->flags
& SWP_NOSIZE
))
2027 winChanges
.width
= winpos
->cx
;
2028 winChanges
.height
= winpos
->cy
;
2029 changeMask
|= CWWidth
| CWHeight
;
2031 /* Tweak dialog window size hints */
2033 if ((wndPtr
->flags
& WIN_MANAGED
) &&
2034 (wndPtr
->dwExStyle
& WS_EX_DLGMODALFRAME
))
2036 XSizeHints
*size_hints
= TSXAllocSizeHints();
2040 long supplied_return
;
2042 TSXGetWMSizeHints( display
, wndPtr
->window
, size_hints
,
2043 &supplied_return
, XA_WM_NORMAL_HINTS
);
2044 size_hints
->min_width
= size_hints
->max_width
= winpos
->cx
;
2045 size_hints
->min_height
= size_hints
->max_height
= winpos
->cy
;
2046 TSXSetWMSizeHints( display
, wndPtr
->window
, size_hints
,
2047 XA_WM_NORMAL_HINTS
);
2048 TSXFree(size_hints
);
2052 if (!(winpos
->flags
& SWP_NOMOVE
))
2054 winChanges
.x
= winpos
->x
;
2055 winChanges
.y
= winpos
->y
;
2056 changeMask
|= CWX
| CWY
;
2058 if (!(winpos
->flags
& SWP_NOZORDER
))
2060 winChanges
.stack_mode
= Below
;
2061 changeMask
|= CWStackMode
;
2063 if (winpos
->hwndInsertAfter
== HWND_TOP
) winChanges
.stack_mode
= Above
;
2064 else if (winpos
->hwndInsertAfter
!= HWND_BOTTOM
)
2066 WND
* insertPtr
= WIN_FindWndPtr( winpos
->hwndInsertAfter
);
2069 stack
[0] = WINPOS_FindDeskTopXWindow( insertPtr
);
2070 stack
[1] = WINPOS_FindDeskTopXWindow( wndPtr
);
2072 /* for stupid window managers (i.e. all of them) */
2074 TSXRestackWindows(display
, stack
, 2);
2075 changeMask
&= ~CWStackMode
;
2078 if (!changeMask
) return;
2080 TSXReconfigureWMWindow( display
, wndPtr
->window
, 0, changeMask
, &winChanges
);
2084 /***********************************************************************
2085 * SetWindowPos (USER.232)
2087 BOOL16 WINAPI
SetWindowPos16( HWND16 hwnd
, HWND16 hwndInsertAfter
,
2088 INT16 x
, INT16 y
, INT16 cx
, INT16 cy
, WORD flags
)
2090 return SetWindowPos32(hwnd
,(INT32
)(INT16
)hwndInsertAfter
,x
,y
,cx
,cy
,flags
);
2093 /***********************************************************************
2094 * SetWindowPos (USER32.520)
2096 BOOL32 WINAPI
SetWindowPos32( HWND32 hwnd
, HWND32 hwndInsertAfter
,
2097 INT32 x
, INT32 y
, INT32 cx
, INT32 cy
, WORD flags
)
2101 RECT32 newWindowRect
, newClientRect
, oldWindowRect
;
2103 HWND32 tempInsertAfter
= 0;
2106 BOOL32 resync
= FALSE
;
2108 TRACE(win
,"hwnd %04x, (%i,%i)-(%i,%i) flags %08x\n",
2109 hwnd
, x
, y
, x
+cx
, y
+cy
, flags
);
2110 /* Check window handle */
2112 if (hwnd
== GetDesktopWindow32()) return FALSE
;
2113 if (!(wndPtr
= WIN_FindWndPtr( hwnd
))) return FALSE
;
2115 if(wndPtr
->dwStyle
& WS_VISIBLE
)
2116 flags
&= ~SWP_SHOWWINDOW
;
2119 uFlags
|= SMC_NOPARENTERASE
;
2120 flags
&= ~SWP_HIDEWINDOW
;
2121 if (!(flags
& SWP_SHOWWINDOW
)) flags
|= SWP_NOREDRAW
;
2124 /* Check for windows that may not be resized
2125 FIXME: this should be done only for Windows 3.0 programs
2126 if (flags & (SWP_SHOWWINDOW | SWP_HIDEWINDOW ) )
2127 flags |= SWP_NOSIZE | SWP_NOMOVE;
2129 /* Check dimensions */
2131 if (cx
<= 0) cx
= 1;
2132 if (cy
<= 0) cy
= 1;
2136 if (hwnd
== hwndActive
) flags
|= SWP_NOACTIVATE
; /* Already active */
2137 if ((wndPtr
->rectWindow
.right
- wndPtr
->rectWindow
.left
== cx
) &&
2138 (wndPtr
->rectWindow
.bottom
- wndPtr
->rectWindow
.top
== cy
))
2139 flags
|= SWP_NOSIZE
; /* Already the right size */
2140 if ((wndPtr
->rectWindow
.left
== x
) && (wndPtr
->rectWindow
.top
== y
))
2141 flags
|= SWP_NOMOVE
; /* Already the right position */
2143 /* Check hwndInsertAfter */
2145 if (!(flags
& (SWP_NOZORDER
| SWP_NOACTIVATE
)))
2147 /* Ignore TOPMOST flags when activating a window */
2148 /* _and_ moving it in Z order. */
2149 if ((hwndInsertAfter
== HWND_TOPMOST
) ||
2150 (hwndInsertAfter
== HWND_NOTOPMOST
))
2151 hwndInsertAfter
= HWND_TOP
;
2153 /* TOPMOST not supported yet */
2154 if ((hwndInsertAfter
== HWND_TOPMOST
) ||
2155 (hwndInsertAfter
== HWND_NOTOPMOST
)) hwndInsertAfter
= HWND_TOP
;
2157 /* hwndInsertAfter must be a sibling of the window */
2158 if ((hwndInsertAfter
!= HWND_TOP
) && (hwndInsertAfter
!= HWND_BOTTOM
))
2160 WND
* wnd
= WIN_FindWndPtr(hwndInsertAfter
);
2161 if( wnd
->parent
!= wndPtr
->parent
) return FALSE
;
2162 if( wnd
->next
== wndPtr
) flags
|= SWP_NOZORDER
;
2164 else if (!(wndPtr
->window
))
2165 /* FIXME: the following optimization is no good for "X-ed" windows */
2166 if (hwndInsertAfter
== HWND_TOP
)
2167 flags
|= ( wndPtr
->parent
->child
== wndPtr
)? SWP_NOZORDER
: 0;
2168 else /* HWND_BOTTOM */
2169 flags
|= ( wndPtr
->next
)? 0: SWP_NOZORDER
;
2171 /* Fill the WINDOWPOS structure */
2174 winpos
.hwndInsertAfter
= hwndInsertAfter
;
2179 winpos
.flags
= flags
;
2181 /* Send WM_WINDOWPOSCHANGING message */
2183 if (!(winpos
.flags
& SWP_NOSENDCHANGING
))
2184 SendMessage32A( hwnd
, WM_WINDOWPOSCHANGING
, 0, (LPARAM
)&winpos
);
2186 /* Calculate new position and size */
2188 newWindowRect
= wndPtr
->rectWindow
;
2189 newClientRect
= (wndPtr
->dwStyle
& WS_MINIMIZE
) ? wndPtr
->rectWindow
2190 : wndPtr
->rectClient
;
2192 if (!(winpos
.flags
& SWP_NOSIZE
))
2194 newWindowRect
.right
= newWindowRect
.left
+ winpos
.cx
;
2195 newWindowRect
.bottom
= newWindowRect
.top
+ winpos
.cy
;
2197 if (!(winpos
.flags
& SWP_NOMOVE
))
2199 newWindowRect
.left
= winpos
.x
;
2200 newWindowRect
.top
= winpos
.y
;
2201 newWindowRect
.right
+= winpos
.x
- wndPtr
->rectWindow
.left
;
2202 newWindowRect
.bottom
+= winpos
.y
- wndPtr
->rectWindow
.top
;
2204 OffsetRect32( &newClientRect
, winpos
.x
- wndPtr
->rectWindow
.left
,
2205 winpos
.y
- wndPtr
->rectWindow
.top
);
2208 winpos
.flags
|= SWP_NOCLIENTMOVE
| SWP_NOCLIENTSIZE
;
2210 /* Reposition window in Z order */
2212 if (!(winpos
.flags
& SWP_NOZORDER
))
2214 /* reorder owned popups if hwnd is top-level window
2216 if( wndPtr
->parent
== WIN_GetDesktop() )
2217 hwndInsertAfter
= WINPOS_ReorderOwnedPopups( hwndInsertAfter
,
2218 wndPtr
, winpos
.flags
);
2222 WIN_UnlinkWindow( winpos
.hwnd
);
2223 WIN_LinkWindow( winpos
.hwnd
, hwndInsertAfter
);
2225 else WINPOS_MoveWindowZOrder( winpos
.hwnd
, hwndInsertAfter
);
2228 if ( !wndPtr
->window
&& !(winpos
.flags
& SWP_NOREDRAW
) &&
2229 ((winpos
.flags
& (SWP_NOMOVE
| SWP_NOSIZE
| SWP_FRAMECHANGED
))
2230 != (SWP_NOMOVE
| SWP_NOSIZE
)) )
2231 visRgn
= DCE_GetVisRgn(hwnd
, DCX_WINDOW
| DCX_CLIPSIBLINGS
);
2234 /* Send WM_NCCALCSIZE message to get new client area */
2235 if( (winpos
.flags
& (SWP_FRAMECHANGED
| SWP_NOSIZE
)) != SWP_NOSIZE
)
2237 result
= WINPOS_SendNCCalcSize( winpos
.hwnd
, TRUE
, &newWindowRect
,
2238 &wndPtr
->rectWindow
, &wndPtr
->rectClient
,
2239 &winpos
, &newClientRect
);
2241 /* FIXME: WVR_ALIGNxxx */
2243 if( newClientRect
.left
!= wndPtr
->rectClient
.left
||
2244 newClientRect
.top
!= wndPtr
->rectClient
.top
)
2245 winpos
.flags
&= ~SWP_NOCLIENTMOVE
;
2247 if( (newClientRect
.right
- newClientRect
.left
!=
2248 wndPtr
->rectClient
.right
- wndPtr
->rectClient
.left
) ||
2249 (newClientRect
.bottom
- newClientRect
.top
!=
2250 wndPtr
->rectClient
.bottom
- wndPtr
->rectClient
.top
) )
2251 winpos
.flags
&= ~SWP_NOCLIENTSIZE
;
2254 if( !(flags
& SWP_NOMOVE
) && (newClientRect
.left
!= wndPtr
->rectClient
.left
||
2255 newClientRect
.top
!= wndPtr
->rectClient
.top
) )
2256 winpos
.flags
&= ~SWP_NOCLIENTMOVE
;
2258 /* Update active DCEs
2259 * TODO: Optimize conditions that trigger DCE update.
2262 if( (((winpos
.flags
& SWP_AGG_NOPOSCHANGE
) != SWP_AGG_NOPOSCHANGE
) &&
2263 wndPtr
->dwStyle
& WS_VISIBLE
) ||
2264 (flags
& (SWP_HIDEWINDOW
| SWP_SHOWWINDOW
)) )
2268 UnionRect32(&rect
, &newWindowRect
, &wndPtr
->rectWindow
);
2269 DCE_InvalidateDCE(wndPtr
, &rect
);
2272 /* change geometry */
2274 oldWindowRect
= wndPtr
->rectWindow
;
2278 RECT32 oldClientRect
= wndPtr
->rectClient
;
2280 tempInsertAfter
= winpos
.hwndInsertAfter
;
2282 winpos
.hwndInsertAfter
= hwndInsertAfter
;
2284 /* postpone geometry change */
2286 if( !(flags
& (SWP_SHOWWINDOW
| SWP_HIDEWINDOW
)) )
2288 WINPOS_SetXWindowPos( &winpos
);
2289 winpos
.hwndInsertAfter
= tempInsertAfter
;
2291 else uFlags
|= SMC_SETXPOS
;
2293 wndPtr
->rectWindow
= newWindowRect
;
2294 wndPtr
->rectClient
= newClientRect
;
2296 if( !(flags
& (SWP_SHOWWINDOW
| SWP_HIDEWINDOW
)) )
2297 if( (oldClientRect
.left
- oldWindowRect
.left
!=
2298 newClientRect
.left
- newWindowRect
.left
) ||
2299 (oldClientRect
.top
- oldWindowRect
.top
!=
2300 newClientRect
.top
- newWindowRect
.top
) ||
2301 winpos
.flags
& SWP_NOCOPYBITS
)
2303 PAINT_RedrawWindow( wndPtr
->hwndSelf
, NULL
, 0, RDW_INVALIDATE
|
2304 RDW_ALLCHILDREN
| RDW_FRAME
| RDW_ERASE
, 0 );
2306 if( winpos
.flags
& SWP_FRAMECHANGED
)
2311 if( oldClientRect
.right
> newClientRect
.right
)
2313 rect
.left
= newClientRect
.right
; rect
.top
= newClientRect
.top
;
2314 rect
.right
= oldClientRect
.right
; rect
.bottom
= newClientRect
.bottom
;
2316 PAINT_RedrawWindow( wndPtr
->hwndSelf
, &rect
, 0,
2317 RDW_INVALIDATE
| RDW_FRAME
| RDW_ALLCHILDREN
, 0 );
2319 if( oldClientRect
.bottom
> newClientRect
.bottom
)
2321 rect
.left
= newClientRect
.left
; rect
.top
= newClientRect
.bottom
;
2322 rect
.right
= (wErase
)?oldClientRect
.right
:newClientRect
.right
;
2323 rect
.bottom
= oldClientRect
.bottom
;
2325 PAINT_RedrawWindow( wndPtr
->hwndSelf
, &rect
, 0,
2326 RDW_INVALIDATE
| RDW_FRAME
| RDW_ALLCHILDREN
, 0 );
2328 if( !wErase
) wndPtr
->flags
|= WIN_NEEDS_NCPAINT
;
2333 RECT32 oldClientRect
= wndPtr
->rectClient
;
2335 wndPtr
->rectWindow
= newWindowRect
;
2336 wndPtr
->rectClient
= newClientRect
;
2338 if( oldClientRect
.bottom
- oldClientRect
.top
==
2339 newClientRect
.bottom
- newClientRect
.top
) result
&= ~WVR_VREDRAW
;
2341 if( oldClientRect
.right
- oldClientRect
.left
==
2342 newClientRect
.right
- newClientRect
.left
) result
&= ~WVR_HREDRAW
;
2344 if( !(flags
& (SWP_NOREDRAW
| SWP_HIDEWINDOW
| SWP_SHOWWINDOW
)) )
2346 uFlags
|= ((winpos
.flags
& SWP_NOCOPYBITS
) ||
2347 (result
>= WVR_HREDRAW
&& result
< WVR_VALIDRECTS
)) ? SMC_NOCOPY
: 0;
2348 uFlags
|= (winpos
.flags
& SWP_FRAMECHANGED
) ? SMC_DRAWFRAME
: 0;
2350 if( (winpos
.flags
& SWP_AGG_NOGEOMETRYCHANGE
) != SWP_AGG_NOGEOMETRYCHANGE
)
2351 uFlags
= WINPOS_SizeMoveClean(wndPtr
, visRgn
, &oldWindowRect
,
2352 &oldClientRect
, uFlags
);
2355 /* adjust frame and do not erase parent */
2357 if( winpos
.flags
& SWP_FRAMECHANGED
) wndPtr
->flags
|= WIN_NEEDS_NCPAINT
;
2358 if( winpos
.flags
& SWP_NOZORDER
) uFlags
|= SMC_NOPARENTERASE
;
2361 DeleteObject32(visRgn
);
2364 if (flags
& SWP_SHOWWINDOW
)
2366 wndPtr
->dwStyle
|= WS_VISIBLE
;
2371 if( uFlags
& SMC_SETXPOS
)
2373 WINPOS_SetXWindowPos( &winpos
);
2374 winpos
.hwndInsertAfter
= tempInsertAfter
;
2376 TSXMapWindow( display
, wndPtr
->window
);
2377 if (wndPtr
->flags
& WIN_MANAGED
) resync
= TRUE
;
2379 /* If focus was set to an unmapped window, reset X focus now */
2380 focus
= curr
= GetFocus32();
2384 SetFocus32( focus
);
2387 curr
= GetParent32(curr
);
2392 if (!(flags
& SWP_NOREDRAW
))
2393 PAINT_RedrawWindow( winpos
.hwnd
, NULL
, 0,
2394 RDW_INVALIDATE
| RDW_ALLCHILDREN
|
2395 RDW_FRAME
| RDW_ERASENOW
| RDW_ERASE
, 0 );
2398 else if (flags
& SWP_HIDEWINDOW
)
2400 wndPtr
->dwStyle
&= ~WS_VISIBLE
;
2403 TSXUnmapWindow( display
, wndPtr
->window
);
2404 if( uFlags
& SMC_SETXPOS
)
2406 WINPOS_SetXWindowPos( &winpos
);
2407 winpos
.hwndInsertAfter
= tempInsertAfter
;
2412 if (!(flags
& SWP_NOREDRAW
))
2413 PAINT_RedrawWindow( wndPtr
->parent
->hwndSelf
, &oldWindowRect
,
2414 0, RDW_INVALIDATE
| RDW_ALLCHILDREN
|
2415 RDW_ERASE
| RDW_ERASENOW
, 0 );
2416 uFlags
|= SMC_NOPARENTERASE
;
2419 if ((winpos
.hwnd
== GetFocus32()) ||
2420 IsChild32( winpos
.hwnd
, GetFocus32()))
2422 /* Revert focus to parent */
2423 SetFocus32( GetParent32(winpos
.hwnd
) );
2425 if (hwnd
== CARET_GetHwnd()) DestroyCaret32();
2427 if (winpos
.hwnd
== hwndActive
)
2428 WINPOS_ActivateOtherWindow( wndPtr
);
2431 /* Activate the window */
2433 if (!(flags
& SWP_NOACTIVATE
))
2434 WINPOS_ChangeActiveWindow( winpos
.hwnd
, FALSE
);
2436 /* Repaint the window */
2438 if (wndPtr
->window
) EVENT_Synchronize(); /* Wait for all expose events */
2440 if (!GetCapture32())
2441 EVENT_DummyMotionNotify(); /* Simulate a mouse event to set the cursor */
2443 if (!(flags
& SWP_DEFERERASE
) && !(uFlags
& SMC_NOPARENTERASE
) )
2444 PAINT_RedrawWindow( wndPtr
->parent
->hwndSelf
, NULL
, 0, RDW_ALLCHILDREN
| RDW_ERASENOW
, 0 );
2445 else if( wndPtr
->parent
== WIN_GetDesktop() && wndPtr
->parent
->flags
& WIN_NEEDS_ERASEBKGND
)
2446 PAINT_RedrawWindow( wndPtr
->parent
->hwndSelf
, NULL
, 0, RDW_NOCHILDREN
| RDW_ERASENOW
, 0 );
2448 /* And last, send the WM_WINDOWPOSCHANGED message */
2450 TRACE(win
,"\tstatus flags = %04x\n", winpos
.flags
& SWP_AGG_STATUSFLAGS
);
2453 (((winpos
.flags
& SWP_AGG_STATUSFLAGS
) != SWP_AGG_NOPOSCHANGE
) &&
2454 !(winpos
.flags
& SWP_NOSENDCHANGING
)) )
2456 SendMessage32A( winpos
.hwnd
, WM_WINDOWPOSCHANGED
, 0, (LPARAM
)&winpos
);
2457 if (resync
) EVENT_Synchronize ();
2464 /***********************************************************************
2465 * BeginDeferWindowPos16 (USER.259)
2467 HDWP16 WINAPI
BeginDeferWindowPos16( INT16 count
)
2469 return BeginDeferWindowPos32( count
);
2473 /***********************************************************************
2474 * BeginDeferWindowPos32 (USER32.9)
2476 HDWP32 WINAPI
BeginDeferWindowPos32( INT32 count
)
2481 if (count
<= 0) return 0;
2482 handle
= USER_HEAP_ALLOC( sizeof(DWP
) + (count
-1)*sizeof(WINDOWPOS32
) );
2483 if (!handle
) return 0;
2484 pDWP
= (DWP
*) USER_HEAP_LIN_ADDR( handle
);
2485 pDWP
->actualCount
= 0;
2486 pDWP
->suggestedCount
= count
;
2488 pDWP
->wMagic
= DWP_MAGIC
;
2489 pDWP
->hwndParent
= 0;
2494 /***********************************************************************
2495 * DeferWindowPos16 (USER.260)
2497 HDWP16 WINAPI
DeferWindowPos16( HDWP16 hdwp
, HWND16 hwnd
, HWND16 hwndAfter
,
2498 INT16 x
, INT16 y
, INT16 cx
, INT16 cy
,
2501 return DeferWindowPos32( hdwp
, hwnd
, (INT32
)(INT16
)hwndAfter
,
2502 x
, y
, cx
, cy
, flags
);
2506 /***********************************************************************
2507 * DeferWindowPos32 (USER32.128)
2509 HDWP32 WINAPI
DeferWindowPos32( HDWP32 hdwp
, HWND32 hwnd
, HWND32 hwndAfter
,
2510 INT32 x
, INT32 y
, INT32 cx
, INT32 cy
,
2515 HDWP32 newhdwp
= hdwp
;
2516 /* HWND32 parent; */
2519 pDWP
= (DWP
*) USER_HEAP_LIN_ADDR( hdwp
);
2520 if (!pDWP
) return 0;
2521 if (hwnd
== GetDesktopWindow32()) return 0;
2523 if (!(pWnd
=WIN_FindWndPtr( hwnd
))) {
2524 USER_HEAP_FREE( hdwp
);
2528 /* Numega Bounds Checker Demo dislikes the following code.
2529 In fact, I've not been able to find any "same parent" requirement in any docu
2533 /* All the windows of a DeferWindowPos() must have the same parent */
2534 parent
= pWnd
->parent
->hwndSelf
;
2535 if (pDWP
->actualCount
== 0) pDWP
->hwndParent
= parent
;
2536 else if (parent
!= pDWP
->hwndParent
)
2538 USER_HEAP_FREE( hdwp
);
2543 for (i
= 0; i
< pDWP
->actualCount
; i
++)
2545 if (pDWP
->winPos
[i
].hwnd
== hwnd
)
2547 /* Merge with the other changes */
2548 if (!(flags
& SWP_NOZORDER
))
2550 pDWP
->winPos
[i
].hwndInsertAfter
= hwndAfter
;
2552 if (!(flags
& SWP_NOMOVE
))
2554 pDWP
->winPos
[i
].x
= x
;
2555 pDWP
->winPos
[i
].y
= y
;
2557 if (!(flags
& SWP_NOSIZE
))
2559 pDWP
->winPos
[i
].cx
= cx
;
2560 pDWP
->winPos
[i
].cy
= cy
;
2562 pDWP
->winPos
[i
].flags
&= flags
| ~(SWP_NOSIZE
| SWP_NOMOVE
|
2563 SWP_NOZORDER
| SWP_NOREDRAW
|
2564 SWP_NOACTIVATE
| SWP_NOCOPYBITS
|
2566 pDWP
->winPos
[i
].flags
|= flags
& (SWP_SHOWWINDOW
| SWP_HIDEWINDOW
|
2571 if (pDWP
->actualCount
>= pDWP
->suggestedCount
)
2573 newhdwp
= USER_HEAP_REALLOC( hdwp
,
2574 sizeof(DWP
) + pDWP
->suggestedCount
*sizeof(WINDOWPOS32
) );
2575 if (!newhdwp
) return 0;
2576 pDWP
= (DWP
*) USER_HEAP_LIN_ADDR( newhdwp
);
2577 pDWP
->suggestedCount
++;
2579 pDWP
->winPos
[pDWP
->actualCount
].hwnd
= hwnd
;
2580 pDWP
->winPos
[pDWP
->actualCount
].hwndInsertAfter
= hwndAfter
;
2581 pDWP
->winPos
[pDWP
->actualCount
].x
= x
;
2582 pDWP
->winPos
[pDWP
->actualCount
].y
= y
;
2583 pDWP
->winPos
[pDWP
->actualCount
].cx
= cx
;
2584 pDWP
->winPos
[pDWP
->actualCount
].cy
= cy
;
2585 pDWP
->winPos
[pDWP
->actualCount
].flags
= flags
;
2586 pDWP
->actualCount
++;
2591 /***********************************************************************
2592 * EndDeferWindowPos16 (USER.261)
2594 BOOL16 WINAPI
EndDeferWindowPos16( HDWP16 hdwp
)
2596 return EndDeferWindowPos32( hdwp
);
2600 /***********************************************************************
2601 * EndDeferWindowPos32 (USER32.173)
2603 BOOL32 WINAPI
EndDeferWindowPos32( HDWP32 hdwp
)
2606 WINDOWPOS32
*winpos
;
2610 pDWP
= (DWP
*) USER_HEAP_LIN_ADDR( hdwp
);
2611 if (!pDWP
) return FALSE
;
2612 for (i
= 0, winpos
= pDWP
->winPos
; i
< pDWP
->actualCount
; i
++, winpos
++)
2614 if (!(res
= SetWindowPos32( winpos
->hwnd
, winpos
->hwndInsertAfter
,
2615 winpos
->x
, winpos
->y
, winpos
->cx
,
2616 winpos
->cy
, winpos
->flags
))) break;
2618 USER_HEAP_FREE( hdwp
);
2623 /***********************************************************************
2624 * TileChildWindows (USER.199)
2626 void WINAPI
TileChildWindows( HWND16 parent
, WORD action
)
2628 FIXME(win
, "(%04x, %d): stub\n", parent
, action
);
2631 /***********************************************************************
2632 * CascageChildWindows (USER.198)
2634 void WINAPI
CascadeChildWindows( HWND16 parent
, WORD action
)
2636 FIXME(win
, "(%04x, %d): stub\n", parent
, action
);