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