2 * Window position related functions.
4 * Copyright 1993, 1994, 1995 Alexandre Julliard
5 * 1995,1996 Alex Korobka
8 #define NO_TRANSITION_TYPES
10 #include <X11/Xutil.h>
11 #include <X11/Xatom.h>
12 #include "sysmetrics.h"
23 #include "nonclient.h"
25 /* #define DEBUG_WIN */
28 #define SWP_AGG_NOGEOMETRYCHANGE \
29 (SWP_NOSIZE | SWP_NOMOVE | SWP_NOCLIENTSIZE | SWP_NOCLIENTMOVE)
30 #define SWP_AGG_NOPOSCHANGE \
31 (SWP_AGG_NOGEOMETRYCHANGE | SWP_NOZORDER)
32 #define SWP_AGG_STATUSFLAGS \
33 (SWP_AGG_NOPOSCHANGE | SWP_FRAMECHANGED | SWP_HIDEWINDOW | SWP_SHOWWINDOW)
35 #define SMC_NOCOPY 0x0001
36 #define SMC_NOPARENTERASE 0x0002
37 #define SMC_DRAWFRAME 0x0004
38 #define SMC_SETXPOS 0x0008
40 /* ----- external functions ----- */
42 extern void FOCUS_SwitchFocus( HWND32
, HWND32
);
43 extern HRGN32
DCE_GetVisRgn( HWND32
, WORD
);
44 extern HWND32
CARET_GetHwnd();
45 extern BOOL32
DCE_InvalidateDCE(WND
*, RECT16
* );
47 /* ----- internal variables ----- */
49 static HWND32 hwndActive
= 0; /* Currently active window */
50 static HWND32 hwndPrevActive
= 0; /* Previously active window */
52 extern MESSAGEQUEUE
* pActiveQueue
;
54 /***********************************************************************
57 void WINPOS_CheckActive( HWND32 hwnd
)
59 if( hwnd
== hwndPrevActive
) hwndPrevActive
= 0;
60 if( hwnd
== hwndActive
)
63 dprintf_win(stddeb
,"\tattempt to activate destroyed window!\n");
67 /***********************************************************************
70 * Find a suitable place for an iconic window.
71 * The new position is stored into wndPtr->ptIconPos.
73 void WINPOS_FindIconPos( HWND32 hwnd
)
76 short x
, y
, xspacing
, yspacing
;
77 WND
* wndPtr
= WIN_FindWndPtr( hwnd
);
79 if (!wndPtr
|| !wndPtr
->parent
) return;
80 GetClientRect16( wndPtr
->parent
->hwndSelf
, &rectParent
);
81 if ((wndPtr
->ptIconPos
.x
>= rectParent
.left
) &&
82 (wndPtr
->ptIconPos
.x
+ SYSMETRICS_CXICON
< rectParent
.right
) &&
83 (wndPtr
->ptIconPos
.y
>= rectParent
.top
) &&
84 (wndPtr
->ptIconPos
.y
+ SYSMETRICS_CYICON
< rectParent
.bottom
))
85 return; /* The icon already has a suitable position */
87 xspacing
= yspacing
= 70; /* FIXME: This should come from WIN.INI */
88 y
= rectParent
.bottom
;
91 for (x
= rectParent
.left
; x
<=rectParent
.right
-xspacing
; x
+= xspacing
)
93 /* Check if another icon already occupies this spot */
94 WND
*childPtr
= wndPtr
->parent
->child
;
97 if ((childPtr
->dwStyle
& WS_MINIMIZE
) && (childPtr
!= wndPtr
))
99 if ((childPtr
->rectWindow
.left
< x
+ xspacing
) &&
100 (childPtr
->rectWindow
.right
>= x
) &&
101 (childPtr
->rectWindow
.top
<= y
) &&
102 (childPtr
->rectWindow
.bottom
> y
- yspacing
))
103 break; /* There's a window in there */
105 childPtr
= childPtr
->next
;
109 /* No window was found, so it's OK for us */
110 wndPtr
->ptIconPos
.x
= x
+ (xspacing
- SYSMETRICS_CXICON
) / 2;
111 wndPtr
->ptIconPos
.y
= y
- (yspacing
+ SYSMETRICS_CYICON
) / 2;
120 /***********************************************************************
121 * ArrangeIconicWindows (USER32.6)
123 UINT16
ArrangeIconicWindows16( HWND16 parent
) {
124 return ArrangeIconicWindows32(parent
);
126 /***********************************************************************
127 * ArrangeIconicWindows (USER.170)
129 UINT32
ArrangeIconicWindows32( HWND32 parent
)
133 INT32 x
, y
, xspacing
, yspacing
;
135 GetClientRect32( parent
, &rectParent
);
137 y
= rectParent
.bottom
;
138 xspacing
= yspacing
= 70; /* FIXME: This should come from WIN.INI */
139 hwndChild
= GetWindow32( parent
, GW_CHILD
);
142 if (IsIconic32( hwndChild
))
144 SetWindowPos32( hwndChild
, 0, x
+ (xspacing
- SYSMETRICS_CXICON
) / 2,
145 y
- (yspacing
+ SYSMETRICS_CYICON
) / 2, 0, 0,
146 SWP_NOSIZE
|SWP_NOZORDER
|SWP_NOACTIVATE
);
147 if (x
<= rectParent
.right
- xspacing
) x
+= xspacing
;
154 hwndChild
= GetWindow32( hwndChild
, GW_HWNDNEXT
);
160 /***********************************************************************
161 * GetWindowRect16 (USER.32)
163 void GetWindowRect16( HWND16 hwnd
, LPRECT16 rect
)
165 WND
* wndPtr
= WIN_FindWndPtr( hwnd
);
168 *rect
= wndPtr
->rectWindow
;
169 if (wndPtr
->dwStyle
& WS_CHILD
)
170 MapWindowPoints16( wndPtr
->parent
->hwndSelf
, 0, (POINT16
*)rect
, 2 );
174 /***********************************************************************
175 * GetWindowRect32 (USER.32)
177 void GetWindowRect32( HWND32 hwnd
, LPRECT32 rect
)
179 WND
* wndPtr
= WIN_FindWndPtr( hwnd
);
182 CONV_RECT16TO32( &wndPtr
->rectWindow
, rect
);
183 if (wndPtr
->dwStyle
& WS_CHILD
)
184 MapWindowPoints32( wndPtr
->parent
->hwndSelf
, 0, (POINT32
*)rect
, 2 );
188 /***********************************************************************
189 * GetClientRect16 (USER.33)
191 void GetClientRect16( HWND16 hwnd
, LPRECT16 rect
)
193 WND
* wndPtr
= WIN_FindWndPtr( hwnd
);
195 rect
->left
= rect
->top
= rect
->right
= rect
->bottom
= 0;
198 rect
->right
= wndPtr
->rectClient
.right
- wndPtr
->rectClient
.left
;
199 rect
->bottom
= wndPtr
->rectClient
.bottom
- wndPtr
->rectClient
.top
;
204 /***********************************************************************
205 * GetClientRect32 (USER32.219)
207 void GetClientRect32( HWND32 hwnd
, LPRECT32 rect
)
209 WND
* wndPtr
= WIN_FindWndPtr( hwnd
);
211 rect
->left
= rect
->top
= rect
->right
= rect
->bottom
= 0;
214 rect
->right
= wndPtr
->rectClient
.right
- wndPtr
->rectClient
.left
;
215 rect
->bottom
= wndPtr
->rectClient
.bottom
- wndPtr
->rectClient
.top
;
220 /*******************************************************************
221 * ClientToScreen16 (USER.28)
223 BOOL16
ClientToScreen16( HWND16 hwnd
, LPPOINT16 lppnt
)
225 MapWindowPoints16( hwnd
, 0, lppnt
, 1 );
230 /*******************************************************************
231 * ClientToScreen32 (USER32.51)
233 BOOL32
ClientToScreen32( HWND32 hwnd
, LPPOINT32 lppnt
)
235 MapWindowPoints32( hwnd
, 0, lppnt
, 1 );
240 /*******************************************************************
241 * ScreenToClient16 (USER.29)
243 void ScreenToClient16( HWND16 hwnd
, LPPOINT16 lppnt
)
245 MapWindowPoints16( 0, hwnd
, lppnt
, 1 );
249 /*******************************************************************
250 * ScreenToClient32 (USER32.446)
252 void ScreenToClient32( HWND32 hwnd
, LPPOINT32 lppnt
)
254 MapWindowPoints32( 0, hwnd
, lppnt
, 1 );
258 /***********************************************************************
259 * WINPOS_WindowFromPoint
261 * Find the window and hittest for a given point.
263 INT16
WINPOS_WindowFromPoint( WND
* wndScope
, POINT16 pt
, WND
**ppWnd
)
266 INT16 hittest
= HTERROR
;
272 wndPtr
= wndScope
->child
;
277 /* If point is in window, and window is visible, and it */
278 /* is enabled (or it's a top-level window), then explore */
279 /* its children. Otherwise, go to the next window. */
281 if ((wndPtr
->dwStyle
& WS_VISIBLE
) &&
282 (!(wndPtr
->dwStyle
& WS_DISABLED
) ||
283 ((wndPtr
->dwStyle
& (WS_POPUP
| WS_CHILD
)) != WS_CHILD
)) &&
284 (x
>= wndPtr
->rectWindow
.left
) &&
285 (x
< wndPtr
->rectWindow
.right
) &&
286 (y
>= wndPtr
->rectWindow
.top
) &&
287 (y
< wndPtr
->rectWindow
.bottom
))
289 *ppWnd
= wndPtr
; /* Got a suitable window */
291 /* If window is minimized or disabled, return at once */
292 if (wndPtr
->dwStyle
& WS_MINIMIZE
) return HTCAPTION
;
293 if (wndPtr
->dwStyle
& WS_DISABLED
) return HTERROR
;
295 /* If point is not in client area, ignore the children */
296 if ((x
< wndPtr
->rectClient
.left
) ||
297 (x
>= wndPtr
->rectClient
.right
) ||
298 (y
< wndPtr
->rectClient
.top
) ||
299 (y
>= wndPtr
->rectClient
.bottom
)) break;
301 x
-= wndPtr
->rectClient
.left
;
302 y
-= wndPtr
->rectClient
.top
;
303 wndPtr
= wndPtr
->child
;
305 else wndPtr
= wndPtr
->next
;
308 /* If nothing found, return the scope window */
312 if( pt
.x
>= (wndScope
->rectClient
.left
- wndScope
->rectWindow
.left
) &&
313 pt
.x
>= (wndScope
->rectClient
.top
- wndScope
->rectWindow
.top
) &&
314 pt
.x
<= (wndScope
->rectClient
.right
- wndScope
->rectWindow
.left
) &&
315 pt
.x
<= (wndScope
->rectClient
.bottom
- wndScope
->rectWindow
.top
) )
317 if( pt
.x
< 0 || pt
.y
< 0 ||
318 pt
.x
> (wndScope
->rectWindow
.right
- wndScope
->rectWindow
.left
) ||
319 pt
.y
> (wndScope
->rectWindow
.bottom
- wndScope
->rectWindow
.top
) )
321 return HTCAPTION
; /* doesn't matter in this case */
324 /* Send the WM_NCHITTEST message (only if to the same task) */
325 if ((*ppWnd
)->hmemTaskQ
!= GetTaskQueue(0)) return HTCLIENT
;
326 hittest
= (INT16
)SendMessage16( (*ppWnd
)->hwndSelf
, WM_NCHITTEST
, 0,
327 MAKELONG( pt
.x
, pt
.y
) );
328 if (hittest
!= HTTRANSPARENT
) return hittest
; /* Found the window */
330 /* If no children found in last search, make point relative to parent*/
333 x
+= (*ppWnd
)->rectClient
.left
;
334 y
+= (*ppWnd
)->rectClient
.top
;
337 /* Restart the search from the next sibling */
338 wndPtr
= (*ppWnd
)->next
;
339 *ppWnd
= (*ppWnd
)->parent
;
344 /*******************************************************************
345 * WindowFromPoint16 (USER.30)
347 HWND16
WindowFromPoint16( POINT16 pt
)
350 WINPOS_WindowFromPoint( WIN_GetDesktop(), pt
, &pWnd
);
351 return pWnd
->hwndSelf
;
355 /*******************************************************************
356 * WindowFromPoint32 (USER32.581)
358 HWND32
WindowFromPoint32( POINT32 pt
)
362 CONV_POINT32TO16( &pt
, &pt16
);
363 WINPOS_WindowFromPoint( WIN_GetDesktop(), pt16
, &pWnd
);
364 return (HWND32
)pWnd
->hwndSelf
;
368 /*******************************************************************
369 * ChildWindowFromPoint16 (USER.191)
371 HWND16
ChildWindowFromPoint16( HWND16 hwndParent
, POINT16 pt
)
373 /* pt is in the client coordinates */
375 WND
* wnd
= WIN_FindWndPtr(hwndParent
);
380 /* get client rect fast */
381 rect
.top
= rect
.left
= 0;
382 rect
.right
= wnd
->rectClient
.right
- wnd
->rectClient
.left
;
383 rect
.bottom
= wnd
->rectClient
.bottom
- wnd
->rectClient
.top
;
385 if (!PtInRect16( &rect
, pt
)) return 0;
390 if (PtInRect16( &wnd
->rectWindow
, pt
)) return wnd
->hwndSelf
;
397 /*******************************************************************
398 * ChildWindowFromPoint32 (USER32.)
400 HWND32
ChildWindowFromPoint32( HWND32 hwndParent
, POINT32 pt
)
403 CONV_POINT32TO16( &pt
, &pt16
);
404 return (HWND32
)ChildWindowFromPoint16( hwndParent
, pt16
);
408 /*******************************************************************
409 * WINPOS_GetWinOffset
411 * Calculate the offset between the origin of the two windows. Used
412 * to implement MapWindowPoints.
414 static void WINPOS_GetWinOffset( HWND32 hwndFrom
, HWND32 hwndTo
,
419 offset
->x
= offset
->y
= 0;
420 if (hwndFrom
== hwndTo
) return;
422 /* Translate source window origin to screen coords */
425 if (!(wndPtr
= WIN_FindWndPtr( hwndFrom
)))
427 fprintf(stderr
,"MapWindowPoints: bad hwndFrom = %04x\n",hwndFrom
);
430 while (wndPtr
->parent
)
432 offset
->x
+= wndPtr
->rectClient
.left
;
433 offset
->y
+= wndPtr
->rectClient
.top
;
434 wndPtr
= wndPtr
->parent
;
438 /* Translate origin to destination window coords */
441 if (!(wndPtr
= WIN_FindWndPtr( hwndTo
)))
443 fprintf(stderr
,"MapWindowPoints: bad hwndTo = %04x\n", hwndTo
);
446 while (wndPtr
->parent
)
448 offset
->x
-= wndPtr
->rectClient
.left
;
449 offset
->y
-= wndPtr
->rectClient
.top
;
450 wndPtr
= wndPtr
->parent
;
456 /*******************************************************************
457 * MapWindowPoints16 (USER.258)
459 void MapWindowPoints16( HWND16 hwndFrom
, HWND16 hwndTo
,
460 LPPOINT16 lppt
, UINT16 count
)
464 WINPOS_GetWinOffset( hwndFrom
, hwndTo
, &offset
);
474 /*******************************************************************
475 * MapWindowPoints32 (USER32.385)
477 void MapWindowPoints32( HWND32 hwndFrom
, HWND32 hwndTo
,
478 LPPOINT32 lppt
, UINT32 count
)
482 WINPOS_GetWinOffset( hwndFrom
, hwndTo
, &offset
);
492 /***********************************************************************
495 BOOL16
IsIconic16(HWND16 hWnd
)
497 return IsIconic32(hWnd
);
499 /***********************************************************************
500 * IsIconic (USER32.344)
502 BOOL32
IsIconic32(HWND32 hWnd
)
504 WND
* wndPtr
= WIN_FindWndPtr(hWnd
);
505 if (wndPtr
== NULL
) return FALSE
;
506 return (wndPtr
->dwStyle
& WS_MINIMIZE
) != 0;
510 /***********************************************************************
511 * IsZoomed (USER.272)
513 BOOL16
IsZoomed16(HWND16 hWnd
)
515 return IsZoomed32(hWnd
);
517 /***********************************************************************
518 * IsZoomed (USER32.351)
520 BOOL32
IsZoomed32(HWND32 hWnd
)
522 WND
* wndPtr
= WIN_FindWndPtr(hWnd
);
523 if (wndPtr
== NULL
) return FALSE
;
524 return (wndPtr
->dwStyle
& WS_MAXIMIZE
) != 0;
528 /*******************************************************************
529 * GetActiveWindow (USER.60)
531 HWND16
GetActiveWindow16(void)
533 return GetActiveWindow32();
535 /*******************************************************************
536 * GetActiveWindow (USER32.204)
538 HWND32
GetActiveWindow32(void)
544 /*******************************************************************
545 * WINPOS_IsGoodEnough
547 static BOOL32
WINPOS_IsGoodEnough(WND
* pWnd
)
549 return (pWnd
) ? ((!(pWnd
->dwStyle
& WS_DISABLED
) &&
550 pWnd
->dwStyle
& WS_VISIBLE
) ? TRUE
: FALSE
) : FALSE
;
554 /*******************************************************************
555 * SetActiveWindow (USER.59)
557 HWND16
SetActiveWindow16( HWND16 hwnd
)
559 return SetActiveWindow32(hwnd
);
561 /*******************************************************************
562 * SetActiveWindow (USER.59)
564 HWND32
SetActiveWindow32( HWND32 hwnd
)
566 HWND32 prev
= hwndActive
;
567 WND
*wndPtr
= WIN_FindWndPtr( hwnd
);
569 if ( !WINPOS_IsGoodEnough(wndPtr
) ) return 0;
571 WINPOS_SetActiveWindow( hwnd
, 0, 0 );
576 /***********************************************************************
577 * BringWindowToTop (USER.45)
579 BOOL16
BringWindowToTop16( HWND16 hwnd
)
581 return BringWindowToTop32(hwnd
);
583 /***********************************************************************
584 * BringWindowToTop (USER32.10)
586 BOOL32
BringWindowToTop32( HWND32 hwnd
)
588 return SetWindowPos32( hwnd
, HWND_TOP
, 0, 0, 0, 0, SWP_NOMOVE
|SWP_NOSIZE
);
592 /***********************************************************************
593 * MoveWindow (USER.56)
596 HWND16 hwnd
, INT16 x
, INT16 y
, INT16 cx
, INT16 cy
, BOOL16 repaint
598 return MoveWindow32(hwnd
,x
,y
,cx
,cy
,repaint
);
600 /***********************************************************************
601 * MoveWindow (USER32.398)
604 HWND32 hwnd
, INT32 x
, INT32 y
, INT32 cx
, INT32 cy
, BOOL32 repaint
606 int flags
= SWP_NOZORDER
| SWP_NOACTIVATE
;
607 if (!repaint
) flags
|= SWP_NOREDRAW
;
608 dprintf_win(stddeb
, "MoveWindow: %04x %d,%d %dx%d %d\n",
609 hwnd
, x
, y
, cx
, cy
, repaint
);
610 return SetWindowPos32( hwnd
, 0, x
, y
, cx
, cy
, flags
);
613 /***********************************************************************
614 * ShowWindow (USER.42)
616 BOOL16
ShowWindow16( HWND16 hwnd
, INT16 cmd
)
618 return ShowWindow32(hwnd
,cmd
);
620 /***********************************************************************
621 * ShowWindow (USER.42)
623 BOOL32
ShowWindow32( HWND32 hwnd
, INT32 cmd
)
625 WND
* wndPtr
= WIN_FindWndPtr( hwnd
);
626 BOOL32 wasVisible
, showFlag
;
629 short x
= 0, y
= 0, cx
= 0, cy
= 0;
631 if (!wndPtr
) return FALSE
;
633 dprintf_win(stddeb
,"ShowWindow: hwnd=%04x, cmd=%d\n", hwnd
, cmd
);
635 wasVisible
= (wndPtr
->dwStyle
& WS_VISIBLE
) != 0;
640 if (!wasVisible
) return FALSE
;
641 swpflags
|= SWP_HIDEWINDOW
| SWP_NOSIZE
| SWP_NOMOVE
|
642 SWP_NOACTIVATE
| SWP_NOZORDER
;
645 case SW_SHOWMINNOACTIVE
:
646 swpflags
|= SWP_NOACTIVATE
| SWP_NOZORDER
;
648 case SW_SHOWMINIMIZED
:
649 swpflags
|= SWP_SHOWWINDOW
;
652 swpflags
|= SWP_FRAMECHANGED
;
653 if (!(wndPtr
->dwStyle
& WS_MINIMIZE
))
655 if( HOOK_CallHooks16( WH_CBT
, HCBT_MINMAX
, hwnd
, cmd
) )
658 if (wndPtr
->dwStyle
& WS_MAXIMIZE
)
660 wndPtr
->flags
|= WIN_RESTORE_MAX
;
661 wndPtr
->dwStyle
&= ~WS_MAXIMIZE
;
665 wndPtr
->flags
&= ~WIN_RESTORE_MAX
;
666 wndPtr
->rectNormal
= wndPtr
->rectWindow
;
668 wndPtr
->dwStyle
|= WS_MINIMIZE
;
669 WINPOS_FindIconPos( hwnd
);
670 x
= wndPtr
->ptIconPos
.x
;
671 y
= wndPtr
->ptIconPos
.y
;
672 cx
= SYSMETRICS_CXICON
;
673 cy
= SYSMETRICS_CYICON
;
674 swpflags
|= SWP_NOCOPYBITS
;
676 else swpflags
|= SWP_NOSIZE
| SWP_NOMOVE
;
679 case SW_SHOWMAXIMIZED
: /* same as SW_MAXIMIZE: */
680 swpflags
|= SWP_SHOWWINDOW
| SWP_FRAMECHANGED
;
681 if (!(wndPtr
->dwStyle
& WS_MAXIMIZE
))
683 if( HOOK_CallHooks16( WH_CBT
, HCBT_MINMAX
, hwnd
, cmd
) )
686 /* Store the current position and find the maximized size */
687 if (!(wndPtr
->dwStyle
& WS_MINIMIZE
))
688 wndPtr
->rectNormal
= wndPtr
->rectWindow
;
690 NC_GetMinMaxInfo( wndPtr
, &maxSize
,
691 &wndPtr
->ptMaxPos
, NULL
, NULL
);
692 x
= wndPtr
->ptMaxPos
.x
;
693 y
= wndPtr
->ptMaxPos
.y
;
695 if( wndPtr
->dwStyle
& WS_MINIMIZE
)
696 if( !SendMessage32A( hwnd
, WM_QUERYOPEN
, 0, 0L ) )
698 swpflags
|= SWP_NOSIZE
| SWP_NOMOVE
;
701 else swpflags
|= SWP_NOCOPYBITS
;
705 wndPtr
->dwStyle
&= ~WS_MINIMIZE
;
706 wndPtr
->dwStyle
|= WS_MAXIMIZE
;
708 else swpflags
|= SWP_NOSIZE
| SWP_NOMOVE
;
712 swpflags
|= SWP_NOACTIVATE
| SWP_NOZORDER
;
715 swpflags
|= SWP_SHOWWINDOW
| SWP_NOSIZE
| SWP_NOMOVE
;
718 case SW_SHOWNOACTIVATE
:
719 swpflags
|= SWP_NOZORDER
;
720 if (GetActiveWindow32()) swpflags
|= SWP_NOACTIVATE
;
722 case SW_SHOWNORMAL
: /* same as SW_NORMAL: */
723 case SW_SHOWDEFAULT
: /* FIXME: should have its own handler */
725 swpflags
|= SWP_SHOWWINDOW
| SWP_FRAMECHANGED
;
727 if (wndPtr
->dwStyle
& WS_MINIMIZE
)
729 if( HOOK_CallHooks16( WH_CBT
, HCBT_MINMAX
, hwnd
, cmd
) )
732 if( !SendMessage16( hwnd
, WM_QUERYOPEN
, 0, 0L) )
734 swpflags
|= SWP_NOSIZE
| SWP_NOMOVE
;
737 wndPtr
->ptIconPos
.x
= wndPtr
->rectWindow
.left
;
738 wndPtr
->ptIconPos
.y
= wndPtr
->rectWindow
.top
;
739 wndPtr
->dwStyle
&= ~WS_MINIMIZE
;
740 if (wndPtr
->flags
& WIN_RESTORE_MAX
)
742 /* Restore to maximized position */
743 NC_GetMinMaxInfo( wndPtr
, &maxSize
, &wndPtr
->ptMaxPos
,
745 x
= wndPtr
->ptMaxPos
.x
;
746 y
= wndPtr
->ptMaxPos
.y
;
749 wndPtr
->dwStyle
|= WS_MAXIMIZE
;
751 else /* Restore to normal position */
753 x
= wndPtr
->rectNormal
.left
;
754 y
= wndPtr
->rectNormal
.top
;
755 cx
= wndPtr
->rectNormal
.right
- wndPtr
->rectNormal
.left
;
756 cy
= wndPtr
->rectNormal
.bottom
- wndPtr
->rectNormal
.top
;
758 swpflags
|= SWP_NOCOPYBITS
;
760 else if (wndPtr
->dwStyle
& WS_MAXIMIZE
)
762 if( HOOK_CallHooks16( WH_CBT
, HCBT_MINMAX
, hwnd
, cmd
) )
765 wndPtr
->ptMaxPos
.x
= wndPtr
->rectWindow
.left
;
766 wndPtr
->ptMaxPos
.y
= wndPtr
->rectWindow
.top
;
767 wndPtr
->dwStyle
&= ~WS_MAXIMIZE
;
768 x
= wndPtr
->rectNormal
.left
;
769 y
= wndPtr
->rectNormal
.top
;
770 cx
= wndPtr
->rectNormal
.right
- wndPtr
->rectNormal
.left
;
771 cy
= wndPtr
->rectNormal
.bottom
- wndPtr
->rectNormal
.top
;
773 else swpflags
|= SWP_NOSIZE
| SWP_NOMOVE
;
777 showFlag
= (cmd
!= SW_HIDE
);
778 if (showFlag
!= wasVisible
)
780 SendMessage16( hwnd
, WM_SHOWWINDOW
, showFlag
, 0 );
781 if (!IsWindow( hwnd
)) return wasVisible
;
784 if ((wndPtr
->dwStyle
& WS_CHILD
) &&
785 !IsWindowVisible32( wndPtr
->parent
->hwndSelf
) &&
786 (swpflags
& SWP_NOSIZE
) && (swpflags
& SWP_NOMOVE
))
788 /* Don't call SetWindowPos32() on invisible child windows */
789 if (cmd
== SW_HIDE
) wndPtr
->dwStyle
&= ~WS_VISIBLE
;
790 else wndPtr
->dwStyle
|= WS_VISIBLE
;
794 /* We can't activate a child window */
795 if (wndPtr
->dwStyle
& WS_CHILD
)
796 swpflags
|= SWP_NOACTIVATE
| SWP_NOZORDER
;
797 SetWindowPos32( hwnd
, HWND_TOP
, x
, y
, cx
, cy
, swpflags
);
798 if (!IsWindow( hwnd
)) return wasVisible
;
801 if (wndPtr
->flags
& WIN_NEED_SIZE
)
803 /* should happen only in CreateWindowEx() */
804 int wParam
= SIZE_RESTORED
;
806 wndPtr
->flags
&= ~WIN_NEED_SIZE
;
807 if (wndPtr
->dwStyle
& WS_MAXIMIZE
) wParam
= SIZE_MAXIMIZED
;
808 else if (wndPtr
->dwStyle
& WS_MINIMIZE
) wParam
= SIZE_MINIMIZED
;
809 SendMessage16( hwnd
, WM_SIZE
, wParam
,
810 MAKELONG(wndPtr
->rectClient
.right
-wndPtr
->rectClient
.left
,
811 wndPtr
->rectClient
.bottom
-wndPtr
->rectClient
.top
));
812 SendMessage16( hwnd
, WM_MOVE
, 0,
813 MAKELONG(wndPtr
->rectClient
.left
, wndPtr
->rectClient
.top
) );
820 /***********************************************************************
821 * GetInternalWindowPos16 (USER.460)
823 UINT16
GetInternalWindowPos16( HWND16 hwnd
, LPRECT16 rectWnd
, LPPOINT16 ptIcon
)
825 WINDOWPLACEMENT16 wndpl
;
826 if (!GetWindowPlacement16( hwnd
, &wndpl
)) return 0;
827 if (rectWnd
) *rectWnd
= wndpl
.rcNormalPosition
;
828 if (ptIcon
) *ptIcon
= wndpl
.ptMinPosition
;
829 return wndpl
.showCmd
;
833 /***********************************************************************
834 * GetInternalWindowPos32 (USER32.244)
836 UINT32
GetInternalWindowPos32( HWND32 hwnd
, LPRECT32 rectWnd
, LPPOINT32 ptIcon
)
838 WINDOWPLACEMENT32 wndpl
;
839 if (!GetWindowPlacement32( hwnd
, &wndpl
)) return 0;
840 if (rectWnd
) *rectWnd
= wndpl
.rcNormalPosition
;
841 if (ptIcon
) *ptIcon
= wndpl
.ptMinPosition
;
842 return wndpl
.showCmd
;
846 /***********************************************************************
847 * SetInternalWindowPos16 (USER.461)
849 void SetInternalWindowPos16( HWND16 hwnd
, UINT16 showCmd
,
850 LPRECT16 rect
, LPPOINT16 pt
)
852 WINDOWPLACEMENT16 wndpl
;
853 WND
*wndPtr
= WIN_FindWndPtr( hwnd
);
855 wndpl
.length
= sizeof(wndpl
);
856 wndpl
.flags
= (pt
!= NULL
) ? WPF_SETMINPOSITION
: 0;
857 wndpl
.showCmd
= showCmd
;
858 if (pt
) wndpl
.ptMinPosition
= *pt
;
859 wndpl
.rcNormalPosition
= (rect
!= NULL
) ? *rect
: wndPtr
->rectNormal
;
860 wndpl
.ptMaxPosition
= wndPtr
->ptMaxPos
;
861 SetWindowPlacement16( hwnd
, &wndpl
);
865 /***********************************************************************
866 * SetInternalWindowPos32 (USER32.482)
868 void SetInternalWindowPos32( HWND32 hwnd
, UINT32 showCmd
,
869 LPRECT32 rect
, LPPOINT32 pt
)
871 WINDOWPLACEMENT32 wndpl
;
872 WND
*wndPtr
= WIN_FindWndPtr( hwnd
);
874 wndpl
.length
= sizeof(wndpl
);
875 wndpl
.flags
= (pt
!= NULL
) ? WPF_SETMINPOSITION
: 0;
876 wndpl
.showCmd
= showCmd
;
877 if (pt
) wndpl
.ptMinPosition
= *pt
;
878 if (rect
) wndpl
.rcNormalPosition
= *rect
;
879 else CONV_RECT16TO32( &wndPtr
->rectNormal
, &wndpl
.rcNormalPosition
);
880 CONV_POINT16TO32( &wndPtr
->ptMaxPos
, &wndpl
.ptMaxPosition
);
881 SetWindowPlacement32( hwnd
, &wndpl
);
885 /***********************************************************************
886 * GetWindowPlacement16 (USER.370)
888 BOOL16
GetWindowPlacement16( HWND16 hwnd
, WINDOWPLACEMENT16
*wndpl
)
890 WND
*wndPtr
= WIN_FindWndPtr( hwnd
);
891 if (!wndPtr
) return FALSE
;
893 wndpl
->length
= sizeof(*wndpl
);
895 wndpl
->showCmd
= IsZoomed16(hwnd
) ? SW_SHOWMAXIMIZED
:
896 (IsIconic16(hwnd
) ? SW_SHOWMINIMIZED
: SW_SHOWNORMAL
);
897 wndpl
->ptMinPosition
= wndPtr
->ptIconPos
;
898 wndpl
->ptMaxPosition
= wndPtr
->ptMaxPos
;
899 wndpl
->rcNormalPosition
= wndPtr
->rectNormal
;
904 /***********************************************************************
905 * GetWindowPlacement32 (USER32.306)
907 BOOL32
GetWindowPlacement32( HWND32 hwnd
, WINDOWPLACEMENT32
*wndpl
)
909 WND
*wndPtr
= WIN_FindWndPtr( hwnd
);
910 if (!wndPtr
) return FALSE
;
912 wndpl
->length
= sizeof(*wndpl
);
914 wndpl
->showCmd
= IsZoomed32(hwnd
) ? SW_SHOWMAXIMIZED
:
915 (IsIconic32(hwnd
) ? SW_SHOWMINIMIZED
: SW_SHOWNORMAL
);
916 CONV_POINT16TO32( &wndPtr
->ptIconPos
, &wndpl
->ptMinPosition
);
917 CONV_POINT16TO32( &wndPtr
->ptMaxPos
, &wndpl
->ptMaxPosition
);
918 CONV_RECT16TO32( &wndPtr
->rectNormal
, &wndpl
->rcNormalPosition
);
923 /***********************************************************************
924 * SetWindowPlacement16 (USER.371)
926 BOOL16
SetWindowPlacement16( HWND16 hwnd
, const WINDOWPLACEMENT16
*wndpl
)
928 WND
*wndPtr
= WIN_FindWndPtr( hwnd
);
929 if (!wndPtr
) return FALSE
;
931 if (wndpl
->flags
& WPF_SETMINPOSITION
)
932 wndPtr
->ptIconPos
= wndpl
->ptMinPosition
;
933 if ((wndpl
->flags
& WPF_RESTORETOMAXIMIZED
) &&
934 (wndpl
->showCmd
== SW_SHOWMINIMIZED
)) wndPtr
->flags
|= WIN_RESTORE_MAX
;
935 wndPtr
->ptMaxPos
= wndpl
->ptMaxPosition
;
936 wndPtr
->rectNormal
= wndpl
->rcNormalPosition
;
937 ShowWindow16( hwnd
, wndpl
->showCmd
);
942 /***********************************************************************
943 * SetWindowPlacement32 (USER32.518)
945 BOOL32
SetWindowPlacement32( HWND32 hwnd
, const WINDOWPLACEMENT32
*wndpl
)
947 WND
*wndPtr
= WIN_FindWndPtr( hwnd
);
948 if (!wndPtr
) return FALSE
;
950 if (wndpl
->flags
& WPF_SETMINPOSITION
)
951 CONV_POINT32TO16( &wndpl
->ptMinPosition
, &wndPtr
->ptIconPos
);
952 if ((wndpl
->flags
& WPF_RESTORETOMAXIMIZED
) &&
953 (wndpl
->showCmd
== SW_SHOWMINIMIZED
)) wndPtr
->flags
|= WIN_RESTORE_MAX
;
954 CONV_POINT32TO16( &wndpl
->ptMaxPosition
, &wndPtr
->ptMaxPos
);
955 CONV_RECT32TO16( &wndpl
->rcNormalPosition
, &wndPtr
->rectNormal
);
956 ShowWindow32( hwnd
, wndpl
->showCmd
);
961 /***********************************************************************
962 * WINPOS_ForceXWindowRaise
964 * Raise a window on top of the X stacking order, while preserving
965 * the correct Windows Z order.
967 static void WINPOS_ForceXWindowRaise( WND
* pWnd
)
969 XWindowChanges winChanges
;
972 /* Raise all windows up to pWnd according to their Z order.
973 * (it would be easier with sibling-related Below but it doesn't
974 * work very well with SGI mwm for instance)
976 winChanges
.stack_mode
= Above
;
979 if (pWnd
->window
) XReconfigureWMWindow( display
, pWnd
->window
, 0,
980 CWStackMode
, &winChanges
);
981 wndPrev
= WIN_GetDesktop()->child
;
982 if (wndPrev
== pWnd
) break;
983 while (wndPrev
&& (wndPrev
->next
!= pWnd
)) wndPrev
= wndPrev
->next
;
989 /*******************************************************************
990 * WINPOS_SetActiveWindow
992 * back-end to SetActiveWindow
994 BOOL32
WINPOS_SetActiveWindow( HWND32 hWnd
, BOOL32 fMouse
, BOOL32 fChangeFocus
)
996 WND
*wndPtr
= WIN_FindWndPtr(hWnd
);
997 WND
*wndTemp
= WIN_FindWndPtr(hwndActive
);
998 CBTACTIVATESTRUCT16
*cbtStruct
;
1000 HQUEUE16 hOldActiveQueue
= (pActiveQueue
)?pActiveQueue
->self
:0;
1001 HQUEUE16 hNewActiveQueue
;
1003 /* paranoid checks */
1004 if( hWnd
== GetDesktopWindow32() || hWnd
== hwndActive
)
1007 /* if (wndPtr && (GetTaskQueue(0) != wndPtr->hmemTaskQ))
1012 wIconized
= HIWORD(wndTemp
->dwStyle
& WS_MINIMIZE
);
1014 dprintf_win(stddeb
,"WINPOS_ActivateWindow: no current active window.\n");
1016 /* call CBT hook chain */
1017 if ((cbtStruct
= SEGPTR_NEW(CBTACTIVATESTRUCT16
)))
1020 cbtStruct
->fMouse
= fMouse
;
1021 cbtStruct
->hWndActive
= hwndActive
;
1022 wRet
= HOOK_CallHooks16( WH_CBT
, HCBT_ACTIVATE
, (WPARAM16
)hWnd
,
1023 (LPARAM
)SEGPTR_GET(cbtStruct
) );
1024 SEGPTR_FREE(cbtStruct
);
1025 if (wRet
) return wRet
;
1028 /* set prev active wnd to current active wnd and send notification */
1029 if ((hwndPrevActive
= hwndActive
) && IsWindow(hwndPrevActive
))
1031 if (!SendMessage16( hwndPrevActive
, WM_NCACTIVATE
, FALSE
, 0 ))
1033 if (GetSysModalWindow16() != hWnd
) return 0;
1034 /* disregard refusal if hWnd is sysmodal */
1038 SendMessage32A( hwndPrevActive
, WM_ACTIVATE
,
1039 MAKEWPARAM( WA_INACTIVE
, wIconized
),
1042 /* FIXME: must be SendMessage16() because 32A doesn't do
1043 * intertask at this time */
1044 SendMessage16( hwndPrevActive
, WM_ACTIVATE
, WA_INACTIVE
,
1045 MAKELPARAM( (HWND16
)hWnd
, wIconized
) );
1048 /* check if something happened during message processing */
1049 if( hwndPrevActive
!= hwndActive
) return 0;
1052 /* set active wnd */
1055 /* send palette messages */
1056 if (hWnd
&& SendMessage16( hWnd
, WM_QUERYNEWPALETTE
, 0, 0L))
1057 SendMessage16((HWND16
)-1, WM_PALETTEISCHANGING
, (WPARAM16
)hWnd
, 0L );
1059 /* if prev wnd is minimized redraw icon title
1060 if( hwndPrevActive )
1062 wndTemp = WIN_FindWndPtr( WIN_GetTopParent( hwndPrevActive ) );
1064 if(wndTemp->dwStyle & WS_MINIMIZE)
1065 RedrawIconTitle(hwndPrevActive);
1069 /* managed windows will get ConfigureNotify event */
1070 if (wndPtr
&& !(wndPtr
->dwStyle
& WS_CHILD
) && !(wndPtr
->flags
& WIN_MANAGED
))
1072 /* check Z-order and bring hWnd to the top */
1073 for (wndTemp
= WIN_GetDesktop()->child
; wndTemp
; wndTemp
= wndTemp
->next
)
1074 if (wndTemp
->dwStyle
& WS_VISIBLE
) break;
1076 if( wndTemp
!= wndPtr
)
1077 SetWindowPos32(hWnd
, HWND_TOP
, 0,0,0,0,
1078 SWP_NOSIZE
| SWP_NOMOVE
| SWP_NOACTIVATE
);
1079 if( !IsWindow(hWnd
) ) return 0;
1082 hNewActiveQueue
= wndPtr
? wndPtr
->hmemTaskQ
: 0;
1084 /* send WM_ACTIVATEAPP if necessary */
1085 if (hOldActiveQueue
!= hNewActiveQueue
)
1087 WND
**list
, **ppWnd
;
1089 if ((list
= WIN_BuildWinArray( WIN_GetDesktop() )))
1091 for (ppWnd
= list
; *ppWnd
; ppWnd
++)
1093 if (!IsWindow( (*ppWnd
)->hwndSelf
)) continue;
1095 if ((*ppWnd
)->hmemTaskQ
== hOldActiveQueue
)
1096 SendMessage16( (*ppWnd
)->hwndSelf
, WM_ACTIVATEAPP
,
1097 0, QUEUE_GetQueueTask(hNewActiveQueue
) );
1099 HeapFree( SystemHeap
, 0, list
);
1102 pActiveQueue
= (hNewActiveQueue
)
1103 ? (MESSAGEQUEUE
*) GlobalLock16(hNewActiveQueue
) : NULL
;
1105 if ((list
= WIN_BuildWinArray( WIN_GetDesktop() )))
1107 for (ppWnd
= list
; *ppWnd
; ppWnd
++)
1109 if (!IsWindow( (*ppWnd
)->hwndSelf
)) continue;
1111 if ((*ppWnd
)->hmemTaskQ
== hNewActiveQueue
)
1112 SendMessage16( (*ppWnd
)->hwndSelf
, WM_ACTIVATEAPP
,
1113 1, QUEUE_GetQueueTask( hOldActiveQueue
) );
1115 HeapFree( SystemHeap
, 0, list
);
1117 if (!IsWindow(hWnd
)) return 0;
1122 /* walk up to the first unowned window */
1124 while (wndTemp
->owner
) wndTemp
= wndTemp
->owner
;
1125 /* and set last active owned popup */
1126 wndTemp
->hwndLastActive
= hWnd
;
1128 wIconized
= HIWORD(wndTemp
->dwStyle
& WS_MINIMIZE
);
1129 SendMessage16( hWnd
, WM_NCACTIVATE
, TRUE
, 0 );
1131 SendMessage32A( hWnd
, WM_ACTIVATE
,
1132 MAKEWPARAM( (fMouse
) ? WA_CLICKACTIVE
: WA_ACTIVE
, wIconized
),
1133 (LPARAM
)hwndPrevActive
);
1135 SendMessage16(hWnd
, WM_ACTIVATE
, (fMouse
) ? WA_CLICKACTIVE
: WA_ACTIVE
,
1136 MAKELPARAM( (HWND16
)hwndPrevActive
, wIconized
) );
1139 if( !IsWindow(hWnd
) ) return 0;
1142 /* change focus if possible */
1143 if( fChangeFocus
&& GetFocus32() )
1144 if( WIN_GetTopParent(GetFocus32()) != hwndActive
)
1145 FOCUS_SwitchFocus( GetFocus32(),
1146 (wndPtr
->dwStyle
& WS_MINIMIZE
)? 0: hwndActive
);
1148 if( !hwndPrevActive
&& wndPtr
&&
1149 wndPtr
->window
&& !(wndPtr
->flags
& WIN_MANAGED
) )
1150 WINPOS_ForceXWindowRaise(wndPtr
);
1152 /* if active wnd is minimized redraw icon title
1155 wndPtr = WIN_FindWndPtr(hwndActive);
1156 if(wndPtr->dwStyle & WS_MINIMIZE)
1157 RedrawIconTitle(hwndActive);
1160 return (hWnd
== hwndActive
);
1163 /*******************************************************************
1164 * WINPOS_ActivateOtherWindow
1166 * DestroyWindow() helper. pWnd must be a top-level window.
1168 BOOL32
WINPOS_ActivateOtherWindow(WND
* pWnd
)
1173 if( pWnd
->hwndSelf
== hwndPrevActive
)
1176 if( hwndActive
!= pWnd
->hwndSelf
&&
1177 ( hwndActive
|| QUEUE_IsDoomedQueue(pWnd
->hmemTaskQ
)) )
1180 if( pWnd
->dwStyle
& WS_POPUP
&&
1181 WINPOS_IsGoodEnough( pWnd
->owner
) ) pWndTo
= pWnd
->owner
;
1184 WND
* pWndPtr
= pWnd
;
1186 pWndTo
= WIN_FindWndPtr(hwndPrevActive
);
1188 while( !WINPOS_IsGoodEnough(pWndTo
) )
1190 /* by now owned windows should've been taken care of */
1192 pWndTo
= pWndPtr
->next
;
1194 if( !pWndTo
) return 0;
1198 bRet
= WINPOS_SetActiveWindow( pWndTo
->hwndSelf
, FALSE
, TRUE
);
1200 /* switch desktop queue to current active */
1201 if( pWndTo
->parent
== WIN_GetDesktop())
1202 WIN_GetDesktop()->hmemTaskQ
= pWndTo
->hmemTaskQ
;
1208 /*******************************************************************
1209 * WINPOS_ChangeActiveWindow
1212 BOOL32
WINPOS_ChangeActiveWindow( HWND32 hWnd
, BOOL32 mouseMsg
)
1214 WND
*wndPtr
= WIN_FindWndPtr(hWnd
);
1216 if (!hWnd
) return WINPOS_SetActiveWindow( 0, mouseMsg
, TRUE
);
1218 if( !wndPtr
) return FALSE
;
1220 /* child windows get WM_CHILDACTIVATE message */
1221 if( (wndPtr
->dwStyle
& (WS_CHILD
| WS_POPUP
)) == WS_CHILD
)
1222 return SendMessage16(hWnd
, WM_CHILDACTIVATE
, 0, 0L);
1224 /* owned popups imply owner activation - not sure */
1225 if ((wndPtr
->dwStyle
& WS_POPUP
) && wndPtr
->owner
&&
1226 !(wndPtr
->owner
->dwStyle
& WS_DISABLED
))
1228 if (!(wndPtr
= wndPtr
->owner
)) return FALSE
;
1229 hWnd
= wndPtr
->hwndSelf
;
1232 if( hWnd
== hwndActive
) return FALSE
;
1234 if( !WINPOS_SetActiveWindow(hWnd
,mouseMsg
,TRUE
) )
1237 /* switch desktop queue to current active */
1238 if( wndPtr
->parent
== WIN_GetDesktop())
1239 WIN_GetDesktop()->hmemTaskQ
= wndPtr
->hmemTaskQ
;
1245 /***********************************************************************
1246 * WINPOS_SendNCCalcSize
1248 * Send a WM_NCCALCSIZE message to a window.
1249 * All parameters are read-only except newClientRect.
1250 * oldWindowRect, oldClientRect and winpos must be non-NULL only
1251 * when calcValidRect is TRUE.
1253 LONG
WINPOS_SendNCCalcSize( HWND32 hwnd
, BOOL32 calcValidRect
,
1254 RECT16
*newWindowRect
, RECT16
*oldWindowRect
,
1255 RECT16
*oldClientRect
, SEGPTR winpos
,
1256 RECT16
*newClientRect
)
1258 NCCALCSIZE_PARAMS16
*params
;
1261 if (!(params
= SEGPTR_NEW(NCCALCSIZE_PARAMS16
))) return 0;
1262 params
->rgrc
[0] = *newWindowRect
;
1265 params
->rgrc
[1] = *oldWindowRect
;
1266 params
->rgrc
[2] = *oldClientRect
;
1267 params
->lppos
= winpos
;
1269 result
= SendMessage16( hwnd
, WM_NCCALCSIZE
, calcValidRect
,
1270 (LPARAM
)SEGPTR_GET( params
) );
1271 dprintf_win( stddeb
, "WINPOS_SendNCCalcSize: %d,%d-%d,%d\n",
1272 params
->rgrc
[0].left
, params
->rgrc
[0].top
,
1273 params
->rgrc
[0].right
, params
->rgrc
[0].bottom
);
1274 *newClientRect
= params
->rgrc
[0];
1275 SEGPTR_FREE(params
);
1280 /***********************************************************************
1281 * WINPOS_HandleWindowPosChanging16
1283 * Default handling for a WM_WINDOWPOSCHANGING. Called from DefWindowProc().
1285 LONG
WINPOS_HandleWindowPosChanging16( WND
*wndPtr
, WINDOWPOS16
*winpos
)
1288 if (winpos
->flags
& SWP_NOSIZE
) return 0;
1289 if ((wndPtr
->dwStyle
& WS_THICKFRAME
) ||
1290 ((wndPtr
->dwStyle
& (WS_POPUP
| WS_CHILD
)) == 0))
1292 NC_GetMinMaxInfo( wndPtr
, &maxSize
, NULL
, NULL
, NULL
);
1293 winpos
->cx
= MIN( winpos
->cx
, maxSize
.x
);
1294 winpos
->cy
= MIN( winpos
->cy
, maxSize
.y
);
1300 /***********************************************************************
1301 * WINPOS_HandleWindowPosChanging32
1303 * Default handling for a WM_WINDOWPOSCHANGING. Called from DefWindowProc().
1305 LONG
WINPOS_HandleWindowPosChanging32( WND
*wndPtr
, WINDOWPOS32
*winpos
)
1308 if (winpos
->flags
& SWP_NOSIZE
) return 0;
1309 if ((wndPtr
->dwStyle
& WS_THICKFRAME
) ||
1310 ((wndPtr
->dwStyle
& (WS_POPUP
| WS_CHILD
)) == 0))
1312 NC_GetMinMaxInfo( wndPtr
, &maxSize
, NULL
, NULL
, NULL
);
1313 winpos
->cx
= MIN( winpos
->cx
, maxSize
.x
);
1314 winpos
->cy
= MIN( winpos
->cy
, maxSize
.y
);
1320 /***********************************************************************
1321 * WINPOS_MoveWindowZOrder
1323 * Move a window in Z order, invalidating everything that needs it.
1324 * Only necessary for windows without associated X window.
1326 static void WINPOS_MoveWindowZOrder( HWND32 hwnd
, HWND32 hwndAfter
)
1329 WND
*pWndAfter
, *pWndCur
, *wndPtr
= WIN_FindWndPtr( hwnd
);
1331 /* We have two possible cases:
1332 * - The window is moving up: we have to invalidate all areas
1333 * of the window that were covered by other windows
1334 * - The window is moving down: we have to invalidate areas
1335 * of other windows covered by this one.
1338 if (hwndAfter
== HWND_TOP
)
1342 else if (hwndAfter
== HWND_BOTTOM
)
1344 if (!wndPtr
->next
) return; /* Already at the bottom */
1349 if (!(pWndAfter
= WIN_FindWndPtr( hwndAfter
))) return;
1350 if (wndPtr
->next
== pWndAfter
) return; /* Already placed right */
1352 /* Determine which window we encounter first in Z-order */
1353 pWndCur
= wndPtr
->parent
->child
;
1354 while ((pWndCur
!= wndPtr
) && (pWndCur
!= pWndAfter
))
1355 pWndCur
= pWndCur
->next
;
1356 movingUp
= (pWndCur
== pWndAfter
);
1361 WND
*pWndPrevAfter
= wndPtr
->next
;
1362 WIN_UnlinkWindow( hwnd
);
1363 WIN_LinkWindow( hwnd
, hwndAfter
);
1364 pWndCur
= wndPtr
->next
;
1365 while (pWndCur
!= pWndPrevAfter
)
1367 RECT32 rect
= { pWndCur
->rectWindow
.left
,
1368 pWndCur
->rectWindow
.top
,
1369 pWndCur
->rectWindow
.right
,
1370 pWndCur
->rectWindow
.bottom
};
1371 OffsetRect32( &rect
, -wndPtr
->rectClient
.left
,
1372 -wndPtr
->rectClient
.top
);
1373 PAINT_RedrawWindow( hwnd
, &rect
, 0, RDW_INVALIDATE
| RDW_ALLCHILDREN
|
1374 RDW_FRAME
| RDW_ERASE
, 0 );
1375 pWndCur
= pWndCur
->next
;
1378 else /* Moving down */
1380 pWndCur
= wndPtr
->next
;
1381 WIN_UnlinkWindow( hwnd
);
1382 WIN_LinkWindow( hwnd
, hwndAfter
);
1383 while (pWndCur
!= wndPtr
)
1385 RECT32 rect
= { pWndCur
->rectWindow
.left
,
1386 pWndCur
->rectWindow
.top
,
1387 pWndCur
->rectWindow
.right
,
1388 pWndCur
->rectWindow
.bottom
};
1389 OffsetRect32( &rect
, -pWndCur
->rectClient
.left
,
1390 -pWndCur
->rectClient
.top
);
1391 PAINT_RedrawWindow( pWndCur
->hwndSelf
, &rect
, 0, RDW_INVALIDATE
|
1392 RDW_ALLCHILDREN
| RDW_FRAME
| RDW_ERASE
, 0 );
1393 pWndCur
= pWndCur
->next
;
1398 /***********************************************************************
1399 * WINPOS_ReorderOwnedPopups
1401 * fix Z order taking into account owned popups -
1402 * basically we need to maintain them above owner window
1404 HWND32
WINPOS_ReorderOwnedPopups(HWND32 hwndInsertAfter
,WND
* wndPtr
,WORD flags
)
1406 WND
* w
= WIN_GetDesktop()->child
;
1408 if( wndPtr
->dwStyle
& WS_POPUP
&& wndPtr
->owner
)
1410 /* implement "local z-order" between the top and owner window */
1412 HWND32 hwndLocalPrev
= HWND_TOP
;
1414 if( hwndInsertAfter
!= HWND_TOP
)
1416 while( w
!= wndPtr
->owner
)
1418 if (w
!= wndPtr
) hwndLocalPrev
= w
->hwndSelf
;
1419 if( hwndLocalPrev
== hwndInsertAfter
) break;
1422 hwndInsertAfter
= hwndLocalPrev
;
1426 else if( wndPtr
->dwStyle
& WS_CHILD
) return hwndInsertAfter
;
1428 w
= WIN_GetDesktop()->child
;
1431 if( w
== wndPtr
) break;
1433 if( w
->dwStyle
& WS_POPUP
&& w
->owner
== wndPtr
)
1435 SetWindowPos32(w
->hwndSelf
, hwndInsertAfter
, 0, 0, 0, 0, SWP_NOMOVE
| SWP_NOSIZE
|
1436 SWP_NOACTIVATE
| SWP_NOSENDCHANGING
| SWP_DEFERERASE
);
1437 hwndInsertAfter
= w
->hwndSelf
;
1442 return hwndInsertAfter
;
1445 /***********************************************************************
1446 * WINPOS_SizeMoveClean
1448 * Make window look nice without excessive repainting
1452 * visible regions are in window coordinates
1453 * update regions are in window client coordinates
1454 * client and window rectangles are in parent client coordinates
1456 static UINT32
WINPOS_SizeMoveClean(WND
* Wnd
, HRGN32 oldVisRgn
, LPRECT16 lpOldWndRect
, LPRECT16 lpOldClientRect
, UINT32 uFlags
)
1458 HRGN32 newVisRgn
= DCE_GetVisRgn(Wnd
->hwndSelf
,DCX_WINDOW
| DCX_CLIPSIBLINGS
);
1459 HRGN32 dirtyRgn
= CreateRectRgn32(0,0,0,0);
1462 dprintf_win(stddeb
,"cleaning up...new wnd=(%i %i-%i %i) old wnd=(%i %i-%i %i)\n\
1463 \t\tnew client=(%i %i-%i %i) old client=(%i %i-%i %i)\n",
1464 Wnd
->rectWindow
.left
, Wnd
->rectWindow
.top
, Wnd
->rectWindow
.right
, Wnd
->rectWindow
.bottom
,
1465 lpOldWndRect
->left
, lpOldWndRect
->top
, lpOldWndRect
->right
, lpOldWndRect
->bottom
,
1466 Wnd
->rectClient
.left
,Wnd
->rectClient
.top
,Wnd
->rectClient
.right
,Wnd
->rectClient
.bottom
,
1467 lpOldClientRect
->left
,lpOldClientRect
->top
,lpOldClientRect
->right
,lpOldClientRect
->bottom
);
1469 if( (lpOldWndRect
->right
- lpOldWndRect
->left
) != (Wnd
->rectWindow
.right
- Wnd
->rectWindow
.left
) ||
1470 (lpOldWndRect
->bottom
- lpOldWndRect
->top
) != (Wnd
->rectWindow
.bottom
- Wnd
->rectWindow
.top
) )
1471 uFlags
|= SMC_DRAWFRAME
;
1473 CombineRgn32( dirtyRgn
, newVisRgn
, 0, RGN_COPY
);
1475 if( !(uFlags
& SMC_NOCOPY
) )
1476 CombineRgn32( newVisRgn
, newVisRgn
, oldVisRgn
, RGN_AND
);
1478 /* map regions to the parent client area */
1480 OffsetRgn32( dirtyRgn
, Wnd
->rectWindow
.left
, Wnd
->rectWindow
.top
);
1481 OffsetRgn32( oldVisRgn
, lpOldWndRect
->left
, lpOldWndRect
->top
);
1483 /* compute invalidated region outside Wnd - (in client coordinates of the parent window) */
1485 other
= CombineRgn32(dirtyRgn
, oldVisRgn
, dirtyRgn
, RGN_DIFF
);
1487 /* map visible region to the Wnd client area */
1489 OffsetRgn32( newVisRgn
, Wnd
->rectWindow
.left
- Wnd
->rectClient
.left
,
1490 Wnd
->rectWindow
.top
- Wnd
->rectClient
.top
);
1492 /* substract previously invalidated region from the Wnd visible region */
1494 my
= (Wnd
->hrgnUpdate
> 1) ? CombineRgn32( newVisRgn
, newVisRgn
,
1495 Wnd
->hrgnUpdate
, RGN_DIFF
)
1498 if( uFlags
& SMC_NOCOPY
) /* invalidate Wnd visible region */
1500 if (my
!= NULLREGION
)
1501 PAINT_RedrawWindow( Wnd
->hwndSelf
, NULL
, newVisRgn
, RDW_INVALIDATE
|
1502 RDW_FRAME
| RDW_ALLCHILDREN
| RDW_ERASE
, RDW_C_USEHRGN
);
1503 else if(uFlags
& SMC_DRAWFRAME
)
1504 Wnd
->flags
|= WIN_NEEDS_NCPAINT
;
1506 else /* bitblt old client area */
1511 int xfrom
,yfrom
,xto
,yto
,width
,height
;
1513 if( uFlags
& SMC_DRAWFRAME
)
1515 /* copy only client area, frame will be redrawn anyway */
1517 xfrom
= lpOldClientRect
->left
; yfrom
= lpOldClientRect
->top
;
1518 xto
= Wnd
->rectClient
.left
; yto
= Wnd
->rectClient
.top
;
1519 width
= lpOldClientRect
->right
- xfrom
; height
= lpOldClientRect
->bottom
- yfrom
;
1520 updateRgn
= CreateRectRgn32( 0, 0, width
, height
);
1521 CombineRgn32( newVisRgn
, newVisRgn
, updateRgn
, RGN_AND
);
1522 SetRectRgn( updateRgn
, 0, 0, Wnd
->rectClient
.right
- xto
, Wnd
->rectClient
.bottom
- yto
);
1526 xfrom
= lpOldWndRect
->left
; yfrom
= lpOldWndRect
->top
;
1527 xto
= Wnd
->rectWindow
.left
; yto
= Wnd
->rectWindow
.top
;
1528 width
= lpOldWndRect
->right
- xfrom
; height
= lpOldWndRect
->bottom
- yfrom
;
1529 updateRgn
= CreateRectRgn32( xto
- Wnd
->rectClient
.left
,
1530 yto
- Wnd
->rectClient
.top
,
1531 Wnd
->rectWindow
.right
- Wnd
->rectClient
.left
,
1532 Wnd
->rectWindow
.bottom
- Wnd
->rectClient
.top
);
1535 CombineRgn32( newVisRgn
, newVisRgn
, updateRgn
, RGN_AND
);
1537 /* substract new visRgn from target rect to get a region that won't be copied */
1539 update
= CombineRgn32( updateRgn
, updateRgn
, newVisRgn
, RGN_DIFF
);
1541 /* Blt valid bits using parent window DC */
1543 if( my
!= NULLREGION
&& (xfrom
!= xto
|| yfrom
!= yto
) )
1546 /* compute clipping region in parent client coordinates */
1548 OffsetRgn32( newVisRgn
, Wnd
->rectClient
.left
, Wnd
->rectClient
.top
);
1549 CombineRgn32( oldVisRgn
, oldVisRgn
, newVisRgn
, RGN_OR
);
1551 hDC
= GetDCEx32( Wnd
->parent
->hwndSelf
, oldVisRgn
,
1552 DCX_KEEPCLIPRGN
| DCX_INTERSECTRGN
|
1553 DCX_CACHE
| DCX_CLIPSIBLINGS
);
1555 BitBlt32( hDC
, xto
, yto
, width
, height
, hDC
, xfrom
, yfrom
, SRCCOPY
);
1556 ReleaseDC32( Wnd
->parent
->hwndSelf
, hDC
);
1559 if( update
!= NULLREGION
)
1560 PAINT_RedrawWindow( Wnd
->hwndSelf
, NULL
, updateRgn
, RDW_INVALIDATE
|
1561 RDW_FRAME
| RDW_ALLCHILDREN
| RDW_ERASE
, RDW_C_USEHRGN
);
1562 else if( uFlags
& SMC_DRAWFRAME
) Wnd
->flags
|= WIN_NEEDS_NCPAINT
;
1563 DeleteObject32( updateRgn
);
1566 /* erase uncovered areas */
1568 if( !(uFlags
& SMC_NOPARENTERASE
) && (other
!= NULLREGION
) )
1569 PAINT_RedrawWindow( Wnd
->parent
->hwndSelf
, NULL
, dirtyRgn
,
1570 RDW_INVALIDATE
| RDW_ALLCHILDREN
| RDW_ERASE
, RDW_C_USEHRGN
);
1571 DeleteObject32(dirtyRgn
);
1572 DeleteObject32(newVisRgn
);
1577 /***********************************************************************
1578 * WINPOS_FindDeskTopXWindow
1580 * Find the actual X window which needs be restacked.
1581 * Used by WINPOS_SetXWindowPos().
1583 static Window
WINPOS_FindDeskTopXWindow( WND
*wndPtr
)
1585 if (!(wndPtr
->flags
& WIN_MANAGED
))
1586 return wndPtr
->window
;
1589 Window window
, root
, parent
, *children
;
1591 window
= wndPtr
->window
;
1594 XQueryTree( display
, window
, &root
, &parent
,
1595 &children
, &nchildren
);
1604 /***********************************************************************
1605 * WINPOS_SetXWindowPos
1607 * SetWindowPos() for an X window. Used by the real SetWindowPos().
1609 static void WINPOS_SetXWindowPos( WINDOWPOS16
*winpos
)
1611 XWindowChanges winChanges
;
1613 WND
*wndPtr
= WIN_FindWndPtr( winpos
->hwnd
);
1615 if (!(winpos
->flags
& SWP_NOSIZE
))
1617 winChanges
.width
= winpos
->cx
;
1618 winChanges
.height
= winpos
->cy
;
1619 changeMask
|= CWWidth
| CWHeight
;
1621 /* Tweak dialog window size hints */
1623 if ((wndPtr
->flags
& WIN_MANAGED
) &&
1624 (wndPtr
->dwExStyle
& WS_EX_DLGMODALFRAME
))
1626 XSizeHints
*size_hints
= XAllocSizeHints();
1630 long supplied_return
;
1632 XGetWMSizeHints( display
, wndPtr
->window
, size_hints
,
1633 &supplied_return
, XA_WM_NORMAL_HINTS
);
1634 size_hints
->min_width
= size_hints
->max_width
= winpos
->cx
;
1635 size_hints
->min_height
= size_hints
->max_height
= winpos
->cy
;
1636 XSetWMSizeHints( display
, wndPtr
->window
, size_hints
,
1637 XA_WM_NORMAL_HINTS
);
1642 if (!(winpos
->flags
& SWP_NOMOVE
))
1644 winChanges
.x
= winpos
->x
;
1645 winChanges
.y
= winpos
->y
;
1646 changeMask
|= CWX
| CWY
;
1648 if (!(winpos
->flags
& SWP_NOZORDER
))
1650 winChanges
.stack_mode
= Below
;
1651 changeMask
|= CWStackMode
;
1653 if (winpos
->hwndInsertAfter
== HWND_TOP
) winChanges
.stack_mode
= Above
;
1654 else if (winpos
->hwndInsertAfter
!= HWND_BOTTOM
)
1656 WND
* insertPtr
= WIN_FindWndPtr( winpos
->hwndInsertAfter
);
1659 stack
[0] = WINPOS_FindDeskTopXWindow( insertPtr
);
1660 stack
[1] = WINPOS_FindDeskTopXWindow( wndPtr
);
1662 /* for stupid window managers (i.e. all of them) */
1664 XRestackWindows(display
, stack
, 2);
1665 changeMask
&= ~CWStackMode
;
1668 if (!changeMask
) return;
1670 XReconfigureWMWindow( display
, wndPtr
->window
, 0, changeMask
, &winChanges
);
1674 /***********************************************************************
1675 * SetWindowPos (USER.232)
1677 BOOL16
SetWindowPos16( HWND16 hwnd
, HWND16 hwndInsertAfter
, INT16 x
, INT16 y
,
1678 INT16 cx
, INT16 cy
, WORD flags
)
1680 return SetWindowPos32(hwnd
,(INT32
)(INT16
)hwndInsertAfter
,x
,y
,cx
,cy
,flags
);
1683 /***********************************************************************
1684 * SetWindowPos (USER32.519)
1686 BOOL32
SetWindowPos32( HWND32 hwnd
, HWND32 hwndInsertAfter
, INT32 x
, INT32 y
,
1687 INT32 cx
, INT32 cy
, WORD flags
)
1689 WINDOWPOS16
*winpos
;
1691 RECT16 newWindowRect
, newClientRect
, oldWindowRect
;
1693 HWND32 tempInsertAfter
= 0;
1697 dprintf_win(stddeb
,"SetWindowPos: hwnd %04x, (%i,%i)-(%i,%i) flags %08x\n",
1698 hwnd
, x
, y
, x
+cx
, y
+cy
, flags
);
1699 /* Check window handle */
1701 if (hwnd
== GetDesktopWindow32()) return FALSE
;
1702 if (!(wndPtr
= WIN_FindWndPtr( hwnd
))) return FALSE
;
1704 if (wndPtr
->dwStyle
& WS_VISIBLE
) flags
&= ~SWP_SHOWWINDOW
;
1707 uFlags
|= SMC_NOPARENTERASE
;
1708 flags
&= ~SWP_HIDEWINDOW
;
1709 if (!(flags
& SWP_SHOWWINDOW
)) flags
|= SWP_NOREDRAW
;
1712 /* Check for windows that may not be resized
1713 FIXME: this should be done only for Windows 3.0 programs
1714 if (flags & (SWP_SHOWWINDOW | SWP_HIDEWINDOW ) )
1715 flags |= SWP_NOSIZE | SWP_NOMOVE;
1717 /* Check dimensions */
1719 if (cx
<= 0) cx
= 1;
1720 if (cy
<= 0) cy
= 1;
1724 if (hwnd
== hwndActive
) flags
|= SWP_NOACTIVATE
; /* Already active */
1725 if ((wndPtr
->rectWindow
.right
- wndPtr
->rectWindow
.left
== cx
) &&
1726 (wndPtr
->rectWindow
.bottom
- wndPtr
->rectWindow
.top
== cy
))
1727 flags
|= SWP_NOSIZE
; /* Already the right size */
1728 if ((wndPtr
->rectWindow
.left
== x
) && (wndPtr
->rectWindow
.top
== y
))
1729 flags
|= SWP_NOMOVE
; /* Already the right position */
1731 /* Check hwndInsertAfter */
1733 if (!(flags
& (SWP_NOZORDER
| SWP_NOACTIVATE
)))
1735 /* Ignore TOPMOST flags when activating a window */
1736 /* _and_ moving it in Z order. */
1737 if ((hwndInsertAfter
== HWND_TOPMOST
) ||
1738 (hwndInsertAfter
== HWND_NOTOPMOST
))
1739 hwndInsertAfter
= HWND_TOP
;
1741 /* TOPMOST not supported yet */
1742 if ((hwndInsertAfter
== HWND_TOPMOST
) ||
1743 (hwndInsertAfter
== HWND_NOTOPMOST
)) hwndInsertAfter
= HWND_TOP
;
1745 /* hwndInsertAfter must be a sibling of the window */
1746 if ((hwndInsertAfter
!= HWND_TOP
) && (hwndInsertAfter
!= HWND_BOTTOM
))
1748 WND
* wnd
= WIN_FindWndPtr(hwndInsertAfter
);
1749 if( wnd
->parent
!= wndPtr
->parent
) return FALSE
;
1750 if( wnd
->next
== wndPtr
) flags
|= SWP_NOZORDER
;
1752 else if (!(wndPtr
->window
))
1753 /* FIXME: the following optimization is no good for "X-ed" windows */
1754 if (hwndInsertAfter
== HWND_TOP
)
1755 flags
|= ( wndPtr
->parent
->child
== wndPtr
)? SWP_NOZORDER
: 0;
1756 else /* HWND_BOTTOM */
1757 flags
|= ( wndPtr
->next
)? 0: SWP_NOZORDER
;
1759 /* Fill the WINDOWPOS structure */
1761 if (!(winpos
= SEGPTR_NEW(WINDOWPOS16
))) return FALSE
;
1762 winpos
->hwnd
= hwnd
;
1763 winpos
->hwndInsertAfter
= hwndInsertAfter
;
1768 winpos
->flags
= flags
;
1770 /* Send WM_WINDOWPOSCHANGING message */
1772 if (!(flags
& SWP_NOSENDCHANGING
))
1773 SendMessage16( hwnd
, WM_WINDOWPOSCHANGING
, 0,
1774 (LPARAM
)SEGPTR_GET(winpos
) );
1776 /* Calculate new position and size */
1778 newWindowRect
= wndPtr
->rectWindow
;
1779 newClientRect
= (wndPtr
->dwStyle
& WS_MINIMIZE
) ? wndPtr
->rectWindow
1780 : wndPtr
->rectClient
;
1782 if (!(winpos
->flags
& SWP_NOSIZE
))
1784 newWindowRect
.right
= newWindowRect
.left
+ winpos
->cx
;
1785 newWindowRect
.bottom
= newWindowRect
.top
+ winpos
->cy
;
1787 if (!(winpos
->flags
& SWP_NOMOVE
))
1789 newWindowRect
.left
= winpos
->x
;
1790 newWindowRect
.top
= winpos
->y
;
1791 newWindowRect
.right
+= winpos
->x
- wndPtr
->rectWindow
.left
;
1792 newWindowRect
.bottom
+= winpos
->y
- wndPtr
->rectWindow
.top
;
1794 OffsetRect16( &newClientRect
, winpos
->x
- wndPtr
->rectWindow
.left
,
1795 winpos
->y
- wndPtr
->rectWindow
.top
);
1798 winpos
->flags
|= SWP_NOCLIENTMOVE
| SWP_NOCLIENTSIZE
;
1800 /* Reposition window in Z order */
1802 if (!(winpos
->flags
& SWP_NOZORDER
))
1804 /* reorder owned popups if hwnd is top-level window
1806 if( wndPtr
->parent
== WIN_GetDesktop() )
1807 hwndInsertAfter
= WINPOS_ReorderOwnedPopups( hwndInsertAfter
,
1812 WIN_UnlinkWindow( winpos
->hwnd
);
1813 WIN_LinkWindow( winpos
->hwnd
, hwndInsertAfter
);
1815 else WINPOS_MoveWindowZOrder( winpos
->hwnd
, hwndInsertAfter
);
1818 if ( !wndPtr
->window
&& !(flags
& SWP_NOREDRAW
) &&
1819 (!(flags
& SWP_NOMOVE
) || !(flags
& SWP_NOSIZE
) || (flags
& SWP_FRAMECHANGED
)) )
1820 visRgn
= DCE_GetVisRgn(hwnd
, DCX_WINDOW
| DCX_CLIPSIBLINGS
);
1823 /* Send WM_NCCALCSIZE message to get new client area */
1824 if( (flags
& (SWP_FRAMECHANGED
| SWP_NOSIZE
)) != SWP_NOSIZE
)
1826 result
= WINPOS_SendNCCalcSize( winpos
->hwnd
, TRUE
, &newWindowRect
,
1827 &wndPtr
->rectWindow
, &wndPtr
->rectClient
,
1828 SEGPTR_GET(winpos
), &newClientRect
);
1830 /* FIXME: WVR_ALIGNxxx */
1832 if( newClientRect
.left
!= wndPtr
->rectClient
.left
||
1833 newClientRect
.top
!= wndPtr
->rectClient
.top
)
1834 winpos
->flags
&= ~SWP_NOCLIENTMOVE
;
1836 if( (newClientRect
.right
- newClientRect
.left
!=
1837 wndPtr
->rectClient
.right
- wndPtr
->rectClient
.left
) ||
1838 (newClientRect
.bottom
- newClientRect
.top
!=
1839 wndPtr
->rectClient
.bottom
- wndPtr
->rectClient
.top
) )
1840 winpos
->flags
&= ~SWP_NOCLIENTSIZE
;
1843 if( !(flags
& SWP_NOMOVE
) && (newClientRect
.left
!= wndPtr
->rectClient
.left
||
1844 newClientRect
.top
!= wndPtr
->rectClient
.top
) )
1845 winpos
->flags
&= ~SWP_NOCLIENTMOVE
;
1847 /* Update active DCEs */
1849 if( !(flags
& SWP_NOZORDER
) || (flags
& SWP_HIDEWINDOW
) || (flags
& SWP_SHOWWINDOW
)
1850 || (memcmp(&newWindowRect
,&wndPtr
->rectWindow
,sizeof(RECT16
))
1851 && wndPtr
->dwStyle
& WS_VISIBLE
) )
1855 UnionRect16(&rect
,&newWindowRect
,&wndPtr
->rectWindow
);
1856 DCE_InvalidateDCE(wndPtr
->parent
, &rect
);
1859 /* change geometry */
1861 oldWindowRect
= wndPtr
->rectWindow
;
1865 RECT16 oldClientRect
= wndPtr
->rectClient
;
1867 tempInsertAfter
= winpos
->hwndInsertAfter
;
1869 winpos
->hwndInsertAfter
= hwndInsertAfter
;
1871 /* postpone geometry change */
1873 if( !(flags
& (SWP_SHOWWINDOW
| SWP_HIDEWINDOW
)) )
1875 WINPOS_SetXWindowPos( winpos
);
1876 winpos
->hwndInsertAfter
= tempInsertAfter
;
1878 else uFlags
|= SMC_SETXPOS
;
1880 wndPtr
->rectWindow
= newWindowRect
;
1881 wndPtr
->rectClient
= newClientRect
;
1883 if( !(flags
& (SWP_SHOWWINDOW
| SWP_HIDEWINDOW
)) )
1884 if( (oldClientRect
.left
- oldWindowRect
.left
!=
1885 newClientRect
.left
- newWindowRect
.left
) ||
1886 (oldClientRect
.top
- oldWindowRect
.top
!=
1887 newClientRect
.top
- newWindowRect
.top
) || winpos
->flags
& SWP_NOCOPYBITS
)
1889 PAINT_RedrawWindow( wndPtr
->hwndSelf
, NULL
, 0, RDW_INVALIDATE
|
1890 RDW_ALLCHILDREN
| RDW_FRAME
| RDW_ERASE
, 0 );
1892 if( winpos
->flags
& SWP_FRAMECHANGED
)
1897 if( oldClientRect
.right
> newClientRect
.right
)
1899 rect
.left
= newClientRect
.right
; rect
.top
= newClientRect
.top
;
1900 rect
.right
= oldClientRect
.right
; rect
.bottom
= newClientRect
.bottom
;
1902 PAINT_RedrawWindow( wndPtr
->hwndSelf
, &rect
, 0,
1903 RDW_INVALIDATE
| RDW_FRAME
| RDW_ALLCHILDREN
, 0 );
1905 if( oldClientRect
.bottom
> newClientRect
.bottom
)
1907 rect
.left
= newClientRect
.left
; rect
.top
= newClientRect
.bottom
;
1908 rect
.right
= (wErase
)?oldClientRect
.right
:newClientRect
.right
;
1909 rect
.bottom
= oldClientRect
.bottom
;
1911 PAINT_RedrawWindow( wndPtr
->hwndSelf
, &rect
, 0,
1912 RDW_INVALIDATE
| RDW_FRAME
| RDW_ALLCHILDREN
, 0 );
1914 if( !wErase
) wndPtr
->flags
|= WIN_NEEDS_NCPAINT
;
1919 RECT16 oldClientRect
= wndPtr
->rectClient
;
1921 wndPtr
->rectWindow
= newWindowRect
;
1922 wndPtr
->rectClient
= newClientRect
;
1924 if( oldClientRect
.bottom
- oldClientRect
.top
==
1925 newClientRect
.bottom
- newClientRect
.top
) result
&= ~WVR_VREDRAW
;
1927 if( oldClientRect
.right
- oldClientRect
.left
==
1928 newClientRect
.right
- newClientRect
.left
) result
&= ~WVR_HREDRAW
;
1930 if( !(flags
& (SWP_NOREDRAW
| SWP_HIDEWINDOW
| SWP_SHOWWINDOW
)) )
1932 uFlags
|= ((winpos
->flags
& SWP_NOCOPYBITS
) ||
1933 (result
>= WVR_HREDRAW
&& result
< WVR_VALIDRECTS
)) ? SMC_NOCOPY
: 0;
1934 uFlags
|= (winpos
->flags
& SWP_FRAMECHANGED
) ? SMC_DRAWFRAME
: 0;
1936 if( (winpos
->flags
& SWP_AGG_NOGEOMETRYCHANGE
) != SWP_AGG_NOGEOMETRYCHANGE
)
1937 uFlags
= WINPOS_SizeMoveClean(wndPtr
, visRgn
, &oldWindowRect
,
1938 &oldClientRect
, uFlags
);
1941 /* adjust frame and do not erase parent */
1943 if( winpos
->flags
& SWP_FRAMECHANGED
) wndPtr
->flags
|= WIN_NEEDS_NCPAINT
;
1944 if( winpos
->flags
& SWP_NOZORDER
) uFlags
|= SMC_NOPARENTERASE
;
1947 DeleteObject32(visRgn
);
1950 if (flags
& SWP_SHOWWINDOW
)
1952 wndPtr
->dwStyle
|= WS_VISIBLE
;
1955 if( uFlags
& SMC_SETXPOS
)
1957 WINPOS_SetXWindowPos( winpos
);
1958 winpos
->hwndInsertAfter
= tempInsertAfter
;
1960 XMapWindow( display
, wndPtr
->window
);
1964 if (!(flags
& SWP_NOREDRAW
))
1965 PAINT_RedrawWindow( winpos
->hwnd
, NULL
, 0,
1966 RDW_INVALIDATE
| RDW_ALLCHILDREN
|
1967 RDW_FRAME
| RDW_ERASENOW
| RDW_ERASE
, 0 );
1970 else if (flags
& SWP_HIDEWINDOW
)
1972 wndPtr
->dwStyle
&= ~WS_VISIBLE
;
1975 XUnmapWindow( display
, wndPtr
->window
);
1976 if( uFlags
& SMC_SETXPOS
)
1978 WINPOS_SetXWindowPos( winpos
);
1979 winpos
->hwndInsertAfter
= tempInsertAfter
;
1984 if (!(flags
& SWP_NOREDRAW
))
1986 RECT32 rect
= { oldWindowRect
.left
, oldWindowRect
.top
,
1987 oldWindowRect
.right
, oldWindowRect
.bottom
};
1988 PAINT_RedrawWindow( wndPtr
->parent
->hwndSelf
, &rect
, 0,
1989 RDW_INVALIDATE
| RDW_ALLCHILDREN
| RDW_ERASE
| RDW_ERASENOW
, 0);
1991 uFlags
|= SMC_NOPARENTERASE
;
1994 if ((winpos
->hwnd
== GetFocus32()) ||
1995 IsChild32( winpos
->hwnd
, GetFocus32()))
1997 /* Revert focus to parent */
1998 SetFocus32( GetParent32(winpos
->hwnd
) );
2000 if (hwnd
== CARET_GetHwnd()) DestroyCaret();
2002 if (winpos
->hwnd
== hwndActive
)
2004 /* Activate previously active window if possible */
2005 HWND32 newActive
= hwndPrevActive
;
2006 if (!IsWindow(newActive
) || (newActive
== winpos
->hwnd
))
2008 newActive
= GetTopWindow32( GetDesktopWindow32() );
2009 if (newActive
== winpos
->hwnd
)
2010 newActive
= wndPtr
->next
? wndPtr
->next
->hwndSelf
: 0;
2012 WINPOS_ChangeActiveWindow( newActive
, FALSE
);
2016 /* Activate the window */
2018 if (!(flags
& SWP_NOACTIVATE
))
2019 WINPOS_ChangeActiveWindow( winpos
->hwnd
, FALSE
);
2021 /* Repaint the window */
2023 if (wndPtr
->window
) EVENT_Synchronize(); /* Wait for all expose events */
2025 EVENT_DummyMotionNotify(); /* Simulate a mouse event to set the cursor */
2027 if (!(flags
& SWP_DEFERERASE
) && !(uFlags
& SMC_NOPARENTERASE
) )
2030 CONV_RECT16TO32( &oldWindowRect
, &rect
);
2031 PAINT_RedrawWindow( wndPtr
->parent
->hwndSelf
, (wndPtr
->flags
& WIN_SAVEUNDER_OVERRIDE
)
2032 ? &rect
: NULL
, 0, RDW_ALLCHILDREN
| RDW_ERASENOW
|
2033 ((wndPtr
->flags
& WIN_SAVEUNDER_OVERRIDE
) ? RDW_INVALIDATE
: 0), 0 );
2034 wndPtr
->flags
&= ~WIN_SAVEUNDER_OVERRIDE
;
2036 else if( wndPtr
->parent
== WIN_GetDesktop() && wndPtr
->parent
->flags
& WIN_NEEDS_ERASEBKGND
)
2037 PAINT_RedrawWindow( wndPtr
->parent
->hwndSelf
, NULL
, 0, RDW_NOCHILDREN
| RDW_ERASENOW
, 0 );
2039 /* And last, send the WM_WINDOWPOSCHANGED message */
2041 dprintf_win(stddeb
,"\tstatus flags = %04x\n", winpos
->flags
& SWP_AGG_STATUSFLAGS
);
2043 if ( ((winpos
->flags
& SWP_AGG_STATUSFLAGS
) != SWP_AGG_NOPOSCHANGE
) &&
2044 !(winpos
->flags
& SWP_NOSENDCHANGING
))
2045 SendMessage16( winpos
->hwnd
, WM_WINDOWPOSCHANGED
,
2046 0, (LPARAM
)SEGPTR_GET(winpos
) );
2048 SEGPTR_FREE(winpos
);
2053 /***********************************************************************
2054 * BeginDeferWindowPos16 (USER.259)
2056 HDWP16
BeginDeferWindowPos16( INT16 count
)
2058 return BeginDeferWindowPos32( count
);
2062 /***********************************************************************
2063 * BeginDeferWindowPos32 (USER32.8)
2065 HDWP32
BeginDeferWindowPos32( INT32 count
)
2070 if (count
<= 0) return 0;
2071 handle
= USER_HEAP_ALLOC( sizeof(DWP
) + (count
-1)*sizeof(WINDOWPOS32
) );
2072 if (!handle
) return 0;
2073 pDWP
= (DWP
*) USER_HEAP_LIN_ADDR( handle
);
2074 pDWP
->actualCount
= 0;
2075 pDWP
->suggestedCount
= count
;
2077 pDWP
->wMagic
= DWP_MAGIC
;
2078 pDWP
->hwndParent
= 0;
2083 /***********************************************************************
2084 * DeferWindowPos16 (USER.260)
2086 HDWP16
DeferWindowPos16( HDWP16 hdwp
, HWND16 hwnd
, HWND16 hwndAfter
,
2087 INT16 x
, INT16 y
, INT16 cx
, INT16 cy
, UINT16 flags
)
2089 return DeferWindowPos32( hdwp
, hwnd
, (INT32
)(INT16
)hwndAfter
,
2090 x
, y
, cx
, cy
, flags
);
2094 /***********************************************************************
2095 * DeferWindowPos32 (USER32.127)
2097 HDWP32
DeferWindowPos32( HDWP32 hdwp
, HWND32 hwnd
, HWND32 hwndAfter
,
2098 INT32 x
, INT32 y
, INT32 cx
, INT32 cy
, UINT32 flags
)
2102 HDWP32 newhdwp
= hdwp
;
2105 pDWP
= (DWP
*) USER_HEAP_LIN_ADDR( hdwp
);
2106 if (!pDWP
) return 0;
2107 if (hwnd
== GetDesktopWindow32()) return 0;
2109 /* All the windows of a DeferWindowPos() must have the same parent */
2111 parent
= WIN_FindWndPtr( hwnd
)->parent
->hwndSelf
;
2112 if (pDWP
->actualCount
== 0) pDWP
->hwndParent
= parent
;
2113 else if (parent
!= pDWP
->hwndParent
)
2115 USER_HEAP_FREE( hdwp
);
2119 for (i
= 0; i
< pDWP
->actualCount
; i
++)
2121 if (pDWP
->winPos
[i
].hwnd
== hwnd
)
2123 /* Merge with the other changes */
2124 if (!(flags
& SWP_NOZORDER
))
2126 pDWP
->winPos
[i
].hwndInsertAfter
= hwndAfter
;
2128 if (!(flags
& SWP_NOMOVE
))
2130 pDWP
->winPos
[i
].x
= x
;
2131 pDWP
->winPos
[i
].y
= y
;
2133 if (!(flags
& SWP_NOSIZE
))
2135 pDWP
->winPos
[i
].cx
= cx
;
2136 pDWP
->winPos
[i
].cy
= cy
;
2138 pDWP
->winPos
[i
].flags
&= flags
& (SWP_NOSIZE
| SWP_NOMOVE
|
2139 SWP_NOZORDER
| SWP_NOREDRAW
|
2140 SWP_NOACTIVATE
| SWP_NOCOPYBITS
|
2142 pDWP
->winPos
[i
].flags
|= flags
& (SWP_SHOWWINDOW
| SWP_HIDEWINDOW
|
2147 if (pDWP
->actualCount
>= pDWP
->suggestedCount
)
2149 newhdwp
= USER_HEAP_REALLOC( hdwp
,
2150 sizeof(DWP
) + pDWP
->suggestedCount
*sizeof(WINDOWPOS32
) );
2151 if (!newhdwp
) return 0;
2152 pDWP
= (DWP
*) USER_HEAP_LIN_ADDR( newhdwp
);
2153 pDWP
->suggestedCount
++;
2155 pDWP
->winPos
[pDWP
->actualCount
].hwnd
= hwnd
;
2156 pDWP
->winPos
[pDWP
->actualCount
].hwndInsertAfter
= hwndAfter
;
2157 pDWP
->winPos
[pDWP
->actualCount
].x
= x
;
2158 pDWP
->winPos
[pDWP
->actualCount
].y
= y
;
2159 pDWP
->winPos
[pDWP
->actualCount
].cx
= cx
;
2160 pDWP
->winPos
[pDWP
->actualCount
].cy
= cy
;
2161 pDWP
->winPos
[pDWP
->actualCount
].flags
= flags
;
2162 pDWP
->actualCount
++;
2167 /***********************************************************************
2168 * EndDeferWindowPos16 (USER.261)
2170 BOOL16
EndDeferWindowPos16( HDWP16 hdwp
)
2172 return EndDeferWindowPos32( hdwp
);
2176 /***********************************************************************
2177 * EndDeferWindowPos32 (USER32.172)
2179 BOOL32
EndDeferWindowPos32( HDWP32 hdwp
)
2182 WINDOWPOS32
*winpos
;
2186 pDWP
= (DWP
*) USER_HEAP_LIN_ADDR( hdwp
);
2187 if (!pDWP
) return FALSE
;
2188 for (i
= 0, winpos
= pDWP
->winPos
; i
< pDWP
->actualCount
; i
++, winpos
++)
2190 if (!(res
= SetWindowPos32( winpos
->hwnd
, winpos
->hwndInsertAfter
,
2191 winpos
->x
, winpos
->y
, winpos
->cx
,
2192 winpos
->cy
, winpos
->flags
))) break;
2194 USER_HEAP_FREE( hdwp
);
2199 /***********************************************************************
2200 * TileChildWindows (USER.199)
2202 void TileChildWindows( HWND16 parent
, WORD action
)
2204 printf("STUB TileChildWindows(%04x, %d)\n", parent
, action
);
2207 /***********************************************************************
2208 * CascageChildWindows (USER.198)
2210 void CascadeChildWindows( HWND16 parent
, WORD action
)
2212 printf("STUB CascadeChildWindows(%04x, %d)\n", parent
, action
);