Windows treats dialog control class ids 0-5 same way as 0x80-0x85.
[wine] / windows / 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20  */
21
22 #include <string.h>
23 #include "winerror.h"
24 #include "windef.h"
25 #include "wingdi.h"
26 #include "winerror.h"
27 #include "wine/winuser16.h"
28 #include "wine/server.h"
29 #include "controls.h"
30 #include "user.h"
31 #include "win.h"
32 #include "message.h"
33 #include "winpos.h"
34 #include "nonclient.h"
35 #include "wine/debug.h"
36
37 WINE_DEFAULT_DEBUG_CHANNEL(win);
38
39 #define HAS_DLGFRAME(style,exStyle) \
40     (((exStyle) & WS_EX_DLGMODALFRAME) || \
41      (((style) & WS_DLGFRAME) && !((style) & WS_BORDER)))
42
43 #define HAS_THICKFRAME(style) \
44     (((style) & WS_THICKFRAME) && \
45      !(((style) & (WS_DLGFRAME|WS_BORDER)) == WS_DLGFRAME))
46
47 #define EMPTYPOINT(pt)          ((*(LONG*)&(pt)) == -1)
48
49 #define PLACE_MIN               0x0001
50 #define PLACE_MAX               0x0002
51 #define PLACE_RECT              0x0004
52
53
54 #define DWP_MAGIC  ((INT)('W' | ('P' << 8) | ('O' << 16) | ('S' << 24)))
55
56 typedef struct
57 {
58     INT       actualCount;
59     INT       suggestedCount;
60     BOOL      valid;
61     INT       wMagic;
62     HWND      hwndParent;
63     WINDOWPOS winPos[1];
64 } DWP;
65
66 /* ----- internal variables ----- */
67
68 static HWND hGlobalShellWindow=0; /*the shell*/
69 static HWND hGlobalTaskmanWindow=0;
70 static HWND hGlobalProgmanWindow=0;
71
72 static LPCSTR atomInternalPos;
73
74
75 /***********************************************************************
76  *           WINPOS_CreateInternalPosAtom
77  */
78 BOOL WINPOS_CreateInternalPosAtom()
79 {
80     LPSTR str = "SysIP";
81     atomInternalPos = (LPCSTR)(DWORD)GlobalAddAtomA(str);
82     return (atomInternalPos) ? TRUE : FALSE;
83 }
84
85 /***********************************************************************
86  *           WINPOS_CheckInternalPos
87  *
88  * Called when a window is destroyed.
89  */
90 void WINPOS_CheckInternalPos( HWND hwnd )
91 {
92     LPINTERNALPOS lpPos = (LPINTERNALPOS) GetPropA( hwnd, atomInternalPos );
93
94     if( lpPos )
95     {
96         if( IsWindow(lpPos->hwndIconTitle) )
97             DestroyWindow( lpPos->hwndIconTitle );
98         HeapFree( GetProcessHeap(), 0, lpPos );
99     }
100 }
101
102 /***********************************************************************
103  *              ArrangeIconicWindows (USER32.@)
104  */
105 UINT WINAPI ArrangeIconicWindows( HWND parent )
106 {
107     RECT rectParent;
108     HWND hwndChild;
109     INT x, y, xspacing, yspacing;
110
111     GetClientRect( parent, &rectParent );
112     x = rectParent.left;
113     y = rectParent.bottom;
114     xspacing = GetSystemMetrics(SM_CXICONSPACING);
115     yspacing = GetSystemMetrics(SM_CYICONSPACING);
116
117     hwndChild = GetWindow( parent, GW_CHILD );
118     while (hwndChild)
119     {
120         if( IsIconic( hwndChild ) )
121         {
122             WINPOS_ShowIconTitle( hwndChild, FALSE );
123
124             SetWindowPos( hwndChild, 0, x + (xspacing - GetSystemMetrics(SM_CXICON)) / 2,
125                             y - yspacing - GetSystemMetrics(SM_CYICON)/2, 0, 0,
126                             SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE );
127             if( IsWindow(hwndChild) )
128                 WINPOS_ShowIconTitle(hwndChild , TRUE );
129
130             if (x <= rectParent.right - xspacing) x += xspacing;
131             else
132             {
133                 x = rectParent.left;
134                 y -= yspacing;
135             }
136         }
137         hwndChild = GetWindow( hwndChild, GW_HWNDNEXT );
138     }
139     return yspacing;
140 }
141
142
143 /***********************************************************************
144  *              SwitchToThisWindow (USER32.@)
145  */
146 void WINAPI SwitchToThisWindow( HWND hwnd, BOOL restore )
147 {
148     ShowWindow( hwnd, restore ? SW_RESTORE : SW_SHOWMINIMIZED );
149 }
150
151
152 /***********************************************************************
153  *              GetWindowRect (USER32.@)
154  */
155 BOOL WINAPI GetWindowRect( HWND hwnd, LPRECT rect )
156 {
157     BOOL ret = WIN_GetRectangles( hwnd, rect, NULL );
158     if (ret)
159     {
160         MapWindowPoints( GetAncestor( hwnd, GA_PARENT ), 0, (POINT *)rect, 2 );
161         TRACE( "hwnd %p (%ld,%ld)-(%ld,%ld)\n",
162                hwnd, rect->left, rect->top, rect->right, rect->bottom);
163     }
164     return ret;
165 }
166
167
168 /***********************************************************************
169  *              GetWindowRgn (USER32.@)
170  */
171 int WINAPI GetWindowRgn ( HWND hwnd, HRGN hrgn )
172 {
173     int nRet = ERROR;
174     WND *wndPtr = WIN_GetPtr( hwnd );
175
176     if (wndPtr == WND_OTHER_PROCESS)
177     {
178         if (IsWindow( hwnd ))
179             FIXME( "not supported on other process window %p\n", hwnd );
180         wndPtr = NULL;
181     }
182     if (!wndPtr)
183     {
184         SetLastError( ERROR_INVALID_WINDOW_HANDLE );
185         return ERROR;
186     }
187     if (wndPtr->hrgnWnd) nRet = CombineRgn( hrgn, wndPtr->hrgnWnd, 0, RGN_COPY );
188     WIN_ReleasePtr( wndPtr );
189     return nRet;
190 }
191
192
193 /***********************************************************************
194  *              SetWindowRgn (USER32.@)
195  */
196 int WINAPI SetWindowRgn( HWND hwnd, HRGN hrgn, BOOL bRedraw )
197 {
198     RECT rect;
199     WND *wndPtr;
200
201     if (hrgn) /* verify that region really exists */
202     {
203         if (GetRgnBox( hrgn, &rect ) == ERROR) return FALSE;
204     }
205
206     if (USER_Driver.pSetWindowRgn)
207         return USER_Driver.pSetWindowRgn( hwnd, hrgn, bRedraw );
208
209     if ((wndPtr = WIN_GetPtr( hwnd )) == WND_OTHER_PROCESS)
210     {
211         if (IsWindow( hwnd ))
212             FIXME( "not supported on other process window %p\n", hwnd );
213         wndPtr = NULL;
214     }
215     if (!wndPtr)
216     {
217         SetLastError( ERROR_INVALID_WINDOW_HANDLE );
218         return FALSE;
219     }
220
221     if (wndPtr->hrgnWnd == hrgn)
222     {
223         WIN_ReleasePtr( wndPtr );
224         return TRUE;
225     }
226
227     if (wndPtr->hrgnWnd)
228     {
229         /* delete previous region */
230         DeleteObject(wndPtr->hrgnWnd);
231         wndPtr->hrgnWnd = 0;
232     }
233     wndPtr->hrgnWnd = hrgn;
234     WIN_ReleasePtr( wndPtr );
235
236     /* Size the window to the rectangle of the new region (if it isn't NULL) */
237     if (hrgn) SetWindowPos( hwnd, 0, rect.left, rect.top,
238                             rect.right  - rect.left, rect.bottom - rect.top,
239                             SWP_NOSIZE | SWP_FRAMECHANGED | SWP_NOMOVE | SWP_NOACTIVATE |
240                             SWP_NOZORDER | (bRedraw ? 0 : SWP_NOREDRAW) );
241     return TRUE;
242 }
243
244
245 /***********************************************************************
246  *              GetClientRect (USER32.@)
247  */
248 BOOL WINAPI GetClientRect( HWND hwnd, LPRECT rect )
249 {
250     BOOL ret;
251
252     rect->right = rect->bottom = 0;
253     if ((ret = WIN_GetRectangles( hwnd, NULL, rect )))
254     {
255         rect->right -= rect->left;
256         rect->bottom -= rect->top;
257     }
258     rect->left = rect->top = 0;
259     return ret;
260 }
261
262
263 /*******************************************************************
264  *              ClientToScreen (USER32.@)
265  */
266 BOOL WINAPI ClientToScreen( HWND hwnd, LPPOINT lppnt )
267 {
268     MapWindowPoints( hwnd, 0, lppnt, 1 );
269     return TRUE;
270 }
271
272
273 /*******************************************************************
274  *              ScreenToClient (USER32.@)
275  */
276 BOOL WINAPI ScreenToClient( HWND hwnd, LPPOINT lppnt )
277 {
278     MapWindowPoints( 0, hwnd, lppnt, 1 );
279     return TRUE;
280 }
281
282
283 /***********************************************************************
284  *           find_child_from_point
285  *
286  * Find the child that contains pt. Helper for WindowFromPoint.
287  * pt is in parent client coordinates.
288  * lparam is the param to pass in the WM_NCHITTEST message.
289  */
290 static HWND find_child_from_point( HWND parent, POINT pt, INT *hittest, LPARAM lparam )
291 {
292     int i, res;
293     LONG style, exstyle;
294     RECT rectWindow, rectClient;
295     WND *wndPtr;
296     HWND *list = WIN_ListChildren( parent );
297     HWND retvalue = 0;
298
299     if (!list) return 0;
300     for (i = 0; list[i]; i++)
301     {
302         /* If point is in window, and window is visible, and it  */
303         /* is enabled (or it's a top-level window), then explore */
304         /* its children. Otherwise, go to the next window.       */
305
306         style = GetWindowLongW( list[i], GWL_STYLE );
307         if (!(style & WS_VISIBLE)) continue;  /* not visible -> skip */
308         if ((style & (WS_POPUP | WS_CHILD | WS_DISABLED)) == (WS_CHILD | WS_DISABLED))
309             continue;  /* disabled child -> skip */
310         exstyle = GetWindowLongW( list[i], GWL_EXSTYLE );
311         if ((exstyle & (WS_EX_LAYERED | WS_EX_TRANSPARENT)) == (WS_EX_LAYERED | WS_EX_TRANSPARENT))
312             continue;  /* transparent -> skip */
313
314         if (!WIN_GetRectangles( list[i], &rectWindow, &rectClient )) continue;
315         if (!PtInRect( &rectWindow, pt )) continue;  /* not in window -> skip */
316
317         /* FIXME: check window region for other processes too */
318         if ((wndPtr = WIN_GetPtr( list[i] )) && wndPtr != WND_OTHER_PROCESS)
319         {
320             if (wndPtr->hrgnWnd && !PtInRegion( wndPtr->hrgnWnd,
321                                                 pt.x - rectWindow.left, pt.y - rectWindow.top ))
322             {
323                 WIN_ReleasePtr( wndPtr );
324                 continue;  /* point outside window region -> skip */
325             }
326             WIN_ReleasePtr( wndPtr );
327         }
328
329         /* If window is minimized or disabled, return at once */
330         if (style & WS_MINIMIZE)
331         {
332             *hittest = HTCAPTION;
333             retvalue = list[i];
334             break;
335         }
336         if (style & WS_DISABLED)
337         {
338             *hittest = HTERROR;
339             retvalue = list[i];
340             break;
341         }
342
343         /* If point is in client area, explore children */
344         if (PtInRect( &rectClient, pt ))
345         {
346             POINT new_pt;
347
348             new_pt.x = pt.x - rectClient.left;
349             new_pt.y = pt.y - rectClient.top;
350             if ((retvalue = find_child_from_point( list[i], new_pt, hittest, lparam ))) break;
351         }
352
353         /* Now it's inside window, send WM_NCCHITTEST (if same thread) */
354         if (!WIN_IsCurrentThread( list[i] ))
355         {
356             *hittest = HTCLIENT;
357             retvalue = list[i];
358             break;
359         }
360         if ((res = SendMessageA( list[i], WM_NCHITTEST, 0, lparam )) != HTTRANSPARENT)
361         {
362             *hittest = res;  /* Found the window */
363             retvalue = list[i];
364             break;
365         }
366         /* continue search with next sibling */
367     }
368     HeapFree( GetProcessHeap(), 0, list );
369     return retvalue;
370 }
371
372
373 /***********************************************************************
374  *           WINPOS_WindowFromPoint
375  *
376  * Find the window and hittest for a given point.
377  */
378 HWND WINPOS_WindowFromPoint( HWND hwndScope, POINT pt, INT *hittest )
379 {
380     POINT xy = pt;
381     int res;
382     LONG style;
383
384     TRACE("scope %p %ld,%ld\n", hwndScope, pt.x, pt.y);
385
386     if (!hwndScope) hwndScope = GetDesktopWindow();
387     style = GetWindowLongW( hwndScope, GWL_STYLE );
388
389     *hittest = HTERROR;
390     if (style & WS_DISABLED) return 0;
391
392     MapWindowPoints( GetDesktopWindow(), GetAncestor( hwndScope, GA_PARENT ), &xy, 1 );
393
394     if (!(style & WS_MINIMIZE))
395     {
396         RECT rectClient;
397         if (WIN_GetRectangles( hwndScope, NULL, &rectClient ) && PtInRect( &rectClient, xy ))
398         {
399             HWND ret;
400
401             xy.x -= rectClient.left;
402             xy.y -= rectClient.top;
403             if ((ret = find_child_from_point( hwndScope, xy, hittest, MAKELONG( pt.x, pt.y ) )))
404             {
405                 TRACE( "found child %p\n", ret );
406                 return ret;
407             }
408         }
409     }
410
411     /* If nothing found, try the scope window */
412     if (!WIN_IsCurrentThread( hwndScope ))
413     {
414         *hittest = HTCLIENT;
415         TRACE( "returning %p\n", hwndScope );
416         return hwndScope;
417     }
418     res = SendMessageA( hwndScope, WM_NCHITTEST, 0, MAKELONG( pt.x, pt.y ) );
419     if (res != HTTRANSPARENT)
420     {
421         *hittest = res;  /* Found the window */
422         TRACE( "returning %p\n", hwndScope );
423         return hwndScope;
424     }
425     *hittest = HTNOWHERE;
426     TRACE( "nothing found\n" );
427     return 0;
428 }
429
430
431 /*******************************************************************
432  *              WindowFromPoint (USER32.@)
433  */
434 HWND WINAPI WindowFromPoint( POINT pt )
435 {
436     INT hittest;
437     return WINPOS_WindowFromPoint( 0, pt, &hittest );
438 }
439
440
441 /*******************************************************************
442  *              ChildWindowFromPoint (USER32.@)
443  */
444 HWND WINAPI ChildWindowFromPoint( HWND hwndParent, POINT pt )
445 {
446     return ChildWindowFromPointEx( hwndParent, pt, CWP_ALL );
447 }
448
449 /*******************************************************************
450  *              ChildWindowFromPointEx (USER32.@)
451  */
452 HWND WINAPI ChildWindowFromPointEx( HWND hwndParent, POINT pt, UINT uFlags)
453 {
454     /* pt is in the client coordinates */
455     HWND *list;
456     int i;
457     RECT rect;
458     HWND retvalue;
459
460     GetClientRect( hwndParent, &rect );
461     if (!PtInRect( &rect, pt )) return 0;
462     if (!(list = WIN_ListChildren( hwndParent ))) return 0;
463
464     for (i = 0; list[i]; i++)
465     {
466         if (!WIN_GetRectangles( list[i], &rect, NULL )) continue;
467         if (!PtInRect( &rect, pt )) continue;
468         if (uFlags & (CWP_SKIPINVISIBLE|CWP_SKIPDISABLED))
469         {
470             LONG style = GetWindowLongW( list[i], GWL_STYLE );
471             if ((uFlags & CWP_SKIPINVISIBLE) && !(style & WS_VISIBLE)) continue;
472             if ((uFlags & CWP_SKIPDISABLED) && (style & WS_DISABLED)) continue;
473         }
474         if (uFlags & CWP_SKIPTRANSPARENT)
475         {
476             if (GetWindowLongW( list[i], GWL_EXSTYLE ) & WS_EX_TRANSPARENT) continue;
477         }
478         break;
479     }
480     retvalue = list[i];
481     HeapFree( GetProcessHeap(), 0, list );
482     if (!retvalue) retvalue = hwndParent;
483     return retvalue;
484 }
485
486
487 /*******************************************************************
488  *         WINPOS_GetWinOffset
489  *
490  * Calculate the offset between the origin of the two windows. Used
491  * to implement MapWindowPoints.
492  */
493 static void WINPOS_GetWinOffset( HWND hwndFrom, HWND hwndTo, POINT *offset )
494 {
495     WND * wndPtr;
496
497     offset->x = offset->y = 0;
498
499     /* Translate source window origin to screen coords */
500     if (hwndFrom)
501     {
502         HWND hwnd = hwndFrom;
503
504         while (hwnd)
505         {
506             if (hwnd == hwndTo) return;
507             if (!(wndPtr = WIN_GetPtr( hwnd )))
508             {
509                 ERR( "bad hwndFrom = %p\n", hwnd );
510                 return;
511             }
512             if (wndPtr == WND_OTHER_PROCESS) goto other_process;
513             offset->x += wndPtr->rectClient.left;
514             offset->y += wndPtr->rectClient.top;
515             hwnd = wndPtr->parent;
516             WIN_ReleasePtr( wndPtr );
517         }
518     }
519
520     /* Translate origin to destination window coords */
521     if (hwndTo)
522     {
523         HWND hwnd = hwndTo;
524
525         while (hwnd)
526         {
527             if (!(wndPtr = WIN_GetPtr( hwnd )))
528             {
529                 ERR( "bad hwndTo = %p\n", hwnd );
530                 return;
531             }
532             if (wndPtr == WND_OTHER_PROCESS) goto other_process;
533             offset->x -= wndPtr->rectClient.left;
534             offset->y -= wndPtr->rectClient.top;
535             hwnd = wndPtr->parent;
536             WIN_ReleasePtr( wndPtr );
537         }
538     }
539     return;
540
541  other_process:  /* one of the parents may belong to another process, do it the hard way */
542     offset->x = offset->y = 0;
543     SERVER_START_REQ( get_windows_offset )
544     {
545         req->from = hwndFrom;
546         req->to   = hwndTo;
547         if (!wine_server_call( req ))
548         {
549             offset->x = reply->x;
550             offset->y = reply->y;
551         }
552     }
553     SERVER_END_REQ;
554 }
555
556
557 /*******************************************************************
558  *              MapWindowPoints (USER.258)
559  */
560 void WINAPI MapWindowPoints16( HWND16 hwndFrom, HWND16 hwndTo,
561                                LPPOINT16 lppt, UINT16 count )
562 {
563     POINT offset;
564
565     WINPOS_GetWinOffset( WIN_Handle32(hwndFrom), WIN_Handle32(hwndTo), &offset );
566     while (count--)
567     {
568         lppt->x += offset.x;
569         lppt->y += offset.y;
570         lppt++;
571     }
572 }
573
574
575 /*******************************************************************
576  *              MapWindowPoints (USER32.@)
577  */
578 INT WINAPI MapWindowPoints( HWND hwndFrom, HWND hwndTo, LPPOINT lppt, UINT count )
579 {
580     POINT offset;
581
582     WINPOS_GetWinOffset( hwndFrom, hwndTo, &offset );
583     while (count--)
584     {
585         lppt->x += offset.x;
586         lppt->y += offset.y;
587         lppt++;
588     }
589     return MAKELONG( LOWORD(offset.x), LOWORD(offset.y) );
590 }
591
592
593 /***********************************************************************
594  *              IsIconic (USER32.@)
595  */
596 BOOL WINAPI IsIconic(HWND hWnd)
597 {
598     return (GetWindowLongW( hWnd, GWL_STYLE ) & WS_MINIMIZE) != 0;
599 }
600
601
602 /***********************************************************************
603  *              IsZoomed (USER32.@)
604  */
605 BOOL WINAPI IsZoomed(HWND hWnd)
606 {
607     return (GetWindowLongW( hWnd, GWL_STYLE ) & WS_MAXIMIZE) != 0;
608 }
609
610
611 /*******************************************************************
612  *              AllowSetForegroundWindow (USER32.@)
613  */
614 BOOL WINAPI AllowSetForegroundWindow( DWORD procid )
615 {
616     /* FIXME: If Win98/2000 style SetForegroundWindow behavior is
617      * implemented, then fix this function. */
618     return TRUE;
619 }
620
621
622 /*******************************************************************
623  *              LockSetForegroundWindow (USER32.@)
624  */
625 BOOL WINAPI LockSetForegroundWindow( UINT lockcode )
626 {
627     /* FIXME: If Win98/2000 style SetForegroundWindow behavior is
628      * implemented, then fix this function. */
629     return TRUE;
630 }
631
632
633 /*******************************************************************
634  *              SetShellWindow (USER32.@)
635  */
636 HWND WINAPI SetShellWindow(HWND hwndshell)
637 {   WARN("(hWnd=%p) semi stub\n",hwndshell );
638
639     hGlobalShellWindow = WIN_GetFullHandle( hwndshell );
640     return hGlobalShellWindow;
641 }
642
643
644 /*******************************************************************
645  *              GetShellWindow (USER32.@)
646  */
647 HWND WINAPI GetShellWindow(void)
648 {   WARN("(hWnd=%p) semi stub\n",hGlobalShellWindow );
649
650     return hGlobalShellWindow;
651 }
652
653
654 /***********************************************************************
655  *              BringWindowToTop (USER32.@)
656  */
657 BOOL WINAPI BringWindowToTop( HWND hwnd )
658 {
659     return SetWindowPos( hwnd, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE );
660 }
661
662
663 /***********************************************************************
664  *              MoveWindow (USER32.@)
665  */
666 BOOL WINAPI MoveWindow( HWND hwnd, INT x, INT y, INT cx, INT cy,
667                             BOOL repaint )
668 {
669     int flags = SWP_NOZORDER | SWP_NOACTIVATE;
670     if (!repaint) flags |= SWP_NOREDRAW;
671     TRACE("%p %d,%d %dx%d %d\n", hwnd, x, y, cx, cy, repaint );
672     return SetWindowPos( hwnd, 0, x, y, cx, cy, flags );
673 }
674
675 /***********************************************************************
676  *           WINPOS_InitInternalPos
677  */
678 static LPINTERNALPOS WINPOS_InitInternalPos( WND* wnd, POINT pt, const RECT *restoreRect )
679 {
680     LPINTERNALPOS lpPos = (LPINTERNALPOS) GetPropA( wnd->hwndSelf,
681                                                       atomInternalPos );
682     if( !lpPos )
683     {
684         /* this happens when the window is minimized/maximized
685          * for the first time (rectWindow is not adjusted yet) */
686
687         lpPos = HeapAlloc( GetProcessHeap(), 0, sizeof(INTERNALPOS) );
688         if( !lpPos ) return NULL;
689
690         SetPropA( wnd->hwndSelf, atomInternalPos, (HANDLE)lpPos );
691         lpPos->hwndIconTitle = 0; /* defer until needs to be shown */
692         CONV_RECT32TO16( &wnd->rectWindow, &lpPos->rectNormal );
693         *(UINT*)&lpPos->ptIconPos = *(UINT*)&lpPos->ptMaxPos = 0xFFFFFFFF;
694     }
695
696     if( wnd->dwStyle & WS_MINIMIZE )
697         CONV_POINT32TO16( &pt, &lpPos->ptIconPos );
698     else if( wnd->dwStyle & WS_MAXIMIZE )
699         CONV_POINT32TO16( &pt, &lpPos->ptMaxPos );
700     else if( restoreRect )
701         CONV_RECT32TO16( restoreRect, &lpPos->rectNormal );
702
703     return lpPos;
704 }
705
706 /***********************************************************************
707  *           WINPOS_RedrawIconTitle
708  */
709 BOOL WINPOS_RedrawIconTitle( HWND hWnd )
710 {
711     LPINTERNALPOS lpPos = (LPINTERNALPOS)GetPropA( hWnd, atomInternalPos );
712     if( lpPos )
713     {
714         if( lpPos->hwndIconTitle )
715         {
716             SendMessageA( lpPos->hwndIconTitle, WM_SHOWWINDOW, TRUE, 0);
717             InvalidateRect( lpPos->hwndIconTitle, NULL, TRUE );
718             return TRUE;
719         }
720     }
721     return FALSE;
722 }
723
724 /***********************************************************************
725  *           WINPOS_ShowIconTitle
726  */
727 BOOL WINPOS_ShowIconTitle( HWND hwnd, BOOL bShow )
728 {
729     LPINTERNALPOS lpPos = (LPINTERNALPOS)GetPropA( hwnd, atomInternalPos );
730
731     if( lpPos && !(GetWindowLongA( hwnd, GWL_EXSTYLE) & WS_EX_MANAGED))
732     {
733         HWND title = lpPos->hwndIconTitle;
734
735         TRACE("%p %i\n", hwnd, (bShow != 0) );
736
737         if( !title )
738             lpPos->hwndIconTitle = title = ICONTITLE_Create( hwnd );
739         if( bShow )
740         {
741             if (!IsWindowVisible(title))
742             {
743                 SendMessageA( title, WM_SHOWWINDOW, TRUE, 0 );
744                 SetWindowPos( title, 0, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE |
745                               SWP_NOACTIVATE | SWP_NOZORDER | SWP_SHOWWINDOW );
746             }
747         }
748         else ShowWindow( title, SW_HIDE );
749     }
750     return FALSE;
751 }
752
753 /*******************************************************************
754  *           WINPOS_GetMinMaxInfo
755  *
756  * Get the minimized and maximized information for a window.
757  */
758 void WINPOS_GetMinMaxInfo( HWND hwnd, POINT *maxSize, POINT *maxPos,
759                            POINT *minTrack, POINT *maxTrack )
760 {
761     LPINTERNALPOS lpPos;
762     MINMAXINFO MinMax;
763     INT xinc, yinc;
764     LONG style = GetWindowLongA( hwnd, GWL_STYLE );
765     LONG exstyle = GetWindowLongA( hwnd, GWL_EXSTYLE );
766
767     /* Compute default values */
768
769     MinMax.ptMaxSize.x = GetSystemMetrics(SM_CXSCREEN);
770     MinMax.ptMaxSize.y = GetSystemMetrics(SM_CYSCREEN);
771     MinMax.ptMinTrackSize.x = GetSystemMetrics(SM_CXMINTRACK);
772     MinMax.ptMinTrackSize.y = GetSystemMetrics(SM_CYMINTRACK);
773     MinMax.ptMaxTrackSize.x = GetSystemMetrics(SM_CXSCREEN);
774     MinMax.ptMaxTrackSize.y = GetSystemMetrics(SM_CYSCREEN);
775
776     if (HAS_DLGFRAME( style, exstyle ))
777     {
778         xinc = GetSystemMetrics(SM_CXDLGFRAME);
779         yinc = GetSystemMetrics(SM_CYDLGFRAME);
780     }
781     else
782     {
783         xinc = yinc = 0;
784         if (HAS_THICKFRAME(style))
785         {
786             xinc += GetSystemMetrics(SM_CXFRAME);
787             yinc += GetSystemMetrics(SM_CYFRAME);
788         }
789         if (style & WS_BORDER)
790         {
791             xinc += GetSystemMetrics(SM_CXBORDER);
792             yinc += GetSystemMetrics(SM_CYBORDER);
793         }
794     }
795     MinMax.ptMaxSize.x += 2 * xinc;
796     MinMax.ptMaxSize.y += 2 * yinc;
797
798     lpPos = (LPINTERNALPOS)GetPropA( hwnd, atomInternalPos );
799     if( lpPos && !EMPTYPOINT(lpPos->ptMaxPos) )
800         CONV_POINT16TO32( &lpPos->ptMaxPos, &MinMax.ptMaxPosition );
801     else
802     {
803         MinMax.ptMaxPosition.x = -xinc;
804         MinMax.ptMaxPosition.y = -yinc;
805     }
806
807     SendMessageA( hwnd, WM_GETMINMAXINFO, 0, (LPARAM)&MinMax );
808
809       /* Some sanity checks */
810
811     TRACE("%ld %ld / %ld %ld / %ld %ld / %ld %ld\n",
812                       MinMax.ptMaxSize.x, MinMax.ptMaxSize.y,
813                       MinMax.ptMaxPosition.x, MinMax.ptMaxPosition.y,
814                       MinMax.ptMaxTrackSize.x, MinMax.ptMaxTrackSize.y,
815                       MinMax.ptMinTrackSize.x, MinMax.ptMinTrackSize.y);
816     MinMax.ptMaxTrackSize.x = max( MinMax.ptMaxTrackSize.x,
817                                    MinMax.ptMinTrackSize.x );
818     MinMax.ptMaxTrackSize.y = max( MinMax.ptMaxTrackSize.y,
819                                    MinMax.ptMinTrackSize.y );
820
821     if (maxSize) *maxSize = MinMax.ptMaxSize;
822     if (maxPos) *maxPos = MinMax.ptMaxPosition;
823     if (minTrack) *minTrack = MinMax.ptMinTrackSize;
824     if (maxTrack) *maxTrack = MinMax.ptMaxTrackSize;
825 }
826
827 /***********************************************************************
828  *              ShowWindowAsync (USER32.@)
829  *
830  * doesn't wait; returns immediately.
831  * used by threads to toggle windows in other (possibly hanging) threads
832  */
833 BOOL WINAPI ShowWindowAsync( HWND hwnd, INT cmd )
834 {
835     HWND full_handle;
836
837     if ((full_handle = WIN_IsCurrentThread( hwnd )))
838         return USER_Driver.pShowWindow( full_handle, cmd );
839     return SendNotifyMessageW( hwnd, WM_WINE_SHOWWINDOW, cmd, 0 );
840 }
841
842
843 /***********************************************************************
844  *              ShowWindow (USER32.@)
845  */
846 BOOL WINAPI ShowWindow( HWND hwnd, INT cmd )
847 {
848     HWND full_handle;
849
850     if ((full_handle = WIN_IsCurrentThread( hwnd )))
851         return USER_Driver.pShowWindow( full_handle, cmd );
852     return SendMessageW( hwnd, WM_WINE_SHOWWINDOW, cmd, 0 );
853 }
854
855
856 /***********************************************************************
857  *              GetInternalWindowPos (USER32.@)
858  */
859 UINT WINAPI GetInternalWindowPos( HWND hwnd, LPRECT rectWnd,
860                                       LPPOINT ptIcon )
861 {
862     WINDOWPLACEMENT wndpl;
863     if (GetWindowPlacement( hwnd, &wndpl ))
864     {
865         if (rectWnd) *rectWnd = wndpl.rcNormalPosition;
866         if (ptIcon)  *ptIcon = wndpl.ptMinPosition;
867         return wndpl.showCmd;
868     }
869     return 0;
870 }
871
872
873 /***********************************************************************
874  *              GetWindowPlacement (USER32.@)
875  *
876  * Win95:
877  * Fails if wndpl->length of Win95 (!) apps is invalid.
878  */
879 BOOL WINAPI GetWindowPlacement( HWND hwnd, WINDOWPLACEMENT *wndpl )
880 {
881     WND *pWnd = WIN_FindWndPtr( hwnd );
882     LPINTERNALPOS lpPos;
883
884     if(!pWnd ) return FALSE;
885
886     lpPos = WINPOS_InitInternalPos( pWnd, *(LPPOINT)&pWnd->rectWindow.left, &pWnd->rectWindow );
887     wndpl->length  = sizeof(*wndpl);
888     if( pWnd->dwStyle & WS_MINIMIZE )
889         wndpl->showCmd = SW_SHOWMINIMIZED;
890     else
891         wndpl->showCmd = ( pWnd->dwStyle & WS_MAXIMIZE ) ? SW_SHOWMAXIMIZED : SW_SHOWNORMAL ;
892     if( pWnd->flags & WIN_RESTORE_MAX )
893         wndpl->flags = WPF_RESTORETOMAXIMIZED;
894     else
895         wndpl->flags = 0;
896     CONV_POINT16TO32( &lpPos->ptIconPos, &wndpl->ptMinPosition );
897     CONV_POINT16TO32( &lpPos->ptMaxPos, &wndpl->ptMaxPosition );
898     CONV_RECT16TO32( &lpPos->rectNormal, &wndpl->rcNormalPosition );
899     WIN_ReleaseWndPtr(pWnd);
900     return TRUE;
901 }
902
903
904 /***********************************************************************
905  *           WINPOS_SetPlacement
906  */
907 static BOOL WINPOS_SetPlacement( HWND hwnd, const WINDOWPLACEMENT *wndpl, UINT flags )
908 {
909     WND *pWnd = WIN_FindWndPtr( hwnd );
910     if( pWnd )
911     {
912         LPINTERNALPOS lpPos = (LPINTERNALPOS)WINPOS_InitInternalPos( pWnd,
913                              *(LPPOINT)&pWnd->rectWindow.left, &pWnd->rectWindow );
914
915         if( flags & PLACE_MIN ) CONV_POINT32TO16( &wndpl->ptMinPosition, &lpPos->ptIconPos );
916         if( flags & PLACE_MAX ) CONV_POINT32TO16( &wndpl->ptMaxPosition, &lpPos->ptMaxPos );
917         if( flags & PLACE_RECT) CONV_RECT32TO16( &wndpl->rcNormalPosition, &lpPos->rectNormal );
918
919         if( pWnd->dwStyle & WS_MINIMIZE )
920         {
921             WINPOS_ShowIconTitle( pWnd->hwndSelf, FALSE );
922             if( wndpl->flags & WPF_SETMINPOSITION && !EMPTYPOINT(lpPos->ptIconPos))
923                 SetWindowPos( hwnd, 0, lpPos->ptIconPos.x, lpPos->ptIconPos.y,
924                                 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE );
925         }
926         else if( pWnd->dwStyle & WS_MAXIMIZE )
927         {
928             if( !EMPTYPOINT(lpPos->ptMaxPos) )
929                 SetWindowPos( hwnd, 0, lpPos->ptMaxPos.x, lpPos->ptMaxPos.y,
930                                 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE );
931         }
932         else if( flags & PLACE_RECT )
933                 SetWindowPos( hwnd, 0, lpPos->rectNormal.left, lpPos->rectNormal.top,
934                                 lpPos->rectNormal.right - lpPos->rectNormal.left,
935                                 lpPos->rectNormal.bottom - lpPos->rectNormal.top,
936                                 SWP_NOZORDER | SWP_NOACTIVATE );
937
938         ShowWindow( hwnd, wndpl->showCmd );
939         if( IsWindow(hwnd) && pWnd->dwStyle & WS_MINIMIZE )
940         {
941             if( pWnd->dwStyle & WS_VISIBLE ) WINPOS_ShowIconTitle( pWnd->hwndSelf, TRUE );
942
943             /* SDK: ...valid only the next time... */
944             if( wndpl->flags & WPF_RESTORETOMAXIMIZED ) pWnd->flags |= WIN_RESTORE_MAX;
945         }
946         WIN_ReleaseWndPtr(pWnd);
947         return TRUE;
948     }
949     return FALSE;
950 }
951
952
953 /***********************************************************************
954  *              SetWindowPlacement (USER32.@)
955  *
956  * Win95:
957  * Fails if wndpl->length of Win95 (!) apps is invalid.
958  */
959 BOOL WINAPI SetWindowPlacement( HWND hwnd, const WINDOWPLACEMENT *wpl )
960 {
961     if (!wpl) return FALSE;
962     return WINPOS_SetPlacement( hwnd, wpl, PLACE_MIN | PLACE_MAX | PLACE_RECT );
963 }
964
965
966 /***********************************************************************
967  *              AnimateWindow (USER32.@)
968  *              Shows/Hides a window with an animation
969  *              NO ANIMATION YET
970  */
971 BOOL WINAPI AnimateWindow(HWND hwnd, DWORD dwTime, DWORD dwFlags)
972 {
973         FIXME("partial stub\n");
974
975         /* If trying to show/hide and it's already   *
976          * shown/hidden or invalid window, fail with *
977          * invalid parameter                         */
978         if(!IsWindow(hwnd) ||
979            (IsWindowVisible(hwnd) && !(dwFlags & AW_HIDE)) ||
980            (!IsWindowVisible(hwnd) && (dwFlags & AW_HIDE)))
981         {
982                 SetLastError(ERROR_INVALID_PARAMETER);
983                 return FALSE;
984         }
985
986         ShowWindow(hwnd, (dwFlags & AW_HIDE) ? SW_HIDE : ((dwFlags & AW_ACTIVATE) ? SW_SHOW : SW_SHOWNA));
987
988         return TRUE;
989 }
990
991 /***********************************************************************
992  *              SetInternalWindowPos (USER32.@)
993  */
994 void WINAPI SetInternalWindowPos( HWND hwnd, UINT showCmd,
995                                     LPRECT rect, LPPOINT pt )
996 {
997     if( IsWindow(hwnd) )
998     {
999         WINDOWPLACEMENT wndpl;
1000         UINT flags;
1001
1002         wndpl.length  = sizeof(wndpl);
1003         wndpl.showCmd = showCmd;
1004         wndpl.flags = flags = 0;
1005
1006         if( pt )
1007         {
1008             flags |= PLACE_MIN;
1009             wndpl.flags |= WPF_SETMINPOSITION;
1010             wndpl.ptMinPosition = *pt;
1011         }
1012         if( rect )
1013         {
1014             flags |= PLACE_RECT;
1015             wndpl.rcNormalPosition = *rect;
1016         }
1017         WINPOS_SetPlacement( hwnd, &wndpl, flags );
1018     }
1019 }
1020
1021
1022 /*******************************************************************
1023  *         can_activate_window
1024  *
1025  * Check if we can activate the specified window.
1026  */
1027 static BOOL can_activate_window( HWND hwnd )
1028 {
1029     LONG style;
1030
1031     if (!hwnd) return FALSE;
1032     style = GetWindowLongW( hwnd, GWL_STYLE );
1033     if (!(style & WS_VISIBLE)) return FALSE;
1034     if ((style & (WS_POPUP|WS_CHILD)) == WS_CHILD) return FALSE;
1035     return !(style & WS_DISABLED);
1036 }
1037
1038
1039 /*******************************************************************
1040  *         WINPOS_ActivateOtherWindow
1041  *
1042  *  Activates window other than pWnd.
1043  */
1044 void WINPOS_ActivateOtherWindow(HWND hwnd)
1045 {
1046     HWND hwndTo, fg;
1047
1048     if ((GetWindowLongW( hwnd, GWL_STYLE ) & WS_POPUP) && (hwndTo = GetWindow( hwnd, GW_OWNER )))
1049     {
1050         hwndTo = GetAncestor( hwndTo, GA_ROOT );
1051         if (can_activate_window( hwndTo )) goto done;
1052     }
1053
1054     hwndTo = hwnd;
1055     for (;;)
1056     {
1057         if (!(hwndTo = GetWindow( hwndTo, GW_HWNDNEXT ))) break;
1058         if (can_activate_window( hwndTo )) break;
1059     }
1060
1061  done:
1062     fg = GetForegroundWindow();
1063     TRACE("win = %p fg = %p\n", hwndTo, fg);
1064     if (!fg || (hwnd == fg))
1065     {
1066         if (SetForegroundWindow( hwndTo )) return;
1067     }
1068     if (!SetActiveWindow( hwndTo )) SetActiveWindow(0);
1069 }
1070
1071
1072 /***********************************************************************
1073  *           WINPOS_HandleWindowPosChanging16
1074  *
1075  * Default handling for a WM_WINDOWPOSCHANGING. Called from DefWindowProc().
1076  */
1077 LONG WINPOS_HandleWindowPosChanging16( HWND hwnd, WINDOWPOS16 *winpos )
1078 {
1079     POINT maxSize, minTrack;
1080     LONG style = GetWindowLongA( hwnd, GWL_STYLE );
1081
1082     if (winpos->flags & SWP_NOSIZE) return 0;
1083     if ((style & WS_THICKFRAME) || ((style & (WS_POPUP | WS_CHILD)) == 0))
1084     {
1085         WINPOS_GetMinMaxInfo( hwnd, &maxSize, NULL, &minTrack, NULL );
1086         if (maxSize.x < winpos->cx) winpos->cx = maxSize.x;
1087         if (maxSize.y < winpos->cy) winpos->cy = maxSize.y;
1088         if (!(style & WS_MINIMIZE))
1089         {
1090             if (winpos->cx < minTrack.x ) winpos->cx = minTrack.x;
1091             if (winpos->cy < minTrack.y ) winpos->cy = minTrack.y;
1092         }
1093     }
1094     return 0;
1095 }
1096
1097
1098 /***********************************************************************
1099  *           WINPOS_HandleWindowPosChanging
1100  *
1101  * Default handling for a WM_WINDOWPOSCHANGING. Called from DefWindowProc().
1102  */
1103 LONG WINPOS_HandleWindowPosChanging( HWND hwnd, WINDOWPOS *winpos )
1104 {
1105     POINT maxSize, minTrack;
1106     LONG style = GetWindowLongA( hwnd, GWL_STYLE );
1107
1108     if (winpos->flags & SWP_NOSIZE) return 0;
1109     if ((style & WS_THICKFRAME) || ((style & (WS_POPUP | WS_CHILD)) == 0))
1110     {
1111         WINPOS_GetMinMaxInfo( hwnd, &maxSize, NULL, &minTrack, NULL );
1112         winpos->cx = min( winpos->cx, maxSize.x );
1113         winpos->cy = min( winpos->cy, maxSize.y );
1114         if (!(style & WS_MINIMIZE))
1115         {
1116             if (winpos->cx < minTrack.x ) winpos->cx = minTrack.x;
1117             if (winpos->cy < minTrack.y ) winpos->cy = minTrack.y;
1118         }
1119     }
1120     return 0;
1121 }
1122
1123
1124 /***********************************************************************
1125  *           dump_winpos_flags
1126  */
1127 static void dump_winpos_flags(UINT flags)
1128 {
1129     TRACE("flags:");
1130     if(flags & SWP_NOSIZE) TRACE(" SWP_NOSIZE");
1131     if(flags & SWP_NOMOVE) TRACE(" SWP_NOMOVE");
1132     if(flags & SWP_NOZORDER) TRACE(" SWP_NOZORDER");
1133     if(flags & SWP_NOREDRAW) TRACE(" SWP_NOREDRAW");
1134     if(flags & SWP_NOACTIVATE) TRACE(" SWP_NOACTIVATE");
1135     if(flags & SWP_FRAMECHANGED) TRACE(" SWP_FRAMECHANGED");
1136     if(flags & SWP_SHOWWINDOW) TRACE(" SWP_SHOWWINDOW");
1137     if(flags & SWP_HIDEWINDOW) TRACE(" SWP_HIDEWINDOW");
1138     if(flags & SWP_NOCOPYBITS) TRACE(" SWP_NOCOPYBITS");
1139     if(flags & SWP_NOOWNERZORDER) TRACE(" SWP_NOOWNERZORDER");
1140     if(flags & SWP_NOSENDCHANGING) TRACE(" SWP_NOSENDCHANGING");
1141     if(flags & SWP_DEFERERASE) TRACE(" SWP_DEFERERASE");
1142     if(flags & SWP_ASYNCWINDOWPOS) TRACE(" SWP_ASYNCWINDOWPOS");
1143
1144 #define DUMPED_FLAGS \
1145     (SWP_NOSIZE | \
1146     SWP_NOMOVE | \
1147     SWP_NOZORDER | \
1148     SWP_NOREDRAW | \
1149     SWP_NOACTIVATE | \
1150     SWP_FRAMECHANGED | \
1151     SWP_SHOWWINDOW | \
1152     SWP_HIDEWINDOW | \
1153     SWP_NOCOPYBITS | \
1154     SWP_NOOWNERZORDER | \
1155     SWP_NOSENDCHANGING | \
1156     SWP_DEFERERASE | \
1157     SWP_ASYNCWINDOWPOS)
1158
1159     if(flags & ~DUMPED_FLAGS) TRACE(" %08x", flags & ~DUMPED_FLAGS);
1160     TRACE("\n");
1161 #undef DUMPED_FLAGS
1162 }
1163
1164 /***********************************************************************
1165  *              SetWindowPos (USER32.@)
1166  */
1167 BOOL WINAPI SetWindowPos( HWND hwnd, HWND hwndInsertAfter,
1168                           INT x, INT y, INT cx, INT cy, UINT flags )
1169 {
1170     WINDOWPOS winpos;
1171
1172     TRACE("hwnd %p, after %p, %d,%d (%dx%d), flags %08x\n",
1173           hwnd, hwndInsertAfter, x, y, cx, cy, flags);
1174     if(TRACE_ON(win)) dump_winpos_flags(flags);
1175
1176     winpos.hwnd = WIN_GetFullHandle(hwnd);
1177     winpos.hwndInsertAfter = WIN_GetFullHandle(hwndInsertAfter);
1178     winpos.x = x;
1179     winpos.y = y;
1180     winpos.cx = cx;
1181     winpos.cy = cy;
1182     winpos.flags = flags;
1183     if (WIN_IsCurrentThread( hwnd )) return USER_Driver.pSetWindowPos( &winpos );
1184     return SendMessageW( winpos.hwnd, WM_WINE_SETWINDOWPOS, 0, (LPARAM)&winpos );
1185 }
1186
1187
1188 /***********************************************************************
1189  *              BeginDeferWindowPos (USER32.@)
1190  */
1191 HDWP WINAPI BeginDeferWindowPos( INT count )
1192 {
1193     HDWP handle;
1194     DWP *pDWP;
1195
1196     if (count < 0)
1197     {
1198         SetLastError(ERROR_INVALID_PARAMETER);
1199         return 0;
1200     }
1201     /* Windows allows zero count, in which case it allocates context for 8 moves */
1202     if (count == 0) count = 8;
1203
1204     handle = USER_HEAP_ALLOC( sizeof(DWP) + (count-1)*sizeof(WINDOWPOS) );
1205     if (!handle) return 0;
1206     pDWP = (DWP *) USER_HEAP_LIN_ADDR( handle );
1207     pDWP->actualCount    = 0;
1208     pDWP->suggestedCount = count;
1209     pDWP->valid          = TRUE;
1210     pDWP->wMagic         = DWP_MAGIC;
1211     pDWP->hwndParent     = 0;
1212     return handle;
1213 }
1214
1215
1216 /***********************************************************************
1217  *              DeferWindowPos (USER32.@)
1218  */
1219 HDWP WINAPI DeferWindowPos( HDWP hdwp, HWND hwnd, HWND hwndAfter,
1220                                 INT x, INT y, INT cx, INT cy,
1221                                 UINT flags )
1222 {
1223     DWP *pDWP;
1224     int i;
1225     HDWP newhdwp = hdwp,retvalue;
1226
1227     hwnd = WIN_GetFullHandle( hwnd );
1228     if (hwnd == GetDesktopWindow()) return 0;
1229
1230     if (!(pDWP = USER_HEAP_LIN_ADDR( hdwp ))) return 0;
1231
1232     USER_Lock();
1233
1234     for (i = 0; i < pDWP->actualCount; i++)
1235     {
1236         if (pDWP->winPos[i].hwnd == hwnd)
1237         {
1238               /* Merge with the other changes */
1239             if (!(flags & SWP_NOZORDER))
1240             {
1241                 pDWP->winPos[i].hwndInsertAfter = WIN_GetFullHandle(hwndAfter);
1242             }
1243             if (!(flags & SWP_NOMOVE))
1244             {
1245                 pDWP->winPos[i].x = x;
1246                 pDWP->winPos[i].y = y;
1247             }
1248             if (!(flags & SWP_NOSIZE))
1249             {
1250                 pDWP->winPos[i].cx = cx;
1251                 pDWP->winPos[i].cy = cy;
1252             }
1253             pDWP->winPos[i].flags &= flags | ~(SWP_NOSIZE | SWP_NOMOVE |
1254                                                SWP_NOZORDER | SWP_NOREDRAW |
1255                                                SWP_NOACTIVATE | SWP_NOCOPYBITS|
1256                                                SWP_NOOWNERZORDER);
1257             pDWP->winPos[i].flags |= flags & (SWP_SHOWWINDOW | SWP_HIDEWINDOW |
1258                                               SWP_FRAMECHANGED);
1259             retvalue = hdwp;
1260             goto END;
1261         }
1262     }
1263     if (pDWP->actualCount >= pDWP->suggestedCount)
1264     {
1265         newhdwp = USER_HEAP_REALLOC( hdwp,
1266                       sizeof(DWP) + pDWP->suggestedCount*sizeof(WINDOWPOS) );
1267         if (!newhdwp)
1268         {
1269             retvalue = 0;
1270             goto END;
1271         }
1272         pDWP = (DWP *) USER_HEAP_LIN_ADDR( newhdwp );
1273         pDWP->suggestedCount++;
1274     }
1275     pDWP->winPos[pDWP->actualCount].hwnd = hwnd;
1276     pDWP->winPos[pDWP->actualCount].hwndInsertAfter = hwndAfter;
1277     pDWP->winPos[pDWP->actualCount].x = x;
1278     pDWP->winPos[pDWP->actualCount].y = y;
1279     pDWP->winPos[pDWP->actualCount].cx = cx;
1280     pDWP->winPos[pDWP->actualCount].cy = cy;
1281     pDWP->winPos[pDWP->actualCount].flags = flags;
1282     pDWP->actualCount++;
1283     retvalue = newhdwp;
1284 END:
1285     USER_Unlock();
1286     return retvalue;
1287 }
1288
1289
1290 /***********************************************************************
1291  *              EndDeferWindowPos (USER32.@)
1292  */
1293 BOOL WINAPI EndDeferWindowPos( HDWP hdwp )
1294 {
1295     DWP *pDWP;
1296     WINDOWPOS *winpos;
1297     BOOL res = TRUE;
1298     int i;
1299
1300     pDWP = (DWP *) USER_HEAP_LIN_ADDR( hdwp );
1301     if (!pDWP) return FALSE;
1302     for (i = 0, winpos = pDWP->winPos; i < pDWP->actualCount; i++, winpos++)
1303     {
1304         if (!(res = USER_Driver.pSetWindowPos( winpos ))) break;
1305     }
1306     USER_HEAP_FREE( hdwp );
1307     return res;
1308 }
1309
1310
1311 /***********************************************************************
1312  *              TileChildWindows (USER.199)
1313  */
1314 void WINAPI TileChildWindows16( HWND16 parent, WORD action )
1315 {
1316     FIXME("(%04x, %d): stub\n", parent, action);
1317 }
1318
1319 /***********************************************************************
1320  *              CascadeChildWindows (USER.198)
1321  */
1322 void WINAPI CascadeChildWindows16( HWND16 parent, WORD action )
1323 {
1324     FIXME("(%04x, %d): stub\n", parent, action);
1325 }
1326
1327 /***********************************************************************
1328  *              SetProgmanWindow (USER32.@)
1329  */
1330 HWND WINAPI SetProgmanWindow ( HWND hwnd )
1331 {
1332         hGlobalProgmanWindow = hwnd;
1333         return hGlobalProgmanWindow;
1334 }
1335
1336 /***********************************************************************
1337  *              GetProgmanWindow (USER32.@)
1338  */
1339 HWND WINAPI GetProgmanWindow(void)
1340 {
1341         return hGlobalProgmanWindow;
1342 }
1343
1344 /***********************************************************************
1345  *              SetShellWindowEx (USER32.@)
1346  * hwndProgman =  Progman[Program Manager]
1347  *                |-> SHELLDLL_DefView
1348  * hwndListView = |   |-> SysListView32
1349  *                |   |   |-> tooltips_class32
1350  *                |   |
1351  *                |   |-> SysHeader32
1352  *                |
1353  *                |-> ProxyTarget
1354  */
1355 HWND WINAPI SetShellWindowEx ( HWND hwndProgman, HWND hwndListView )
1356 {
1357         FIXME("%p %p stub\n",hwndProgman ,hwndListView );
1358         hGlobalShellWindow = hwndProgman;
1359         return hGlobalShellWindow;
1360
1361 }
1362
1363 /***********************************************************************
1364  *              SetTaskmanWindow (USER32.@)
1365  * NOTES
1366  *   hwnd = MSTaskSwWClass
1367  *          |-> SysTabControl32
1368  */
1369 HWND WINAPI SetTaskmanWindow ( HWND hwnd )
1370 {
1371         hGlobalTaskmanWindow = hwnd;
1372         return hGlobalTaskmanWindow;
1373 }
1374
1375 /***********************************************************************
1376  *              GetTaskmanWindow (USER32.@)
1377  */
1378 HWND WINAPI GetTaskmanWindow(void)
1379 {
1380         return hGlobalTaskmanWindow;
1381 }