wined3d: Add some missing checkGLcall calls.
[wine] / dlls / user32 / winpos.c
1 /*
2  * Window position related functions.
3  *
4  * Copyright 1993, 1994, 1995 Alexandre Julliard
5  *                       1995, 1996, 1999 Alex Korobka
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20  */
21
22 #include "config.h"
23 #include "wine/port.h"
24
25 #include <stdarg.h>
26 #include <string.h>
27 #include "ntstatus.h"
28 #define WIN32_NO_STATUS
29 #include "windef.h"
30 #include "winbase.h"
31 #include "wingdi.h"
32 #include "winerror.h"
33 #include "wine/server.h"
34 #include "controls.h"
35 #include "user_private.h"
36 #include "win.h"
37 #include "wine/debug.h"
38
39 WINE_DEFAULT_DEBUG_CHANNEL(win);
40
41 #define SWP_AGG_NOGEOMETRYCHANGE \
42     (SWP_NOSIZE | SWP_NOCLIENTSIZE | SWP_NOZORDER)
43 #define SWP_AGG_NOPOSCHANGE \
44     (SWP_NOSIZE | SWP_NOMOVE | SWP_NOCLIENTSIZE | SWP_NOCLIENTMOVE | SWP_NOZORDER)
45 #define SWP_AGG_STATUSFLAGS \
46     (SWP_AGG_NOPOSCHANGE | SWP_FRAMECHANGED | SWP_HIDEWINDOW | SWP_SHOWWINDOW)
47
48 #define HAS_DLGFRAME(style,exStyle) \
49     (((exStyle) & WS_EX_DLGMODALFRAME) || \
50      (((style) & WS_DLGFRAME) && !((style) & WS_BORDER)))
51
52 #define HAS_THICKFRAME(style) \
53     (((style) & WS_THICKFRAME) && \
54      !(((style) & (WS_DLGFRAME|WS_BORDER)) == WS_DLGFRAME))
55
56 #define EMPTYPOINT(pt)          ((*(LONG*)&(pt)) == -1)
57
58 #define PLACE_MIN               0x0001
59 #define PLACE_MAX               0x0002
60 #define PLACE_RECT              0x0004
61
62
63 #define DWP_MAGIC  ((INT)('W' | ('P' << 8) | ('O' << 16) | ('S' << 24)))
64
65 typedef struct
66 {
67     INT       actualCount;
68     INT       suggestedCount;
69     BOOL      valid;
70     INT       wMagic;
71     HWND      hwndParent;
72     WINDOWPOS winPos[1];
73 } DWP;
74
75 typedef struct
76 {
77     RECT16   rectNormal;
78     POINT16  ptIconPos;
79     POINT16  ptMaxPos;
80     HWND     hwndIconTitle;
81 } INTERNALPOS, *LPINTERNALPOS;
82
83 /* ----- internal functions ----- */
84
85 static const WCHAR SysIP_W[] = { 'S','y','s','I','P',0 };
86
87 static inline INTERNALPOS *get_internal_pos( HWND hwnd )
88 {
89     return GetPropW( hwnd, SysIP_W );
90 }
91
92 static inline void set_internal_pos( HWND hwnd, INTERNALPOS *pos )
93 {
94     SetPropW( hwnd, SysIP_W, pos );
95 }
96
97 /***********************************************************************
98  *           WINPOS_CheckInternalPos
99  *
100  * Called when a window is destroyed.
101  */
102 void WINPOS_CheckInternalPos( HWND hwnd )
103 {
104     LPINTERNALPOS lpPos = get_internal_pos( hwnd );
105
106     if ( lpPos )
107     {
108         if( IsWindow(lpPos->hwndIconTitle) )
109             DestroyWindow( lpPos->hwndIconTitle );
110         HeapFree( GetProcessHeap(), 0, lpPos );
111     }
112 }
113
114 /***********************************************************************
115  *              ArrangeIconicWindows (USER32.@)
116  */
117 UINT WINAPI ArrangeIconicWindows( HWND parent )
118 {
119     RECT rectParent;
120     HWND hwndChild;
121     INT x, y, xspacing, yspacing;
122
123     GetClientRect( parent, &rectParent );
124     x = rectParent.left;
125     y = rectParent.bottom;
126     xspacing = GetSystemMetrics(SM_CXICONSPACING);
127     yspacing = GetSystemMetrics(SM_CYICONSPACING);
128
129     hwndChild = GetWindow( parent, GW_CHILD );
130     while (hwndChild)
131     {
132         if( IsIconic( hwndChild ) )
133         {
134             WINPOS_ShowIconTitle( hwndChild, FALSE );
135
136             SetWindowPos( hwndChild, 0, x + (xspacing - GetSystemMetrics(SM_CXICON)) / 2,
137                             y - yspacing - GetSystemMetrics(SM_CYICON)/2, 0, 0,
138                             SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE );
139             if( IsWindow(hwndChild) )
140                 WINPOS_ShowIconTitle(hwndChild , TRUE );
141
142             if (x <= rectParent.right - xspacing) x += xspacing;
143             else
144             {
145                 x = rectParent.left;
146                 y -= yspacing;
147             }
148         }
149         hwndChild = GetWindow( hwndChild, GW_HWNDNEXT );
150     }
151     return yspacing;
152 }
153
154
155 /***********************************************************************
156  *              SwitchToThisWindow (USER32.@)
157  */
158 void WINAPI SwitchToThisWindow( HWND hwnd, BOOL restore )
159 {
160     ShowWindow( hwnd, restore ? SW_RESTORE : SW_SHOWMINIMIZED );
161 }
162
163
164 /***********************************************************************
165  *              GetWindowRect (USER32.@)
166  */
167 BOOL WINAPI GetWindowRect( HWND hwnd, LPRECT rect )
168 {
169     BOOL ret = WIN_GetRectangles( hwnd, rect, NULL );
170     if (ret)
171     {
172         MapWindowPoints( GetAncestor( hwnd, GA_PARENT ), 0, (POINT *)rect, 2 );
173         TRACE( "hwnd %p (%d,%d)-(%d,%d)\n",
174                hwnd, rect->left, rect->top, rect->right, rect->bottom);
175     }
176     return ret;
177 }
178
179
180 /***********************************************************************
181  *              GetWindowRgn (USER32.@)
182  */
183 int WINAPI GetWindowRgn ( HWND hwnd, HRGN hrgn )
184 {
185     int nRet = ERROR;
186     NTSTATUS status;
187     HRGN win_rgn = 0;
188     RGNDATA *data;
189     size_t size = 256;
190
191     do
192     {
193         if (!(data = HeapAlloc( GetProcessHeap(), 0, sizeof(*data) + size - 1 )))
194         {
195             SetLastError( ERROR_OUTOFMEMORY );
196             return ERROR;
197         }
198         SERVER_START_REQ( get_window_region )
199         {
200             req->window = hwnd;
201             wine_server_set_reply( req, data->Buffer, size );
202             if (!(status = wine_server_call( req )))
203             {
204                 size_t reply_size = wine_server_reply_size( reply );
205                 if (reply_size)
206                 {
207                     data->rdh.dwSize   = sizeof(data->rdh);
208                     data->rdh.iType    = RDH_RECTANGLES;
209                     data->rdh.nCount   = reply_size / sizeof(RECT);
210                     data->rdh.nRgnSize = reply_size;
211                     win_rgn = ExtCreateRegion( NULL, size, data );
212                 }
213             }
214             else size = reply->total_size;
215         }
216         SERVER_END_REQ;
217         HeapFree( GetProcessHeap(), 0, data );
218     } while (status == STATUS_BUFFER_OVERFLOW);
219
220     if (status) SetLastError( RtlNtStatusToDosError(status) );
221     else if (win_rgn)
222     {
223         nRet = CombineRgn( hrgn, win_rgn, 0, RGN_COPY );
224         DeleteObject( win_rgn );
225     }
226     return nRet;
227 }
228
229
230 /***********************************************************************
231  *              SetWindowRgn (USER32.@)
232  */
233 int WINAPI SetWindowRgn( HWND hwnd, HRGN hrgn, BOOL bRedraw )
234 {
235     static const RECT empty_rect;
236     BOOL ret;
237
238     if (hrgn)
239     {
240         RGNDATA *data;
241         DWORD size;
242
243         if (!(size = GetRegionData( hrgn, 0, NULL ))) return FALSE;
244         if (!(data = HeapAlloc( GetProcessHeap(), 0, size ))) return FALSE;
245         if (!GetRegionData( hrgn, size, data ))
246         {
247             HeapFree( GetProcessHeap(), 0, data );
248             return FALSE;
249         }
250         SERVER_START_REQ( set_window_region )
251         {
252             req->window = hwnd;
253             req->redraw = (bRedraw != 0);
254             if (data->rdh.nCount)
255                 wine_server_add_data( req, data->Buffer, data->rdh.nCount * sizeof(RECT) );
256             else
257                 wine_server_add_data( req, &empty_rect, sizeof(empty_rect) );
258             ret = !wine_server_call_err( req );
259         }
260         SERVER_END_REQ;
261     }
262     else  /* clear existing region */
263     {
264         SERVER_START_REQ( set_window_region )
265         {
266             req->window = hwnd;
267             req->redraw = (bRedraw != 0);
268             ret = !wine_server_call_err( req );
269         }
270         SERVER_END_REQ;
271     }
272
273     if (ret) ret = USER_Driver->pSetWindowRgn( hwnd, hrgn, bRedraw );
274
275     if (ret)
276     {
277         UINT swp_flags = SWP_NOSIZE|SWP_NOMOVE|SWP_NOZORDER|SWP_NOACTIVATE|SWP_FRAMECHANGED;
278         if (hrgn) swp_flags |= SWP_NOCLIENTSIZE|SWP_NOCLIENTMOVE;
279         if (!bRedraw) swp_flags |= SWP_NOREDRAW;
280         SetWindowPos( hwnd, 0, 0, 0, 0, 0, swp_flags );
281     }
282     return ret;
283 }
284
285
286 /***********************************************************************
287  *              GetClientRect (USER32.@)
288  */
289 BOOL WINAPI GetClientRect( HWND hwnd, LPRECT rect )
290 {
291     BOOL ret;
292
293     if ((ret = WIN_GetRectangles( hwnd, NULL, rect )))
294     {
295         rect->right -= rect->left;
296         rect->bottom -= rect->top;
297         rect->left = rect->top = 0;
298     }
299     return ret;
300 }
301
302
303 /*******************************************************************
304  *              ClientToScreen (USER32.@)
305  */
306 BOOL WINAPI ClientToScreen( HWND hwnd, LPPOINT lppnt )
307 {
308     MapWindowPoints( hwnd, 0, lppnt, 1 );
309     return TRUE;
310 }
311
312
313 /*******************************************************************
314  *              ScreenToClient (USER32.@)
315  */
316 BOOL WINAPI ScreenToClient( HWND hwnd, LPPOINT lppnt )
317 {
318     MapWindowPoints( 0, hwnd, lppnt, 1 );
319     return TRUE;
320 }
321
322
323 /***********************************************************************
324  *           list_children_from_point
325  *
326  * Get the list of children that can contain point from the server.
327  * Point is in screen coordinates.
328  * Returned list must be freed by caller.
329  */
330 static HWND *list_children_from_point( HWND hwnd, POINT pt )
331 {
332     HWND *list;
333     int size = 32;
334
335     for (;;)
336     {
337         int count = 0;
338
339         if (!(list = HeapAlloc( GetProcessHeap(), 0, size * sizeof(HWND) ))) break;
340
341         SERVER_START_REQ( get_window_children_from_point )
342         {
343             req->parent = hwnd;
344             req->x = pt.x;
345             req->y = pt.y;
346             wine_server_set_reply( req, list, (size-1) * sizeof(HWND) );
347             if (!wine_server_call( req )) count = reply->count;
348         }
349         SERVER_END_REQ;
350         if (count && count < size)
351         {
352             list[count] = 0;
353             return list;
354         }
355         HeapFree( GetProcessHeap(), 0, list );
356         if (!count) break;
357         size = count + 1;  /* restart with a large enough buffer */
358     }
359     return NULL;
360 }
361
362
363 /***********************************************************************
364  *           WINPOS_WindowFromPoint
365  *
366  * Find the window and hittest for a given point.
367  */
368 HWND WINPOS_WindowFromPoint( HWND hwndScope, POINT pt, INT *hittest )
369 {
370     int i, res;
371     HWND ret, *list;
372
373     if (!hwndScope) hwndScope = GetDesktopWindow();
374
375     *hittest = HTNOWHERE;
376
377     if (!(list = list_children_from_point( hwndScope, pt ))) return 0;
378
379     /* now determine the hittest */
380
381     for (i = 0; list[i]; i++)
382     {
383         LONG style = GetWindowLongW( list[i], GWL_STYLE );
384
385         /* If window is minimized or disabled, return at once */
386         if (style & WS_MINIMIZE)
387         {
388             *hittest = HTCAPTION;
389             break;
390         }
391         if (style & WS_DISABLED)
392         {
393             *hittest = HTERROR;
394             break;
395         }
396         /* Send WM_NCCHITTEST (if same thread) */
397         if (!WIN_IsCurrentThread( list[i] ))
398         {
399             *hittest = HTCLIENT;
400             break;
401         }
402         res = SendMessageW( list[i], WM_NCHITTEST, 0, MAKELONG(pt.x,pt.y) );
403         if (res != HTTRANSPARENT)
404         {
405             *hittest = res;  /* Found the window */
406             break;
407         }
408         /* continue search with next window in z-order */
409     }
410     ret = list[i];
411     HeapFree( GetProcessHeap(), 0, list );
412     TRACE( "scope %p (%d,%d) returning %p\n", hwndScope, pt.x, pt.y, ret );
413     return ret;
414 }
415
416
417 /*******************************************************************
418  *              WindowFromPoint (USER32.@)
419  */
420 HWND WINAPI WindowFromPoint( POINT pt )
421 {
422     INT hittest;
423     return WINPOS_WindowFromPoint( 0, pt, &hittest );
424 }
425
426
427 /*******************************************************************
428  *              ChildWindowFromPoint (USER32.@)
429  */
430 HWND WINAPI ChildWindowFromPoint( HWND hwndParent, POINT pt )
431 {
432     return ChildWindowFromPointEx( hwndParent, pt, CWP_ALL );
433 }
434
435 /*******************************************************************
436  *              RealChildWindowFromPoint (USER32.@)
437  */
438 HWND WINAPI RealChildWindowFromPoint( HWND hwndParent, POINT pt )
439 {
440     return ChildWindowFromPointEx( hwndParent, pt, CWP_SKIPTRANSPARENT );
441 }
442
443 /*******************************************************************
444  *              ChildWindowFromPointEx (USER32.@)
445  */
446 HWND WINAPI ChildWindowFromPointEx( HWND hwndParent, POINT pt, UINT uFlags)
447 {
448     /* pt is in the client coordinates */
449     HWND *list;
450     int i;
451     RECT rect;
452     HWND retvalue;
453
454     GetClientRect( hwndParent, &rect );
455     if (!PtInRect( &rect, pt )) return 0;
456     if (!(list = WIN_ListChildren( hwndParent ))) return hwndParent;
457
458     for (i = 0; list[i]; i++)
459     {
460         if (!WIN_GetRectangles( list[i], &rect, NULL )) continue;
461         if (!PtInRect( &rect, pt )) continue;
462         if (uFlags & (CWP_SKIPINVISIBLE|CWP_SKIPDISABLED))
463         {
464             LONG style = GetWindowLongW( list[i], GWL_STYLE );
465             if ((uFlags & CWP_SKIPINVISIBLE) && !(style & WS_VISIBLE)) continue;
466             if ((uFlags & CWP_SKIPDISABLED) && (style & WS_DISABLED)) continue;
467         }
468         if (uFlags & CWP_SKIPTRANSPARENT)
469         {
470             if (GetWindowLongW( list[i], GWL_EXSTYLE ) & WS_EX_TRANSPARENT) continue;
471         }
472         break;
473     }
474     retvalue = list[i];
475     HeapFree( GetProcessHeap(), 0, list );
476     if (!retvalue) retvalue = hwndParent;
477     return retvalue;
478 }
479
480
481 /*******************************************************************
482  *         WINPOS_GetWinOffset
483  *
484  * Calculate the offset between the origin of the two windows. Used
485  * to implement MapWindowPoints.
486  */
487 static void WINPOS_GetWinOffset( HWND hwndFrom, HWND hwndTo, POINT *offset )
488 {
489     WND * wndPtr;
490
491     offset->x = offset->y = 0;
492
493     /* Translate source window origin to screen coords */
494     if (hwndFrom)
495     {
496         HWND hwnd = hwndFrom;
497
498         while (hwnd)
499         {
500             if (hwnd == hwndTo) return;
501             if (!(wndPtr = WIN_GetPtr( hwnd )))
502             {
503                 ERR( "bad hwndFrom = %p\n", hwnd );
504                 return;
505             }
506             if (wndPtr == WND_DESKTOP) break;
507             if (wndPtr == WND_OTHER_PROCESS) goto other_process;
508             offset->x += wndPtr->rectClient.left;
509             offset->y += wndPtr->rectClient.top;
510             hwnd = wndPtr->parent;
511             WIN_ReleasePtr( wndPtr );
512         }
513     }
514
515     /* Translate origin to destination window coords */
516     if (hwndTo)
517     {
518         HWND hwnd = hwndTo;
519
520         while (hwnd)
521         {
522             if (!(wndPtr = WIN_GetPtr( hwnd )))
523             {
524                 ERR( "bad hwndTo = %p\n", hwnd );
525                 return;
526             }
527             if (wndPtr == WND_DESKTOP) break;
528             if (wndPtr == WND_OTHER_PROCESS) goto other_process;
529             offset->x -= wndPtr->rectClient.left;
530             offset->y -= wndPtr->rectClient.top;
531             hwnd = wndPtr->parent;
532             WIN_ReleasePtr( wndPtr );
533         }
534     }
535     return;
536
537  other_process:  /* one of the parents may belong to another process, do it the hard way */
538     offset->x = offset->y = 0;
539     SERVER_START_REQ( get_windows_offset )
540     {
541         req->from = hwndFrom;
542         req->to   = hwndTo;
543         if (!wine_server_call( req ))
544         {
545             offset->x = reply->x;
546             offset->y = reply->y;
547         }
548     }
549     SERVER_END_REQ;
550 }
551
552
553 /*******************************************************************
554  *              MapWindowPoints (USER.258)
555  */
556 void WINAPI MapWindowPoints16( HWND16 hwndFrom, HWND16 hwndTo,
557                                LPPOINT16 lppt, UINT16 count )
558 {
559     POINT offset;
560
561     WINPOS_GetWinOffset( WIN_Handle32(hwndFrom), WIN_Handle32(hwndTo), &offset );
562     while (count--)
563     {
564         lppt->x += offset.x;
565         lppt->y += offset.y;
566         lppt++;
567     }
568 }
569
570
571 /*******************************************************************
572  *              MapWindowPoints (USER32.@)
573  */
574 INT WINAPI MapWindowPoints( HWND hwndFrom, HWND hwndTo, LPPOINT lppt, UINT count )
575 {
576     POINT offset;
577
578     WINPOS_GetWinOffset( hwndFrom, hwndTo, &offset );
579     while (count--)
580     {
581         lppt->x += offset.x;
582         lppt->y += offset.y;
583         lppt++;
584     }
585     return MAKELONG( LOWORD(offset.x), LOWORD(offset.y) );
586 }
587
588
589 /***********************************************************************
590  *              IsIconic (USER32.@)
591  */
592 BOOL WINAPI IsIconic(HWND hWnd)
593 {
594     return (GetWindowLongW( hWnd, GWL_STYLE ) & WS_MINIMIZE) != 0;
595 }
596
597
598 /***********************************************************************
599  *              IsZoomed (USER32.@)
600  */
601 BOOL WINAPI IsZoomed(HWND hWnd)
602 {
603     return (GetWindowLongW( hWnd, GWL_STYLE ) & WS_MAXIMIZE) != 0;
604 }
605
606
607 /*******************************************************************
608  *              AllowSetForegroundWindow (USER32.@)
609  */
610 BOOL WINAPI AllowSetForegroundWindow( DWORD procid )
611 {
612     /* FIXME: If Win98/2000 style SetForegroundWindow behavior is
613      * implemented, then fix this function. */
614     return TRUE;
615 }
616
617
618 /*******************************************************************
619  *              LockSetForegroundWindow (USER32.@)
620  */
621 BOOL WINAPI LockSetForegroundWindow( UINT lockcode )
622 {
623     /* FIXME: If Win98/2000 style SetForegroundWindow behavior is
624      * implemented, then fix this function. */
625     return TRUE;
626 }
627
628
629 /***********************************************************************
630  *              BringWindowToTop (USER32.@)
631  */
632 BOOL WINAPI BringWindowToTop( HWND hwnd )
633 {
634     return SetWindowPos( hwnd, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE );
635 }
636
637
638 /***********************************************************************
639  *              MoveWindow (USER32.@)
640  */
641 BOOL WINAPI MoveWindow( HWND hwnd, INT x, INT y, INT cx, INT cy,
642                             BOOL repaint )
643 {
644     int flags = SWP_NOZORDER | SWP_NOACTIVATE;
645     if (!repaint) flags |= SWP_NOREDRAW;
646     TRACE("%p %d,%d %dx%d %d\n", hwnd, x, y, cx, cy, repaint );
647     return SetWindowPos( hwnd, 0, x, y, cx, cy, flags );
648 }
649
650 /***********************************************************************
651  *           WINPOS_InitInternalPos
652  */
653 static LPINTERNALPOS WINPOS_InitInternalPos( WND* wnd )
654 {
655     LPINTERNALPOS lpPos = get_internal_pos( wnd->hwndSelf );
656     if( !lpPos )
657     {
658         /* this happens when the window is minimized/maximized
659          * for the first time (rectWindow is not adjusted yet) */
660
661         lpPos = HeapAlloc( GetProcessHeap(), 0, sizeof(INTERNALPOS) );
662         if( !lpPos ) return NULL;
663
664         set_internal_pos( wnd->hwndSelf, lpPos );
665         lpPos->hwndIconTitle = 0; /* defer until needs to be shown */
666         lpPos->rectNormal.left   = wnd->rectWindow.left;
667         lpPos->rectNormal.top    = wnd->rectWindow.top;
668         lpPos->rectNormal.right  = wnd->rectWindow.right;
669         lpPos->rectNormal.bottom = wnd->rectWindow.bottom;
670         lpPos->ptIconPos.x = lpPos->ptIconPos.y = -1;
671         lpPos->ptMaxPos.x = lpPos->ptMaxPos.y = -1;
672     }
673
674     if( wnd->dwStyle & WS_MINIMIZE )
675     {
676         lpPos->ptIconPos.x = wnd->rectWindow.left;
677         lpPos->ptIconPos.y = wnd->rectWindow.top;
678     }
679     else if( wnd->dwStyle & WS_MAXIMIZE )
680     {
681         lpPos->ptMaxPos.x = wnd->rectWindow.left;
682         lpPos->ptMaxPos.y = wnd->rectWindow.top;
683     }
684     else
685     {
686         lpPos->rectNormal.left   = wnd->rectWindow.left;
687         lpPos->rectNormal.top    = wnd->rectWindow.top;
688         lpPos->rectNormal.right  = wnd->rectWindow.right;
689         lpPos->rectNormal.bottom = wnd->rectWindow.bottom;
690     }
691     return lpPos;
692 }
693
694 /***********************************************************************
695  *           WINPOS_RedrawIconTitle
696  */
697 BOOL WINPOS_RedrawIconTitle( HWND hWnd )
698 {
699     LPINTERNALPOS lpPos = get_internal_pos( hWnd );
700     if( lpPos )
701     {
702         if( lpPos->hwndIconTitle )
703         {
704             SendMessageW( lpPos->hwndIconTitle, WM_SHOWWINDOW, TRUE, 0);
705             InvalidateRect( lpPos->hwndIconTitle, NULL, TRUE );
706             return TRUE;
707         }
708     }
709     return FALSE;
710 }
711
712 /***********************************************************************
713  *           WINPOS_ShowIconTitle
714  */
715 BOOL WINPOS_ShowIconTitle( HWND hwnd, BOOL bShow )
716 {
717     LPINTERNALPOS lpPos = get_internal_pos( hwnd );
718
719     if (lpPos && !GetPropA( hwnd, "__wine_x11_managed" ))
720     {
721         HWND title = lpPos->hwndIconTitle;
722
723         TRACE("%p %i\n", hwnd, (bShow != 0) );
724
725         if( !title )
726             lpPos->hwndIconTitle = title = ICONTITLE_Create( hwnd );
727         if( bShow )
728         {
729             if (!IsWindowVisible(title))
730             {
731                 SendMessageW( title, WM_SHOWWINDOW, TRUE, 0 );
732                 SetWindowPos( title, 0, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE |
733                               SWP_NOACTIVATE | SWP_NOZORDER | SWP_SHOWWINDOW );
734             }
735         }
736         else ShowWindow( title, SW_HIDE );
737     }
738     return FALSE;
739 }
740
741 /*******************************************************************
742  *           WINPOS_GetMinMaxInfo
743  *
744  * Get the minimized and maximized information for a window.
745  */
746 void WINPOS_GetMinMaxInfo( HWND hwnd, POINT *maxSize, POINT *maxPos,
747                            POINT *minTrack, POINT *maxTrack )
748 {
749     LPINTERNALPOS lpPos;
750     MINMAXINFO MinMax;
751     HMONITOR monitor;
752     INT xinc, yinc;
753     LONG style = GetWindowLongA( hwnd, GWL_STYLE );
754     LONG exstyle = GetWindowLongA( hwnd, GWL_EXSTYLE );
755     RECT rc;
756
757     /* Compute default values */
758
759     GetWindowRect(hwnd, &rc);
760     MinMax.ptReserved.x = rc.left;
761     MinMax.ptReserved.y = rc.top;
762
763     if (style & WS_CHILD)
764     {
765         if ((style & WS_CAPTION) == WS_CAPTION)
766             style &= ~WS_BORDER; /* WS_CAPTION = WS_DLGFRAME | WS_BORDER */
767
768         GetClientRect(GetAncestor(hwnd,GA_PARENT), &rc);
769         AdjustWindowRectEx(&rc, style, ((style & WS_POPUP) && GetMenu(hwnd)), exstyle);
770
771         /* avoid calculating this twice */
772         style &= ~(WS_DLGFRAME | WS_BORDER | WS_THICKFRAME);
773
774         MinMax.ptMaxSize.x = rc.right - rc.left;
775         MinMax.ptMaxSize.y = rc.bottom - rc.top;
776     }
777     else
778     {
779         MinMax.ptMaxSize.x = GetSystemMetrics(SM_CXSCREEN);
780         MinMax.ptMaxSize.y = GetSystemMetrics(SM_CYSCREEN);
781     }
782     MinMax.ptMinTrackSize.x = GetSystemMetrics(SM_CXMINTRACK);
783     MinMax.ptMinTrackSize.y = GetSystemMetrics(SM_CYMINTRACK);
784     MinMax.ptMaxTrackSize.x = GetSystemMetrics(SM_CXMAXTRACK);
785     MinMax.ptMaxTrackSize.y = GetSystemMetrics(SM_CYMAXTRACK);
786
787     if (HAS_DLGFRAME( style, exstyle ))
788     {
789         xinc = GetSystemMetrics(SM_CXDLGFRAME);
790         yinc = GetSystemMetrics(SM_CYDLGFRAME);
791     }
792     else
793     {
794         xinc = yinc = 0;
795         if (HAS_THICKFRAME(style))
796         {
797             xinc += GetSystemMetrics(SM_CXFRAME);
798             yinc += GetSystemMetrics(SM_CYFRAME);
799         }
800         if (style & WS_BORDER)
801         {
802             xinc += GetSystemMetrics(SM_CXBORDER);
803             yinc += GetSystemMetrics(SM_CYBORDER);
804         }
805     }
806     MinMax.ptMaxSize.x += 2 * xinc;
807     MinMax.ptMaxSize.y += 2 * yinc;
808
809     lpPos = get_internal_pos( hwnd );
810     if( lpPos && !EMPTYPOINT(lpPos->ptMaxPos) )
811     {
812         MinMax.ptMaxPosition.x = lpPos->ptMaxPos.x;
813         MinMax.ptMaxPosition.y = lpPos->ptMaxPos.y;
814     }
815     else
816     {
817         MinMax.ptMaxPosition.x = -xinc;
818         MinMax.ptMaxPosition.y = -yinc;
819     }
820
821     SendMessageW( hwnd, WM_GETMINMAXINFO, 0, (LPARAM)&MinMax );
822
823     /* if the app didn't change the values, adapt them for the current monitor */
824
825     if ((monitor = MonitorFromWindow( hwnd, MONITOR_DEFAULTTOPRIMARY )))
826     {
827         MONITORINFO mon_info;
828
829         mon_info.cbSize = sizeof(mon_info);
830         GetMonitorInfoW( monitor, &mon_info );
831
832         if (MinMax.ptMaxSize.x == GetSystemMetrics(SM_CXSCREEN) + 2 * xinc &&
833             MinMax.ptMaxSize.y == GetSystemMetrics(SM_CYSCREEN) + 2 * yinc)
834         {
835             MinMax.ptMaxSize.x = (mon_info.rcWork.right - mon_info.rcWork.left) + 2 * xinc;
836             MinMax.ptMaxSize.y = (mon_info.rcWork.bottom - mon_info.rcWork.top) + 2 * yinc;
837         }
838         if (MinMax.ptMaxPosition.x == -xinc && MinMax.ptMaxPosition.y == -yinc)
839         {
840             MinMax.ptMaxPosition.x = mon_info.rcWork.left - xinc;
841             MinMax.ptMaxPosition.y = mon_info.rcWork.top - yinc;
842         }
843     }
844
845       /* Some sanity checks */
846
847     TRACE("%d %d / %d %d / %d %d / %d %d\n",
848                       MinMax.ptMaxSize.x, MinMax.ptMaxSize.y,
849                       MinMax.ptMaxPosition.x, MinMax.ptMaxPosition.y,
850                       MinMax.ptMaxTrackSize.x, MinMax.ptMaxTrackSize.y,
851                       MinMax.ptMinTrackSize.x, MinMax.ptMinTrackSize.y);
852     MinMax.ptMaxTrackSize.x = max( MinMax.ptMaxTrackSize.x,
853                                    MinMax.ptMinTrackSize.x );
854     MinMax.ptMaxTrackSize.y = max( MinMax.ptMaxTrackSize.y,
855                                    MinMax.ptMinTrackSize.y );
856
857     if (maxSize) *maxSize = MinMax.ptMaxSize;
858     if (maxPos) *maxPos = MinMax.ptMaxPosition;
859     if (minTrack) *minTrack = MinMax.ptMinTrackSize;
860     if (maxTrack) *maxTrack = MinMax.ptMaxTrackSize;
861 }
862
863 /***********************************************************************
864  *              ShowWindowAsync (USER32.@)
865  *
866  * doesn't wait; returns immediately.
867  * used by threads to toggle windows in other (possibly hanging) threads
868  */
869 BOOL WINAPI ShowWindowAsync( HWND hwnd, INT cmd )
870 {
871     HWND full_handle;
872
873     if (is_broadcast(hwnd))
874     {
875         SetLastError( ERROR_INVALID_PARAMETER );
876         return FALSE;
877     }
878
879     if ((full_handle = WIN_IsCurrentThread( hwnd )))
880         return USER_Driver->pShowWindow( full_handle, cmd );
881
882     return SendNotifyMessageW( hwnd, WM_WINE_SHOWWINDOW, cmd, 0 );
883 }
884
885
886 /***********************************************************************
887  *              ShowWindow (USER32.@)
888  */
889 BOOL WINAPI ShowWindow( HWND hwnd, INT cmd )
890 {
891     HWND full_handle;
892
893     if (is_broadcast(hwnd))
894     {
895         SetLastError( ERROR_INVALID_PARAMETER );
896         return FALSE;
897     }
898     if ((full_handle = WIN_IsCurrentThread( hwnd )))
899         return USER_Driver->pShowWindow( full_handle, cmd );
900
901     return SendMessageW( hwnd, WM_WINE_SHOWWINDOW, cmd, 0 );
902 }
903
904
905 /***********************************************************************
906  *              GetInternalWindowPos (USER32.@)
907  */
908 UINT WINAPI GetInternalWindowPos( HWND hwnd, LPRECT rectWnd,
909                                       LPPOINT ptIcon )
910 {
911     WINDOWPLACEMENT wndpl;
912     if (GetWindowPlacement( hwnd, &wndpl ))
913     {
914         if (rectWnd) *rectWnd = wndpl.rcNormalPosition;
915         if (ptIcon)  *ptIcon = wndpl.ptMinPosition;
916         return wndpl.showCmd;
917     }
918     return 0;
919 }
920
921
922 /***********************************************************************
923  *              GetWindowPlacement (USER32.@)
924  *
925  * Win95:
926  * Fails if wndpl->length of Win95 (!) apps is invalid.
927  */
928 BOOL WINAPI GetWindowPlacement( HWND hwnd, WINDOWPLACEMENT *wndpl )
929 {
930     WND *pWnd = WIN_GetPtr( hwnd );
931     LPINTERNALPOS lpPos;
932
933     if (!pWnd || pWnd == WND_DESKTOP) return FALSE;
934     if (pWnd == WND_OTHER_PROCESS)
935     {
936         if (IsWindow( hwnd )) FIXME( "not supported on other process window %p\n", hwnd );
937         return FALSE;
938     }
939
940     lpPos = WINPOS_InitInternalPos( pWnd );
941     wndpl->length  = sizeof(*wndpl);
942     if( pWnd->dwStyle & WS_MINIMIZE )
943         wndpl->showCmd = SW_SHOWMINIMIZED;
944     else
945         wndpl->showCmd = ( pWnd->dwStyle & WS_MAXIMIZE ) ? SW_SHOWMAXIMIZED : SW_SHOWNORMAL ;
946     if( pWnd->flags & WIN_RESTORE_MAX )
947         wndpl->flags = WPF_RESTORETOMAXIMIZED;
948     else
949         wndpl->flags = 0;
950     wndpl->ptMinPosition.x = lpPos->ptIconPos.x;
951     wndpl->ptMinPosition.y = lpPos->ptIconPos.y;
952     wndpl->ptMaxPosition.x = lpPos->ptMaxPos.x;
953     wndpl->ptMaxPosition.y = lpPos->ptMaxPos.y;
954     wndpl->rcNormalPosition.left   = lpPos->rectNormal.left;
955     wndpl->rcNormalPosition.top    = lpPos->rectNormal.top;
956     wndpl->rcNormalPosition.right  = lpPos->rectNormal.right;
957     wndpl->rcNormalPosition.bottom = lpPos->rectNormal.bottom;
958     WIN_ReleasePtr( pWnd );
959     return TRUE;
960 }
961
962
963 /***********************************************************************
964  *           WINPOS_SetPlacement
965  */
966 static BOOL WINPOS_SetPlacement( HWND hwnd, const WINDOWPLACEMENT *wndpl, UINT flags )
967 {
968     LPINTERNALPOS lpPos;
969     DWORD style;
970     WND *pWnd = WIN_GetPtr( hwnd );
971
972     if (!pWnd || pWnd == WND_OTHER_PROCESS || pWnd == WND_DESKTOP) return FALSE;
973     lpPos = WINPOS_InitInternalPos( pWnd );
974
975     if( flags & PLACE_MIN )
976     {
977         lpPos->ptIconPos.x = wndpl->ptMinPosition.x;
978         lpPos->ptIconPos.y = wndpl->ptMinPosition.y;
979     }
980     if( flags & PLACE_MAX )
981     {
982         lpPos->ptMaxPos.x = wndpl->ptMaxPosition.x;
983         lpPos->ptMaxPos.y = wndpl->ptMaxPosition.y;
984     }
985     if( flags & PLACE_RECT)
986     {
987         lpPos->rectNormal.left   = wndpl->rcNormalPosition.left;
988         lpPos->rectNormal.top    = wndpl->rcNormalPosition.top;
989         lpPos->rectNormal.right  = wndpl->rcNormalPosition.right;
990         lpPos->rectNormal.bottom = wndpl->rcNormalPosition.bottom;
991     }
992
993     style = pWnd->dwStyle;
994     WIN_ReleasePtr( pWnd );
995
996     if( style & WS_MINIMIZE )
997     {
998         WINPOS_ShowIconTitle( hwnd, FALSE );
999         if( wndpl->flags & WPF_SETMINPOSITION && !EMPTYPOINT(lpPos->ptIconPos))
1000             SetWindowPos( hwnd, 0, lpPos->ptIconPos.x, lpPos->ptIconPos.y,
1001                           0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE );
1002     }
1003     else if( style & WS_MAXIMIZE )
1004     {
1005         if( !EMPTYPOINT(lpPos->ptMaxPos) )
1006             SetWindowPos( hwnd, 0, lpPos->ptMaxPos.x, lpPos->ptMaxPos.y,
1007                           0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE );
1008     }
1009     else if( flags & PLACE_RECT )
1010         SetWindowPos( hwnd, 0, lpPos->rectNormal.left, lpPos->rectNormal.top,
1011                       lpPos->rectNormal.right - lpPos->rectNormal.left,
1012                       lpPos->rectNormal.bottom - lpPos->rectNormal.top,
1013                       SWP_NOZORDER | SWP_NOACTIVATE );
1014
1015     ShowWindow( hwnd, wndpl->showCmd );
1016
1017     if (IsIconic( hwnd ))
1018     {
1019         if (GetWindowLongW( hwnd, GWL_STYLE ) & WS_VISIBLE) WINPOS_ShowIconTitle( hwnd, TRUE );
1020
1021         /* SDK: ...valid only the next time... */
1022         if( wndpl->flags & WPF_RESTORETOMAXIMIZED )
1023         {
1024             pWnd = WIN_GetPtr( hwnd );
1025             if (pWnd && pWnd != WND_OTHER_PROCESS)
1026             {
1027                 pWnd->flags |= WIN_RESTORE_MAX;
1028                 WIN_ReleasePtr( pWnd );
1029             }
1030         }
1031     }
1032     return TRUE;
1033 }
1034
1035
1036 /***********************************************************************
1037  *              SetWindowPlacement (USER32.@)
1038  *
1039  * Win95:
1040  * Fails if wndpl->length of Win95 (!) apps is invalid.
1041  */
1042 BOOL WINAPI SetWindowPlacement( HWND hwnd, const WINDOWPLACEMENT *wpl )
1043 {
1044     if (!wpl) return FALSE;
1045     return WINPOS_SetPlacement( hwnd, wpl, PLACE_MIN | PLACE_MAX | PLACE_RECT );
1046 }
1047
1048
1049 /***********************************************************************
1050  *              AnimateWindow (USER32.@)
1051  *              Shows/Hides a window with an animation
1052  *              NO ANIMATION YET
1053  */
1054 BOOL WINAPI AnimateWindow(HWND hwnd, DWORD dwTime, DWORD dwFlags)
1055 {
1056         FIXME("partial stub\n");
1057
1058         /* If trying to show/hide and it's already   *
1059          * shown/hidden or invalid window, fail with *
1060          * invalid parameter                         */
1061         if(!IsWindow(hwnd) ||
1062            (IsWindowVisible(hwnd) && !(dwFlags & AW_HIDE)) ||
1063            (!IsWindowVisible(hwnd) && (dwFlags & AW_HIDE)))
1064         {
1065                 SetLastError(ERROR_INVALID_PARAMETER);
1066                 return FALSE;
1067         }
1068
1069         ShowWindow(hwnd, (dwFlags & AW_HIDE) ? SW_HIDE : ((dwFlags & AW_ACTIVATE) ? SW_SHOW : SW_SHOWNA));
1070
1071         return TRUE;
1072 }
1073
1074 /***********************************************************************
1075  *              SetInternalWindowPos (USER32.@)
1076  */
1077 void WINAPI SetInternalWindowPos( HWND hwnd, UINT showCmd,
1078                                     LPRECT rect, LPPOINT pt )
1079 {
1080     if( IsWindow(hwnd) )
1081     {
1082         WINDOWPLACEMENT wndpl;
1083         UINT flags;
1084
1085         wndpl.length  = sizeof(wndpl);
1086         wndpl.showCmd = showCmd;
1087         wndpl.flags = flags = 0;
1088
1089         if( pt )
1090         {
1091             flags |= PLACE_MIN;
1092             wndpl.flags |= WPF_SETMINPOSITION;
1093             wndpl.ptMinPosition = *pt;
1094         }
1095         if( rect )
1096         {
1097             flags |= PLACE_RECT;
1098             wndpl.rcNormalPosition = *rect;
1099         }
1100         WINPOS_SetPlacement( hwnd, &wndpl, flags );
1101     }
1102 }
1103
1104
1105 /*******************************************************************
1106  *         can_activate_window
1107  *
1108  * Check if we can activate the specified window.
1109  */
1110 static BOOL can_activate_window( HWND hwnd )
1111 {
1112     LONG style;
1113
1114     if (!hwnd) return FALSE;
1115     style = GetWindowLongW( hwnd, GWL_STYLE );
1116     if (!(style & WS_VISIBLE)) return FALSE;
1117     if ((style & (WS_POPUP|WS_CHILD)) == WS_CHILD) return FALSE;
1118     return !(style & WS_DISABLED);
1119 }
1120
1121
1122 /*******************************************************************
1123  *         WINPOS_ActivateOtherWindow
1124  *
1125  *  Activates window other than pWnd.
1126  */
1127 void WINPOS_ActivateOtherWindow(HWND hwnd)
1128 {
1129     HWND hwndTo, fg;
1130
1131     if ((GetWindowLongW( hwnd, GWL_STYLE ) & WS_POPUP) && (hwndTo = GetWindow( hwnd, GW_OWNER )))
1132     {
1133         hwndTo = GetAncestor( hwndTo, GA_ROOT );
1134         if (can_activate_window( hwndTo )) goto done;
1135     }
1136
1137     hwndTo = hwnd;
1138     for (;;)
1139     {
1140         if (!(hwndTo = GetWindow( hwndTo, GW_HWNDNEXT ))) break;
1141         if (can_activate_window( hwndTo )) break;
1142     }
1143
1144  done:
1145     fg = GetForegroundWindow();
1146     TRACE("win = %p fg = %p\n", hwndTo, fg);
1147     if (!fg || (hwnd == fg))
1148     {
1149         if (SetForegroundWindow( hwndTo )) return;
1150     }
1151     if (!SetActiveWindow( hwndTo )) SetActiveWindow(0);
1152 }
1153
1154
1155 /***********************************************************************
1156  *           WINPOS_HandleWindowPosChanging
1157  *
1158  * Default handling for a WM_WINDOWPOSCHANGING. Called from DefWindowProc().
1159  */
1160 LONG WINPOS_HandleWindowPosChanging( HWND hwnd, WINDOWPOS *winpos )
1161 {
1162     POINT minTrack, maxTrack;
1163     LONG style = GetWindowLongW( hwnd, GWL_STYLE );
1164
1165     if (winpos->flags & SWP_NOSIZE) return 0;
1166     if ((style & WS_THICKFRAME) || ((style & (WS_POPUP | WS_CHILD)) == 0))
1167     {
1168         WINPOS_GetMinMaxInfo( hwnd, NULL, NULL, &minTrack, &maxTrack );
1169         if (winpos->cx > maxTrack.x) winpos->cx = maxTrack.x;
1170         if (winpos->cy > maxTrack.y) winpos->cy = maxTrack.y;
1171         if (!(style & WS_MINIMIZE))
1172         {
1173             if (winpos->cx < minTrack.x ) winpos->cx = minTrack.x;
1174             if (winpos->cy < minTrack.y ) winpos->cy = minTrack.y;
1175         }
1176     }
1177     return 0;
1178 }
1179
1180
1181 /***********************************************************************
1182  *           dump_winpos_flags
1183  */
1184 static void dump_winpos_flags(UINT flags)
1185 {
1186     TRACE("flags:");
1187     if(flags & SWP_NOSIZE) TRACE(" SWP_NOSIZE");
1188     if(flags & SWP_NOMOVE) TRACE(" SWP_NOMOVE");
1189     if(flags & SWP_NOZORDER) TRACE(" SWP_NOZORDER");
1190     if(flags & SWP_NOREDRAW) TRACE(" SWP_NOREDRAW");
1191     if(flags & SWP_NOACTIVATE) TRACE(" SWP_NOACTIVATE");
1192     if(flags & SWP_FRAMECHANGED) TRACE(" SWP_FRAMECHANGED");
1193     if(flags & SWP_SHOWWINDOW) TRACE(" SWP_SHOWWINDOW");
1194     if(flags & SWP_HIDEWINDOW) TRACE(" SWP_HIDEWINDOW");
1195     if(flags & SWP_NOCOPYBITS) TRACE(" SWP_NOCOPYBITS");
1196     if(flags & SWP_NOOWNERZORDER) TRACE(" SWP_NOOWNERZORDER");
1197     if(flags & SWP_NOSENDCHANGING) TRACE(" SWP_NOSENDCHANGING");
1198     if(flags & SWP_DEFERERASE) TRACE(" SWP_DEFERERASE");
1199     if(flags & SWP_ASYNCWINDOWPOS) TRACE(" SWP_ASYNCWINDOWPOS");
1200
1201 #define DUMPED_FLAGS \
1202     (SWP_NOSIZE | \
1203     SWP_NOMOVE | \
1204     SWP_NOZORDER | \
1205     SWP_NOREDRAW | \
1206     SWP_NOACTIVATE | \
1207     SWP_FRAMECHANGED | \
1208     SWP_SHOWWINDOW | \
1209     SWP_HIDEWINDOW | \
1210     SWP_NOCOPYBITS | \
1211     SWP_NOOWNERZORDER | \
1212     SWP_NOSENDCHANGING | \
1213     SWP_DEFERERASE | \
1214     SWP_ASYNCWINDOWPOS)
1215
1216     if(flags & ~DUMPED_FLAGS) TRACE(" %08x", flags & ~DUMPED_FLAGS);
1217     TRACE("\n");
1218 #undef DUMPED_FLAGS
1219 }
1220
1221 /***********************************************************************
1222  *           SWP_DoWinPosChanging
1223  */
1224 static BOOL SWP_DoWinPosChanging( WINDOWPOS* pWinpos, RECT* pNewWindowRect, RECT* pNewClientRect )
1225 {
1226     WND *wndPtr;
1227
1228     /* Send WM_WINDOWPOSCHANGING message */
1229
1230     if (!(pWinpos->flags & SWP_NOSENDCHANGING))
1231         SendMessageW( pWinpos->hwnd, WM_WINDOWPOSCHANGING, 0, (LPARAM)pWinpos );
1232
1233     if (!(wndPtr = WIN_GetPtr( pWinpos->hwnd )) ||
1234         wndPtr == WND_OTHER_PROCESS || wndPtr == WND_DESKTOP) return FALSE;
1235
1236     /* Calculate new position and size */
1237
1238     *pNewWindowRect = wndPtr->rectWindow;
1239     *pNewClientRect = (wndPtr->dwStyle & WS_MINIMIZE) ? wndPtr->rectWindow
1240                                                     : wndPtr->rectClient;
1241
1242     if (!(pWinpos->flags & SWP_NOSIZE))
1243     {
1244         pNewWindowRect->right  = pNewWindowRect->left + pWinpos->cx;
1245         pNewWindowRect->bottom = pNewWindowRect->top + pWinpos->cy;
1246     }
1247     if (!(pWinpos->flags & SWP_NOMOVE))
1248     {
1249         pNewWindowRect->left    = pWinpos->x;
1250         pNewWindowRect->top     = pWinpos->y;
1251         pNewWindowRect->right  += pWinpos->x - wndPtr->rectWindow.left;
1252         pNewWindowRect->bottom += pWinpos->y - wndPtr->rectWindow.top;
1253
1254         OffsetRect( pNewClientRect, pWinpos->x - wndPtr->rectWindow.left,
1255                                     pWinpos->y - wndPtr->rectWindow.top );
1256     }
1257     pWinpos->flags |= SWP_NOCLIENTMOVE | SWP_NOCLIENTSIZE;
1258
1259     TRACE( "hwnd %p, after %p, swp %d,%d %dx%d flags %08x\n",
1260            pWinpos->hwnd, pWinpos->hwndInsertAfter, pWinpos->x, pWinpos->y,
1261            pWinpos->cx, pWinpos->cy, pWinpos->flags );
1262     TRACE( "current %s style %08x new %s\n",
1263            wine_dbgstr_rect( &wndPtr->rectWindow ), wndPtr->dwStyle,
1264            wine_dbgstr_rect( pNewWindowRect ));
1265
1266     WIN_ReleasePtr( wndPtr );
1267     return TRUE;
1268 }
1269
1270 /***********************************************************************
1271  *           get_valid_rects
1272  *
1273  * Compute the valid rects from the old and new client rect and WVR_* flags.
1274  * Helper for WM_NCCALCSIZE handling.
1275  */
1276 static inline void get_valid_rects( const RECT *old_client, const RECT *new_client, UINT flags,
1277                                     RECT *valid )
1278 {
1279     int cx, cy;
1280
1281     if (flags & WVR_REDRAW)
1282     {
1283         SetRectEmpty( &valid[0] );
1284         SetRectEmpty( &valid[1] );
1285         return;
1286     }
1287
1288     if (flags & WVR_VALIDRECTS)
1289     {
1290         if (!IntersectRect( &valid[0], &valid[0], new_client ) ||
1291             !IntersectRect( &valid[1], &valid[1], old_client ))
1292         {
1293             SetRectEmpty( &valid[0] );
1294             SetRectEmpty( &valid[1] );
1295             return;
1296         }
1297         flags = WVR_ALIGNLEFT | WVR_ALIGNTOP;
1298     }
1299     else
1300     {
1301         valid[0] = *new_client;
1302         valid[1] = *old_client;
1303     }
1304
1305     /* make sure the rectangles have the same size */
1306     cx = min( valid[0].right - valid[0].left, valid[1].right - valid[1].left );
1307     cy = min( valid[0].bottom - valid[0].top, valid[1].bottom - valid[1].top );
1308
1309     if (flags & WVR_ALIGNBOTTOM)
1310     {
1311         valid[0].top = valid[0].bottom - cy;
1312         valid[1].top = valid[1].bottom - cy;
1313     }
1314     else
1315     {
1316         valid[0].bottom = valid[0].top + cy;
1317         valid[1].bottom = valid[1].top + cy;
1318     }
1319     if (flags & WVR_ALIGNRIGHT)
1320     {
1321         valid[0].left = valid[0].right - cx;
1322         valid[1].left = valid[1].right - cx;
1323     }
1324     else
1325     {
1326         valid[0].right = valid[0].left + cx;
1327         valid[1].right = valid[1].left + cx;
1328     }
1329 }
1330
1331 struct move_owned_info
1332 {
1333     HWND owner;
1334     HWND insert_after;
1335 };
1336
1337 static BOOL CALLBACK move_owned_popups( HWND hwnd, LPARAM lparam )
1338 {
1339     struct move_owned_info *info = (struct move_owned_info *)lparam;
1340
1341     if (hwnd == info->owner) return FALSE;
1342     if ((GetWindowLongW( hwnd, GWL_STYLE ) & WS_POPUP) &&
1343         GetWindow( hwnd, GW_OWNER ) == info->owner)
1344     {
1345         SetWindowPos( hwnd, info->insert_after, 0, 0, 0, 0,
1346                       SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE |
1347                       SWP_NOSENDCHANGING | SWP_DEFERERASE );
1348         info->insert_after = hwnd;
1349     }
1350     return TRUE;
1351 }
1352
1353 /***********************************************************************
1354  *           SWP_DoOwnedPopups
1355  *
1356  * fix Z order taking into account owned popups -
1357  * basically we need to maintain them above the window that owns them
1358  *
1359  * FIXME: hide/show owned popups when owner visibility changes.
1360  */
1361 static HWND SWP_DoOwnedPopups(HWND hwnd, HWND hwndInsertAfter)
1362 {
1363     HWND owner = GetWindow( hwnd, GW_OWNER );
1364     LONG style = GetWindowLongW( hwnd, GWL_STYLE );
1365     struct move_owned_info info;
1366
1367     TRACE("(%p) hInsertAfter = %p\n", hwnd, hwndInsertAfter );
1368
1369     if ((style & WS_POPUP) && owner)
1370     {
1371         /* make sure this popup stays above the owner */
1372
1373         if (hwndInsertAfter != HWND_TOP && hwndInsertAfter != HWND_TOPMOST)
1374         {
1375             HWND hwndLocalPrev = HWND_TOP;
1376             HWND prev = GetWindow( owner, GW_HWNDPREV );
1377
1378             while (prev && prev != hwndInsertAfter)
1379             {
1380                 if (hwndLocalPrev == HWND_TOP && GetWindowLongW( prev, GWL_STYLE ) & WS_VISIBLE)
1381                     hwndLocalPrev = prev;
1382                 prev = GetWindow( prev, GW_HWNDPREV );
1383             }
1384             if (!prev) hwndInsertAfter = hwndLocalPrev;
1385         }
1386     }
1387     else if (style & WS_CHILD) return hwndInsertAfter;
1388
1389     info.owner = hwnd;
1390     info.insert_after = hwndInsertAfter;
1391     EnumWindows( move_owned_popups, (LPARAM)&info );
1392     return info.insert_after;
1393 }
1394
1395 /***********************************************************************
1396  *           SWP_DoNCCalcSize
1397  */
1398 static UINT SWP_DoNCCalcSize( WINDOWPOS* pWinpos, const RECT* pNewWindowRect, RECT* pNewClientRect,
1399                               RECT *validRects )
1400 {
1401     UINT wvrFlags = 0;
1402     WND *wndPtr;
1403
1404     if (!(wndPtr = WIN_GetPtr( pWinpos->hwnd )) || wndPtr == WND_OTHER_PROCESS) return 0;
1405
1406       /* Send WM_NCCALCSIZE message to get new client area */
1407     if( (pWinpos->flags & (SWP_FRAMECHANGED | SWP_NOSIZE)) != SWP_NOSIZE )
1408     {
1409         NCCALCSIZE_PARAMS params;
1410         WINDOWPOS winposCopy;
1411
1412         params.rgrc[0] = *pNewWindowRect;
1413         params.rgrc[1] = wndPtr->rectWindow;
1414         params.rgrc[2] = wndPtr->rectClient;
1415         params.lppos = &winposCopy;
1416         winposCopy = *pWinpos;
1417         WIN_ReleasePtr( wndPtr );
1418
1419         wvrFlags = SendMessageW( pWinpos->hwnd, WM_NCCALCSIZE, TRUE, (LPARAM)&params );
1420
1421         *pNewClientRect = params.rgrc[0];
1422
1423         if (!(wndPtr = WIN_GetPtr( pWinpos->hwnd )) || wndPtr == WND_OTHER_PROCESS) return 0;
1424
1425         TRACE( "hwnd %p old win %s old client %s new win %s new client %s\n", pWinpos->hwnd,
1426                wine_dbgstr_rect(&wndPtr->rectWindow), wine_dbgstr_rect(&wndPtr->rectClient),
1427                wine_dbgstr_rect(pNewWindowRect), wine_dbgstr_rect(pNewClientRect) );
1428
1429         if( pNewClientRect->left != wndPtr->rectClient.left ||
1430             pNewClientRect->top != wndPtr->rectClient.top )
1431             pWinpos->flags &= ~SWP_NOCLIENTMOVE;
1432
1433         if( (pNewClientRect->right - pNewClientRect->left !=
1434              wndPtr->rectClient.right - wndPtr->rectClient.left))
1435             pWinpos->flags &= ~SWP_NOCLIENTSIZE;
1436         else
1437             wvrFlags &= ~WVR_HREDRAW;
1438
1439         if (pNewClientRect->bottom - pNewClientRect->top !=
1440              wndPtr->rectClient.bottom - wndPtr->rectClient.top)
1441             pWinpos->flags &= ~SWP_NOCLIENTSIZE;
1442         else
1443             wvrFlags &= ~WVR_VREDRAW;
1444
1445         validRects[0] = params.rgrc[1];
1446         validRects[1] = params.rgrc[2];
1447     }
1448     else
1449     {
1450         if (!(pWinpos->flags & SWP_NOMOVE) &&
1451             (pNewClientRect->left != wndPtr->rectClient.left ||
1452              pNewClientRect->top != wndPtr->rectClient.top))
1453             pWinpos->flags &= ~SWP_NOCLIENTMOVE;
1454     }
1455
1456     if (pWinpos->flags & (SWP_NOCOPYBITS | SWP_NOREDRAW | SWP_SHOWWINDOW | SWP_HIDEWINDOW))
1457     {
1458         SetRectEmpty( &validRects[0] );
1459         SetRectEmpty( &validRects[1] );
1460     }
1461     else get_valid_rects( &wndPtr->rectClient, pNewClientRect, wvrFlags, validRects );
1462
1463     WIN_ReleasePtr( wndPtr );
1464     return wvrFlags;
1465 }
1466
1467 /* fix redundant flags and values in the WINDOWPOS structure */
1468 static BOOL fixup_flags( WINDOWPOS *winpos )
1469 {
1470     HWND parent;
1471     WND *wndPtr = WIN_GetPtr( winpos->hwnd );
1472     BOOL ret = TRUE;
1473
1474     if (!wndPtr || wndPtr == WND_OTHER_PROCESS)
1475     {
1476         SetLastError( ERROR_INVALID_WINDOW_HANDLE );
1477         return FALSE;
1478     }
1479     winpos->hwnd = wndPtr->hwndSelf;  /* make it a full handle */
1480
1481     /* Finally make sure that all coordinates are valid */
1482     if (winpos->x < -32768) winpos->x = -32768;
1483     else if (winpos->x > 32767) winpos->x = 32767;
1484     if (winpos->y < -32768) winpos->y = -32768;
1485     else if (winpos->y > 32767) winpos->y = 32767;
1486
1487     if (winpos->cx < 0) winpos->cx = 0;
1488     else if (winpos->cx > 32767) winpos->cx = 32767;
1489     if (winpos->cy < 0) winpos->cy = 0;
1490     else if (winpos->cy > 32767) winpos->cy = 32767;
1491
1492     parent = GetAncestor( winpos->hwnd, GA_PARENT );
1493     if (!IsWindowVisible( parent )) winpos->flags |= SWP_NOREDRAW;
1494
1495     if (wndPtr->dwStyle & WS_VISIBLE) winpos->flags &= ~SWP_SHOWWINDOW;
1496     else
1497     {
1498         winpos->flags &= ~SWP_HIDEWINDOW;
1499         if (!(winpos->flags & SWP_SHOWWINDOW)) winpos->flags |= SWP_NOREDRAW;
1500     }
1501
1502     if ((wndPtr->rectWindow.right - wndPtr->rectWindow.left == winpos->cx) &&
1503         (wndPtr->rectWindow.bottom - wndPtr->rectWindow.top == winpos->cy))
1504         winpos->flags |= SWP_NOSIZE;    /* Already the right size */
1505
1506     if ((wndPtr->rectWindow.left == winpos->x) && (wndPtr->rectWindow.top == winpos->y))
1507         winpos->flags |= SWP_NOMOVE;    /* Already the right position */
1508
1509     if ((wndPtr->dwStyle & (WS_POPUP | WS_CHILD)) != WS_CHILD)
1510     {
1511         if (!(winpos->flags & (SWP_NOACTIVATE|SWP_HIDEWINDOW)) && /* Bring to the top when activating */
1512             (winpos->flags & SWP_NOZORDER ||
1513              (winpos->hwndInsertAfter != HWND_TOPMOST && winpos->hwndInsertAfter != HWND_NOTOPMOST)))
1514         {
1515             winpos->flags &= ~SWP_NOZORDER;
1516             winpos->hwndInsertAfter = HWND_TOP;
1517         }
1518     }
1519
1520     /* Check hwndInsertAfter */
1521     if (winpos->flags & SWP_NOZORDER) goto done;
1522
1523     /* fix sign extension */
1524     if (winpos->hwndInsertAfter == (HWND)0xffff) winpos->hwndInsertAfter = HWND_TOPMOST;
1525     else if (winpos->hwndInsertAfter == (HWND)0xfffe) winpos->hwndInsertAfter = HWND_NOTOPMOST;
1526
1527     /* hwndInsertAfter must be a sibling of the window */
1528     if (winpos->hwndInsertAfter == HWND_TOP)
1529     {
1530         if (GetWindow(winpos->hwnd, GW_HWNDFIRST) == winpos->hwnd)
1531             winpos->flags |= SWP_NOZORDER;
1532     }
1533     else if (winpos->hwndInsertAfter == HWND_BOTTOM)
1534     {
1535         if (!(wndPtr->dwExStyle & WS_EX_TOPMOST) && GetWindow(winpos->hwnd, GW_HWNDLAST) == winpos->hwnd)
1536             winpos->flags |= SWP_NOZORDER;
1537     }
1538     else if (winpos->hwndInsertAfter == HWND_TOPMOST)
1539     {
1540         if ((wndPtr->dwExStyle & WS_EX_TOPMOST) && GetWindow(winpos->hwnd, GW_HWNDFIRST) == winpos->hwnd)
1541             winpos->flags |= SWP_NOZORDER;
1542     }
1543     else if (winpos->hwndInsertAfter == HWND_NOTOPMOST)
1544     {
1545         if (!(wndPtr->dwExStyle & WS_EX_TOPMOST))
1546             winpos->flags |= SWP_NOZORDER;
1547     }
1548     else
1549     {
1550         if (GetAncestor( winpos->hwndInsertAfter, GA_PARENT ) != parent) ret = FALSE;
1551         else
1552         {
1553             /* don't need to change the Zorder of hwnd if it's already inserted
1554              * after hwndInsertAfter or when inserting hwnd after itself.
1555              */
1556             if ((winpos->hwnd == winpos->hwndInsertAfter) ||
1557                 (winpos->hwnd == GetWindow( winpos->hwndInsertAfter, GW_HWNDNEXT )))
1558                 winpos->flags |= SWP_NOZORDER;
1559         }
1560     }
1561  done:
1562     WIN_ReleasePtr( wndPtr );
1563     return ret;
1564 }
1565
1566 /***********************************************************************
1567  *              USER_SetWindowPos
1568  *
1569  *     User32 internal function
1570  */
1571 BOOL USER_SetWindowPos( WINDOWPOS * winpos )
1572 {
1573     RECT newWindowRect, newClientRect, valid_rects[2];
1574     UINT orig_flags;
1575     
1576     orig_flags = winpos->flags;
1577     
1578     /* First make sure that coordinates are valid for WM_WINDOWPOSCHANGING */
1579     if (!(winpos->flags & SWP_NOMOVE))
1580     {
1581         if (winpos->x < -32768) winpos->x = -32768;
1582         else if (winpos->x > 32767) winpos->x = 32767;
1583         if (winpos->y < -32768) winpos->y = -32768;
1584         else if (winpos->y > 32767) winpos->y = 32767;
1585     }
1586     if (!(winpos->flags & SWP_NOSIZE))
1587     {
1588         if (winpos->cx < 0) winpos->cx = 0;
1589         else if (winpos->cx > 32767) winpos->cx = 32767;
1590         if (winpos->cy < 0) winpos->cy = 0;
1591         else if (winpos->cy > 32767) winpos->cy = 32767;
1592     }
1593
1594     if (!SWP_DoWinPosChanging( winpos, &newWindowRect, &newClientRect )) return FALSE;
1595
1596     /* Fix redundant flags */
1597     if (!fixup_flags( winpos )) return FALSE;
1598
1599     if((winpos->flags & (SWP_NOZORDER | SWP_HIDEWINDOW | SWP_SHOWWINDOW)) != SWP_NOZORDER)
1600     {
1601         if (GetAncestor( winpos->hwnd, GA_PARENT ) == GetDesktopWindow())
1602             winpos->hwndInsertAfter = SWP_DoOwnedPopups( winpos->hwnd, winpos->hwndInsertAfter );
1603     }
1604
1605     /* Common operations */
1606
1607     SWP_DoNCCalcSize( winpos, &newWindowRect, &newClientRect, valid_rects );
1608
1609     if(!USER_Driver->pSetWindowPos( winpos->hwnd, winpos->hwndInsertAfter, 
1610                             &newWindowRect, &newClientRect, orig_flags, valid_rects ))
1611         return FALSE;
1612
1613     /* erase parent when hiding or resizing child */
1614     if (!(orig_flags & SWP_DEFERERASE) &&
1615         ((orig_flags & SWP_HIDEWINDOW) ||
1616          (!(orig_flags & SWP_SHOWWINDOW) &&
1617           (winpos->flags & SWP_AGG_STATUSFLAGS) != SWP_AGG_NOGEOMETRYCHANGE)))
1618     {
1619         HWND parent = GetAncestor( winpos->hwnd, GA_PARENT );
1620         if (!parent || parent == GetDesktopWindow()) parent = winpos->hwnd;
1621         erase_now( parent, 0 );
1622     }
1623
1624     if( winpos->flags & SWP_HIDEWINDOW )
1625         HideCaret(winpos->hwnd);
1626     else if (winpos->flags & SWP_SHOWWINDOW)
1627         ShowCaret(winpos->hwnd);
1628
1629     if (!(winpos->flags & (SWP_NOACTIVATE|SWP_HIDEWINDOW)))
1630     {
1631         /* child windows get WM_CHILDACTIVATE message */
1632         if ((GetWindowLongW( winpos->hwnd, GWL_STYLE ) & (WS_CHILD | WS_POPUP)) == WS_CHILD)
1633             SendMessageW( winpos->hwnd, WM_CHILDACTIVATE, 0, 0 );
1634         else
1635             SetForegroundWindow( winpos->hwnd );
1636     }
1637
1638       /* And last, send the WM_WINDOWPOSCHANGED message */
1639
1640     TRACE("\tstatus flags = %04x\n", winpos->flags & SWP_AGG_STATUSFLAGS);
1641
1642     if (((winpos->flags & SWP_AGG_STATUSFLAGS) != SWP_AGG_NOPOSCHANGE))
1643     {
1644         /* WM_WINDOWPOSCHANGED is sent even if SWP_NOSENDCHANGING is set
1645            and always contains final window position.
1646          */
1647         winpos->x = newWindowRect.left;
1648         winpos->y = newWindowRect.top;
1649         winpos->cx = newWindowRect.right - newWindowRect.left;
1650         winpos->cy = newWindowRect.bottom - newWindowRect.top;
1651         SendMessageW( winpos->hwnd, WM_WINDOWPOSCHANGED, 0, (LPARAM)winpos );
1652     }
1653     return TRUE;
1654 }
1655
1656 /***********************************************************************
1657  *              SetWindowPos (USER32.@)
1658  */
1659 BOOL WINAPI SetWindowPos( HWND hwnd, HWND hwndInsertAfter,
1660                           INT x, INT y, INT cx, INT cy, UINT flags )
1661 {
1662     WINDOWPOS winpos;
1663
1664     TRACE("hwnd %p, after %p, %d,%d (%dx%d), flags %08x\n",
1665           hwnd, hwndInsertAfter, x, y, cx, cy, flags);
1666     if(TRACE_ON(win)) dump_winpos_flags(flags);
1667
1668     if (is_broadcast(hwnd))
1669     {
1670         SetLastError( ERROR_INVALID_PARAMETER );
1671         return FALSE;
1672     }
1673
1674     winpos.hwnd = WIN_GetFullHandle(hwnd);
1675     winpos.hwndInsertAfter = WIN_GetFullHandle(hwndInsertAfter);
1676     winpos.x = x;
1677     winpos.y = y;
1678     winpos.cx = cx;
1679     winpos.cy = cy;
1680     winpos.flags = flags;
1681     
1682     if (WIN_IsCurrentThread( hwnd ))
1683         return USER_SetWindowPos(&winpos);
1684
1685     return SendMessageW( winpos.hwnd, WM_WINE_SETWINDOWPOS, 0, (LPARAM)&winpos );
1686 }
1687
1688
1689 /***********************************************************************
1690  *              BeginDeferWindowPos (USER32.@)
1691  */
1692 HDWP WINAPI BeginDeferWindowPos( INT count )
1693 {
1694     HDWP handle;
1695     DWP *pDWP;
1696
1697     TRACE("%d\n", count);
1698
1699     if (count < 0)
1700     {
1701         SetLastError(ERROR_INVALID_PARAMETER);
1702         return 0;
1703     }
1704     /* Windows allows zero count, in which case it allocates context for 8 moves */
1705     if (count == 0) count = 8;
1706
1707     handle = USER_HEAP_ALLOC( sizeof(DWP) + (count-1)*sizeof(WINDOWPOS) );
1708     if (!handle) return 0;
1709     pDWP = (DWP *) USER_HEAP_LIN_ADDR( handle );
1710     pDWP->actualCount    = 0;
1711     pDWP->suggestedCount = count;
1712     pDWP->valid          = TRUE;
1713     pDWP->wMagic         = DWP_MAGIC;
1714     pDWP->hwndParent     = 0;
1715
1716     TRACE("returning hdwp %p\n", handle);
1717     return handle;
1718 }
1719
1720
1721 /***********************************************************************
1722  *              DeferWindowPos (USER32.@)
1723  */
1724 HDWP WINAPI DeferWindowPos( HDWP hdwp, HWND hwnd, HWND hwndAfter,
1725                                 INT x, INT y, INT cx, INT cy,
1726                                 UINT flags )
1727 {
1728     DWP *pDWP;
1729     int i;
1730     HDWP newhdwp = hdwp,retvalue;
1731
1732     TRACE("hdwp %p, hwnd %p, after %p, %d,%d (%dx%d), flags %08x\n",
1733           hdwp, hwnd, hwndAfter, x, y, cx, cy, flags);
1734
1735     hwnd = WIN_GetFullHandle( hwnd );
1736     if (hwnd == GetDesktopWindow()) return 0;
1737
1738     if (!(pDWP = USER_HEAP_LIN_ADDR( hdwp ))) return 0;
1739
1740     USER_Lock();
1741
1742     for (i = 0; i < pDWP->actualCount; i++)
1743     {
1744         if (pDWP->winPos[i].hwnd == hwnd)
1745         {
1746               /* Merge with the other changes */
1747             if (!(flags & SWP_NOZORDER))
1748             {
1749                 pDWP->winPos[i].hwndInsertAfter = WIN_GetFullHandle(hwndAfter);
1750             }
1751             if (!(flags & SWP_NOMOVE))
1752             {
1753                 pDWP->winPos[i].x = x;
1754                 pDWP->winPos[i].y = y;
1755             }
1756             if (!(flags & SWP_NOSIZE))
1757             {
1758                 pDWP->winPos[i].cx = cx;
1759                 pDWP->winPos[i].cy = cy;
1760             }
1761             pDWP->winPos[i].flags &= flags | ~(SWP_NOSIZE | SWP_NOMOVE |
1762                                                SWP_NOZORDER | SWP_NOREDRAW |
1763                                                SWP_NOACTIVATE | SWP_NOCOPYBITS|
1764                                                SWP_NOOWNERZORDER);
1765             pDWP->winPos[i].flags |= flags & (SWP_SHOWWINDOW | SWP_HIDEWINDOW |
1766                                               SWP_FRAMECHANGED);
1767             retvalue = hdwp;
1768             goto END;
1769         }
1770     }
1771     if (pDWP->actualCount >= pDWP->suggestedCount)
1772     {
1773         newhdwp = USER_HEAP_REALLOC( hdwp,
1774                       sizeof(DWP) + pDWP->suggestedCount*sizeof(WINDOWPOS) );
1775         if (!newhdwp)
1776         {
1777             retvalue = 0;
1778             goto END;
1779         }
1780         pDWP = (DWP *) USER_HEAP_LIN_ADDR( newhdwp );
1781         pDWP->suggestedCount++;
1782     }
1783     pDWP->winPos[pDWP->actualCount].hwnd = hwnd;
1784     pDWP->winPos[pDWP->actualCount].hwndInsertAfter = hwndAfter;
1785     pDWP->winPos[pDWP->actualCount].x = x;
1786     pDWP->winPos[pDWP->actualCount].y = y;
1787     pDWP->winPos[pDWP->actualCount].cx = cx;
1788     pDWP->winPos[pDWP->actualCount].cy = cy;
1789     pDWP->winPos[pDWP->actualCount].flags = flags;
1790     pDWP->actualCount++;
1791     retvalue = newhdwp;
1792 END:
1793     USER_Unlock();
1794     return retvalue;
1795 }
1796
1797
1798 /***********************************************************************
1799  *              EndDeferWindowPos (USER32.@)
1800  */
1801 BOOL WINAPI EndDeferWindowPos( HDWP hdwp )
1802 {
1803     DWP *pDWP;
1804     WINDOWPOS *winpos;
1805     BOOL res = TRUE;
1806     int i;
1807
1808     TRACE("%p\n", hdwp);
1809
1810     pDWP = (DWP *) USER_HEAP_LIN_ADDR( hdwp );
1811     if (!pDWP) return FALSE;
1812     for (i = 0, winpos = pDWP->winPos; i < pDWP->actualCount; i++, winpos++)
1813     {
1814         TRACE("hwnd %p, after %p, %d,%d (%dx%d), flags %08x\n",
1815                winpos->hwnd, winpos->hwndInsertAfter, winpos->x, winpos->y,
1816                winpos->cx, winpos->cy, winpos->flags);
1817
1818         if (!(res = USER_SetWindowPos( winpos ))) break;
1819     }
1820     USER_HEAP_FREE( hdwp );
1821     return res;
1822 }
1823
1824
1825 /***********************************************************************
1826  *              TileChildWindows (USER.199)
1827  */
1828 void WINAPI TileChildWindows16( HWND16 parent, WORD action )
1829 {
1830     FIXME("(%04x, %d): stub\n", parent, action);
1831 }
1832
1833 /***********************************************************************
1834  *              CascadeChildWindows (USER.198)
1835  */
1836 void WINAPI CascadeChildWindows16( HWND16 parent, WORD action )
1837 {
1838     FIXME("(%04x, %d): stub\n", parent, action);
1839 }