Release 940714
[wine/multimedia.git] / windows / winpos.c
blobf60ea4ac07a093b8a5e0079b00c5fd4c136a1e8f
1 /*
2 * Window position related functions.
4 * Copyright 1993 Alexandre Julliard
5 */
7 static char Copyright[] = "Copyright Alexandre Julliard, 1993";
9 #include "sysmetrics.h"
10 #include "user.h"
11 #include "win.h"
12 #include "message.h"
14 static HWND hwndActive = 0; /* Currently active window */
17 /***********************************************************************
18 * GetWindowRect (USER.32)
20 void GetWindowRect( HWND hwnd, LPRECT rect )
22 WND * wndPtr = WIN_FindWndPtr( hwnd );
23 if (!wndPtr) return;
25 *rect = wndPtr->rectWindow;
26 if (wndPtr->dwStyle & WS_CHILD)
27 MapWindowPoints( wndPtr->hwndParent, 0, (POINT *)rect, 2 );
31 /***********************************************************************
32 * GetClientRect (USER.33)
34 void GetClientRect( HWND hwnd, LPRECT rect )
36 WND * wndPtr = WIN_FindWndPtr( hwnd );
38 rect->left = rect->top = rect->right = rect->bottom = 0;
39 if (wndPtr)
41 rect->right = wndPtr->rectClient.right - wndPtr->rectClient.left;
42 rect->bottom = wndPtr->rectClient.bottom - wndPtr->rectClient.top;
47 /*******************************************************************
48 * ClientToScreen (USER.28)
50 void ClientToScreen( HWND hwnd, LPPOINT lppnt )
52 MapWindowPoints( hwnd, 0, lppnt, 1 );
56 /*******************************************************************
57 * ScreenToClient (USER.29)
59 void ScreenToClient( HWND hwnd, LPPOINT lppnt )
61 MapWindowPoints( 0, hwnd, lppnt, 1 );
65 /*******************************************************************
66 * WindowFromPoint (USER.30)
68 HWND WindowFromPoint( POINT pt )
70 HWND hwndRet = 0;
71 HWND hwnd = GetDesktopWindow();
73 while(hwnd)
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. */
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))
88 pt.x -= wndPtr->rectClient.left;
89 pt.y -= wndPtr->rectClient.top;
90 hwndRet = hwnd;
91 hwnd = wndPtr->hwndChild;
93 else hwnd = wndPtr->hwndNext;
95 return hwndRet;
99 /*******************************************************************
100 * ChildWindowFromPoint (USER.191)
102 HWND ChildWindowFromPoint( HWND hwndParent, POINT pt )
104 RECT rect;
105 HWND hwnd;
107 GetWindowRect( hwndParent, &rect );
108 if (!PtInRect( &rect, pt )) return 0;
109 hwnd = GetTopWindow( hwndParent );
110 while (hwnd)
112 GetWindowRect( hwnd, &rect );
113 if (PtInRect( &rect, pt )) return hwnd;
114 hwnd = GetWindow( hwnd, GW_HWNDNEXT );
116 return hwndParent;
120 /*******************************************************************
121 * MapWindowPoints (USER.258)
123 void MapWindowPoints( HWND hwndFrom, HWND hwndTo, LPPOINT lppt, WORD count )
125 WND * wndPtr;
126 POINT * curpt;
127 POINT origin = { 0, 0 };
128 WORD i;
130 /* Translate source window origin to screen coords */
131 while(hwndFrom)
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;
139 /* Translate origin to destination window coords */
140 while(hwndTo)
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;
148 /* Translate points */
149 for (i = 0, curpt = lppt; i < count; i++, curpt++)
151 curpt->x += origin.x;
152 curpt->y += origin.y;
157 /***********************************************************************
158 * IsIconic (USER.31)
160 BOOL IsIconic(HWND hWnd)
162 WND * wndPtr = WIN_FindWndPtr(hWnd);
163 if (wndPtr == NULL) return FALSE;
164 return (wndPtr->dwStyle & WS_MINIMIZE) != 0;
168 /***********************************************************************
169 * IsZoomed (USER.272)
171 BOOL IsZoomed(HWND hWnd)
173 WND * wndPtr = WIN_FindWndPtr(hWnd);
174 if (wndPtr == NULL) return FALSE;
175 return (wndPtr->dwStyle & WS_MAXIMIZE) != 0;
179 /*******************************************************************
180 * GetActiveWindow (USER.60)
182 HWND GetActiveWindow()
184 return hwndActive;
187 /*******************************************************************
188 * SetActiveWindow (USER.59)
190 HWND SetActiveWindow( HWND hwnd )
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;
200 /***********************************************************************
201 * BringWindowToTop (USER.45)
203 BOOL BringWindowToTop( HWND hwnd )
205 return SetWindowPos( hwnd, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE );
209 /***********************************************************************
210 * MoveWindow (USER.56)
212 BOOL MoveWindow( HWND hwnd, short x, short y, short cx, short cy, BOOL repaint)
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 );
223 /***********************************************************************
224 * ShowWindow (USER.42)
226 BOOL ShowWindow( HWND hwnd, int cmd )
228 WND * wndPtr = WIN_FindWndPtr( hwnd );
229 BOOL wasVisible;
230 int swpflags = 0;
232 #ifdef DEBUG_WIN
233 printf("ShowWindow: hwnd=%04X, cmd=%d\n", hwnd, cmd);
234 #endif
236 if (!wndPtr) return FALSE;
237 wasVisible = (wndPtr->dwStyle & WS_VISIBLE) != 0;
238 switch(cmd)
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;
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;
255 case SW_SHOWNA:
256 case SW_MAXIMIZE:
257 case SW_SHOW:
258 swpflags |= SWP_SHOWWINDOW | SWP_NOSIZE | SWP_NOMOVE;
259 break;
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)
270 swpflags |= SWP_NOZORDER;
271 if (GetActiveWindow()) swpflags |= SWP_NOACTIVATE;
273 break;
275 SendMessage( hwnd, WM_SHOWWINDOW, (cmd != SW_HIDE), 0 );
276 SetWindowPos( hwnd, 0, 0, 0, 0, 0, swpflags );
278 /* Send WM_SIZE and WM_MOVE messages if not already done */
279 if (!(wndPtr->flags & WIN_GOT_SIZEMSG))
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) );
291 return wasVisible;
295 /***********************************************************************
296 * GetInternalWindowPos (USER.460)
298 WORD GetInternalWindowPos( HWND hwnd, LPRECT rectWnd, LPPOINT ptIcon )
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;
308 /***********************************************************************
309 * SetInternalWindowPos (USER.461)
311 void SetInternalWindowPos( HWND hwnd, WORD showCmd, LPRECT rect, LPPOINT pt )
313 WINDOWPLACEMENT wndpl;
314 WND *wndPtr = WIN_FindWndPtr( hwnd );
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 );
326 /***********************************************************************
327 * GetWindowPlacement (USER.370)
329 BOOL GetWindowPlacement( HWND hwnd, WINDOWPLACEMENT *wndpl )
331 WND *wndPtr = WIN_FindWndPtr( hwnd );
332 if (!wndPtr) return FALSE;
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;
345 /***********************************************************************
346 * SetWindowPlacement (USER.371)
348 BOOL SetWindowPlacement( HWND hwnd, WINDOWPLACEMENT *wndpl )
350 WND *wndPtr = WIN_FindWndPtr( hwnd );
351 if (!wndPtr) return FALSE;
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;
364 /*******************************************************************
365 * WINPOS_GetMinMaxInfo
367 * Send a WM_GETMINMAXINFO to the window.
369 void WINPOS_GetMinMaxInfo( HWND hwnd, POINT *maxSize, POINT *maxPos,
370 POINT *minTrack, POINT *maxTrack )
372 HANDLE minmaxHandle;
373 MINMAXINFO MinMax, *pMinMax;
374 WND *wndPtr = WIN_FindWndPtr( hwnd );
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;
384 minmaxHandle = USER_HEAP_ALLOC( LMEM_MOVEABLE, sizeof(MINMAXINFO) );
385 if (minmaxHandle)
387 pMinMax = (MINMAXINFO *) USER_HEAP_ADDR( minmaxHandle );
388 memcpy( pMinMax, &MinMax, sizeof(MinMax) );
389 SendMessage( hwnd, WM_GETMINMAXINFO, 0, (LONG)pMinMax );
391 else pMinMax = &MinMax;
393 /* Some sanity checks */
395 pMinMax->ptMaxTrackSize.x = max( pMinMax->ptMaxTrackSize.x,
396 pMinMax->ptMinTrackSize.x );
397 pMinMax->ptMaxTrackSize.y = max( pMinMax->ptMaxTrackSize.y,
398 pMinMax->ptMinTrackSize.y );
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 );
408 /*******************************************************************
409 * WINPOS_ChangeActiveWindow
411 * Change the active window and send the corresponding messages.
413 HWND WINPOS_ChangeActiveWindow( HWND hwnd, BOOL mouseMsg )
415 HWND prevActive = hwndActive;
416 if (hwnd == hwndActive) return 0;
417 if (hwndActive)
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 */
425 hwndActive = hwnd;
426 if (hwndActive)
428 WND *wndPtr = WIN_FindWndPtr( hwndActive );
429 wndPtr->hwndPrevActive = prevActive;
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 ) );
436 return prevActive;
440 /***********************************************************************
441 * WINPOS_SendNCCalcSize
443 * Send a WM_NCCALCSIZE message to a window.
444 * All parameters are read-only except newClientRect.
445 * oldWindowRect, oldClientRect and winpos must be non-NULL only
446 * when calcValidRect is TRUE.
448 LONG WINPOS_SendNCCalcSize( HWND hwnd, BOOL calcValidRect, RECT *newWindowRect,
449 RECT *oldWindowRect, RECT *oldClientRect,
450 WINDOWPOS *winpos, RECT *newClientRect )
452 NCCALCSIZE_PARAMS *params;
453 HANDLE hparams;
454 LONG result;
456 if (!(hparams = USER_HEAP_ALLOC( GMEM_MOVEABLE, sizeof(*params) )))
457 return 0;
458 params = (NCCALCSIZE_PARAMS *) USER_HEAP_ADDR( hparams );
459 params->rgrc[0] = *newWindowRect;
460 if (calcValidRect)
462 params->rgrc[1] = *oldWindowRect;
463 params->rgrc[2] = *oldClientRect;
464 params->lppos = winpos;
466 result = SendMessage( hwnd, WM_NCCALCSIZE, calcValidRect, (LONG)params);
467 *newClientRect = params->rgrc[0];
468 USER_HEAP_FREE( hparams );
469 return result;
473 /***********************************************************************
474 * WINPOS_HandleWindowPosChanging
476 * Default handling for a WM_WINDOWPOSCHANGING. Called from DefWindowProc().
478 LONG WINPOS_HandleWindowPosChanging( WINDOWPOS *winpos )
480 POINT maxSize;
481 WND *wndPtr = WIN_FindWndPtr( winpos->hwnd );
482 if (!wndPtr || (winpos->flags & SWP_NOSIZE)) return 0;
483 if ((wndPtr->dwStyle & WS_THICKFRAME) ||
484 (wndPtr->dwStyle & (WS_POPUP | WS_CHILD) == 0))
486 WINPOS_GetMinMaxInfo( winpos->hwnd, &maxSize, NULL, NULL, NULL );
487 winpos->cx = min( winpos->cx, maxSize.x );
488 winpos->cy = min( winpos->cy, maxSize.y );
490 return 0;
494 /***********************************************************************
495 * WINPOS_InternalSetWindowPos
497 * Helper function for SetWindowPos.
499 static BOOL WINPOS_InternalSetWindowPos( WINDOWPOS *winpos )
501 HWND hwndAfter;
502 WND *wndPtr;
503 RECT newWindowRect, newClientRect;
504 int flags, result;
505 int changeMask = 0;
506 XWindowChanges winChanges;
508 /* Send WM_WINDOWPOSCHANGING message */
510 if (!(winpos->flags & SWP_NOSENDCHANGING))
511 SendMessage( winpos->hwnd, WM_WINDOWPOSCHANGING, 0, (LONG)winpos );
513 /* Check window handle */
515 if (winpos->hwnd == GetDesktopWindow()) return FALSE;
516 if (!(wndPtr = WIN_FindWndPtr( winpos->hwnd ))) return FALSE;
518 /* Check dimensions */
520 if (winpos->cx <= 0) winpos->cx = 1;
521 if (winpos->cy <= 0) winpos->cy = 1;
523 /* Check flags */
525 flags = winpos->flags;
526 if (flags & (SWP_SHOWWINDOW | SWP_HIDEWINDOW))
527 flags |= SWP_NOMOVE | SWP_NOSIZE;
528 if (winpos->hwnd == hwndActive) flags |= SWP_NOACTIVATE; /*Already active*/
530 /* Check hwndAfter */
532 hwndAfter = winpos->hwndInsertAfter;
533 if (!(flags & (SWP_NOZORDER | SWP_NOACTIVATE)))
535 /* Ignore TOPMOST flags when activating a window */
536 /* _and_ moving it in Z order. */
537 if ((hwndAfter == HWND_TOPMOST) || (hwndAfter == HWND_NOTOPMOST))
538 hwndAfter = HWND_TOP;
540 /* TOPMOST not supported yet */
541 if ((hwndAfter == HWND_TOPMOST) || (hwndAfter == HWND_NOTOPMOST))
542 hwndAfter = HWND_TOP;
543 /* hwndAfter must be a sibling of the window */
544 if ((hwndAfter != HWND_TOP) && (hwndAfter != HWND_BOTTOM) &&
545 (GetParent(winpos->hwnd) != GetParent(hwndAfter))) return FALSE;
547 /* Calculate new position and size */
549 newWindowRect = wndPtr->rectWindow;
550 newClientRect = wndPtr->rectClient;
552 if (!(flags & SWP_NOSIZE))
554 newWindowRect.right = newWindowRect.left + winpos->cx;
555 newWindowRect.bottom = newWindowRect.top + winpos->cy;
556 winChanges.width = winpos->cx;
557 winChanges.height = winpos->cy;
558 changeMask |= CWWidth | CWHeight;
560 if (!(flags & SWP_NOMOVE))
562 newWindowRect.left = winpos->x;
563 newWindowRect.top = winpos->y;
564 newWindowRect.right += winpos->x - wndPtr->rectWindow.left;
565 newWindowRect.bottom += winpos->y - wndPtr->rectWindow.top;
566 if (wndPtr->dwStyle & WS_CHILD)
568 WND *parentPtr = WIN_FindWndPtr(wndPtr->hwndParent);
569 winChanges.x = winpos->x + parentPtr->rectClient.left
570 - parentPtr->rectWindow.left;
571 winChanges.y = winpos->y + parentPtr->rectClient.top
572 - parentPtr->rectWindow.top;
574 else
576 winChanges.x = winpos->x;
577 winChanges.y = winpos->y;
579 changeMask |= CWX | CWY;
582 /* Reposition window in Z order */
584 if (!(flags & SWP_NOZORDER))
586 WIN_UnlinkWindow( winpos->hwnd );
587 WIN_LinkWindow( winpos->hwnd, hwndAfter );
588 if (hwndAfter == HWND_TOP) winChanges.stack_mode = Above;
589 else winChanges.stack_mode = Below;
590 if ((hwndAfter != HWND_TOP) && (hwndAfter != HWND_BOTTOM))
592 WND * insertPtr = WIN_FindWndPtr( hwndAfter );
593 winChanges.sibling = insertPtr->window;
594 changeMask |= CWSibling;
596 changeMask |= CWStackMode;
599 /* Send WM_NCCALCSIZE message to get new client area */
601 result = WINPOS_SendNCCalcSize( winpos->hwnd, TRUE, &newWindowRect,
602 &wndPtr->rectWindow, &wndPtr->rectClient,
603 winpos, &newClientRect );
604 /* .... Should handle result here */
606 /* Perform the moving and resizing */
608 if (changeMask) XConfigureWindow( display, wndPtr->window,
609 changeMask, &winChanges );
610 wndPtr->rectWindow = newWindowRect;
611 wndPtr->rectClient = newClientRect;
613 if (flags & SWP_SHOWWINDOW)
615 wndPtr->dwStyle |= WS_VISIBLE;
616 XMapWindow( display, wndPtr->window );
617 MSG_Synchronize();
618 if (flags & SWP_NOREDRAW) /* Validate the whole window */
619 RedrawWindow( winpos->hwnd, NULL, 0, RDW_VALIDATE );
621 else if (flags & SWP_HIDEWINDOW)
623 wndPtr->dwStyle &= ~WS_VISIBLE;
624 XUnmapWindow( display, wndPtr->window );
625 if ((winpos->hwnd == GetFocus()) || IsChild(winpos->hwnd, GetFocus()))
626 SetFocus( GetParent(winpos->hwnd) ); /* Revert focus to parent */
627 if (winpos->hwnd == hwndActive)
629 /* Activate previously active window if possible */
630 HWND newActive = wndPtr->hwndPrevActive;
631 if (!IsWindow(newActive) || (newActive == winpos->hwnd))
633 newActive = GetTopWindow(GetDesktopWindow());
634 if (newActive == winpos->hwnd) newActive = wndPtr->hwndNext;
636 WINPOS_ChangeActiveWindow( newActive, FALSE );
640 /* Activate the window */
642 if (!(flags & SWP_NOACTIVATE))
644 if (!(wndPtr->dwStyle & WS_CHILD))
645 WINPOS_ChangeActiveWindow( winpos->hwnd, FALSE );
648 /* Send WM_NCPAINT message if needed */
650 if ((flags & (SWP_FRAMECHANGED | SWP_SHOWWINDOW)) ||
651 (!(flags & SWP_NOSIZE)) || (!(flags & SWP_NOMOVE)) ||
652 (!(flags & SWP_NOACTIVATE)) || (!(flags & SWP_NOZORDER)))
653 SendMessage( winpos->hwnd, WM_NCPAINT, 1, 0L );
654 #if 0
655 if ((flags & (SWP_FRAMECHANGED | SWP_SHOWWINDOW)) &&
656 (!(flags & SWP_NOREDRAW)) &&
657 (wndPtr->dwStyle & WS_VISIBLE))
658 InvalidateRect(winpos->hwnd, NULL, TRUE);
659 #endif
661 /* And last, send the WM_WINDOWPOSCHANGED message */
663 SendMessage( winpos->hwnd, WM_WINDOWPOSCHANGED, 0, (LONG)winpos );
664 return TRUE;
668 /***********************************************************************
669 * SetWindowPos (USER.232)
671 /* Note: all this code should be in the DeferWindowPos() routines,
672 * and SetWindowPos() should simply call them. This will be implemented
673 * some day...
675 BOOL SetWindowPos( HWND hwnd, HWND hwndInsertAfter, short x, short y,
676 short cx, short cy, WORD flags )
678 WINDOWPOS *winPos;
679 HANDLE hmem = 0;
680 BOOL res;
682 #ifdef DEBUG_WIN
683 printf( "SetWindowPos: %04X %d %d,%d %dx%d 0x%x\n",
684 hwnd, hwndInsertAfter, x, y, cx, cy, flags );
685 #endif
687 if (!(hmem = USER_HEAP_ALLOC( GMEM_MOVEABLE, sizeof(WINDOWPOS) )))
688 return FALSE;
689 winPos = (WINDOWPOS *)USER_HEAP_ADDR( hmem );
690 winPos->hwnd = hwnd;
691 winPos->hwndInsertAfter = hwndInsertAfter;
692 winPos->x = x;
693 winPos->y = y;
694 winPos->cx = cx;
695 winPos->cy = cy;
696 winPos->flags = flags;
698 res = WINPOS_InternalSetWindowPos( winPos );
700 USER_HEAP_FREE( hmem );
701 return res;