2 * Window position related functions.
4 * Copyright 1993, 1994, 1995 Alexandre Julliard
5 * 1995,1996 Alex Korobka
8 #include "sysmetrics.h"
16 #include "stackframe.h"
18 #include "nonclient.h"
20 /* #define DEBUG_WIN */
23 /* ----- external functions ----- */
25 void FOCUS_SwitchFocus( HWND
, HWND
);
27 /* ----- internal variables ----- */
29 static HWND hwndActive
= 0; /* Currently active window */
30 static HWND hwndPrevActive
= 0; /* Previously active window */
33 /***********************************************************************
36 * Find a suitable place for an iconic window.
37 * The new position is stored into wndPtr->ptIconPos.
39 void WINPOS_FindIconPos( HWND hwnd
)
42 short x
, y
, xspacing
, yspacing
;
43 WND
* wndPtr
= WIN_FindWndPtr( hwnd
);
45 if (!wndPtr
|| !wndPtr
->parent
) return;
46 GetClientRect( wndPtr
->parent
->hwndSelf
, &rectParent
);
47 if ((wndPtr
->ptIconPos
.x
>= rectParent
.left
) &&
48 (wndPtr
->ptIconPos
.x
+ SYSMETRICS_CXICON
< rectParent
.right
) &&
49 (wndPtr
->ptIconPos
.y
>= rectParent
.top
) &&
50 (wndPtr
->ptIconPos
.y
+ SYSMETRICS_CYICON
< rectParent
.bottom
))
51 return; /* The icon already has a suitable position */
53 xspacing
= yspacing
= 70; /* FIXME: This should come from WIN.INI */
54 y
= rectParent
.bottom
;
57 for (x
= rectParent
.left
; x
<=rectParent
.right
-xspacing
; x
+= xspacing
)
59 /* Check if another icon already occupies this spot */
60 WND
*childPtr
= wndPtr
->parent
->child
;
63 if ((childPtr
->dwStyle
& WS_MINIMIZE
) && (childPtr
!= wndPtr
))
65 if ((childPtr
->rectWindow
.left
< x
+ xspacing
) &&
66 (childPtr
->rectWindow
.right
>= x
) &&
67 (childPtr
->rectWindow
.top
<= y
) &&
68 (childPtr
->rectWindow
.bottom
> y
- yspacing
))
69 break; /* There's a window in there */
71 childPtr
= childPtr
->next
;
75 /* No window was found, so it's OK for us */
76 wndPtr
->ptIconPos
.x
= x
+ (xspacing
- SYSMETRICS_CXICON
) / 2;
77 wndPtr
->ptIconPos
.y
= y
- (yspacing
+ SYSMETRICS_CYICON
) / 2;
86 /***********************************************************************
87 * ArrangeIconicWindows (USER.170)
89 UINT
ArrangeIconicWindows( HWND parent
)
93 INT x
, y
, xspacing
, yspacing
;
95 GetClientRect( parent
, &rectParent
);
97 y
= rectParent
.bottom
;
98 xspacing
= yspacing
= 70; /* FIXME: This should come from WIN.INI */
99 hwndChild
= GetWindow( parent
, GW_CHILD
);
102 if (IsIconic( hwndChild
))
104 SetWindowPos( hwndChild
, 0, x
+ (xspacing
- SYSMETRICS_CXICON
) / 2,
105 y
- (yspacing
+ SYSMETRICS_CYICON
) / 2, 0, 0,
106 SWP_NOSIZE
| SWP_NOZORDER
| SWP_NOACTIVATE
);
107 if (x
<= rectParent
.right
- xspacing
) x
+= xspacing
;
114 hwndChild
= GetWindow( hwndChild
, GW_HWNDNEXT
);
120 /***********************************************************************
121 * GetWindowRect (USER.32)
123 void GetWindowRect( HWND hwnd
, LPRECT rect
)
125 WND
* wndPtr
= WIN_FindWndPtr( hwnd
);
128 *rect
= wndPtr
->rectWindow
;
129 if (wndPtr
->dwStyle
& WS_CHILD
)
130 MapWindowPoints( wndPtr
->parent
->hwndSelf
, 0, (POINT
*)rect
, 2 );
134 /***********************************************************************
135 * GetClientRect (USER.33)
137 void GetClientRect( HWND hwnd
, LPRECT rect
)
139 WND
* wndPtr
= WIN_FindWndPtr( hwnd
);
141 rect
->left
= rect
->top
= rect
->right
= rect
->bottom
= 0;
144 rect
->right
= wndPtr
->rectClient
.right
- wndPtr
->rectClient
.left
;
145 rect
->bottom
= wndPtr
->rectClient
.bottom
- wndPtr
->rectClient
.top
;
150 /*******************************************************************
151 * ClientToScreen (USER.28)
153 BOOL
ClientToScreen( HWND hwnd
, LPPOINT lppnt
)
155 MapWindowPoints( hwnd
, 0, lppnt
, 1 );
160 /*******************************************************************
161 * ScreenToClient (USER.29)
163 void ScreenToClient( HWND hwnd
, LPPOINT lppnt
)
165 MapWindowPoints( 0, hwnd
, lppnt
, 1 );
169 /***********************************************************************
170 * WINPOS_WindowFromPoint
172 * Find the window and hittest for a given point.
174 INT
WINPOS_WindowFromPoint( POINT pt
, WND
**ppWnd
)
177 INT hittest
= HTERROR
;
183 wndPtr
= WIN_GetDesktop()->child
;
188 /* If point is in window, and window is visible, and it */
189 /* is enabled (or it's a top-level window), then explore */
190 /* its children. Otherwise, go to the next window. */
192 if ((wndPtr
->dwStyle
& WS_VISIBLE
) &&
193 (!(wndPtr
->dwStyle
& WS_DISABLED
) ||
194 ((wndPtr
->dwStyle
& (WS_POPUP
| WS_CHILD
)) != WS_CHILD
)) &&
195 (x
>= wndPtr
->rectWindow
.left
) &&
196 (x
< wndPtr
->rectWindow
.right
) &&
197 (y
>= wndPtr
->rectWindow
.top
) &&
198 (y
< wndPtr
->rectWindow
.bottom
))
200 *ppWnd
= wndPtr
; /* Got a suitable window */
202 /* If window is minimized or disabled, return at once */
203 if (wndPtr
->dwStyle
& WS_MINIMIZE
) return HTCAPTION
;
204 if (wndPtr
->dwStyle
& WS_DISABLED
) return HTERROR
;
206 /* If point is not in client area, ignore the children */
207 if ((x
< wndPtr
->rectClient
.left
) ||
208 (x
>= wndPtr
->rectClient
.right
) ||
209 (y
< wndPtr
->rectClient
.top
) ||
210 (y
>= wndPtr
->rectClient
.bottom
)) break;
212 x
-= wndPtr
->rectClient
.left
;
213 y
-= wndPtr
->rectClient
.top
;
214 wndPtr
= wndPtr
->child
;
216 else wndPtr
= wndPtr
->next
;
219 /* If nothing found, return the desktop window */
222 *ppWnd
= WIN_GetDesktop();
226 /* Send the WM_NCHITTEST message (only if to the same task) */
227 if ((*ppWnd
)->hmemTaskQ
!= GetTaskQueue(0)) return HTCLIENT
;
228 hittest
= (INT
)SendMessage( (*ppWnd
)->hwndSelf
, WM_NCHITTEST
, 0,
229 MAKELONG( pt
.x
, pt
.y
) );
230 if (hittest
!= HTTRANSPARENT
) return hittest
; /* Found the window */
232 /* If no children found in last search, make point relative to parent*/
235 x
+= (*ppWnd
)->rectClient
.left
;
236 y
+= (*ppWnd
)->rectClient
.top
;
239 /* Restart the search from the next sibling */
240 wndPtr
= (*ppWnd
)->next
;
241 *ppWnd
= (*ppWnd
)->parent
;
246 /*******************************************************************
247 * WindowFromPoint (USER.30)
249 HWND
WindowFromPoint( POINT pt
)
252 WINPOS_WindowFromPoint( pt
, &pWnd
);
253 return pWnd
->hwndSelf
;
257 /*******************************************************************
258 * ChildWindowFromPoint (USER.191)
260 HWND
ChildWindowFromPoint( HWND hwndParent
, POINT pt
)
262 /* pt is in the client coordinates */
264 WND
* wnd
= WIN_FindWndPtr(hwndParent
);
269 /* get client rect fast */
270 rect
.top
= rect
.left
= 0;
271 rect
.right
= wnd
->rectClient
.right
- wnd
->rectClient
.left
;
272 rect
.bottom
= wnd
->rectClient
.bottom
- wnd
->rectClient
.top
;
274 if (!PtInRect( &rect
, pt
)) return 0;
279 if (PtInRect( &wnd
->rectWindow
, pt
)) return wnd
->hwndSelf
;
285 /*******************************************************************
286 * MapWindowPoints (USER.258)
288 void MapWindowPoints( HWND hwndFrom
, HWND hwndTo
, LPPOINT lppt
, WORD count
)
292 POINT origin
= { 0, 0 };
295 if( hwndFrom
== hwndTo
) return;
297 /* Translate source window origin to screen coords */
300 if (!(wndPtr
= WIN_FindWndPtr( hwndFrom
)))
302 fprintf(stderr
,"MapWindowPoints: bad hwndFrom = %04x\n",hwndFrom
);
305 while (wndPtr
->parent
)
307 origin
.x
+= wndPtr
->rectClient
.left
;
308 origin
.y
+= wndPtr
->rectClient
.top
;
309 wndPtr
= wndPtr
->parent
;
313 /* Translate origin to destination window coords */
316 if (!(wndPtr
= WIN_FindWndPtr( hwndTo
)))
318 fprintf(stderr
,"MapWindowPoints: bad hwndTo = %04x\n", hwndTo
);
321 while (wndPtr
->parent
)
323 origin
.x
-= wndPtr
->rectClient
.left
;
324 origin
.y
-= wndPtr
->rectClient
.top
;
325 wndPtr
= wndPtr
->parent
;
329 /* Translate points */
330 for (i
= 0, curpt
= lppt
; i
< count
; i
++, curpt
++)
332 curpt
->x
+= origin
.x
;
333 curpt
->y
+= origin
.y
;
338 /***********************************************************************
341 BOOL
IsIconic(HWND hWnd
)
343 WND
* wndPtr
= WIN_FindWndPtr(hWnd
);
344 if (wndPtr
== NULL
) return FALSE
;
345 return (wndPtr
->dwStyle
& WS_MINIMIZE
) != 0;
349 /***********************************************************************
350 * IsZoomed (USER.272)
352 BOOL
IsZoomed(HWND hWnd
)
354 WND
* wndPtr
= WIN_FindWndPtr(hWnd
);
355 if (wndPtr
== NULL
) return FALSE
;
356 return (wndPtr
->dwStyle
& WS_MAXIMIZE
) != 0;
360 /*******************************************************************
361 * GetActiveWindow (USER.60)
363 HWND
GetActiveWindow()
369 /*******************************************************************
370 * SetActiveWindow (USER.59)
372 HWND
SetActiveWindow( HWND hwnd
)
374 HWND prev
= hwndActive
;
375 WND
*wndPtr
= WIN_FindWndPtr( hwnd
);
377 if (!wndPtr
|| (wndPtr
->dwStyle
& WS_DISABLED
) ||
378 !(wndPtr
->dwStyle
& WS_VISIBLE
)) return 0;
380 WINPOS_SetActiveWindow( hwnd
, 0, 0 );
385 /***********************************************************************
386 * BringWindowToTop (USER.45)
388 BOOL
BringWindowToTop( HWND hwnd
)
390 return SetWindowPos( hwnd
, HWND_TOP
, 0, 0, 0, 0, SWP_NOMOVE
| SWP_NOSIZE
);
394 /***********************************************************************
395 * MoveWindow (USER.56)
397 BOOL
MoveWindow( HWND hwnd
, short x
, short y
, short cx
, short cy
, BOOL repaint
)
399 int flags
= SWP_NOZORDER
| SWP_NOACTIVATE
;
400 if (!repaint
) flags
|= SWP_NOREDRAW
;
401 dprintf_win(stddeb
, "MoveWindow: %04x %d,%d %dx%d %d\n",
402 hwnd
, x
, y
, cx
, cy
, repaint
);
403 return SetWindowPos( hwnd
, 0, x
, y
, cx
, cy
, flags
);
407 /***********************************************************************
408 * ShowWindow (USER.42)
410 BOOL
ShowWindow( HWND hwnd
, int cmd
)
412 WND
* wndPtr
= WIN_FindWndPtr( hwnd
);
416 short x
= 0, y
= 0, cx
= 0, cy
= 0;
418 if (!wndPtr
) return FALSE
;
420 dprintf_win(stddeb
,"ShowWindow: hwnd=%04x, cmd=%d\n", hwnd
, cmd
);
422 wasVisible
= (wndPtr
->dwStyle
& WS_VISIBLE
) != 0;
427 swpflags
|= SWP_HIDEWINDOW
| SWP_NOSIZE
| SWP_NOMOVE
|
428 SWP_NOACTIVATE
| SWP_NOZORDER
;
431 case SW_SHOWMINNOACTIVE
:
432 swpflags
|= SWP_NOACTIVATE
| SWP_NOZORDER
;
434 case SW_SHOWMINIMIZED
:
435 swpflags
|= SWP_SHOWWINDOW
;
438 swpflags
|= SWP_FRAMECHANGED
;
439 if (!(wndPtr
->dwStyle
& WS_MINIMIZE
))
441 if (wndPtr
->dwStyle
& WS_MAXIMIZE
)
443 wndPtr
->flags
|= WIN_RESTORE_MAX
;
444 wndPtr
->dwStyle
&= ~WS_MAXIMIZE
;
448 wndPtr
->flags
&= ~WIN_RESTORE_MAX
;
449 wndPtr
->rectNormal
= wndPtr
->rectWindow
;
451 wndPtr
->dwStyle
|= WS_MINIMIZE
;
452 WINPOS_FindIconPos( hwnd
);
453 x
= wndPtr
->ptIconPos
.x
;
454 y
= wndPtr
->ptIconPos
.y
;
455 cx
= SYSMETRICS_CXICON
;
456 cy
= SYSMETRICS_CYICON
;
458 else swpflags
|= SWP_NOSIZE
| SWP_NOMOVE
;
461 case SW_SHOWMAXIMIZED
: /* same as SW_MAXIMIZE: */
462 swpflags
|= SWP_SHOWWINDOW
| SWP_FRAMECHANGED
;
463 if (!(wndPtr
->dwStyle
& WS_MAXIMIZE
))
465 /* Store the current position and find the maximized size */
466 if (!(wndPtr
->dwStyle
& WS_MINIMIZE
))
467 wndPtr
->rectNormal
= wndPtr
->rectWindow
;
469 NC_GetMinMaxInfo( hwnd
, &maxSize
,
470 &wndPtr
->ptMaxPos
, NULL
, NULL
);
471 x
= wndPtr
->ptMaxPos
.x
;
472 y
= wndPtr
->ptMaxPos
.y
;
474 if( wndPtr
->dwStyle
& WS_MINIMIZE
)
475 if( !SendMessage( hwnd
, WM_QUERYOPEN
, 0, 0L ) )
477 swpflags
|= SWP_NOSIZE
;
483 wndPtr
->dwStyle
&= ~WS_MINIMIZE
;
484 wndPtr
->dwStyle
|= WS_MAXIMIZE
;
486 else swpflags
|= SWP_NOSIZE
| SWP_NOMOVE
;
490 swpflags
|= SWP_NOACTIVATE
| SWP_NOZORDER
;
493 swpflags
|= SWP_SHOWWINDOW
| SWP_NOSIZE
| SWP_NOMOVE
;
496 case SW_SHOWNOACTIVATE
:
497 swpflags
|= SWP_NOZORDER
;
498 if (GetActiveWindow()) swpflags
|= SWP_NOACTIVATE
;
500 case SW_SHOWNORMAL
: /* same as SW_NORMAL: */
501 case SW_SHOWDEFAULT
: /* FIXME: should have its own handler */
503 swpflags
|= SWP_SHOWWINDOW
| SWP_FRAMECHANGED
;
505 if (wndPtr
->dwStyle
& WS_MINIMIZE
)
507 if( !SendMessage( hwnd
, WM_QUERYOPEN
, 0, 0L) )
509 swpflags
|= SWP_NOSIZE
;
512 wndPtr
->ptIconPos
.x
= wndPtr
->rectWindow
.left
;
513 wndPtr
->ptIconPos
.y
= wndPtr
->rectWindow
.top
;
514 wndPtr
->dwStyle
&= ~WS_MINIMIZE
;
515 if (wndPtr
->flags
& WIN_RESTORE_MAX
)
517 /* Restore to maximized position */
518 NC_GetMinMaxInfo( hwnd
, &maxSize
, &wndPtr
->ptMaxPos
,
520 x
= wndPtr
->ptMaxPos
.x
;
521 y
= wndPtr
->ptMaxPos
.y
;
524 wndPtr
->dwStyle
|= WS_MAXIMIZE
;
526 else /* Restore to normal position */
528 x
= wndPtr
->rectNormal
.left
;
529 y
= wndPtr
->rectNormal
.top
;
530 cx
= wndPtr
->rectNormal
.right
- wndPtr
->rectNormal
.left
;
531 cy
= wndPtr
->rectNormal
.bottom
- wndPtr
->rectNormal
.top
;
534 else if (wndPtr
->dwStyle
& WS_MAXIMIZE
)
536 wndPtr
->ptMaxPos
.x
= wndPtr
->rectWindow
.left
;
537 wndPtr
->ptMaxPos
.y
= wndPtr
->rectWindow
.top
;
538 wndPtr
->dwStyle
&= ~WS_MAXIMIZE
;
539 x
= wndPtr
->rectNormal
.left
;
540 y
= wndPtr
->rectNormal
.top
;
541 cx
= wndPtr
->rectNormal
.right
- wndPtr
->rectNormal
.left
;
542 cy
= wndPtr
->rectNormal
.bottom
- wndPtr
->rectNormal
.top
;
544 else swpflags
|= SWP_NOSIZE
| SWP_NOMOVE
;
548 SendMessage( hwnd
, WM_SHOWWINDOW
, (cmd
!= SW_HIDE
), 0 );
549 SetWindowPos( hwnd
, HWND_TOP
, x
, y
, cx
, cy
, swpflags
);
551 /* Send WM_SIZE and WM_MOVE messages if not already done */
552 if (!(wndPtr
->flags
& WIN_GOT_SIZEMSG
))
554 int wParam
= SIZE_RESTORED
;
555 if (wndPtr
->dwStyle
& WS_MAXIMIZE
) wParam
= SIZE_MAXIMIZED
;
556 else if (wndPtr
->dwStyle
& WS_MINIMIZE
) wParam
= SIZE_MINIMIZED
;
557 wndPtr
->flags
|= WIN_GOT_SIZEMSG
;
558 SendMessage( hwnd
, WM_SIZE
, wParam
,
559 MAKELONG(wndPtr
->rectClient
.right
-wndPtr
->rectClient
.left
,
560 wndPtr
->rectClient
.bottom
-wndPtr
->rectClient
.top
));
561 SendMessage( hwnd
, WM_MOVE
, 0,
562 MAKELONG(wndPtr
->rectClient
.left
, wndPtr
->rectClient
.top
) );
569 /***********************************************************************
570 * GetInternalWindowPos (USER.460)
572 WORD
GetInternalWindowPos( HWND hwnd
, LPRECT rectWnd
, LPPOINT ptIcon
)
574 WINDOWPLACEMENT wndpl
;
575 if (!GetWindowPlacement( hwnd
, &wndpl
)) return 0;
576 if (rectWnd
) *rectWnd
= wndpl
.rcNormalPosition
;
577 if (ptIcon
) *ptIcon
= wndpl
.ptMinPosition
;
578 return wndpl
.showCmd
;
582 /***********************************************************************
583 * SetInternalWindowPos (USER.461)
585 void SetInternalWindowPos( HWND hwnd
, WORD showCmd
, LPRECT rect
, LPPOINT pt
)
587 WINDOWPLACEMENT wndpl
;
588 WND
*wndPtr
= WIN_FindWndPtr( hwnd
);
590 wndpl
.length
= sizeof(wndpl
);
591 wndpl
.flags
= (pt
!= NULL
) ? WPF_SETMINPOSITION
: 0;
592 wndpl
.showCmd
= showCmd
;
593 if (pt
) wndpl
.ptMinPosition
= *pt
;
594 wndpl
.rcNormalPosition
= (rect
!= NULL
) ? *rect
: wndPtr
->rectNormal
;
595 wndpl
.ptMaxPosition
= wndPtr
->ptMaxPos
;
596 SetWindowPlacement( hwnd
, &wndpl
);
600 /***********************************************************************
601 * GetWindowPlacement (USER.370)
603 BOOL
GetWindowPlacement( HWND hwnd
, WINDOWPLACEMENT
*wndpl
)
605 WND
*wndPtr
= WIN_FindWndPtr( hwnd
);
606 if (!wndPtr
) return FALSE
;
608 wndpl
->length
= sizeof(*wndpl
);
610 wndpl
->showCmd
= IsZoomed(hwnd
) ? SW_SHOWMAXIMIZED
:
611 (IsIconic(hwnd
) ? SW_SHOWMINIMIZED
: SW_SHOWNORMAL
);
612 wndpl
->ptMinPosition
= wndPtr
->ptIconPos
;
613 wndpl
->ptMaxPosition
= wndPtr
->ptMaxPos
;
614 wndpl
->rcNormalPosition
= wndPtr
->rectNormal
;
619 /***********************************************************************
620 * SetWindowPlacement (USER.371)
622 BOOL
SetWindowPlacement( HWND hwnd
, WINDOWPLACEMENT
*wndpl
)
624 WND
*wndPtr
= WIN_FindWndPtr( hwnd
);
625 if (!wndPtr
) return FALSE
;
627 if (wndpl
->flags
& WPF_SETMINPOSITION
)
628 wndPtr
->ptIconPos
= wndpl
->ptMinPosition
;
629 if ((wndpl
->flags
& WPF_RESTORETOMAXIMIZED
) &&
630 (wndpl
->showCmd
== SW_SHOWMINIMIZED
)) wndPtr
->flags
|= WIN_RESTORE_MAX
;
631 wndPtr
->ptMaxPos
= wndpl
->ptMaxPosition
;
632 wndPtr
->rectNormal
= wndpl
->rcNormalPosition
;
633 ShowWindow( hwnd
, wndpl
->showCmd
);
637 /*******************************************************************
638 * ACTIVATEAPP_callback
640 BOOL
ACTIVATEAPP_callback(HWND hWnd
, LPARAM lParam
)
642 ACTIVATESTRUCT
*lpActStruct
= (ACTIVATESTRUCT
*)lParam
;
644 if (GetWindowTask(hWnd
) != lpActStruct
->hTaskSendTo
) return 1;
646 SendMessage( hWnd
, WM_ACTIVATEAPP
, lpActStruct
->wFlag
,
647 (LPARAM
)((lpActStruct
->hWindowTask
)?lpActStruct
->hWindowTask
:0));
652 /*******************************************************************
653 * WINPOS_SetActiveWindow
655 * back-end to SetActiveWindow
657 BOOL
WINPOS_SetActiveWindow( HWND hWnd
, BOOL fMouse
, BOOL fChangeFocus
)
659 WND
*wndPtr
= WIN_FindWndPtr(hWnd
);
660 WND
*wndTemp
= WIN_FindWndPtr(hwndActive
);
661 CBTACTIVATESTRUCT cbtStruct
= { fMouse
, hwndActive
};
662 FARPROC enumCallback
= MODULE_GetWndProcEntry16("ActivateAppProc");
663 ACTIVATESTRUCT actStruct
;
664 WORD wIconized
=0,wRet
= 0;
666 /* FIXME: When proper support for cooperative multitasking is in place
667 * hActiveQ will be global
672 /* paranoid checks */
673 if( !hWnd
|| hWnd
== GetDesktopWindow() || hWnd
== hwndActive
)
676 if( GetTaskQueue(0) != wndPtr
->hmemTaskQ
)
680 wIconized
= HIWORD(wndTemp
->dwStyle
& WS_MINIMIZE
);
682 dprintf_win(stddeb
,"WINPOS_ActivateWindow: no current active window.\n");
684 /* call CBT hook chain */
685 wRet
= HOOK_CallHooks(WH_CBT
, HCBT_ACTIVATE
, (WPARAM
)hWnd
,
686 (LPARAM
)MAKE_SEGPTR(&cbtStruct
));
688 if( wRet
) return wRet
;
690 /* set prev active wnd to current active wnd and send notification */
691 if( (hwndPrevActive
= hwndActive
) )
693 /* FIXME: need a Win32 translation for WINELIB32 */
694 if( !SendMessage(hwndPrevActive
, WM_NCACTIVATE
, 0, MAKELONG(hWnd
,wIconized
)) )
696 if (GetSysModalWindow() != hWnd
) return 0;
697 /* disregard refusal if hWnd is sysmodal */
701 SendMessage( hwndActive
, WM_ACTIVATE
,
702 MAKEWPARAM( WA_INACTIVE
, wIconized
),
705 SendMessage(hwndPrevActive
, WM_ACTIVATE
, WA_INACTIVE
,
706 MAKELONG(hWnd
,wIconized
));
709 /* check if something happened during message processing */
710 if( hwndPrevActive
!= hwndActive
) return 0;
716 /* send palette messages */
717 if( SendMessage( hWnd
, WM_QUERYNEWPALETTE
, 0, 0L) )
718 SendMessage((HWND
)-1, WM_PALETTEISCHANGING
, (WPARAM
)hWnd
, 0L );
720 /* if prev wnd is minimized redraw icon title
723 wndTemp = WIN_FindWndPtr( WIN_GetTopParent( hwndPrevActive ) );
725 if(wndTemp->dwStyle & WS_MINIMIZE)
726 RedrawIconTitle(hwndPrevActive);
729 if (!(wndPtr
->dwStyle
& WS_CHILD
))
731 /* check Z-order and bring hWnd to the top */
732 for (wndTemp
= WIN_GetDesktop()->child
; wndTemp
; wndTemp
= wndTemp
->next
)
733 if (wndTemp
->dwStyle
& WS_VISIBLE
) break;
735 if( wndTemp
!= wndPtr
)
736 SetWindowPos(hWnd
, HWND_TOP
, 0,0,0,0,
737 SWP_NOSIZE
| SWP_NOMOVE
| SWP_NOACTIVATE
);
740 if( !IsWindow(hWnd
) ) return 0;
744 wndTemp
= WIN_FindWndPtr( hwndPrevActive
);
745 if (wndTemp
) hActiveQ
= wndTemp
->hmemTaskQ
;
748 /* send WM_ACTIVATEAPP if necessary */
749 if (hActiveQ
!= wndPtr
->hmemTaskQ
)
751 HTASK hT
= QUEUE_GetQueueTask( hActiveQ
);
753 actStruct
.wFlag
= 0; /* deactivate */
754 actStruct
.hWindowTask
= QUEUE_GetQueueTask(wndPtr
->hmemTaskQ
);
755 actStruct
.hTaskSendTo
= hT
;
757 /* send WM_ACTIVATEAPP to top-level windows
758 * that belong to the actStruct.hTaskSendTo task
760 EnumWindows( enumCallback
, (LPARAM
)&actStruct
);
762 actStruct
.wFlag
= 1; /* activate */
763 actStruct
.hWindowTask
= hT
;
764 actStruct
.hTaskSendTo
= QUEUE_GetQueueTask( wndPtr
->hmemTaskQ
);
766 EnumWindows( enumCallback
, (LPARAM
)&actStruct
);
768 if( !IsWindow(hWnd
) ) return 0;
771 /* walk up to the first unowned window */
773 while (wndTemp
->owner
) wndTemp
= wndTemp
->owner
;
774 /* and set last active owned popup */
775 wndTemp
->hwndLastActive
= hWnd
;
777 wIconized
= HIWORD(wndTemp
->dwStyle
& WS_MINIMIZE
);
778 /* FIXME: Needs a Win32 translation for WINELIB32 */
779 SendMessage( hWnd
, WM_NCACTIVATE
, 1,
780 MAKELONG(hwndPrevActive
,wIconized
));
782 SendMessage( hWnd
, WM_ACTIVATE
,
783 MAKEWPARAM( (fMouse
)?WA_CLICKACTIVE
:WA_ACTIVE
, wIconized
),
784 (LPARAM
)hwndPrevActive
);
786 SendMessage( hWnd
, WM_ACTIVATE
, (fMouse
)? WA_CLICKACTIVE
: WA_ACTIVE
,
787 MAKELONG(hwndPrevActive
,wIconized
));
790 if( !IsWindow(hWnd
) ) return 0;
792 /* change focus if possible */
793 if( fChangeFocus
&& GetFocus() )
794 if( WIN_GetTopParent(GetFocus()) != hwndActive
)
795 FOCUS_SwitchFocus( GetFocus(),
796 (wndPtr
->dwStyle
& WS_MINIMIZE
)? 0: hwndActive
);
798 /* if active wnd is minimized redraw icon title
801 wndPtr = WIN_FindWndPtr(hwndActive);
802 if(wndPtr->dwStyle & WS_MINIMIZE)
803 RedrawIconTitle(hwndActive);
806 return (hWnd
== hwndActive
);
810 /*******************************************************************
811 * WINPOS_ChangeActiveWindow
814 BOOL
WINPOS_ChangeActiveWindow( HWND hWnd
, BOOL mouseMsg
)
816 WND
*wndPtr
= WIN_FindWndPtr(hWnd
);
818 if( !wndPtr
) return FALSE
;
820 /* child windows get WM_CHILDACTIVATE message */
821 if( (wndPtr
->dwStyle
& WS_CHILD
) && !( wndPtr
->dwStyle
& WS_POPUP
))
822 return SendMessage(hWnd
, WM_CHILDACTIVATE
, 0, 0L);
824 /* owned popups imply owner activation */
825 if( wndPtr
->dwStyle
& WS_POPUP
&& wndPtr
->owner
)
827 wndPtr
= wndPtr
->owner
;
828 if( !wndPtr
) return FALSE
;
829 hWnd
= wndPtr
->hwndSelf
;
832 if( hWnd
== hwndActive
) return FALSE
;
834 if( !WINPOS_SetActiveWindow(hWnd
,mouseMsg
,TRUE
) )
837 /* switch desktop queue to current active */
838 if( wndPtr
->parent
== WIN_GetDesktop())
839 WIN_GetDesktop()->hmemTaskQ
= wndPtr
->hmemTaskQ
;
845 /***********************************************************************
846 * WINPOS_SendNCCalcSize
848 * Send a WM_NCCALCSIZE message to a window.
849 * All parameters are read-only except newClientRect.
850 * oldWindowRect, oldClientRect and winpos must be non-NULL only
851 * when calcValidRect is TRUE.
853 LONG
WINPOS_SendNCCalcSize( HWND hwnd
, BOOL calcValidRect
, RECT
*newWindowRect
,
854 RECT
*oldWindowRect
, RECT
*oldClientRect
,
855 WINDOWPOS
*winpos
, RECT
*newClientRect
)
857 NCCALCSIZE_PARAMS params
;
860 params
.rgrc
[0] = *newWindowRect
;
863 params
.rgrc
[1] = *oldWindowRect
;
864 params
.rgrc
[2] = *oldClientRect
;
865 params
.lppos
= winpos
;
867 result
= SendMessage( hwnd
, WM_NCCALCSIZE
, calcValidRect
,
868 (LPARAM
)MAKE_SEGPTR( ¶ms
) );
869 dprintf_win(stddeb
, "WINPOS_SendNCCalcSize: %d %d %d %d\n",
870 (int)params
.rgrc
[0].top
, (int)params
.rgrc
[0].left
,
871 (int)params
.rgrc
[0].bottom
, (int)params
.rgrc
[0].right
);
872 *newClientRect
= params
.rgrc
[0];
877 /***********************************************************************
878 * WINPOS_HandleWindowPosChanging
880 * Default handling for a WM_WINDOWPOSCHANGING. Called from DefWindowProc().
882 LONG
WINPOS_HandleWindowPosChanging( WINDOWPOS
*winpos
)
885 WND
*wndPtr
= WIN_FindWndPtr( winpos
->hwnd
);
886 if (!wndPtr
|| (winpos
->flags
& SWP_NOSIZE
)) return 0;
887 if ((wndPtr
->dwStyle
& WS_THICKFRAME
) ||
888 ((wndPtr
->dwStyle
& (WS_POPUP
| WS_CHILD
)) == 0))
890 NC_GetMinMaxInfo( winpos
->hwnd
, &maxSize
, NULL
, NULL
, NULL
);
891 winpos
->cx
= MIN( winpos
->cx
, maxSize
.x
);
892 winpos
->cy
= MIN( winpos
->cy
, maxSize
.y
);
898 /***********************************************************************
899 * WINPOS_MoveWindowZOrder
901 * Move a window in Z order, invalidating everything that needs it.
902 * Only necessary for windows without associated X window.
904 static void WINPOS_MoveWindowZOrder( HWND hwnd
, HWND hwndAfter
)
907 WND
*pWndAfter
, *pWndCur
, *wndPtr
= WIN_FindWndPtr( hwnd
);
909 /* We have two possible cases:
910 * - The window is moving up: we have to invalidate all areas
911 * of the window that were covered by other windows
912 * - The window is moving down: we have to invalidate areas
913 * of other windows covered by this one.
916 if (hwndAfter
== HWND_TOP
)
920 else if (hwndAfter
== HWND_BOTTOM
)
922 if (!wndPtr
->next
) return; /* Already at the bottom */
927 if (!(pWndAfter
= WIN_FindWndPtr( hwndAfter
))) return;
928 if (wndPtr
->next
== pWndAfter
) return; /* Already placed right */
930 /* Determine which window we encounter first in Z-order */
931 pWndCur
= wndPtr
->parent
->child
;
932 while ((pWndCur
!= wndPtr
) && (pWndCur
!= pWndAfter
))
933 pWndCur
= pWndCur
->next
;
934 movingUp
= (pWndCur
== pWndAfter
);
939 WND
*pWndPrevAfter
= wndPtr
->next
;
940 WIN_UnlinkWindow( hwnd
);
941 WIN_LinkWindow( hwnd
, hwndAfter
);
942 pWndCur
= wndPtr
->next
;
943 while (pWndCur
!= pWndPrevAfter
)
945 RECT rect
= pWndCur
->rectWindow
;
946 OffsetRect( &rect
, -wndPtr
->rectClient
.left
,
947 -wndPtr
->rectClient
.top
);
948 RedrawWindow( hwnd
, &rect
, 0, RDW_INVALIDATE
| RDW_ALLCHILDREN
|
949 RDW_FRAME
| RDW_ERASE
);
950 pWndCur
= pWndCur
->next
;
953 else /* Moving down */
955 pWndCur
= wndPtr
->next
;
956 WIN_UnlinkWindow( hwnd
);
957 WIN_LinkWindow( hwnd
, hwndAfter
);
958 while (pWndCur
!= wndPtr
)
960 RECT rect
= wndPtr
->rectWindow
;
961 OffsetRect( &rect
, -pWndCur
->rectClient
.left
,
962 -pWndCur
->rectClient
.top
);
963 RedrawWindow( pWndCur
->hwndSelf
, &rect
, 0, RDW_INVALIDATE
|
964 RDW_ALLCHILDREN
| RDW_FRAME
| RDW_ERASE
);
965 pWndCur
= pWndCur
->next
;
970 /***********************************************************************
971 * WINPOS_ReorderOwnedPopups
973 * fix Z order taking into account owned popups -
974 * basically we need to maintain them above owner window
976 HWND
WINPOS_ReorderOwnedPopups(HWND hwndInsertAfter
, WND
* wndPtr
, WORD flags
)
978 WND
* w
= WIN_GetDesktop();
982 /* if we are dealing with owned popup...
984 if( wndPtr
->dwStyle
& WS_POPUP
&& wndPtr
->owner
&& hwndInsertAfter
!= HWND_TOP
)
987 HWND hwndLocalPrev
= HWND_TOP
;
988 HWND hwndNewAfter
= 0;
992 if( !bFound
&& hwndInsertAfter
== hwndLocalPrev
)
993 hwndInsertAfter
= HWND_TOP
;
995 if( w
->dwStyle
& WS_POPUP
&& w
->owner
== wndPtr
->owner
)
999 if( hwndInsertAfter
== HWND_TOP
)
1001 hwndInsertAfter
= hwndLocalPrev
;
1004 hwndNewAfter
= hwndLocalPrev
;
1007 if( w
== wndPtr
->owner
)
1009 /* basically HWND_BOTTOM */
1010 hwndInsertAfter
= hwndLocalPrev
;
1013 hwndInsertAfter
= hwndNewAfter
;
1018 hwndLocalPrev
= w
->hwndSelf
;
1024 /* or overlapped top-level window...
1026 if( !(wndPtr
->dwStyle
& WS_CHILD
) )
1029 if( w
== wndPtr
) break;
1031 if( w
->dwStyle
& WS_POPUP
&& w
->owner
== wndPtr
)
1033 SetWindowPos(w
->hwndSelf
, hwndInsertAfter
, 0, 0, 0, 0, SWP_NOMOVE
| SWP_NOSIZE
|
1034 SWP_NOACTIVATE
| SWP_NOSENDCHANGING
| SWP_DEFERERASE
);
1035 hwndInsertAfter
= w
->hwndSelf
;
1040 return hwndInsertAfter
;
1044 /***********************************************************************
1045 * WINPOS_SetXWindowPos
1047 * SetWindowPos() for an X window. Used by the real SetWindowPos().
1049 static void WINPOS_SetXWindowPos( WINDOWPOS
*winpos
)
1051 XWindowChanges winChanges
;
1053 WND
*wndPtr
= WIN_FindWndPtr( winpos
->hwnd
);
1055 if (!(winpos
->flags
& SWP_NOSIZE
))
1057 winChanges
.width
= winpos
->cx
;
1058 winChanges
.height
= winpos
->cy
;
1059 changeMask
|= CWWidth
| CWHeight
;
1061 if (!(winpos
->flags
& SWP_NOMOVE
))
1063 winChanges
.x
= winpos
->x
;
1064 winChanges
.y
= winpos
->y
;
1065 changeMask
|= CWX
| CWY
;
1067 if (!(winpos
->flags
& SWP_NOZORDER
))
1069 if (winpos
->hwndInsertAfter
== HWND_TOP
) winChanges
.stack_mode
= Above
;
1070 else winChanges
.stack_mode
= Below
;
1071 if ((winpos
->hwndInsertAfter
!= HWND_TOP
) &&
1072 (winpos
->hwndInsertAfter
!= HWND_BOTTOM
))
1074 WND
* insertPtr
= WIN_FindWndPtr( winpos
->hwndInsertAfter
);
1075 winChanges
.sibling
= insertPtr
->window
;
1076 changeMask
|= CWSibling
;
1078 changeMask
|= CWStackMode
;
1081 XConfigureWindow( display
, wndPtr
->window
, changeMask
, &winChanges
);
1085 /***********************************************************************
1086 * SetWindowPos (USER.232)
1088 BOOL
SetWindowPos( HWND hwnd
, HWND hwndInsertAfter
, INT x
, INT y
,
1089 INT cx
, INT cy
, WORD flags
)
1093 RECT newWindowRect
, newClientRect
;
1096 /* Check window handle */
1098 if (hwnd
== GetDesktopWindow()) return FALSE
;
1099 if (!(wndPtr
= WIN_FindWndPtr( hwnd
))) return FALSE
;
1101 /* Check for windows that may not be resized
1102 FIXME: this should be done only for Windows 3.0 programs */
1103 if (flags
==(SWP_SHOWWINDOW
) || flags
==(SWP_HIDEWINDOW
) )
1104 flags
|= SWP_NOSIZE
| SWP_NOMOVE
;
1106 /* Check dimensions */
1108 if (cx
<= 0) cx
= 1;
1109 if (cy
<= 0) cy
= 1;
1113 if (hwnd
== hwndActive
) flags
|= SWP_NOACTIVATE
; /* Already active */
1114 if ((wndPtr
->rectWindow
.right
- wndPtr
->rectWindow
.left
== cx
) &&
1115 (wndPtr
->rectWindow
.bottom
- wndPtr
->rectWindow
.top
== cy
))
1116 flags
|= SWP_NOSIZE
; /* Already the right size */
1117 if ((wndPtr
->rectWindow
.left
== x
) && (wndPtr
->rectWindow
.top
== y
))
1118 flags
|= SWP_NOMOVE
; /* Already the right position */
1120 /* Check hwndInsertAfter */
1122 if (!(flags
& (SWP_NOZORDER
| SWP_NOACTIVATE
)))
1124 /* Ignore TOPMOST flags when activating a window */
1125 /* _and_ moving it in Z order. */
1126 if ((hwndInsertAfter
== HWND_TOPMOST
) ||
1127 (hwndInsertAfter
== HWND_NOTOPMOST
))
1128 hwndInsertAfter
= HWND_TOP
;
1130 /* TOPMOST not supported yet */
1131 if ((hwndInsertAfter
== HWND_TOPMOST
) ||
1132 (hwndInsertAfter
== HWND_NOTOPMOST
)) hwndInsertAfter
= HWND_TOP
;
1133 /* hwndInsertAfter must be a sibling of the window */
1134 if ((hwndInsertAfter
!= HWND_TOP
) && (hwndInsertAfter
!= HWND_BOTTOM
) &&
1135 (wndPtr
->parent
!= WIN_FindWndPtr(hwndInsertAfter
)->parent
))
1138 /* Fill the WINDOWPOS structure */
1141 winpos
.hwndInsertAfter
= hwndInsertAfter
;
1146 winpos
.flags
= flags
;
1148 /* Send WM_WINDOWPOSCHANGING message */
1150 if (!(flags
& SWP_NOSENDCHANGING
))
1151 SendMessage( hwnd
, WM_WINDOWPOSCHANGING
, 0, (LPARAM
)MAKE_SEGPTR(&winpos
) );
1153 /* Calculate new position and size */
1155 newWindowRect
= wndPtr
->rectWindow
;
1156 newClientRect
= wndPtr
->rectClient
;
1158 if (!(winpos
.flags
& SWP_NOSIZE
))
1160 newWindowRect
.right
= newWindowRect
.left
+ winpos
.cx
;
1161 newWindowRect
.bottom
= newWindowRect
.top
+ winpos
.cy
;
1163 if (!(winpos
.flags
& SWP_NOMOVE
))
1165 newWindowRect
.left
= winpos
.x
;
1166 newWindowRect
.top
= winpos
.y
;
1167 newWindowRect
.right
+= winpos
.x
- wndPtr
->rectWindow
.left
;
1168 newWindowRect
.bottom
+= winpos
.y
- wndPtr
->rectWindow
.top
;
1171 /* Reposition window in Z order */
1173 if (!(winpos
.flags
& SWP_NOZORDER
))
1175 /* reorder owned popups if hwnd is top-level window
1177 if( wndPtr
->parent
== WIN_GetDesktop() )
1178 hwndInsertAfter
= WINPOS_ReorderOwnedPopups( hwndInsertAfter
,
1183 WIN_UnlinkWindow( winpos
.hwnd
);
1184 WIN_LinkWindow( winpos
.hwnd
, hwndInsertAfter
);
1186 else WINPOS_MoveWindowZOrder( winpos
.hwnd
, hwndInsertAfter
);
1189 /* Send WM_NCCALCSIZE message to get new client area */
1191 result
= WINPOS_SendNCCalcSize( winpos
.hwnd
, TRUE
, &newWindowRect
,
1192 &wndPtr
->rectWindow
, &wndPtr
->rectClient
,
1193 &winpos
, &newClientRect
);
1194 /* FIXME: Should handle result here */
1196 /* Perform the moving and resizing */
1200 HWND bogusInsertAfter
= winpos
.hwndInsertAfter
;
1202 winpos
.hwndInsertAfter
= hwndInsertAfter
;
1203 WINPOS_SetXWindowPos( &winpos
);
1205 wndPtr
->rectWindow
= newWindowRect
;
1206 wndPtr
->rectClient
= newClientRect
;
1207 winpos
.hwndInsertAfter
= bogusInsertAfter
;
1211 RECT oldWindowRect
= wndPtr
->rectWindow
;
1213 wndPtr
->rectWindow
= newWindowRect
;
1214 wndPtr
->rectClient
= newClientRect
;
1216 if (!(flags
& SWP_NOREDRAW
) &&
1217 (!(flags
& SWP_NOSIZE
) || !(flags
& SWP_NOMOVE
) ||
1218 (!(flags
& SWP_NOZORDER
) && (hwndInsertAfter
!= HWND_TOP
))))
1220 HRGN hrgn1
= CreateRectRgnIndirect( &oldWindowRect
);
1221 HRGN hrgn2
= CreateRectRgnIndirect( &wndPtr
->rectWindow
);
1222 HRGN hrgn3
= CreateRectRgn( 0, 0, 0, 0 );
1223 CombineRgn( hrgn3
, hrgn1
, hrgn2
, RGN_DIFF
);
1224 RedrawWindow( wndPtr
->parent
->hwndSelf
, NULL
, hrgn3
,
1225 RDW_INVALIDATE
| RDW_ALLCHILDREN
| RDW_ERASE
);
1227 /* DCE_GetVisRgn should be called for old coordinates
1228 * and for new, then OffsetRgn and CombineRgn -
1229 * voila, a nice update region to use here - AK.
1231 if ((oldWindowRect
.left
!= wndPtr
->rectWindow
.left
) ||
1232 (oldWindowRect
.top
!= wndPtr
->rectWindow
.top
))
1234 RedrawWindow( winpos
.hwnd
, NULL
, 0, RDW_INVALIDATE
|
1235 RDW_FRAME
| RDW_ALLCHILDREN
| RDW_ERASE
);
1238 if( CombineRgn( hrgn3
, hrgn2
, hrgn1
, RGN_DIFF
) != NULLREGION
)
1239 RedrawWindow( winpos
.hwnd
, NULL
, hrgn3
, RDW_INVALIDATE
|
1240 RDW_FRAME
| RDW_ALLCHILDREN
| RDW_ERASE
);
1242 DeleteObject( hrgn1
);
1243 DeleteObject( hrgn2
);
1244 DeleteObject( hrgn3
);
1248 if (flags
& SWP_SHOWWINDOW
)
1250 wndPtr
->dwStyle
|= WS_VISIBLE
;
1253 XMapWindow( display
, wndPtr
->window
);
1257 if (!(flags
& SWP_NOREDRAW
))
1258 RedrawWindow( winpos
.hwnd
, NULL
, 0,
1259 RDW_INVALIDATE
| RDW_ALLCHILDREN
|
1260 RDW_FRAME
| RDW_ERASE
);
1263 else if (flags
& SWP_HIDEWINDOW
)
1265 wndPtr
->dwStyle
&= ~WS_VISIBLE
;
1268 XUnmapWindow( display
, wndPtr
->window
);
1272 if (!(flags
& SWP_NOREDRAW
))
1273 RedrawWindow( wndPtr
->parent
->hwndSelf
, &wndPtr
->rectWindow
, 0,
1274 RDW_INVALIDATE
| RDW_FRAME
|
1275 RDW_ALLCHILDREN
| RDW_ERASE
);
1278 if ((winpos
.hwnd
== GetFocus()) || IsChild(winpos
.hwnd
, GetFocus()))
1279 SetFocus( GetParent(winpos
.hwnd
) ); /* Revert focus to parent */
1281 if (winpos
.hwnd
== hwndActive
)
1283 /* Activate previously active window if possible */
1284 HWND newActive
= hwndPrevActive
;
1285 if (!IsWindow(newActive
) || (newActive
== winpos
.hwnd
))
1287 newActive
= GetTopWindow( GetDesktopWindow() );
1288 if (newActive
== winpos
.hwnd
)
1289 newActive
= wndPtr
->next
? wndPtr
->next
->hwndSelf
: 0;
1291 WINPOS_ChangeActiveWindow( newActive
, FALSE
);
1295 /* Activate the window */
1297 if (!(flags
& SWP_NOACTIVATE
))
1298 WINPOS_ChangeActiveWindow( winpos
.hwnd
, FALSE
);
1300 /* Repaint the window */
1302 if (wndPtr
->window
) MSG_Synchronize(); /* Wait for all expose events */
1304 EVENT_DummyMotionNotify(); /* Simulate a mouse event to set the cursor */
1306 if ((flags
& SWP_FRAMECHANGED
) && !(flags
& SWP_NOREDRAW
))
1307 RedrawWindow( winpos
.hwnd
, NULL
, 0,
1308 RDW_ALLCHILDREN
| /*FIXME: this should not be necessary*/
1309 RDW_INVALIDATE
| RDW_FRAME
| RDW_ERASE
);
1310 if (!(flags
& SWP_DEFERERASE
))
1311 RedrawWindow( wndPtr
->parent
->hwndSelf
, NULL
, 0,
1312 RDW_ALLCHILDREN
| RDW_ERASENOW
);
1314 /* And last, send the WM_WINDOWPOSCHANGED message */
1316 winpos
.flags
|= SWP_NOMOVE
; /* prevent looping.. window is already moved ??? (FIXME)*/
1318 if (!(winpos
.flags
& SWP_NOSENDCHANGING
))
1319 SendMessage( winpos
.hwnd
, WM_WINDOWPOSCHANGED
,
1320 0, (LPARAM
)MAKE_SEGPTR(&winpos
) );
1326 /***********************************************************************
1327 * BeginDeferWindowPos (USER.259)
1329 HDWP
BeginDeferWindowPos( INT count
)
1334 if (count
<= 0) return 0;
1335 handle
= USER_HEAP_ALLOC( sizeof(DWP
) + (count
-1)*sizeof(WINDOWPOS
) );
1336 if (!handle
) return 0;
1337 pDWP
= (DWP
*) USER_HEAP_LIN_ADDR( handle
);
1338 pDWP
->actualCount
= 0;
1339 pDWP
->suggestedCount
= count
;
1341 pDWP
->wMagic
= DWP_MAGIC
;
1342 pDWP
->hwndParent
= 0;
1347 /***********************************************************************
1348 * DeferWindowPos (USER.260)
1350 HDWP
DeferWindowPos( HDWP hdwp
, HWND hwnd
, HWND hwndAfter
, INT x
, INT y
,
1351 INT cx
, INT cy
, UINT flags
)
1355 HDWP newhdwp
= hdwp
;
1358 pDWP
= (DWP
*) USER_HEAP_LIN_ADDR( hdwp
);
1359 if (!pDWP
) return 0;
1360 if (hwnd
== GetDesktopWindow()) return 0;
1362 /* All the windows of a DeferWindowPos() must have the same parent */
1364 parent
= WIN_FindWndPtr( hwnd
)->parent
->hwndSelf
;
1365 if (pDWP
->actualCount
== 0) pDWP
->hwndParent
= parent
;
1366 else if (parent
!= pDWP
->hwndParent
)
1368 USER_HEAP_FREE( hdwp
);
1372 for (i
= 0; i
< pDWP
->actualCount
; i
++)
1374 if (pDWP
->winPos
[i
].hwnd
== hwnd
)
1376 /* Merge with the other changes */
1377 if (!(flags
& SWP_NOZORDER
))
1379 pDWP
->winPos
[i
].hwndInsertAfter
= hwndAfter
;
1381 if (!(flags
& SWP_NOMOVE
))
1383 pDWP
->winPos
[i
].x
= x
;
1384 pDWP
->winPos
[i
].y
= y
;
1386 if (!(flags
& SWP_NOSIZE
))
1388 pDWP
->winPos
[i
].cx
= cx
;
1389 pDWP
->winPos
[i
].cy
= cy
;
1391 pDWP
->winPos
[i
].flags
&= flags
& (SWP_NOSIZE
| SWP_NOMOVE
|
1392 SWP_NOZORDER
| SWP_NOREDRAW
|
1393 SWP_NOACTIVATE
| SWP_NOCOPYBITS
|
1395 pDWP
->winPos
[i
].flags
|= flags
& (SWP_SHOWWINDOW
| SWP_HIDEWINDOW
|
1400 if (pDWP
->actualCount
>= pDWP
->suggestedCount
)
1402 newhdwp
= USER_HEAP_REALLOC( hdwp
,
1403 sizeof(DWP
) + pDWP
->suggestedCount
*sizeof(WINDOWPOS
) );
1404 if (!newhdwp
) return 0;
1405 pDWP
= (DWP
*) USER_HEAP_LIN_ADDR( newhdwp
);
1406 pDWP
->suggestedCount
++;
1408 pDWP
->winPos
[pDWP
->actualCount
].hwnd
= hwnd
;
1409 pDWP
->winPos
[pDWP
->actualCount
].hwndInsertAfter
= hwndAfter
;
1410 pDWP
->winPos
[pDWP
->actualCount
].x
= x
;
1411 pDWP
->winPos
[pDWP
->actualCount
].y
= y
;
1412 pDWP
->winPos
[pDWP
->actualCount
].cx
= cx
;
1413 pDWP
->winPos
[pDWP
->actualCount
].cy
= cy
;
1414 pDWP
->winPos
[pDWP
->actualCount
].flags
= flags
;
1415 pDWP
->actualCount
++;
1420 /***********************************************************************
1421 * EndDeferWindowPos (USER.261)
1423 BOOL
EndDeferWindowPos( HDWP hdwp
)
1430 pDWP
= (DWP
*) USER_HEAP_LIN_ADDR( hdwp
);
1431 if (!pDWP
) return FALSE
;
1432 for (i
= 0, winpos
= pDWP
->winPos
; i
< pDWP
->actualCount
; i
++, winpos
++)
1434 if (!(res
= SetWindowPos( winpos
->hwnd
, winpos
->hwndInsertAfter
,
1435 winpos
->x
, winpos
->y
, winpos
->cx
, winpos
->cy
,
1436 winpos
->flags
))) break;
1438 USER_HEAP_FREE( hdwp
);
1443 /***********************************************************************
1444 * TileChildWindows (USER.199)
1446 void TileChildWindows( HWND parent
, WORD action
)
1448 printf("STUB TileChildWindows(%04x, %d)\n", parent
, action
);
1451 /***********************************************************************
1452 * CascageChildWindows (USER.198)
1454 void CascadeChildWindows( HWND parent
, WORD action
)
1456 printf("STUB CascadeChildWindows(%04x, %d)\n", parent
, action
);