2 * Window position related functions.
4 * Copyright 1993 Alexandre Julliard
7 static char Copyright
[] = "Copyright Alexandre Julliard, 1993";
9 #include "sysmetrics.h"
15 static HWND hwndActive
= 0; /* Currently active window */
17 /* #define DEBUG_WIN /**/
20 /***********************************************************************
21 * GetWindowRect (USER.32)
23 void GetWindowRect( HWND hwnd
, LPRECT rect
)
25 WND
* wndPtr
= WIN_FindWndPtr( hwnd
);
28 *rect
= wndPtr
->rectWindow
;
29 if (wndPtr
->dwStyle
& WS_CHILD
)
30 MapWindowPoints( wndPtr
->hwndParent
, 0, (POINT
*)rect
, 2 );
34 /***********************************************************************
35 * GetClientRect (USER.33)
37 void GetClientRect( HWND hwnd
, LPRECT rect
)
39 WND
* wndPtr
= WIN_FindWndPtr( hwnd
);
41 rect
->left
= rect
->top
= rect
->right
= rect
->bottom
= 0;
44 rect
->right
= wndPtr
->rectClient
.right
- wndPtr
->rectClient
.left
;
45 rect
->bottom
= wndPtr
->rectClient
.bottom
- wndPtr
->rectClient
.top
;
50 /*******************************************************************
51 * ClientToScreen (USER.28)
53 void ClientToScreen( HWND hwnd
, LPPOINT lppnt
)
55 MapWindowPoints( hwnd
, 0, lppnt
, 1 );
59 /*******************************************************************
60 * ScreenToClient (USER.29)
62 void ScreenToClient( HWND hwnd
, LPPOINT lppnt
)
64 MapWindowPoints( 0, hwnd
, lppnt
, 1 );
68 /*******************************************************************
69 * WindowFromPoint (USER.30)
71 HWND
WindowFromPoint( POINT pt
)
74 HWND hwnd
= GetDesktopWindow();
78 /* If point is in window, and window is visible, */
79 /* not disabled and not transparent, then explore */
80 /* its children. Otherwise, go to the next window. */
82 WND
*wndPtr
= WIN_FindWndPtr( hwnd
);
83 if ((pt
.x
>= wndPtr
->rectWindow
.left
) &&
84 (pt
.x
< wndPtr
->rectWindow
.right
) &&
85 (pt
.y
>= wndPtr
->rectWindow
.top
) &&
86 (pt
.y
< wndPtr
->rectWindow
.bottom
) &&
87 !(wndPtr
->dwStyle
& WS_DISABLED
) &&
88 (wndPtr
->dwStyle
& WS_VISIBLE
) &&
89 !(wndPtr
->dwExStyle
& WS_EX_TRANSPARENT
))
91 pt
.x
-= wndPtr
->rectClient
.left
;
92 pt
.y
-= wndPtr
->rectClient
.top
;
94 hwnd
= wndPtr
->hwndChild
;
96 else hwnd
= wndPtr
->hwndNext
;
102 /*******************************************************************
103 * ChildWindowFromPoint (USER.191)
105 HWND
ChildWindowFromPoint( HWND hwndParent
, POINT pt
)
110 GetWindowRect( hwndParent
, &rect
);
111 if (!PtInRect( &rect
, pt
)) return 0;
112 hwnd
= GetTopWindow( hwndParent
);
115 GetWindowRect( hwnd
, &rect
);
116 if (PtInRect( &rect
, pt
)) return hwnd
;
117 hwnd
= GetWindow( hwnd
, GW_HWNDNEXT
);
123 /*******************************************************************
124 * MapWindowPoints (USER.258)
126 void MapWindowPoints( HWND hwndFrom
, HWND hwndTo
, LPPOINT lppt
, WORD count
)
130 POINT origin
= { 0, 0 };
133 /* Translate source window origin to screen coords */
136 wndPtr
= WIN_FindWndPtr( hwndFrom
);
137 origin
.x
+= wndPtr
->rectClient
.left
;
138 origin
.y
+= wndPtr
->rectClient
.top
;
139 hwndFrom
= (wndPtr
->dwStyle
& WS_CHILD
) ? wndPtr
->hwndParent
: 0;
142 /* Translate origin to destination window coords */
145 wndPtr
= WIN_FindWndPtr( hwndTo
);
146 origin
.x
-= wndPtr
->rectClient
.left
;
147 origin
.y
-= wndPtr
->rectClient
.top
;
148 hwndTo
= (wndPtr
->dwStyle
& WS_CHILD
) ? wndPtr
->hwndParent
: 0;
151 /* Translate points */
152 for (i
= 0, curpt
= lppt
; i
< count
; i
++, curpt
++)
154 curpt
->x
+= origin
.x
;
155 curpt
->y
+= origin
.y
;
160 /***********************************************************************
163 BOOL
IsIconic(HWND hWnd
)
165 WND
* wndPtr
= WIN_FindWndPtr(hWnd
);
166 if (wndPtr
== NULL
) return FALSE
;
167 return (wndPtr
->dwStyle
& WS_MINIMIZE
) != 0;
171 /***********************************************************************
172 * IsZoomed (USER.272)
174 BOOL
IsZoomed(HWND hWnd
)
176 WND
* wndPtr
= WIN_FindWndPtr(hWnd
);
177 if (wndPtr
== NULL
) return FALSE
;
178 return (wndPtr
->dwStyle
& WS_MAXIMIZE
) != 0;
182 /*******************************************************************
183 * GetActiveWindow (USER.60)
185 HWND
GetActiveWindow()
190 /*******************************************************************
191 * SetActiveWindow (USER.59)
193 HWND
SetActiveWindow( HWND hwnd
)
195 HWND prev
= hwndActive
;
196 WND
*wndPtr
= WIN_FindWndPtr( hwnd
);
197 if (!wndPtr
|| (wndPtr
->dwStyle
& WS_CHILD
)) return 0;
198 SetWindowPos( hwnd
, HWND_TOP
, 0, 0, 0, 0, SWP_NOMOVE
| SWP_NOSIZE
);
203 /***********************************************************************
204 * BringWindowToTop (USER.45)
206 BOOL
BringWindowToTop( HWND hwnd
)
208 return SetWindowPos( hwnd
, HWND_TOP
, 0, 0, 0, 0, SWP_NOMOVE
| SWP_NOSIZE
);
212 /***********************************************************************
213 * MoveWindow (USER.56)
215 BOOL
MoveWindow( HWND hwnd
, short x
, short y
, short cx
, short cy
, BOOL repaint
)
217 int flags
= SWP_NOZORDER
| SWP_NOACTIVATE
;
218 if (!repaint
) flags
|= SWP_NOREDRAW
;
220 printf( "MoveWindow: %d %d,%d %dx%d %d\n", hwnd
, x
, y
, cx
, cy
, repaint
);
222 return SetWindowPos( hwnd
, 0, x
, y
, cx
, cy
, flags
);
227 * hwnd is the handle to the first child window to hide
229 static void WINPOS_hideChildren(HWND hwnd
)
234 ShowWindow(hwnd
, SW_HIDE
);
235 wndPtr
= WIN_FindWndPtr(hwnd
);
237 WINPOS_hideChildren(wndPtr
->hwndChild
);
238 hwnd
= wndPtr
->hwndNext
;
243 static void WINPOS_ChildrenComeOutToPlay(HWND hwnd
)
249 * we shouldn't really be calling SW_SHOWNOACTIVATE
250 * here because we wake up all windows, even the ones
251 * the user has decided to iconify or hide
253 * have to use SHOWNOACTIVATE instead of SHOWNORMAL
254 * since we are traversing the window tree and don't
255 * want windows linked/unlined under us
257 ShowWindow(hwnd
, SW_SHOWNOACTIVATE
);
258 wndPtr
= WIN_FindWndPtr(hwnd
);
260 WINPOS_ChildrenComeOutToPlay(wndPtr
->hwndChild
);
261 hwnd
= wndPtr
->hwndNext
;
265 /***********************************************************************
266 * ShowWindow (USER.42)
268 BOOL
ShowWindow( HWND hwnd
, int cmd
)
270 WND
* wndPtr
= WIN_FindWndPtr( hwnd
);
275 if (!wndPtr
) return FALSE
;
278 printf("ShowWindow: hwnd=%04X, cmd=%d\n", hwnd
, cmd
);
282 * wasVisible is true if user has not made window invisible
283 * wasIconic is true if the window is not iconified
285 wasVisible
= (wndPtr
->dwStyle
& WS_VISIBLE
) != 0;
291 * if the window wasn't visible to begin with -- just return
294 return FALSE
; /* Nothing to do */
295 swpflags
|= SWP_HIDEWINDOW
| SWP_NOSIZE
| SWP_NOMOVE
|
296 SWP_NOACTIVATE
| SWP_NOZORDER
;
300 case SW_SHOWMINNOACTIVE
:
301 case SW_SHOWMINIMIZED
:
303 wndPtr
->dwStyle
|= WS_MINIMIZE
;
304 swpflags
|= SWP_SHOWWINDOW
| SWP_NOSIZE
| SWP_NOMOVE
|
305 SWP_NOACTIVATE
| SWP_NOZORDER
;
308 * tell children that they are getting hidden
310 WINPOS_hideChildren(wndPtr
->hwndChild
);
312 /* store the size and position of the window, so we can
313 * deiconify it to the same size and position
315 wndPtr
->rectNormal
= wndPtr
->rectWindow
;
316 wndPtr
->ptIconPos
.x
= wndPtr
->rectWindow
.left
;
317 wndPtr
->ptIconPos
.y
= wndPtr
->rectWindow
.top
;
318 /* move the window to icon size and position and
319 * tell it that it is going to have to be painted
321 MoveWindow(hwnd
, wndPtr
->ptIconPos
.x
, wndPtr
->ptIconPos
.y
,
322 wndPtr
->iconWidth
, wndPtr
->iconHeight
, FALSE
);
323 SendMessage(hwnd
, WM_PAINTICON
, 0, 0);
328 case SW_SHOWMAXIMIZED
: /* same as SW_MAXIMIZE: */
330 swpflags
|= SWP_SHOWWINDOW
| SWP_NOSIZE
| SWP_NOMOVE
;
334 case SW_SHOWNORMAL
: /* same as SW_NORMAL: */
335 case SW_SHOWNOACTIVATE
:
337 wasIconic
= IsIconic(hwnd
);
338 wndPtr
->dwStyle
&= ~WS_MINIMIZE
;
339 wndPtr
->dwStyle
&= ~WS_MAXIMIZE
;
340 swpflags
|= SWP_SHOWWINDOW
| SWP_NOSIZE
| SWP_NOMOVE
;
341 if (cmd
== SW_SHOWNOACTIVATE
)
343 swpflags
|= SWP_NOZORDER
;
344 if (GetActiveWindow()) swpflags
|= SWP_NOACTIVATE
;
347 MoveWindow(hwnd
, wndPtr
->rectNormal
.left
,
348 wndPtr
->rectNormal
.top
,
349 wndPtr
->rectNormal
.right
- wndPtr
->rectNormal
.left
,
350 wndPtr
->rectNormal
.bottom
- wndPtr
->rectNormal
.top
,
353 WINPOS_ChildrenComeOutToPlay(wndPtr
->hwndChild
);
357 SendMessage( hwnd
, WM_SHOWWINDOW
, (cmd
!= SW_HIDE
), 0 );
358 SetWindowPos( hwnd
, 0, 0, 0, 0, 0, swpflags
);
360 /* Send WM_SIZE and WM_MOVE messages if not already done */
361 if (!(wndPtr
->flags
& WIN_GOT_SIZEMSG
))
363 int wParam
= SIZE_RESTORED
;
364 if (wndPtr
->dwStyle
& WS_MAXIMIZE
) wParam
= SIZE_MAXIMIZED
;
365 else if (wndPtr
->dwStyle
& WS_MINIMIZE
) wParam
= SIZE_MINIMIZED
;
366 wndPtr
->flags
|= WIN_GOT_SIZEMSG
;
367 SendMessage( hwnd
, WM_SIZE
, wParam
,
368 MAKELONG(wndPtr
->rectClient
.right
-wndPtr
->rectClient
.left
,
369 wndPtr
->rectClient
.bottom
-wndPtr
->rectClient
.top
));
370 SendMessage( hwnd
, WM_MOVE
, 0,
371 MAKELONG(wndPtr
->rectClient
.left
, wndPtr
->rectClient
.top
) );
378 /***********************************************************************
379 * GetInternalWindowPos (USER.460)
381 WORD
GetInternalWindowPos( HWND hwnd
, LPRECT rectWnd
, LPPOINT ptIcon
)
383 WINDOWPLACEMENT wndpl
;
384 if (!GetWindowPlacement( hwnd
, &wndpl
)) return 0;
385 if (rectWnd
) *rectWnd
= wndpl
.rcNormalPosition
;
386 if (ptIcon
) *ptIcon
= wndpl
.ptMinPosition
;
387 return wndpl
.showCmd
;
391 /***********************************************************************
392 * SetInternalWindowPos (USER.461)
394 void SetInternalWindowPos( HWND hwnd
, WORD showCmd
, LPRECT rect
, LPPOINT pt
)
396 WINDOWPLACEMENT wndpl
;
397 WND
*wndPtr
= WIN_FindWndPtr( hwnd
);
399 wndpl
.length
= sizeof(wndpl
);
400 wndpl
.flags
= (pt
!= NULL
) ? WPF_SETMINPOSITION
: 0;
401 wndpl
.showCmd
= showCmd
;
402 if (pt
) wndpl
.ptMinPosition
= *pt
;
403 wndpl
.rcNormalPosition
= (rect
!= NULL
) ? *rect
: wndPtr
->rectNormal
;
404 wndpl
.ptMaxPosition
= wndPtr
->ptMaxPos
;
405 SetWindowPlacement( hwnd
, &wndpl
);
409 /***********************************************************************
410 * GetWindowPlacement (USER.370)
412 BOOL
GetWindowPlacement( HWND hwnd
, WINDOWPLACEMENT
*wndpl
)
414 WND
*wndPtr
= WIN_FindWndPtr( hwnd
);
415 if (!wndPtr
) return FALSE
;
417 wndpl
->length
= sizeof(*wndpl
);
419 wndpl
->showCmd
= IsZoomed(hwnd
) ? SW_SHOWMAXIMIZED
:
420 (IsIconic(hwnd
) ? SW_SHOWMINIMIZED
: SW_SHOWNORMAL
);
421 wndpl
->ptMinPosition
= wndPtr
->ptIconPos
;
422 wndpl
->ptMaxPosition
= wndPtr
->ptMaxPos
;
423 wndpl
->rcNormalPosition
= wndPtr
->rectNormal
;
428 /***********************************************************************
429 * SetWindowPlacement (USER.371)
431 BOOL
SetWindowPlacement( HWND hwnd
, WINDOWPLACEMENT
*wndpl
)
433 WND
*wndPtr
= WIN_FindWndPtr( hwnd
);
434 if (!wndPtr
) return FALSE
;
436 if (wndpl
->flags
& WPF_SETMINPOSITION
)
437 wndPtr
->ptIconPos
= wndpl
->ptMinPosition
;
438 if ((wndpl
->flags
& WPF_RESTORETOMAXIMIZED
) &&
439 (wndpl
->showCmd
== SW_SHOWMINIMIZED
)) wndPtr
->flags
|= WIN_RESTORE_MAX
;
440 wndPtr
->ptMaxPos
= wndpl
->ptMaxPosition
;
441 wndPtr
->rectNormal
= wndpl
->rcNormalPosition
;
442 ShowWindow( hwnd
, wndpl
->showCmd
);
447 /*******************************************************************
448 * WINPOS_GetMinMaxInfo
450 * Send a WM_GETMINMAXINFO to the window.
452 void WINPOS_GetMinMaxInfo( HWND hwnd
, POINT
*maxSize
, POINT
*maxPos
,
453 POINT
*minTrack
, POINT
*maxTrack
)
456 MINMAXINFO MinMax
, *pMinMax
;
457 WND
*wndPtr
= WIN_FindWndPtr( hwnd
);
459 MinMax
.ptMaxSize
.x
= SYSMETRICS_CXSCREEN
;
460 MinMax
.ptMaxSize
.y
= SYSMETRICS_CYSCREEN
;
461 MinMax
.ptMaxPosition
= wndPtr
->ptMaxPos
;
462 MinMax
.ptMinTrackSize
.x
= SYSMETRICS_CXMINTRACK
;
463 MinMax
.ptMinTrackSize
.y
= SYSMETRICS_CYMINTRACK
;
464 MinMax
.ptMaxTrackSize
.x
= SYSMETRICS_CXSCREEN
;
465 MinMax
.ptMaxTrackSize
.y
= SYSMETRICS_CYSCREEN
;
467 minmaxHandle
= USER_HEAP_ALLOC( LMEM_MOVEABLE
, sizeof(MINMAXINFO
) );
470 pMinMax
= (MINMAXINFO
*) USER_HEAP_ADDR( minmaxHandle
);
471 memcpy( pMinMax
, &MinMax
, sizeof(MinMax
) );
472 SendMessage( hwnd
, WM_GETMINMAXINFO
, 0, (LONG
)pMinMax
);
474 else pMinMax
= &MinMax
;
476 /* Some sanity checks */
478 pMinMax
->ptMaxTrackSize
.x
= max( pMinMax
->ptMaxTrackSize
.x
,
479 pMinMax
->ptMinTrackSize
.x
);
480 pMinMax
->ptMaxTrackSize
.y
= max( pMinMax
->ptMaxTrackSize
.y
,
481 pMinMax
->ptMinTrackSize
.y
);
483 if (maxSize
) *maxSize
= pMinMax
->ptMaxSize
;
484 if (maxPos
) *maxPos
= pMinMax
->ptMaxPosition
;
485 if (minTrack
) *minTrack
= pMinMax
->ptMinTrackSize
;
486 if (maxTrack
) *maxTrack
= pMinMax
->ptMaxTrackSize
;
487 if (minmaxHandle
) USER_HEAP_FREE( minmaxHandle
);
491 /*******************************************************************
492 * WINPOS_ChangeActiveWindow
494 * Change the active window and send the corresponding messages.
496 HWND
WINPOS_ChangeActiveWindow( HWND hwnd
, BOOL mouseMsg
)
498 HWND prevActive
= hwndActive
;
499 if (hwnd
== hwndActive
) return 0;
502 if (!SendMessage( hwndActive
, WM_NCACTIVATE
, FALSE
, 0 )) return 0;
503 SendMessage( hwndActive
, WM_ACTIVATE
, WA_INACTIVE
,
504 MAKELONG( IsIconic(hwndActive
), hwnd
) );
505 /* Send WM_ACTIVATEAPP here */
511 WND
*wndPtr
= WIN_FindWndPtr( hwndActive
);
512 wndPtr
->hwndPrevActive
= prevActive
;
514 /* Send WM_ACTIVATEAPP here */
515 SendMessage( hwnd
, WM_NCACTIVATE
, TRUE
, 0 );
516 SendMessage( hwnd
, WM_ACTIVATE
, mouseMsg
? WA_CLICKACTIVE
: WA_ACTIVE
,
517 MAKELONG( IsIconic(hwnd
), prevActive
) );
523 /***********************************************************************
524 * WINPOS_SendNCCalcSize
526 * Send a WM_NCCALCSIZE message to a window.
527 * All parameters are read-only except newClientRect.
528 * oldWindowRect, oldClientRect and winpos must be non-NULL only
529 * when calcValidRect is TRUE.
531 LONG
WINPOS_SendNCCalcSize( HWND hwnd
, BOOL calcValidRect
, RECT
*newWindowRect
,
532 RECT
*oldWindowRect
, RECT
*oldClientRect
,
533 WINDOWPOS
*winpos
, RECT
*newClientRect
)
535 NCCALCSIZE_PARAMS
*params
;
539 if (!(hparams
= USER_HEAP_ALLOC( GMEM_MOVEABLE
, sizeof(*params
) )))
541 params
= (NCCALCSIZE_PARAMS
*) USER_HEAP_ADDR( hparams
);
542 params
->rgrc
[0] = *newWindowRect
;
545 params
->rgrc
[1] = *oldWindowRect
;
546 params
->rgrc
[2] = *oldClientRect
;
547 params
->lppos
= winpos
;
549 result
= SendMessage( hwnd
, WM_NCCALCSIZE
, calcValidRect
, (LONG
)params
);
550 *newClientRect
= params
->rgrc
[0];
551 USER_HEAP_FREE( hparams
);
556 /***********************************************************************
557 * WINPOS_HandleWindowPosChanging
559 * Default handling for a WM_WINDOWPOSCHANGING. Called from DefWindowProc().
561 LONG
WINPOS_HandleWindowPosChanging( WINDOWPOS
*winpos
)
564 WND
*wndPtr
= WIN_FindWndPtr( winpos
->hwnd
);
565 if (!wndPtr
|| (winpos
->flags
& SWP_NOSIZE
)) return 0;
566 if ((wndPtr
->dwStyle
& WS_THICKFRAME
) ||
567 (wndPtr
->dwStyle
& (WS_POPUP
| WS_CHILD
) == 0))
569 WINPOS_GetMinMaxInfo( winpos
->hwnd
, &maxSize
, NULL
, NULL
, NULL
);
570 winpos
->cx
= min( winpos
->cx
, maxSize
.x
);
571 winpos
->cy
= min( winpos
->cy
, maxSize
.y
);
577 /***********************************************************************
578 * WINPOS_InternalSetWindowPos
580 * Helper function for SetWindowPos.
582 static BOOL
WINPOS_InternalSetWindowPos( WINDOWPOS
*winpos
)
586 RECT newWindowRect
, newClientRect
;
589 XWindowChanges winChanges
;
591 /* Send WM_WINDOWPOSCHANGING message */
593 if (!(winpos
->flags
& SWP_NOSENDCHANGING
))
594 SendMessage( winpos
->hwnd
, WM_WINDOWPOSCHANGING
, 0, (LONG
)winpos
);
596 /* Check window handle */
598 if (winpos
->hwnd
== GetDesktopWindow()) return FALSE
;
599 if (!(wndPtr
= WIN_FindWndPtr( winpos
->hwnd
))) return FALSE
;
601 /* Check dimensions */
603 if (winpos
->cx
<= 0) winpos
->cx
= 1;
604 if (winpos
->cy
<= 0) winpos
->cy
= 1;
608 flags
= winpos
->flags
;
609 if (flags
& (SWP_SHOWWINDOW
| SWP_HIDEWINDOW
))
610 flags
|= SWP_NOMOVE
| SWP_NOSIZE
;
611 if (winpos
->hwnd
== hwndActive
) flags
|= SWP_NOACTIVATE
; /*Already active*/
613 /* Check hwndAfter */
615 hwndAfter
= winpos
->hwndInsertAfter
;
616 if (!(flags
& (SWP_NOZORDER
| SWP_NOACTIVATE
)))
618 /* Ignore TOPMOST flags when activating a window */
619 /* _and_ moving it in Z order. */
620 if ((hwndAfter
== HWND_TOPMOST
) || (hwndAfter
== HWND_NOTOPMOST
))
621 hwndAfter
= HWND_TOP
;
623 /* TOPMOST not supported yet */
624 if ((hwndAfter
== HWND_TOPMOST
) || (hwndAfter
== HWND_NOTOPMOST
))
625 hwndAfter
= HWND_TOP
;
626 /* hwndAfter must be a sibling of the window */
627 if ((hwndAfter
!= HWND_TOP
) && (hwndAfter
!= HWND_BOTTOM
) &&
628 (GetParent(winpos
->hwnd
) != GetParent(hwndAfter
))) return FALSE
;
630 /* Calculate new position and size */
632 newWindowRect
= wndPtr
->rectWindow
;
633 newClientRect
= wndPtr
->rectClient
;
635 if (!(flags
& SWP_NOSIZE
))
637 newWindowRect
.right
= newWindowRect
.left
+ winpos
->cx
;
638 newWindowRect
.bottom
= newWindowRect
.top
+ winpos
->cy
;
639 winChanges
.width
= winpos
->cx
;
640 winChanges
.height
= winpos
->cy
;
641 changeMask
|= CWWidth
| CWHeight
;
643 if (!(flags
& SWP_NOMOVE
))
645 newWindowRect
.left
= winpos
->x
;
646 newWindowRect
.top
= winpos
->y
;
647 newWindowRect
.right
+= winpos
->x
- wndPtr
->rectWindow
.left
;
648 newWindowRect
.bottom
+= winpos
->y
- wndPtr
->rectWindow
.top
;
649 if (wndPtr
->dwStyle
& WS_CHILD
)
651 WND
*parentPtr
= WIN_FindWndPtr(wndPtr
->hwndParent
);
652 winChanges
.x
= winpos
->x
+ parentPtr
->rectClient
.left
653 - parentPtr
->rectWindow
.left
;
654 winChanges
.y
= winpos
->y
+ parentPtr
->rectClient
.top
655 - parentPtr
->rectWindow
.top
;
659 winChanges
.x
= winpos
->x
;
660 winChanges
.y
= winpos
->y
;
662 changeMask
|= CWX
| CWY
;
665 /* Reposition window in Z order */
667 if (!(flags
& SWP_NOZORDER
))
669 WIN_UnlinkWindow( winpos
->hwnd
);
670 WIN_LinkWindow( winpos
->hwnd
, hwndAfter
);
671 if (hwndAfter
== HWND_TOP
) winChanges
.stack_mode
= Above
;
672 else winChanges
.stack_mode
= Below
;
673 if ((hwndAfter
!= HWND_TOP
) && (hwndAfter
!= HWND_BOTTOM
))
675 WND
* insertPtr
= WIN_FindWndPtr( hwndAfter
);
676 winChanges
.sibling
= insertPtr
->window
;
677 changeMask
|= CWSibling
;
679 changeMask
|= CWStackMode
;
682 /* Send WM_NCCALCSIZE message to get new client area */
684 result
= WINPOS_SendNCCalcSize( winpos
->hwnd
, TRUE
, &newWindowRect
,
685 &wndPtr
->rectWindow
, &wndPtr
->rectClient
,
686 winpos
, &newClientRect
);
687 /* .... Should handle result here */
689 /* Perform the moving and resizing */
691 if (changeMask
) XConfigureWindow( display
, wndPtr
->window
,
692 changeMask
, &winChanges
);
693 wndPtr
->rectWindow
= newWindowRect
;
694 wndPtr
->rectClient
= newClientRect
;
696 if (flags
& SWP_SHOWWINDOW
)
698 wndPtr
->dwStyle
|= WS_VISIBLE
;
699 XMapWindow( display
, wndPtr
->window
);
701 if (flags
& SWP_NOREDRAW
) /* Validate the whole window */
702 RedrawWindow( winpos
->hwnd
, NULL
, 0, RDW_VALIDATE
);
704 else if (flags
& SWP_HIDEWINDOW
)
706 wndPtr
->dwStyle
&= ~WS_VISIBLE
;
707 XUnmapWindow( display
, wndPtr
->window
);
708 if ((winpos
->hwnd
== GetFocus()) || IsChild(winpos
->hwnd
, GetFocus()))
709 SetFocus( GetParent(winpos
->hwnd
) ); /* Revert focus to parent */
710 if (winpos
->hwnd
== hwndActive
)
712 /* Activate previously active window if possible */
713 HWND newActive
= wndPtr
->hwndPrevActive
;
714 if (!IsWindow(newActive
) || (newActive
== winpos
->hwnd
))
716 newActive
= GetTopWindow(GetDesktopWindow());
717 if (newActive
== winpos
->hwnd
) newActive
= wndPtr
->hwndNext
;
719 WINPOS_ChangeActiveWindow( newActive
, FALSE
);
723 /* Activate the window */
725 if (!(flags
& SWP_NOACTIVATE
))
727 if (!(wndPtr
->dwStyle
& WS_CHILD
))
728 WINPOS_ChangeActiveWindow( winpos
->hwnd
, FALSE
);
731 /* Send WM_NCPAINT message if needed */
733 if (flags
& SWP_SHOWWINDOW
)
735 /* Repaint the window frame and background */
736 RedrawWindow( winpos
->hwnd
, NULL
, 0,
737 RDW_INVALIDATE
| RDW_FRAME
| RDW_ERASENOW
);
741 if ((flags
& SWP_FRAMECHANGED
) ||
742 (!(flags
& SWP_NOSIZE
)) ||
743 (!(flags
& SWP_NOMOVE
)) ||
744 (!(flags
& SWP_NOACTIVATE
)) ||
745 (!(flags
& SWP_NOZORDER
)))
746 SendMessage( winpos
->hwnd
, WM_NCPAINT
, 1, 0L );
749 /* And last, send the WM_WINDOWPOSCHANGED message */
751 SendMessage( winpos
->hwnd
, WM_WINDOWPOSCHANGED
, 0, (LONG
)winpos
);
756 /***********************************************************************
757 * SetWindowPos (USER.232)
759 /* Note: all this code should be in the DeferWindowPos() routines,
760 * and SetWindowPos() should simply call them. This will be implemented
763 BOOL
SetWindowPos( HWND hwnd
, HWND hwndInsertAfter
, short x
, short y
,
764 short cx
, short cy
, WORD flags
)
771 printf( "SetWindowPos: %04X %d %d,%d %dx%d 0x%x\n",
772 hwnd
, hwndInsertAfter
, x
, y
, cx
, cy
, flags
);
775 if (!(hmem
= USER_HEAP_ALLOC( GMEM_MOVEABLE
, sizeof(WINDOWPOS
) )))
777 winPos
= (WINDOWPOS
*)USER_HEAP_ADDR( hmem
);
779 winPos
->hwndInsertAfter
= hwndInsertAfter
;
784 winPos
->flags
= flags
;
786 res
= WINPOS_InternalSetWindowPos( winPos
);
788 USER_HEAP_FREE( hmem
);