Fixed some issues found by winapi_check.
[wine] / dlls / ttydrv / wnd.c
1 /*
2  * TTY window driver
3  *
4  * Copyright 1998,1999 Patrik Stridvall
5  */
6
7 #include "config.h"
8
9 #include "gdi.h"
10 #include "ttydrv.h"
11 #include "region.h"
12 #include "win.h"
13 #include "winpos.h"
14 #include "debugtools.h"
15
16 DEFAULT_DEBUG_CHANNEL(ttydrv);
17
18 WND_DRIVER TTYDRV_WND_Driver =
19 {
20   TTYDRV_WND_ForceWindowRaise
21 };
22
23 #define SWP_AGG_NOGEOMETRYCHANGE \
24     (SWP_NOSIZE | SWP_NOMOVE | SWP_NOCLIENTSIZE | SWP_NOCLIENTMOVE)
25 #define SWP_AGG_NOPOSCHANGE \
26     (SWP_AGG_NOGEOMETRYCHANGE | SWP_NOZORDER)
27 #define SWP_AGG_STATUSFLAGS \
28     (SWP_AGG_NOPOSCHANGE | SWP_FRAMECHANGED | SWP_HIDEWINDOW | SWP_SHOWWINDOW)
29
30 /**********************************************************************
31  *              CreateWindow   (TTYDRV.@)
32  */
33 BOOL TTYDRV_CreateWindow( HWND hwnd, CREATESTRUCTA *cs, BOOL unicode )
34 {
35     BOOL ret;
36
37 #ifdef WINE_CURSES
38     WND *wndPtr = WIN_FindWndPtr( hwnd );
39     WINDOW *window;
40     INT cellWidth=8, cellHeight=8; /* FIXME: Hardcoded */
41
42     TRACE("(%x)\n", hwnd);
43
44     /* Only create top-level windows */
45     if (!(wndPtr->dwStyle & WS_CHILD))
46     {
47         if (!wndPtr->parent)  /* desktop */
48             window = root_window;
49         else
50         {
51             int x = wndPtr->rectWindow.left;
52             int y = wndPtr->rectWindow.top;
53             int cx = wndPtr->rectWindow.right - wndPtr->rectWindow.left;
54             int cy = wndPtr->rectWindow.bottom - wndPtr->rectWindow.top;
55
56             window = subwin( root_window, cy/cellHeight, cx/cellWidth,
57                              y/cellHeight, x/cellWidth);
58             werase(window);
59             wrefresh(window);
60         }
61         wndPtr->pDriverData = window;
62     }
63     WIN_ReleaseWndPtr( wndPtr );
64 #else /* defined(WINE_CURSES) */
65     FIXME("(%x): stub\n", hwnd);
66 #endif /* defined(WINE_CURSES) */
67
68     if (unicode)
69     {
70         ret = SendMessageW( hwnd, WM_NCCREATE, 0, (LPARAM)cs );
71         if (ret) ret = (SendMessageW( hwnd, WM_CREATE, 0, (LPARAM)cs ) != -1);
72     }
73     else
74     {
75         ret = SendMessageA( hwnd, WM_NCCREATE, 0, (LPARAM)cs );
76         if (ret) ret = (SendMessageA( hwnd, WM_CREATE, 0, (LPARAM)cs ) != -1);
77     }
78     return ret;
79 }
80
81 /***********************************************************************
82  *              DestroyWindow   (TTYDRV.@)
83  */
84 BOOL TTYDRV_DestroyWindow( HWND hwnd )
85 {
86 #ifdef WINE_CURSES
87     WND *wndPtr = WIN_FindWndPtr( hwnd );
88     WINDOW *window = wndPtr->pDriverData;
89
90     TRACE("(%x)\n", hwnd);
91
92     if (window && window != root_window) delwin(window);
93     wndPtr->pDriverData = NULL;
94     WIN_ReleaseWndPtr( wndPtr );
95 #else /* defined(WINE_CURSES) */
96     FIXME("(%x): stub\n", hwnd);
97 #endif /* defined(WINE_CURSES) */
98     return TRUE;
99 }
100
101 /***********************************************************************
102  *              TTYDRV_WND_ForceWindowRaise
103  */
104 void TTYDRV_WND_ForceWindowRaise(WND *wndPtr)
105 {
106   FIXME("(%p): stub\n", wndPtr);
107 }
108
109
110 /***********************************************************************
111  *           DCE_OffsetVisRgn
112  *
113  * Change region from DC-origin relative coordinates to screen coords.
114  */
115
116 static void DCE_OffsetVisRgn( HDC hDC, HRGN hVisRgn )
117 {
118     DC *dc;
119     if (!(dc = DC_GetDCPtr( hDC ))) return;
120
121     OffsetRgn( hVisRgn, dc->DCOrgX, dc->DCOrgY );
122
123     GDI_ReleaseObj( hDC );
124 }
125
126
127 /***********************************************************************
128  *           DCE_GetVisRect
129  *
130  * Calculate the visible rectangle of a window (i.e. the client or
131  * window area clipped by the client area of all ancestors) in the
132  * corresponding coordinates. Return FALSE if the visible region is empty.
133  */
134 static BOOL DCE_GetVisRect( WND *wndPtr, BOOL clientArea, RECT *lprect )
135 {
136     *lprect = clientArea ? wndPtr->rectClient : wndPtr->rectWindow;
137
138     if (wndPtr->dwStyle & WS_VISIBLE)
139     {
140         INT xoffset = lprect->left;
141         INT yoffset = lprect->top;
142
143         while ((wndPtr = WIN_LockWndPtr(wndPtr->parent)))
144         {
145             if ( (wndPtr->dwStyle & (WS_ICONIC | WS_VISIBLE)) != WS_VISIBLE )
146             {
147                 WIN_ReleaseWndPtr(wndPtr);
148                 goto fail;
149             }
150
151             xoffset += wndPtr->rectClient.left;
152             yoffset += wndPtr->rectClient.top;
153             OffsetRect( lprect, wndPtr->rectClient.left,
154                         wndPtr->rectClient.top );
155
156             if( (wndPtr->rectClient.left >= wndPtr->rectClient.right) ||
157                 (wndPtr->rectClient.top >= wndPtr->rectClient.bottom) ||
158                 (lprect->left >= wndPtr->rectClient.right) ||
159                 (lprect->right <= wndPtr->rectClient.left) ||
160                 (lprect->top >= wndPtr->rectClient.bottom) ||
161                 (lprect->bottom <= wndPtr->rectClient.top) )
162             {
163                 WIN_ReleaseWndPtr(wndPtr);
164                 goto fail;
165             }
166
167             lprect->left = max( lprect->left, wndPtr->rectClient.left );
168             lprect->right = min( lprect->right, wndPtr->rectClient.right );
169             lprect->top = max( lprect->top, wndPtr->rectClient.top );
170             lprect->bottom = min( lprect->bottom, wndPtr->rectClient.bottom );
171
172             WIN_ReleaseWndPtr(wndPtr);
173         }
174         OffsetRect( lprect, -xoffset, -yoffset );
175         return TRUE;
176     }
177
178 fail:
179     SetRectEmpty( lprect );
180     return FALSE;
181 }
182
183
184 /***********************************************************************
185  *           DCE_AddClipRects
186  *
187  * Go through the linked list of windows from pWndStart to pWndEnd,
188  * adding to the clip region the intersection of the target rectangle
189  * with an offset window rectangle.
190  */
191 static BOOL DCE_AddClipRects( WND *pWndStart, WND *pWndEnd,
192                               HRGN hrgnClip, LPRECT lpRect, int x, int y )
193 {
194     RECT rect;
195
196     for (WIN_LockWndPtr(pWndStart); (pWndStart && (pWndStart != pWndEnd)); WIN_UpdateWndPtr(&pWndStart,pWndStart->next))
197     {
198         if( !(pWndStart->dwStyle & WS_VISIBLE) ) continue;
199
200         rect.left = pWndStart->rectWindow.left + x;
201         rect.top = pWndStart->rectWindow.top + y;
202         rect.right = pWndStart->rectWindow.right + x;
203         rect.bottom = pWndStart->rectWindow.bottom + y;
204
205         if( IntersectRect( &rect, &rect, lpRect ))
206         {
207             if(!REGION_UnionRectWithRgn( hrgnClip, &rect )) break;
208         }
209     }
210     WIN_ReleaseWndPtr(pWndStart);
211     return (pWndStart == pWndEnd);
212 }
213
214
215 /***********************************************************************
216  *           DCE_GetVisRgn
217  *
218  * Return the visible region of a window, i.e. the client or window area
219  * clipped by the client area of all ancestors, and then optionally
220  * by siblings and children.
221  */
222 static HRGN DCE_GetVisRgn( HWND hwnd, WORD flags, HWND hwndChild, WORD cflags )
223 {
224     HRGN hrgnVis = 0;
225     RECT rect;
226     WND *wndPtr = WIN_FindWndPtr( hwnd );
227     WND *childWnd = WIN_FindWndPtr( hwndChild );
228
229     /* Get visible rectangle and create a region with it. */
230
231     if (wndPtr && DCE_GetVisRect(wndPtr, !(flags & DCX_WINDOW), &rect))
232     {
233         if((hrgnVis = CreateRectRgnIndirect( &rect )))
234         {
235             HRGN hrgnClip = CreateRectRgn( 0, 0, 0, 0 );
236             INT xoffset, yoffset;
237
238             if( hrgnClip )
239             {
240                 /* Compute obscured region for the visible rectangle by 
241                  * clipping children, siblings, and ancestors. Note that
242                  * DCE_GetVisRect() returns a rectangle either in client
243                  * or in window coordinates (for DCX_WINDOW request). */
244
245                 if( (flags & DCX_CLIPCHILDREN) && wndPtr->child )
246                 {
247                     if( flags & DCX_WINDOW )
248                     {
249                         /* adjust offsets since child window rectangles are 
250                          * in client coordinates */
251
252                         xoffset = wndPtr->rectClient.left - wndPtr->rectWindow.left;
253                         yoffset = wndPtr->rectClient.top - wndPtr->rectWindow.top;
254                     }
255                     else
256                         xoffset = yoffset = 0;
257
258                     DCE_AddClipRects( wndPtr->child, NULL, hrgnClip, &rect, xoffset, yoffset );
259                 }
260
261                 /* We may need to clip children of child window, if a window with PARENTDC
262                  * class style and CLIPCHILDREN window style (like in Free Agent 16
263                  * preference dialogs) gets here, we take the region for the parent window
264                  * but apparently still need to clip the children of the child window... */
265
266                 if( (cflags & DCX_CLIPCHILDREN) && childWnd && childWnd->child )
267                 {
268                     if( flags & DCX_WINDOW )
269                     {
270                         /* adjust offsets since child window rectangles are 
271                          * in client coordinates */
272
273                         xoffset = wndPtr->rectClient.left - wndPtr->rectWindow.left;
274                         yoffset = wndPtr->rectClient.top - wndPtr->rectWindow.top;
275                     }
276                     else
277                         xoffset = yoffset = 0;
278
279                     /* client coordinates of child window */
280                     xoffset += childWnd->rectClient.left;
281                     yoffset += childWnd->rectClient.top;
282
283                     DCE_AddClipRects( childWnd->child, NULL, hrgnClip,
284                                       &rect, xoffset, yoffset );
285                 }
286
287                 /* sibling window rectangles are in client 
288                  * coordinates of the parent window */
289
290                 if (flags & DCX_WINDOW)
291                 {
292                     xoffset = -wndPtr->rectWindow.left;
293                     yoffset = -wndPtr->rectWindow.top;
294                 }
295                 else
296                 {
297                     xoffset = -wndPtr->rectClient.left;
298                     yoffset = -wndPtr->rectClient.top;
299                 }
300
301                 if (flags & DCX_CLIPSIBLINGS && wndPtr->parent )
302                     DCE_AddClipRects( wndPtr->parent->child,
303                                       wndPtr, hrgnClip, &rect, xoffset, yoffset );
304
305                 /* Clip siblings of all ancestors that have the
306                  * WS_CLIPSIBLINGS style
307                  */
308
309                 while (wndPtr->parent)
310                 {
311                     WIN_UpdateWndPtr(&wndPtr,wndPtr->parent);
312                     xoffset -= wndPtr->rectClient.left;
313                     yoffset -= wndPtr->rectClient.top;
314                     if(wndPtr->dwStyle & WS_CLIPSIBLINGS && wndPtr->parent)
315                     {
316                         DCE_AddClipRects( wndPtr->parent->child, wndPtr,
317                                           hrgnClip, &rect, xoffset, yoffset );
318                     }
319                 }
320
321                 /* Now once we've got a jumbo clip region we have
322                  * to substract it from the visible rectangle.
323                  */
324                 CombineRgn( hrgnVis, hrgnVis, hrgnClip, RGN_DIFF );
325                 DeleteObject( hrgnClip );
326             }
327             else
328             {
329                 DeleteObject( hrgnVis );
330                 hrgnVis = 0;
331             }
332         }
333     }
334     else
335         hrgnVis = CreateRectRgn(0, 0, 0, 0); /* empty */
336     WIN_ReleaseWndPtr(wndPtr);
337     WIN_ReleaseWndPtr(childWnd);
338     return hrgnVis;
339 }
340
341
342 /***********************************************************************
343  *              GetDC   (TTYDRV.@)
344  *
345  * Set the drawable, origin and dimensions for the DC associated to
346  * a given window.
347  */
348 BOOL TTYDRV_GetDC( HWND hwnd, HDC hdc, HRGN hrgn, DWORD flags )
349 {
350     WND *wndPtr = WIN_FindWndPtr(hwnd);
351     DC *dc;
352     BOOL updateVisRgn;
353     HRGN hrgnVisible = 0;
354
355     if (!wndPtr) return FALSE;
356
357     if (!(dc = DC_GetDCPtr( hdc )))
358     {
359         WIN_ReleaseWndPtr( wndPtr );
360         return FALSE;
361     }
362
363     if(flags & DCX_WINDOW)
364     {
365         dc->DCOrgX = wndPtr->rectWindow.left;
366         dc->DCOrgY = wndPtr->rectWindow.top;
367     }
368     else
369     {
370         dc->DCOrgX = wndPtr->rectClient.left;
371         dc->DCOrgY = wndPtr->rectClient.top;
372     }
373     updateVisRgn = (dc->flags & DC_DIRTY) != 0;
374     GDI_ReleaseObj( hdc );
375
376     if (updateVisRgn)
377     {
378         if (flags & DCX_PARENTCLIP)
379         {
380             WND *parentPtr = WIN_LockWndPtr(wndPtr->parent);
381
382             if( wndPtr->dwStyle & WS_VISIBLE && !(parentPtr->dwStyle & WS_MINIMIZE) )
383             {
384                 DWORD dcxFlags;
385
386                 if( parentPtr->dwStyle & WS_CLIPSIBLINGS )
387                     dcxFlags = DCX_CLIPSIBLINGS | (flags & ~(DCX_CLIPCHILDREN | DCX_WINDOW));
388                 else
389                     dcxFlags = flags & ~(DCX_CLIPSIBLINGS | DCX_CLIPCHILDREN | DCX_WINDOW);
390
391                 hrgnVisible = DCE_GetVisRgn( parentPtr->hwndSelf, dcxFlags,
392                                              wndPtr->hwndSelf, flags );
393                 if( flags & DCX_WINDOW )
394                     OffsetRgn( hrgnVisible, -wndPtr->rectWindow.left,
395                                -wndPtr->rectWindow.top );
396                 else
397                     OffsetRgn( hrgnVisible, -wndPtr->rectClient.left,
398                                -wndPtr->rectClient.top );
399                 DCE_OffsetVisRgn( hdc, hrgnVisible );
400             }
401             else
402                 hrgnVisible = CreateRectRgn( 0, 0, 0, 0 );
403             WIN_ReleaseWndPtr(parentPtr);
404         }
405         else
406         {
407             hrgnVisible = DCE_GetVisRgn( hwnd, flags, 0, 0 );
408             DCE_OffsetVisRgn( hdc, hrgnVisible );
409         }
410         SelectVisRgn16( hdc, hrgnVisible );
411     }
412
413     /* apply additional region operation (if any) */
414
415     if( flags & (DCX_EXCLUDERGN | DCX_INTERSECTRGN) )
416     {
417         if( !hrgnVisible ) hrgnVisible = CreateRectRgn( 0, 0, 0, 0 );
418
419         TRACE("\tsaved VisRgn, clipRgn = %04x\n", hrgn);
420
421         SaveVisRgn16( hdc );
422         CombineRgn( hrgnVisible, hrgn, 0, RGN_COPY );
423         DCE_OffsetVisRgn( hdc, hrgnVisible );
424         CombineRgn( hrgnVisible, InquireVisRgn16( hdc ), hrgnVisible,
425                       (flags & DCX_INTERSECTRGN) ? RGN_AND : RGN_DIFF );
426         SelectVisRgn16( hdc, hrgnVisible );
427     }
428
429     if (hrgnVisible) DeleteObject( hrgnVisible );
430
431     WIN_ReleaseWndPtr( wndPtr );
432     return TRUE;
433 }
434
435
436 /***********************************************************************
437  *              SetWindowPos   (TTYDRV.@)
438  */
439 BOOL TTYDRV_SetWindowPos( WINDOWPOS *winpos )
440 {
441     WND *wndPtr;
442     RECT newWindowRect, newClientRect;
443     BOOL retvalue;
444     HWND hwndActive = GetForegroundWindow();
445
446     TRACE( "hwnd %04x, swp (%i,%i)-(%i,%i) flags %08x\n",
447            winpos->hwnd, winpos->x, winpos->y,
448            winpos->x + winpos->cx, winpos->y + winpos->cy, winpos->flags);
449
450     /* ------------------------------------------------------------------------ CHECKS */
451
452       /* Check window handle */
453
454     if (winpos->hwnd == GetDesktopWindow()) return FALSE;
455     if (!(wndPtr = WIN_FindWndPtr( winpos->hwnd ))) return FALSE;
456
457     TRACE("\tcurrent (%i,%i)-(%i,%i), style %08x\n",
458           wndPtr->rectWindow.left, wndPtr->rectWindow.top,
459           wndPtr->rectWindow.right, wndPtr->rectWindow.bottom, (unsigned)wndPtr->dwStyle );
460
461     /* Fix redundant flags */
462
463     if(wndPtr->dwStyle & WS_VISIBLE)
464         winpos->flags &= ~SWP_SHOWWINDOW;
465     else
466     {
467         if (!(winpos->flags & SWP_SHOWWINDOW)) winpos->flags |= SWP_NOREDRAW;
468         winpos->flags &= ~SWP_HIDEWINDOW;
469     }
470
471     if ( winpos->cx < 0 ) winpos->cx = 0;
472     if ( winpos->cy < 0 ) winpos->cy = 0;
473
474     if ((wndPtr->rectWindow.right - wndPtr->rectWindow.left == winpos->cx) &&
475         (wndPtr->rectWindow.bottom - wndPtr->rectWindow.top == winpos->cy))
476         winpos->flags |= SWP_NOSIZE;    /* Already the right size */
477
478     if ((wndPtr->rectWindow.left == winpos->x) && (wndPtr->rectWindow.top == winpos->y))
479         winpos->flags |= SWP_NOMOVE;    /* Already the right position */
480
481     if (winpos->hwnd == hwndActive)
482         winpos->flags |= SWP_NOACTIVATE;   /* Already active */
483     else if ( (wndPtr->dwStyle & (WS_POPUP | WS_CHILD)) != WS_CHILD )
484     {
485         if(!(winpos->flags & SWP_NOACTIVATE)) /* Bring to the top when activating */
486         {
487             winpos->flags &= ~SWP_NOZORDER;
488             winpos->hwndInsertAfter = HWND_TOP;
489             goto Pos;
490         }
491     }
492
493     /* Check hwndInsertAfter */
494
495       /* FIXME: TOPMOST not supported yet */
496     if ((winpos->hwndInsertAfter == HWND_TOPMOST) ||
497         (winpos->hwndInsertAfter == HWND_NOTOPMOST)) winpos->hwndInsertAfter = HWND_TOP;
498
499     /* hwndInsertAfter must be a sibling of the window */
500     if ((winpos->hwndInsertAfter != HWND_TOP) && (winpos->hwndInsertAfter != HWND_BOTTOM))
501     {
502         WND* wnd = WIN_FindWndPtr(winpos->hwndInsertAfter);
503
504         if( wnd ) {
505             if( wnd->parent != wndPtr->parent )
506             {
507                 retvalue = FALSE;
508                 WIN_ReleaseWndPtr(wnd);
509                 goto END;
510             }
511             /* don't need to change the Zorder of hwnd if it's already inserted
512              * after hwndInsertAfter or when inserting hwnd after itself.
513              */
514             if(( wnd->next == wndPtr ) || (winpos->hwnd == winpos->hwndInsertAfter))
515                 winpos->flags |= SWP_NOZORDER;
516         }
517         WIN_ReleaseWndPtr(wnd);
518     }
519
520  Pos:  /* ------------------------------------------------------------------------ MAIN part */
521
522       /* Send WM_WINDOWPOSCHANGING message */
523
524     if (!(winpos->flags & SWP_NOSENDCHANGING))
525         SendMessageA( wndPtr->hwndSelf, WM_WINDOWPOSCHANGING, 0, (LPARAM)winpos );
526
527       /* Calculate new position and size */
528
529     newWindowRect = wndPtr->rectWindow;
530     newClientRect = (wndPtr->dwStyle & WS_MINIMIZE) ? wndPtr->rectWindow
531                                                     : wndPtr->rectClient;
532
533     if (!(winpos->flags & SWP_NOSIZE))
534     {
535         newWindowRect.right  = newWindowRect.left + winpos->cx;
536         newWindowRect.bottom = newWindowRect.top + winpos->cy;
537     }
538     if (!(winpos->flags & SWP_NOMOVE))
539     {
540         newWindowRect.left    = winpos->x;
541         newWindowRect.top     = winpos->y;
542         newWindowRect.right  += winpos->x - wndPtr->rectWindow.left;
543         newWindowRect.bottom += winpos->y - wndPtr->rectWindow.top;
544
545         OffsetRect( &newClientRect, winpos->x - wndPtr->rectWindow.left,
546                     winpos->y - wndPtr->rectWindow.top );
547     }
548
549     if( winpos->hwndInsertAfter == HWND_TOP )
550         winpos->flags |= ( wndPtr->parent->child == wndPtr)? SWP_NOZORDER: 0;
551     else
552         if( winpos->hwndInsertAfter == HWND_BOTTOM )
553             winpos->flags |= ( wndPtr->next )? 0: SWP_NOZORDER;
554         else
555             if( !(winpos->flags & SWP_NOZORDER) )
556                 if( GetWindow(winpos->hwndInsertAfter, GW_HWNDNEXT) == wndPtr->hwndSelf )
557                     winpos->flags |= SWP_NOZORDER;
558
559     /* Common operations */
560
561       /* Send WM_NCCALCSIZE message to get new client area */
562     if( (winpos->flags & (SWP_FRAMECHANGED | SWP_NOSIZE)) != SWP_NOSIZE )
563     {
564          WINPOS_SendNCCalcSize( winpos->hwnd, TRUE, &newWindowRect,
565                                 &wndPtr->rectWindow, &wndPtr->rectClient,
566                                 winpos, &newClientRect );
567     }
568
569     if(!(winpos->flags & SWP_NOZORDER) && winpos->hwnd != winpos->hwndInsertAfter)
570     {
571         if ( WIN_UnlinkWindow( winpos->hwnd ) )
572             WIN_LinkWindow( winpos->hwnd, winpos->hwndInsertAfter );
573     }
574
575     /* FIXME: actually do something with WVR_VALIDRECTS */
576
577     wndPtr->rectWindow = newWindowRect;
578     wndPtr->rectClient = newClientRect;
579
580     if( winpos->flags & SWP_SHOWWINDOW )
581     {
582         wndPtr->dwStyle |= WS_VISIBLE;
583     }
584     else if( winpos->flags & SWP_HIDEWINDOW )
585     {
586         wndPtr->dwStyle &= ~WS_VISIBLE;
587     }
588
589     /* ------------------------------------------------------------------------ FINAL */
590
591     /* repaint invalidated region (if any)
592      *
593      * FIXME: if SWP_NOACTIVATE is not set then set invalid regions here without any painting
594      *        and force update after ChangeActiveWindow() to avoid painting frames twice.
595      */
596
597     if( !(winpos->flags & SWP_NOREDRAW) )
598     {
599         RedrawWindow( wndPtr->parent->hwndSelf, NULL, 0,
600                       RDW_ERASE | RDW_INVALIDATE | RDW_ALLCHILDREN );
601         if (wndPtr->parent->hwndSelf == GetDesktopWindow() ||
602             wndPtr->parent->parent->hwndSelf == GetDesktopWindow())
603         {
604             RedrawWindow( wndPtr->parent->hwndSelf, NULL, 0,
605                           RDW_ERASENOW | RDW_NOCHILDREN );
606         }
607     }
608
609     if (!(winpos->flags & SWP_NOACTIVATE))
610         WINPOS_ChangeActiveWindow( winpos->hwnd, FALSE );
611
612       /* And last, send the WM_WINDOWPOSCHANGED message */
613
614     TRACE("\tstatus flags = %04x\n", winpos->flags & SWP_AGG_STATUSFLAGS);
615
616     if ((((winpos->flags & SWP_AGG_STATUSFLAGS) != SWP_AGG_NOPOSCHANGE) &&
617           !(winpos->flags & SWP_NOSENDCHANGING)) )
618         SendMessageA( winpos->hwnd, WM_WINDOWPOSCHANGED, 0, (LPARAM)winpos );
619
620     retvalue = TRUE;
621  END:
622     WIN_ReleaseWndPtr(wndPtr);
623     return retvalue;
624 }