Release 940524
[wine] / windows / winpos.c
1 /*
2  * Window position related functions.
3  *
4  * Copyright 1993 Alexandre Julliard
5  */
6
7 static char Copyright[] = "Copyright  Alexandre Julliard, 1993";
8
9 #include "sysmetrics.h"
10 #include "user.h"
11 #include "win.h"
12 #include "message.h"
13
14 static HWND hwndActive = 0;  /* Currently active window */
15
16
17 /***********************************************************************
18  *           GetWindowRect   (USER.32)
19  */
20 void GetWindowRect( HWND hwnd, LPRECT rect ) 
21 {
22     WND * wndPtr = WIN_FindWndPtr( hwnd ); 
23     if (!wndPtr) return;
24     
25     *rect = wndPtr->rectWindow;
26     if (wndPtr->dwStyle & WS_CHILD)
27         MapWindowPoints( wndPtr->hwndParent, 0, (POINT *)rect, 2 );
28 }
29
30
31 /***********************************************************************
32  *           GetClientRect   (USER.33)
33  */
34 void GetClientRect( HWND hwnd, LPRECT rect ) 
35 {
36     WND * wndPtr = WIN_FindWndPtr( hwnd );
37
38     rect->left = rect->top = rect->right = rect->bottom = 0;
39     if (wndPtr) 
40     {
41         rect->right  = wndPtr->rectClient.right - wndPtr->rectClient.left;
42         rect->bottom = wndPtr->rectClient.bottom - wndPtr->rectClient.top;
43     }
44 }
45
46
47 /*******************************************************************
48  *         ClientToScreen   (USER.28)
49  */
50 void ClientToScreen( HWND hwnd, LPPOINT lppnt )
51 {
52     MapWindowPoints( hwnd, 0, lppnt, 1 );
53 }
54
55
56 /*******************************************************************
57  *         ScreenToClient   (USER.29)
58  */
59 void ScreenToClient( HWND hwnd, LPPOINT lppnt )
60 {
61     MapWindowPoints( 0, hwnd, lppnt, 1 );
62 }
63
64
65 /*******************************************************************
66  *         WindowFromPoint   (USER.30)
67  */
68 HWND WindowFromPoint( POINT pt )
69 {
70     HWND hwndRet = 0;
71     HWND hwnd = GetDesktopWindow();
72
73     while(hwnd)
74     {
75           /* If point is in window, and window is visible,   */
76           /* not disabled and not transparent, then explore  */
77           /* its children. Otherwise, go to the next window. */
78
79         WND *wndPtr = WIN_FindWndPtr( hwnd );
80         if ((pt.x >= wndPtr->rectWindow.left) &&
81             (pt.x < wndPtr->rectWindow.right) &&
82             (pt.y >= wndPtr->rectWindow.top) &&
83             (pt.y < wndPtr->rectWindow.bottom) &&
84             !(wndPtr->dwStyle & WS_DISABLED) &&
85             (wndPtr->dwStyle & WS_VISIBLE) &&
86             !(wndPtr->dwExStyle & WS_EX_TRANSPARENT))
87         {
88             pt.x -= wndPtr->rectClient.left;
89             pt.y -= wndPtr->rectClient.top;
90             hwndRet = hwnd;
91             hwnd = wndPtr->hwndChild;
92         }
93         else hwnd = wndPtr->hwndNext;
94     }
95     return hwndRet;
96 }
97
98
99 /*******************************************************************
100  *         ChildWindowFromPoint   (USER.191)
101  */
102 HWND ChildWindowFromPoint( HWND hwndParent, POINT pt )
103 {
104     RECT rect;
105     HWND hwnd;
106     
107     GetWindowRect( hwndParent, &rect );
108     if (!PtInRect( &rect, pt )) return 0;
109     hwnd = GetTopWindow( hwndParent );
110     while (hwnd)
111     {
112         GetWindowRect( hwnd, &rect );
113         if (PtInRect( &rect, pt )) return hwnd;
114         hwnd = GetWindow( hwnd, GW_HWNDNEXT );
115     }
116     return hwndParent;
117 }
118
119
120 /*******************************************************************
121  *         MapWindowPoints   (USER.258)
122  */
123 void MapWindowPoints( HWND hwndFrom, HWND hwndTo, LPPOINT lppt, WORD count )
124 {
125     WND * wndPtr;
126     POINT * curpt;
127     POINT origin = { 0, 0 };
128     WORD i;
129
130       /* Translate source window origin to screen coords */
131     while(hwndFrom)
132     {
133         wndPtr = WIN_FindWndPtr( hwndFrom );
134         origin.x += wndPtr->rectClient.left;
135         origin.y += wndPtr->rectClient.top;
136         hwndFrom = (wndPtr->dwStyle & WS_CHILD) ? wndPtr->hwndParent : 0;
137     }
138
139       /* Translate origin to destination window coords */
140     while(hwndTo)
141     {
142         wndPtr = WIN_FindWndPtr( hwndTo );
143         origin.x -= wndPtr->rectClient.left;
144         origin.y -= wndPtr->rectClient.top;
145         hwndTo = (wndPtr->dwStyle & WS_CHILD) ? wndPtr->hwndParent : 0;
146     }    
147
148       /* Translate points */
149     for (i = 0, curpt = lppt; i < count; i++, curpt++)
150     {
151         curpt->x += origin.x;
152         curpt->y += origin.y;
153     }
154 }
155
156
157 /***********************************************************************
158  *           IsIconic   (USER.31)
159  */
160 BOOL IsIconic(HWND hWnd)
161 {
162     WND * wndPtr = WIN_FindWndPtr(hWnd);
163     if (wndPtr == NULL) return FALSE;
164     return (wndPtr->dwStyle & WS_MINIMIZE) != 0;
165 }
166  
167  
168 /***********************************************************************
169  *           IsZoomed   (USER.272)
170  */
171 BOOL IsZoomed(HWND hWnd)
172 {
173     WND * wndPtr = WIN_FindWndPtr(hWnd);
174     if (wndPtr == NULL) return FALSE;
175     return (wndPtr->dwStyle & WS_MAXIMIZE) != 0;
176 }
177
178
179 /*******************************************************************
180  *         GetActiveWindow    (USER.60)
181  */
182 HWND GetActiveWindow()
183 {
184     return hwndActive;
185 }
186
187 /*******************************************************************
188  *         SetActiveWindow    (USER.59)
189  */
190 HWND SetActiveWindow( HWND hwnd )
191 {
192     HWND prev = hwndActive;
193     WND *wndPtr = WIN_FindWndPtr( hwnd );
194     if (!wndPtr || (wndPtr->dwStyle & WS_CHILD)) return 0;
195     SetWindowPos( hwnd, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE );
196     return prev;
197 }
198
199
200 /***********************************************************************
201  *           BringWindowToTop   (USER.45)
202  */
203 BOOL BringWindowToTop( HWND hwnd )
204 {
205     return SetWindowPos( hwnd, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE );
206 }
207
208
209 /***********************************************************************
210  *           MoveWindow   (USER.56)
211  */
212 BOOL MoveWindow( HWND hwnd, short x, short y, short cx, short cy, BOOL repaint)
213 {    
214     int flags = SWP_NOZORDER | SWP_NOACTIVATE;
215     if (!repaint) flags |= SWP_NOREDRAW;
216 #ifdef DEBUG_WIN    
217     printf( "MoveWindow: %d %d,%d %dx%d %d\n", hwnd, x, y, cx, cy, repaint );
218 #endif
219     return SetWindowPos( hwnd, 0, x, y, cx, cy, flags );
220 }
221
222
223 /***********************************************************************
224  *           ShowWindow   (USER.42)
225  */
226 BOOL ShowWindow( HWND hwnd, int cmd ) 
227 {    
228     WND * wndPtr = WIN_FindWndPtr( hwnd );
229     BOOL wasVisible;
230     int swpflags = 0;
231
232 #ifdef DEBUG_WIN
233     printf("ShowWindow: hwnd=%04X, cmd=%d\n", hwnd, cmd);
234 #endif
235     
236     if (!wndPtr) return FALSE;
237     wasVisible = (wndPtr->dwStyle & WS_VISIBLE) != 0;
238     switch(cmd)
239     {
240         case SW_HIDE:
241             if (!wasVisible) return FALSE;  /* Nothing to do */
242             swpflags |= SWP_HIDEWINDOW | SWP_NOSIZE | SWP_NOMOVE | 
243                         SWP_NOACTIVATE | SWP_NOZORDER;
244             break;
245
246         case SW_SHOWMINNOACTIVE:
247         case SW_SHOWMINIMIZED:
248         case SW_SHOWMAXIMIZED:
249         case SW_MINIMIZE:
250             wndPtr->dwStyle |= WS_MINIMIZE;
251             swpflags |= SWP_SHOWWINDOW | SWP_NOSIZE | SWP_NOMOVE | 
252                         SWP_NOACTIVATE | SWP_NOZORDER;
253             break;
254
255         case SW_SHOWNA:
256         case SW_MAXIMIZE:
257         case SW_SHOW:
258             swpflags |= SWP_SHOWWINDOW | SWP_NOSIZE | SWP_NOMOVE;
259             break;
260
261         case SW_NORMAL:
262         case SW_SHOWNORMAL:
263         case SW_SHOWNOACTIVATE:
264         case SW_RESTORE:
265             wndPtr->dwStyle &= ~WS_MINIMIZE;
266             wndPtr->dwStyle &= ~WS_MAXIMIZE;
267             swpflags |= SWP_SHOWWINDOW | SWP_NOSIZE | SWP_NOMOVE;
268             if (cmd == SW_SHOWNOACTIVATE)
269             {
270                 swpflags |= SWP_NOZORDER;
271                 if (GetActiveWindow()) swpflags |= SWP_NOACTIVATE;
272             }
273             break;
274     }
275     SendMessage( hwnd, WM_SHOWWINDOW, (cmd != SW_HIDE), 0 );
276     SetWindowPos( hwnd, 0, 0, 0, 0, 0, swpflags );
277
278       /* Send WM_SIZE and WM_MOVE messages if not already done */
279     if (!(wndPtr->flags & WIN_GOT_SIZEMSG))
280     {
281         int wParam = SIZE_RESTORED;
282         if (wndPtr->dwStyle & WS_MAXIMIZE) wParam = SIZE_MAXIMIZED;
283         else if (wndPtr->dwStyle & WS_MINIMIZE) wParam = SIZE_MINIMIZED;
284         wndPtr->flags |= WIN_GOT_SIZEMSG;
285         SendMessage( hwnd, WM_SIZE, wParam,
286                      MAKELONG(wndPtr->rectClient.right-wndPtr->rectClient.left,
287                             wndPtr->rectClient.bottom-wndPtr->rectClient.top));
288         SendMessage( hwnd, WM_MOVE, 0,
289                    MAKELONG(wndPtr->rectClient.left, wndPtr->rectClient.top) );
290     }
291     return wasVisible;
292 }
293
294
295 /***********************************************************************
296  *           GetInternalWindowPos   (USER.460)
297  */
298 WORD GetInternalWindowPos( HWND hwnd, LPRECT rectWnd, LPPOINT ptIcon )
299 {
300     WINDOWPLACEMENT wndpl;
301     if (!GetWindowPlacement( hwnd, &wndpl )) return 0;
302     if (rectWnd) *rectWnd = wndpl.rcNormalPosition;
303     if (ptIcon)  *ptIcon = wndpl.ptMinPosition;
304     return wndpl.showCmd;
305 }
306
307
308 /***********************************************************************
309  *           SetInternalWindowPos   (USER.461)
310  */
311 void SetInternalWindowPos( HWND hwnd, WORD showCmd, LPRECT rect, LPPOINT pt )
312 {
313     WINDOWPLACEMENT wndpl;
314     WND *wndPtr = WIN_FindWndPtr( hwnd );
315
316     wndpl.length  = sizeof(wndpl);
317     wndpl.flags   = (pt != NULL) ? WPF_SETMINPOSITION : 0;
318     wndpl.showCmd = showCmd;
319     if (pt) wndpl.ptMinPosition = *pt;
320     wndpl.rcNormalPosition = (rect != NULL) ? *rect : wndPtr->rectNormal;
321     wndpl.ptMaxPosition = wndPtr->ptMaxPos;
322     SetWindowPlacement( hwnd, &wndpl );
323 }
324
325
326 /***********************************************************************
327  *           GetWindowPlacement   (USER.370)
328  */
329 BOOL GetWindowPlacement( HWND hwnd, WINDOWPLACEMENT *wndpl )
330 {
331     WND *wndPtr = WIN_FindWndPtr( hwnd );
332     if (!wndPtr) return FALSE;
333
334     wndpl->length  = sizeof(*wndpl);
335     wndpl->flags   = 0;
336     wndpl->showCmd = IsZoomed(hwnd) ? SW_SHOWMAXIMIZED : 
337                      (IsIconic(hwnd) ? SW_SHOWMINIMIZED : SW_SHOWNORMAL);
338     wndpl->ptMinPosition = wndPtr->ptIconPos;
339     wndpl->ptMaxPosition = wndPtr->ptMaxPos;
340     wndpl->rcNormalPosition = wndPtr->rectNormal;
341     return TRUE;
342 }
343
344
345 /***********************************************************************
346  *           SetWindowPlacement   (USER.371)
347  */
348 BOOL SetWindowPlacement( HWND hwnd, WINDOWPLACEMENT *wndpl )
349 {
350     WND *wndPtr = WIN_FindWndPtr( hwnd );
351     if (!wndPtr) return FALSE;
352
353     if (wndpl->flags & WPF_SETMINPOSITION)
354         wndPtr->ptIconPos = wndpl->ptMinPosition;
355     if ((wndpl->flags & WPF_RESTORETOMAXIMIZED) &&
356         (wndpl->showCmd == SW_SHOWMINIMIZED)) wndPtr->flags |= WIN_RESTORE_MAX;
357     wndPtr->ptMaxPos   = wndpl->ptMaxPosition;
358     wndPtr->rectNormal = wndpl->rcNormalPosition;
359     ShowWindow( hwnd, wndpl->showCmd );
360     return TRUE;
361 }
362
363
364 /*******************************************************************
365  *         WINPOS_GetMinMaxInfo
366  *
367  * Send a WM_GETMINMAXINFO to the window.
368  */
369 void WINPOS_GetMinMaxInfo( HWND hwnd, POINT *maxSize, POINT *maxPos,
370                            POINT *minTrack, POINT *maxTrack )
371 {
372     HANDLE minmaxHandle;
373     MINMAXINFO MinMax, *pMinMax;
374     WND *wndPtr = WIN_FindWndPtr( hwnd );
375
376     MinMax.ptMaxSize.x = SYSMETRICS_CXSCREEN;
377     MinMax.ptMaxSize.y = SYSMETRICS_CYSCREEN;
378     MinMax.ptMaxPosition = wndPtr->ptMaxPos;
379     MinMax.ptMinTrackSize.x = SYSMETRICS_CXMINTRACK;
380     MinMax.ptMinTrackSize.y = SYSMETRICS_CYMINTRACK;
381     MinMax.ptMaxTrackSize.x = SYSMETRICS_CXSCREEN;
382     MinMax.ptMaxTrackSize.y = SYSMETRICS_CYSCREEN;
383
384     minmaxHandle = USER_HEAP_ALLOC( LMEM_MOVEABLE, sizeof(MINMAXINFO) );
385     if (minmaxHandle)
386     {
387         pMinMax = (MINMAXINFO *) USER_HEAP_ADDR( minmaxHandle );
388         memcpy( pMinMax, &MinMax, sizeof(MinMax) );     
389         SendMessage( hwnd, WM_GETMINMAXINFO, 0, (LONG)pMinMax );
390     }
391     else pMinMax = &MinMax;
392
393       /* Some sanity checks */
394
395     pMinMax->ptMaxTrackSize.x = max( pMinMax->ptMaxTrackSize.x,
396                                      pMinMax->ptMinTrackSize.x );
397     pMinMax->ptMaxTrackSize.y = max( pMinMax->ptMaxTrackSize.y,
398                                      pMinMax->ptMinTrackSize.y );
399     
400     if (maxSize) *maxSize = pMinMax->ptMaxSize;
401     if (maxPos) *maxPos = pMinMax->ptMaxPosition;
402     if (minTrack) *minTrack = pMinMax->ptMinTrackSize;
403     if (maxTrack) *maxTrack = pMinMax->ptMaxTrackSize;
404     if (minmaxHandle) USER_HEAP_FREE( minmaxHandle );
405 }
406
407
408 /*******************************************************************
409  *         WINPOS_ChangeActiveWindow
410  *
411  * Change the active window and send the corresponding messages.
412  */
413 HWND WINPOS_ChangeActiveWindow( HWND hwnd, BOOL mouseMsg )
414 {
415     HWND prevActive = hwndActive;
416     if (hwnd == hwndActive) return 0;
417     if (hwndActive)
418     {
419         if (!SendMessage( hwndActive, WM_NCACTIVATE, FALSE, 0 )) return 0;
420         SendMessage( hwndActive, WM_ACTIVATE, WA_INACTIVE,
421                      MAKELONG( IsIconic(hwndActive), hwnd ) );
422         /* Send WM_ACTIVATEAPP here */
423     }
424
425     hwndActive = hwnd;
426     if (hwndActive)
427     {
428         WND *wndPtr = WIN_FindWndPtr( hwndActive );
429         wndPtr->hwndPrevActive = prevActive;
430
431         /* Send WM_ACTIVATEAPP here */
432         SendMessage( hwnd, WM_NCACTIVATE, TRUE, 0 );
433         SendMessage( hwnd, WM_ACTIVATE, mouseMsg ? WA_CLICKACTIVE : WA_ACTIVE,
434                      MAKELONG( IsIconic(hwnd), prevActive ) );
435     }
436     return prevActive;
437 }
438
439
440 /***********************************************************************
441  *           SetWindowPos   (USER.232)
442  */
443 /* Note: all this code should be in the DeferWindowPos() routines,
444  * and SetWindowPos() should simply call them.  This will be implemented
445  * some day...
446  */
447 BOOL SetWindowPos( HWND hwnd, HWND hwndInsertAfter, short x, short y,
448                    short cx, short cy, WORD flags )
449 {
450     WINDOWPOS *winPos;
451     HANDLE hmem = 0;
452     RECT newWindowRect, newClientRect;
453     WND *wndPtr;
454     int calcsize_result = 0;
455     XWindowChanges winChanges;
456     int changeMask = 0;
457
458 #ifdef DEBUG_WIN
459     printf( "SetWindowPos: %04X %d %d,%d %dx%d 0x%x\n",
460             hwnd, hwndInsertAfter, x, y, cx, cy, flags );
461 #endif
462
463     if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return FALSE;
464     if (flags & (SWP_SHOWWINDOW | SWP_HIDEWINDOW))
465         flags |= SWP_NOMOVE | SWP_NOSIZE;
466
467       /* Send WM_WINDOWPOSCHANGING message */
468
469     if (!(hmem = USER_HEAP_ALLOC( GMEM_MOVEABLE, sizeof(WINDOWPOS) )))
470         return FALSE;
471     winPos = (WINDOWPOS *)USER_HEAP_ADDR( hmem );
472     winPos->hwnd = hwnd;
473     winPos->hwndInsertAfter = hwndInsertAfter;
474     winPos->x = x;
475     winPos->y = y;
476     winPos->cx = cx;
477     winPos->cy = cy;
478     winPos->flags = flags;
479     SendMessage( hwnd, WM_WINDOWPOSCHANGING, 0, (LONG)winPos );
480     hwndInsertAfter = winPos->hwndInsertAfter;
481
482       /* Some sanity checks */
483
484     if (!IsWindow( hwnd ) || (hwnd == GetDesktopWindow())) goto Abort;
485     if (flags & (SWP_SHOWWINDOW | SWP_HIDEWINDOW))
486         flags |= SWP_NOMOVE | SWP_NOSIZE;
487     if (!(flags & (SWP_NOZORDER | SWP_NOACTIVATE)))
488     {
489         if (hwnd != hwndActive) hwndInsertAfter = HWND_TOP;
490         else if ((hwndInsertAfter == HWND_TOPMOST) ||
491                  (hwndInsertAfter == HWND_NOTOPMOST))
492             hwndInsertAfter = HWND_TOP; 
493     }
494
495       /* Calculate new position and size */
496
497     newWindowRect = wndPtr->rectWindow;
498     newClientRect = wndPtr->rectClient;
499
500     if (!(winPos->flags & SWP_NOSIZE))
501     {
502         newWindowRect.right  = newWindowRect.left + winPos->cx;
503         newWindowRect.bottom = newWindowRect.top + winPos->cy;
504     }
505
506     if (!(winPos->flags & SWP_NOMOVE))
507     {
508         newWindowRect.left    = winPos->x;
509         newWindowRect.top     = winPos->y;
510         newWindowRect.right  += winPos->x - wndPtr->rectWindow.left;
511         newWindowRect.bottom += winPos->y - wndPtr->rectWindow.top;
512     }
513
514       /* Reposition window in Z order */
515
516     if (!(winPos->flags & SWP_NOZORDER))
517     {
518           /* TOPMOST not supported yet */
519         if ((hwndInsertAfter == HWND_TOPMOST) ||
520             (hwndInsertAfter == HWND_NOTOPMOST)) hwndInsertAfter = HWND_TOP;
521
522           /* Make sure hwndInsertAfter is a sibling of hwnd */
523         if ((hwndInsertAfter != HWND_TOP) && (hwndInsertAfter != HWND_BOTTOM))
524             if (GetParent(hwnd) != GetParent(hwndInsertAfter)) goto Abort;
525
526         WIN_UnlinkWindow( hwnd );
527         WIN_LinkWindow( hwnd, hwndInsertAfter );
528     }
529
530       /* Recalculate client area position */
531
532     if (winPos->flags & SWP_FRAMECHANGED)
533     {
534           /* Send WM_NCCALCSIZE message */
535         NCCALCSIZE_PARAMS *params;
536         HANDLE hparams;
537         
538         if (!(hparams = USER_HEAP_ALLOC( GMEM_MOVEABLE, sizeof(*params) )))
539             goto Abort;
540         params = (NCCALCSIZE_PARAMS *) USER_HEAP_ADDR( hparams );
541         params->rgrc[0] = newWindowRect;
542         params->rgrc[1] = wndPtr->rectWindow;
543         params->rgrc[2] = wndPtr->rectClient;
544         params->lppos = winPos;
545         calcsize_result = SendMessage(hwnd, WM_NCCALCSIZE, TRUE, (LONG)params);
546         USER_HEAP_FREE( hparams );
547         newClientRect = params->rgrc[0];
548         /* Handle result here */
549     }
550     else
551     {
552         newClientRect.left   = newWindowRect.left + wndPtr->rectClient.left
553                                - wndPtr->rectWindow.left;
554         newClientRect.top    = newWindowRect.top + wndPtr->rectClient.top
555                                - wndPtr->rectWindow.top;
556         newClientRect.right  = newWindowRect.right + wndPtr->rectClient.right
557                                - wndPtr->rectWindow.right;
558         newClientRect.bottom = newWindowRect.bottom + wndPtr->rectClient.bottom
559                                - wndPtr->rectWindow.bottom;
560     }
561     
562       /* Perform the moving and resizing */
563
564     if (!(winPos->flags & SWP_NOMOVE))
565     {
566         WND * parentPtr;
567         winChanges.x = newWindowRect.left;
568         winChanges.y = newWindowRect.top;
569         if (wndPtr->dwStyle & WS_CHILD)
570         {
571             parentPtr = WIN_FindWndPtr(wndPtr->hwndParent);
572             winChanges.x += parentPtr->rectClient.left-parentPtr->rectWindow.left;
573             winChanges.y += parentPtr->rectClient.top-parentPtr->rectWindow.top;
574         }
575         changeMask |= CWX | CWY;
576     }
577     if (!(winPos->flags & SWP_NOSIZE))
578     {
579         winChanges.width  = newWindowRect.right - newWindowRect.left;
580         winChanges.height = newWindowRect.bottom - newWindowRect.top;
581         changeMask |= CWWidth | CWHeight;
582     }
583     if (!(winPos->flags & SWP_NOZORDER))
584     {
585         if (hwndInsertAfter == HWND_TOP) winChanges.stack_mode = Above;
586         else winChanges.stack_mode = Below;
587         if ((hwndInsertAfter != HWND_TOP) && (hwndInsertAfter != HWND_BOTTOM))
588         {
589             WND * insertPtr = WIN_FindWndPtr( hwndInsertAfter );
590             winChanges.sibling = insertPtr->window;
591             changeMask |= CWSibling;
592         }
593         changeMask |= CWStackMode;
594     }
595         if ((newWindowRect.right - newWindowRect.left) != 0 &&
596                 (newWindowRect.bottom - newWindowRect.top) != 0)
597                 if (changeMask) XConfigureWindow( display, wndPtr->window,
598                                                                         changeMask, &winChanges );
599
600         if ((newWindowRect.right - newWindowRect.left) != 0 &&
601                 (newWindowRect.bottom - newWindowRect.top) != 0 &&
602                 (winPos->flags & SWP_SHOWWINDOW))
603     {
604         wndPtr->dwStyle |= WS_VISIBLE;
605         XMapWindow( display, wndPtr->window );
606         MSG_Synchronize();
607         if (winPos->flags & SWP_NOREDRAW)
608             RedrawWindow( hwnd, NULL, 0, RDW_VALIDATE );
609     }
610     else if (winPos->flags & SWP_HIDEWINDOW)
611     {
612         wndPtr->dwStyle &= ~WS_VISIBLE;
613         XUnmapWindow( display, wndPtr->window );
614         if ((hwnd == GetFocus()) || IsChild( hwnd, GetFocus() ))
615             SetFocus( GetParent(hwnd) );  /* Revert focus to parent (if any) */
616         if (hwnd == hwndActive)
617         {
618               /* Activate previously active window if possible */
619             HWND newActive = wndPtr->hwndPrevActive;
620             if (!IsWindow(newActive) || (newActive == hwnd))
621             {
622                 newActive = GetTopWindow(GetDesktopWindow());
623                 if (newActive == hwnd) newActive = wndPtr->hwndNext;
624             }       
625             WINPOS_ChangeActiveWindow( newActive, FALSE );
626         }
627     }
628
629     if (!(winPos->flags & SWP_NOACTIVATE))
630     {
631         if (!(wndPtr->dwStyle & WS_CHILD))
632             WINPOS_ChangeActiveWindow( hwnd, FALSE );
633     }
634     
635       /* Send WM_NCPAINT message if needed */
636     if ((winPos->flags & (SWP_FRAMECHANGED | SWP_SHOWWINDOW)) ||
637         (!(winPos->flags & SWP_NOSIZE)) ||
638         (!(winPos->flags & SWP_NOMOVE)) ||
639         (!(winPos->flags & SWP_NOACTIVATE)) ||
640         (!(winPos->flags & SWP_NOZORDER)))
641             SendMessage( hwnd, WM_NCPAINT, 1, 0L );
642
643       /* Finally send the WM_WINDOWPOSCHANGED message */
644     wndPtr->rectWindow = newWindowRect;
645     wndPtr->rectClient = newClientRect;
646     SendMessage( hwnd, WM_WINDOWPOSCHANGED, 0, (LONG)winPos );
647     USER_HEAP_FREE( hmem );
648
649     return TRUE;
650
651  Abort:  /* Fatal error encountered */
652     if (hmem) USER_HEAP_FREE( hmem );
653     return FALSE;
654 }