Moved server.h to include/wine.
[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_LockWndPtr(wndPtr->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 BOOL DCE_AddClipRects( WND *pWndStart, WND *pWndEnd,
179                               HRGN hrgnClip, LPRECT lpRect, int x, int y )
180 {
181     RECT rect;
182
183     for (WIN_LockWndPtr(pWndStart); (pWndStart && (pWndStart != pWndEnd)); WIN_UpdateWndPtr(&pWndStart,pWndStart->next))
184     {
185         if( !(pWndStart->dwStyle & WS_VISIBLE) ) continue;
186
187         rect.left = pWndStart->rectWindow.left + x;
188         rect.top = pWndStart->rectWindow.top + y;
189         rect.right = pWndStart->rectWindow.right + x;
190         rect.bottom = pWndStart->rectWindow.bottom + y;
191
192         if( IntersectRect( &rect, &rect, lpRect ))
193         {
194             if(!REGION_UnionRectWithRgn( hrgnClip, &rect )) break;
195         }
196     }
197     WIN_ReleaseWndPtr(pWndStart);
198     return (pWndStart == pWndEnd);
199 }
200
201
202 /***********************************************************************
203  *           DCE_GetVisRgn
204  *
205  * Return the visible region of a window, i.e. the client or window area
206  * clipped by the client area of all ancestors, and then optionally
207  * by siblings and children.
208  */
209 static HRGN DCE_GetVisRgn( HWND hwnd, WORD flags, HWND hwndChild, WORD cflags )
210 {
211     HRGN hrgnVis = 0;
212     RECT rect;
213     WND *wndPtr = WIN_FindWndPtr( hwnd );
214     WND *childWnd = WIN_FindWndPtr( hwndChild );
215
216     /* Get visible rectangle and create a region with it. */
217
218     if (wndPtr && DCE_GetVisRect(wndPtr, !(flags & DCX_WINDOW), &rect))
219     {
220         if((hrgnVis = CreateRectRgnIndirect( &rect )))
221         {
222             HRGN hrgnClip = CreateRectRgn( 0, 0, 0, 0 );
223             INT xoffset, yoffset;
224
225             if( hrgnClip )
226             {
227                 /* Compute obscured region for the visible rectangle by 
228                  * clipping children, siblings, and ancestors. Note that
229                  * DCE_GetVisRect() returns a rectangle either in client
230                  * or in window coordinates (for DCX_WINDOW request). */
231
232                 if( (flags & DCX_CLIPCHILDREN) && wndPtr->child )
233                 {
234                     if( flags & DCX_WINDOW )
235                     {
236                         /* adjust offsets since child window rectangles are 
237                          * in client coordinates */
238
239                         xoffset = wndPtr->rectClient.left - wndPtr->rectWindow.left;
240                         yoffset = wndPtr->rectClient.top - wndPtr->rectWindow.top;
241                     }
242                     else
243                         xoffset = yoffset = 0;
244
245                     DCE_AddClipRects( wndPtr->child, NULL, hrgnClip, &rect, xoffset, yoffset );
246                 }
247
248                 /* We may need to clip children of child window, if a window with PARENTDC
249                  * class style and CLIPCHILDREN window style (like in Free Agent 16
250                  * preference dialogs) gets here, we take the region for the parent window
251                  * but apparently still need to clip the children of the child window... */
252
253                 if( (cflags & DCX_CLIPCHILDREN) && childWnd && childWnd->child )
254                 {
255                     if( flags & DCX_WINDOW )
256                     {
257                         /* adjust offsets since child window rectangles are 
258                          * in client coordinates */
259
260                         xoffset = wndPtr->rectClient.left - wndPtr->rectWindow.left;
261                         yoffset = wndPtr->rectClient.top - wndPtr->rectWindow.top;
262                     }
263                     else
264                         xoffset = yoffset = 0;
265
266                     /* client coordinates of child window */
267                     xoffset += childWnd->rectClient.left;
268                     yoffset += childWnd->rectClient.top;
269
270                     DCE_AddClipRects( childWnd->child, NULL, hrgnClip,
271                                       &rect, xoffset, yoffset );
272                 }
273
274                 /* sibling window rectangles are in client 
275                  * coordinates of the parent window */
276
277                 if (flags & DCX_WINDOW)
278                 {
279                     xoffset = -wndPtr->rectWindow.left;
280                     yoffset = -wndPtr->rectWindow.top;
281                 }
282                 else
283                 {
284                     xoffset = -wndPtr->rectClient.left;
285                     yoffset = -wndPtr->rectClient.top;
286                 }
287
288                 if (flags & DCX_CLIPSIBLINGS && wndPtr->parent )
289                     DCE_AddClipRects( wndPtr->parent->child,
290                                       wndPtr, hrgnClip, &rect, xoffset, yoffset );
291
292                 /* Clip siblings of all ancestors that have the
293                  * WS_CLIPSIBLINGS style
294                  */
295
296                 while (wndPtr->parent)
297                 {
298                     WIN_UpdateWndPtr(&wndPtr,wndPtr->parent);
299                     xoffset -= wndPtr->rectClient.left;
300                     yoffset -= wndPtr->rectClient.top;
301                     if(wndPtr->dwStyle & WS_CLIPSIBLINGS && wndPtr->parent)
302                     {
303                         DCE_AddClipRects( wndPtr->parent->child, wndPtr,
304                                           hrgnClip, &rect, xoffset, yoffset );
305                     }
306                 }
307
308                 /* Now once we've got a jumbo clip region we have
309                  * to substract it from the visible rectangle.
310                  */
311                 CombineRgn( hrgnVis, hrgnVis, hrgnClip, RGN_DIFF );
312                 DeleteObject( hrgnClip );
313             }
314             else
315             {
316                 DeleteObject( hrgnVis );
317                 hrgnVis = 0;
318             }
319         }
320     }
321     else
322         hrgnVis = CreateRectRgn(0, 0, 0, 0); /* empty */
323     WIN_ReleaseWndPtr(wndPtr);
324     WIN_ReleaseWndPtr(childWnd);
325     return hrgnVis;
326 }
327
328
329 /***********************************************************************
330  *              GetDC   (TTYDRV.@)
331  *
332  * Set the drawable, origin and dimensions for the DC associated to
333  * a given window.
334  */
335 BOOL TTYDRV_GetDC( HWND hwnd, HDC hdc, HRGN hrgn, DWORD flags )
336 {
337     WND *wndPtr = WIN_FindWndPtr(hwnd);
338     DC *dc;
339     BOOL updateVisRgn;
340     HRGN hrgnVisible = 0;
341
342     if (!wndPtr) return FALSE;
343
344     if (!(dc = DC_GetDCPtr( hdc )))
345     {
346         WIN_ReleaseWndPtr( wndPtr );
347         return FALSE;
348     }
349
350     if(flags & DCX_WINDOW)
351     {
352         dc->DCOrgX = wndPtr->rectWindow.left;
353         dc->DCOrgY = wndPtr->rectWindow.top;
354     }
355     else
356     {
357         dc->DCOrgX = wndPtr->rectClient.left;
358         dc->DCOrgY = wndPtr->rectClient.top;
359     }
360     updateVisRgn = (dc->flags & DC_DIRTY) != 0;
361     GDI_ReleaseObj( hdc );
362
363     if (updateVisRgn)
364     {
365         if (flags & DCX_PARENTCLIP)
366         {
367             WND *parentPtr = WIN_LockWndPtr(wndPtr->parent);
368
369             if( wndPtr->dwStyle & WS_VISIBLE && !(parentPtr->dwStyle & WS_MINIMIZE) )
370             {
371                 DWORD dcxFlags;
372
373                 if( parentPtr->dwStyle & WS_CLIPSIBLINGS )
374                     dcxFlags = DCX_CLIPSIBLINGS | (flags & ~(DCX_CLIPCHILDREN | DCX_WINDOW));
375                 else
376                     dcxFlags = flags & ~(DCX_CLIPSIBLINGS | DCX_CLIPCHILDREN | DCX_WINDOW);
377
378                 hrgnVisible = DCE_GetVisRgn( parentPtr->hwndSelf, dcxFlags,
379                                              wndPtr->hwndSelf, flags );
380                 if( flags & DCX_WINDOW )
381                     OffsetRgn( hrgnVisible, -wndPtr->rectWindow.left,
382                                -wndPtr->rectWindow.top );
383                 else
384                     OffsetRgn( hrgnVisible, -wndPtr->rectClient.left,
385                                -wndPtr->rectClient.top );
386                 DCE_OffsetVisRgn( hdc, hrgnVisible );
387             }
388             else
389                 hrgnVisible = CreateRectRgn( 0, 0, 0, 0 );
390             WIN_ReleaseWndPtr(parentPtr);
391         }
392         else
393         {
394             hrgnVisible = DCE_GetVisRgn( hwnd, flags, 0, 0 );
395             DCE_OffsetVisRgn( hdc, hrgnVisible );
396         }
397         SelectVisRgn16( hdc, hrgnVisible );
398     }
399
400     /* apply additional region operation (if any) */
401
402     if( flags & (DCX_EXCLUDERGN | DCX_INTERSECTRGN) )
403     {
404         if( !hrgnVisible ) hrgnVisible = CreateRectRgn( 0, 0, 0, 0 );
405
406         TRACE("\tsaved VisRgn, clipRgn = %04x\n", hrgn);
407
408         SaveVisRgn16( hdc );
409         CombineRgn( hrgnVisible, hrgn, 0, RGN_COPY );
410         DCE_OffsetVisRgn( hdc, hrgnVisible );
411         CombineRgn( hrgnVisible, InquireVisRgn16( hdc ), hrgnVisible,
412                       (flags & DCX_INTERSECTRGN) ? RGN_AND : RGN_DIFF );
413         SelectVisRgn16( hdc, hrgnVisible );
414     }
415
416     if (hrgnVisible) DeleteObject( hrgnVisible );
417
418     WIN_ReleaseWndPtr( wndPtr );
419     return TRUE;
420 }
421
422
423 /***********************************************************************
424  *              SetWindowPos   (TTYDRV.@)
425  */
426 BOOL TTYDRV_SetWindowPos( WINDOWPOS *winpos )
427 {
428     WND *wndPtr;
429     RECT newWindowRect, newClientRect;
430     BOOL retvalue;
431     HWND hwndActive = GetForegroundWindow();
432
433     TRACE( "hwnd %04x, swp (%i,%i)-(%i,%i) flags %08x\n",
434            winpos->hwnd, winpos->x, winpos->y,
435            winpos->x + winpos->cx, winpos->y + winpos->cy, winpos->flags);
436
437     /* ------------------------------------------------------------------------ CHECKS */
438
439       /* Check window handle */
440
441     if (winpos->hwnd == GetDesktopWindow()) return FALSE;
442     if (!(wndPtr = WIN_FindWndPtr( winpos->hwnd ))) return FALSE;
443
444     TRACE("\tcurrent (%i,%i)-(%i,%i), style %08x\n",
445           wndPtr->rectWindow.left, wndPtr->rectWindow.top,
446           wndPtr->rectWindow.right, wndPtr->rectWindow.bottom, (unsigned)wndPtr->dwStyle );
447
448     /* Fix redundant flags */
449
450     if(wndPtr->dwStyle & WS_VISIBLE)
451         winpos->flags &= ~SWP_SHOWWINDOW;
452     else
453     {
454         if (!(winpos->flags & SWP_SHOWWINDOW)) winpos->flags |= SWP_NOREDRAW;
455         winpos->flags &= ~SWP_HIDEWINDOW;
456     }
457
458     if ( winpos->cx < 0 ) winpos->cx = 0;
459     if ( winpos->cy < 0 ) winpos->cy = 0;
460
461     if ((wndPtr->rectWindow.right - wndPtr->rectWindow.left == winpos->cx) &&
462         (wndPtr->rectWindow.bottom - wndPtr->rectWindow.top == winpos->cy))
463         winpos->flags |= SWP_NOSIZE;    /* Already the right size */
464
465     if ((wndPtr->rectWindow.left == winpos->x) && (wndPtr->rectWindow.top == winpos->y))
466         winpos->flags |= SWP_NOMOVE;    /* Already the right position */
467
468     if (winpos->hwnd == hwndActive)
469         winpos->flags |= SWP_NOACTIVATE;   /* Already active */
470     else if ( (wndPtr->dwStyle & (WS_POPUP | WS_CHILD)) != WS_CHILD )
471     {
472         if(!(winpos->flags & SWP_NOACTIVATE)) /* Bring to the top when activating */
473         {
474             winpos->flags &= ~SWP_NOZORDER;
475             winpos->hwndInsertAfter = HWND_TOP;
476             goto Pos;
477         }
478     }
479
480     /* Check hwndInsertAfter */
481
482       /* FIXME: TOPMOST not supported yet */
483     if ((winpos->hwndInsertAfter == HWND_TOPMOST) ||
484         (winpos->hwndInsertAfter == HWND_NOTOPMOST)) winpos->hwndInsertAfter = HWND_TOP;
485
486     /* hwndInsertAfter must be a sibling of the window */
487     if ((winpos->hwndInsertAfter != HWND_TOP) && (winpos->hwndInsertAfter != HWND_BOTTOM))
488     {
489         WND* wnd = WIN_FindWndPtr(winpos->hwndInsertAfter);
490
491         if( wnd ) {
492             if( wnd->parent != wndPtr->parent )
493             {
494                 retvalue = FALSE;
495                 WIN_ReleaseWndPtr(wnd);
496                 goto END;
497             }
498             /* don't need to change the Zorder of hwnd if it's already inserted
499              * after hwndInsertAfter or when inserting hwnd after itself.
500              */
501             if(( wnd->next == wndPtr ) || (winpos->hwnd == winpos->hwndInsertAfter))
502                 winpos->flags |= SWP_NOZORDER;
503         }
504         WIN_ReleaseWndPtr(wnd);
505     }
506
507  Pos:  /* ------------------------------------------------------------------------ MAIN part */
508
509       /* Send WM_WINDOWPOSCHANGING message */
510
511     if (!(winpos->flags & SWP_NOSENDCHANGING))
512         SendMessageA( wndPtr->hwndSelf, WM_WINDOWPOSCHANGING, 0, (LPARAM)winpos );
513
514       /* Calculate new position and size */
515
516     newWindowRect = wndPtr->rectWindow;
517     newClientRect = (wndPtr->dwStyle & WS_MINIMIZE) ? wndPtr->rectWindow
518                                                     : wndPtr->rectClient;
519
520     if (!(winpos->flags & SWP_NOSIZE))
521     {
522         newWindowRect.right  = newWindowRect.left + winpos->cx;
523         newWindowRect.bottom = newWindowRect.top + winpos->cy;
524     }
525     if (!(winpos->flags & SWP_NOMOVE))
526     {
527         newWindowRect.left    = winpos->x;
528         newWindowRect.top     = winpos->y;
529         newWindowRect.right  += winpos->x - wndPtr->rectWindow.left;
530         newWindowRect.bottom += winpos->y - wndPtr->rectWindow.top;
531
532         OffsetRect( &newClientRect, winpos->x - wndPtr->rectWindow.left,
533                     winpos->y - wndPtr->rectWindow.top );
534     }
535
536     if( winpos->hwndInsertAfter == HWND_TOP )
537         winpos->flags |= ( wndPtr->parent->child == wndPtr)? SWP_NOZORDER: 0;
538     else
539         if( winpos->hwndInsertAfter == HWND_BOTTOM )
540             winpos->flags |= ( wndPtr->next )? 0: SWP_NOZORDER;
541         else
542             if( !(winpos->flags & SWP_NOZORDER) )
543                 if( GetWindow(winpos->hwndInsertAfter, GW_HWNDNEXT) == wndPtr->hwndSelf )
544                     winpos->flags |= SWP_NOZORDER;
545
546     /* Common operations */
547
548       /* Send WM_NCCALCSIZE message to get new client area */
549     if( (winpos->flags & (SWP_FRAMECHANGED | SWP_NOSIZE)) != SWP_NOSIZE )
550     {
551          WINPOS_SendNCCalcSize( winpos->hwnd, TRUE, &newWindowRect,
552                                 &wndPtr->rectWindow, &wndPtr->rectClient,
553                                 winpos, &newClientRect );
554     }
555
556     if(!(winpos->flags & SWP_NOZORDER) && winpos->hwnd != winpos->hwndInsertAfter)
557     {
558         if ( WIN_UnlinkWindow( winpos->hwnd ) )
559             WIN_LinkWindow( winpos->hwnd, winpos->hwndInsertAfter );
560     }
561
562     /* FIXME: actually do something with WVR_VALIDRECTS */
563
564     wndPtr->rectWindow = newWindowRect;
565     wndPtr->rectClient = newClientRect;
566
567     if( winpos->flags & SWP_SHOWWINDOW )
568     {
569         wndPtr->dwStyle |= WS_VISIBLE;
570     }
571     else if( winpos->flags & SWP_HIDEWINDOW )
572     {
573         wndPtr->dwStyle &= ~WS_VISIBLE;
574     }
575
576     /* ------------------------------------------------------------------------ FINAL */
577
578     /* repaint invalidated region (if any)
579      *
580      * FIXME: if SWP_NOACTIVATE is not set then set invalid regions here without any painting
581      *        and force update after ChangeActiveWindow() to avoid painting frames twice.
582      */
583
584     if( !(winpos->flags & SWP_NOREDRAW) )
585     {
586         RedrawWindow( wndPtr->parent->hwndSelf, NULL, 0,
587                       RDW_ERASE | RDW_INVALIDATE | RDW_ALLCHILDREN );
588         if (wndPtr->parent->hwndSelf == GetDesktopWindow() ||
589             wndPtr->parent->parent->hwndSelf == GetDesktopWindow())
590         {
591             RedrawWindow( wndPtr->parent->hwndSelf, NULL, 0,
592                           RDW_ERASENOW | RDW_NOCHILDREN );
593         }
594     }
595
596     if (!(winpos->flags & SWP_NOACTIVATE))
597         WINPOS_ChangeActiveWindow( winpos->hwnd, FALSE );
598
599       /* And last, send the WM_WINDOWPOSCHANGED message */
600
601     TRACE("\tstatus flags = %04x\n", winpos->flags & SWP_AGG_STATUSFLAGS);
602
603     if ((((winpos->flags & SWP_AGG_STATUSFLAGS) != SWP_AGG_NOPOSCHANGE) &&
604           !(winpos->flags & SWP_NOSENDCHANGING)) )
605         SendMessageA( winpos->hwnd, WM_WINDOWPOSCHANGED, 0, (LPARAM)winpos );
606
607     retvalue = TRUE;
608  END:
609     WIN_ReleaseWndPtr(wndPtr);
610     return retvalue;
611 }