2 * Window position related functions.
4 * Copyright 1993, 1994, 1995 Alexandre Julliard
5 * 1995, 1996 Alex Korobka
11 #include "sysmetrics.h"
23 #include "nonclient.h"
28 #define HAS_DLGFRAME(style,exStyle) \
29 (((exStyle) & WS_EX_DLGMODALFRAME) || \
30 (((style) & WS_DLGFRAME) && !((style) & WS_BORDER)))
32 #define HAS_THICKFRAME(style) \
33 (((style) & WS_THICKFRAME) && \
34 !(((style) & (WS_DLGFRAME|WS_BORDER)) == WS_DLGFRAME))
36 #define SWP_AGG_NOGEOMETRYCHANGE \
37 (SWP_NOSIZE | SWP_NOMOVE | SWP_NOCLIENTSIZE | SWP_NOCLIENTMOVE)
38 #define SWP_AGG_NOPOSCHANGE \
39 (SWP_AGG_NOGEOMETRYCHANGE | SWP_NOZORDER)
40 #define SWP_AGG_STATUSFLAGS \
41 (SWP_AGG_NOPOSCHANGE | SWP_FRAMECHANGED | SWP_HIDEWINDOW | SWP_SHOWWINDOW)
43 #define EMPTYPOINT(pt) ((*(LONG*)&(pt)) == -1)
45 #define PLACE_MIN 0x0001
46 #define PLACE_MAX 0x0002
47 #define PLACE_RECT 0x0004
49 #define SMC_NOCOPY 0x0001
50 #define SMC_NOPARENTERASE 0x0002
51 #define SMC_DRAWFRAME 0x0004
52 #define SMC_SETXPOS 0x0008
54 /* ----- internal variables ----- */
56 static HWND32 hwndPrevActive = 0; /* Previously active window */
57 static HWND32 hGlobalShellWindow=0; /*the shell*/
59 static LPCSTR atomInternalPos;
61 extern HQUEUE16 hActiveQueue;
63 /***********************************************************************
64 * WINPOS_CreateInternalPosAtom
66 BOOL32 WINPOS_CreateInternalPosAtom()
69 atomInternalPos = (LPCSTR)(DWORD)GlobalAddAtom32A(str);
70 return (atomInternalPos) ? TRUE : FALSE;
73 /***********************************************************************
74 * WINPOS_CheckInternalPos
76 * Called when a window is destroyed.
78 void WINPOS_CheckInternalPos( WND* wndPtr )
81 MESSAGEQUEUE *pMsgQ = 0;
82 HWND32 hwnd = wndPtr->hwndSelf;
84 lpPos = (LPINTERNALPOS) GetProp32A( hwnd, atomInternalPos );
86 /* Retrieve the message queue associated with this window */
87 pMsgQ = (MESSAGEQUEUE *)QUEUE_Lock( wndPtr->hmemTaskQ );
90 WARN( win, "\tMessage queue not found. Exiting!\n" );
94 if( hwnd == hwndPrevActive ) hwndPrevActive = 0;
96 if( hwnd == PERQDATA_GetActiveWnd( pMsgQ->pQData ) )
98 PERQDATA_SetActiveWnd( pMsgQ->pQData, 0 );
99 WARN(win, "\tattempt to activate destroyed window!\n");
104 if( IsWindow32(lpPos->hwndIconTitle) )
105 DestroyWindow32( lpPos->hwndIconTitle );
106 HeapFree( SystemHeap, 0, lpPos );
109 QUEUE_Unlock( pMsgQ );
113 /***********************************************************************
116 * Find a suitable place for an iconic window.
118 static POINT16 WINPOS_FindIconPos( WND* wndPtr, POINT16 pt )
121 short x, y, xspacing, yspacing;
123 GetClientRect16( wndPtr->parent->hwndSelf, &rectParent );
124 if ((pt.x >= rectParent.left) && (pt.x + SYSMETRICS_CXICON < rectParent.right) &&
125 (pt.y >= rectParent.top) && (pt.y + SYSMETRICS_CYICON < rectParent.bottom))
126 return pt; /* The icon already has a suitable position */
128 xspacing = SYSMETRICS_CXICONSPACING;
129 yspacing = SYSMETRICS_CYICONSPACING;
131 y = rectParent.bottom;
134 for (x = rectParent.left; x <= rectParent.right-xspacing; x += xspacing)
136 /* Check if another icon already occupies this spot */
137 WND *childPtr = wndPtr->parent->child;
140 if ((childPtr->dwStyle & WS_MINIMIZE) && (childPtr != wndPtr))
142 if ((childPtr->rectWindow.left < x + xspacing) &&
143 (childPtr->rectWindow.right >= x) &&
144 (childPtr->rectWindow.top <= y) &&
145 (childPtr->rectWindow.bottom > y - yspacing))
146 break; /* There's a window in there */
148 childPtr = childPtr->next;
150 if (!childPtr) /* No window was found, so it's OK for us */
152 pt.x = x + (xspacing - SYSMETRICS_CXICON) / 2;
153 pt.y = y - (yspacing + SYSMETRICS_CYICON) / 2;
162 /***********************************************************************
163 * ArrangeIconicWindows16 (USER.170)
165 UINT16 WINAPI ArrangeIconicWindows16( HWND16 parent)
167 return ArrangeIconicWindows32(parent);
169 /***********************************************************************
170 * ArrangeIconicWindows32 (USER32.7)
172 UINT32 WINAPI ArrangeIconicWindows32( HWND32 parent )
176 INT32 x, y, xspacing, yspacing;
178 GetClientRect32( parent, &rectParent );
180 y = rectParent.bottom;
181 xspacing = SYSMETRICS_CXICONSPACING;
182 yspacing = SYSMETRICS_CYICONSPACING;
184 hwndChild = GetWindow32( parent, GW_CHILD );
187 if( IsIconic32( hwndChild ) )
189 WINPOS_ShowIconTitle( WIN_FindWndPtr(hwndChild), FALSE );
190 SetWindowPos32( hwndChild, 0, x + (xspacing - SYSMETRICS_CXICON) / 2,
191 y - yspacing - SYSMETRICS_CYICON/2, 0, 0,
192 SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE );
193 if( IsWindow32(hwndChild) )
194 WINPOS_ShowIconTitle( WIN_FindWndPtr(hwndChild), TRUE );
195 if (x <= rectParent.right - xspacing) x += xspacing;
202 hwndChild = GetWindow32( hwndChild, GW_HWNDNEXT );
208 /***********************************************************************
209 * SwitchToThisWindow16 (USER.172)
211 void WINAPI SwitchToThisWindow16( HWND16 hwnd, BOOL16 restore )
213 SwitchToThisWindow32( hwnd, restore );
217 /***********************************************************************
218 * SwitchToThisWindow32 (USER32.539)
220 void WINAPI SwitchToThisWindow32( HWND32 hwnd, BOOL32 restore )
222 ShowWindow32( hwnd, restore ? SW_RESTORE : SW_SHOWMINIMIZED );
226 /***********************************************************************
227 * GetWindowRect16 (USER.32)
229 void WINAPI GetWindowRect16( HWND16 hwnd, LPRECT16 rect )
231 WND * wndPtr = WIN_FindWndPtr( hwnd );
234 CONV_RECT32TO16( &wndPtr->rectWindow, rect );
235 if (wndPtr->dwStyle & WS_CHILD)
236 MapWindowPoints16( wndPtr->parent->hwndSelf, 0, (POINT16 *)rect, 2 );
240 /***********************************************************************
241 * GetWindowRect32 (USER32.308)
243 BOOL32 WINAPI GetWindowRect32( HWND32 hwnd, LPRECT32 rect )
245 WND * wndPtr = WIN_FindWndPtr( hwnd );
246 if (!wndPtr) return FALSE;
248 *rect = wndPtr->rectWindow;
249 if (wndPtr->dwStyle & WS_CHILD)
250 MapWindowPoints32( wndPtr->parent->hwndSelf, 0, (POINT32 *)rect, 2 );
255 /***********************************************************************
258 BOOL32 WINAPI GetWindowRgn32 ( HWND32 hwnd, HRGN32 hrgn )
262 WND * wndPtr = WIN_FindWndPtr( hwnd );
263 if (!wndPtr) return (ERROR);
265 FIXME (win, "GetWindowRgn32: doesn't really do regions\n");
267 memset (&rect, 0, sizeof(rect));
269 GetWindowRect32 ( hwnd, &rect );
271 FIXME (win, "Check whether a valid region here\n");
273 SetRectRgn32 ( hrgn, rect.left, rect.top, rect.right, rect.bottom );
275 return (SIMPLEREGION);
278 /***********************************************************************
281 INT32 WINAPI SetWindowRgn32( HWND32 hwnd, HRGN32 hrgn,BOOL32 bRedraw)
285 FIXME (win, "SetWindowRgn32: stub\n");
289 /***********************************************************************
292 INT16 WINAPI SetWindowRgn16( HWND16 hwnd, HRGN16 hrgn,BOOL16 bRedraw)
296 FIXME (win, "SetWindowRgn16: stub\n");
301 /***********************************************************************
302 * GetClientRect16 (USER.33)
304 void WINAPI GetClientRect16( HWND16 hwnd, LPRECT16 rect )
306 WND * wndPtr = WIN_FindWndPtr( hwnd );
308 rect->left = rect->top = rect->right = rect->bottom = 0;
311 rect->right = wndPtr->rectClient.right - wndPtr->rectClient.left;
312 rect->bottom = wndPtr->rectClient.bottom - wndPtr->rectClient.top;
317 /***********************************************************************
318 * GetClientRect32 (USER32.220)
320 void WINAPI GetClientRect32( HWND32 hwnd, LPRECT32 rect )
322 WND * wndPtr = WIN_FindWndPtr( hwnd );
324 rect->left = rect->top = rect->right = rect->bottom = 0;
327 rect->right = wndPtr->rectClient.right - wndPtr->rectClient.left;
328 rect->bottom = wndPtr->rectClient.bottom - wndPtr->rectClient.top;
333 /*******************************************************************
334 * ClientToScreen16 (USER.28)
336 void WINAPI ClientToScreen16( HWND16 hwnd, LPPOINT16 lppnt )
338 MapWindowPoints16( hwnd, 0, lppnt, 1 );
342 /*******************************************************************
343 * ClientToScreen32 (USER32.52)
345 BOOL32 WINAPI ClientToScreen32( HWND32 hwnd, LPPOINT32 lppnt )
347 MapWindowPoints32( hwnd, 0, lppnt, 1 );
352 /*******************************************************************
353 * ScreenToClient16 (USER.29)
355 void WINAPI ScreenToClient16( HWND16 hwnd, LPPOINT16 lppnt )
357 MapWindowPoints16( 0, hwnd, lppnt, 1 );
361 /*******************************************************************
362 * ScreenToClient32 (USER32.447)
364 void WINAPI ScreenToClient32( HWND32 hwnd, LPPOINT32 lppnt )
366 MapWindowPoints32( 0, hwnd, lppnt, 1 );
370 /***********************************************************************
371 * WINPOS_WindowFromPoint
373 * Find the window and hittest for a given point.
375 INT16 WINPOS_WindowFromPoint( WND* wndScope, POINT16 pt, WND **ppWnd )
378 INT16 hittest = HTERROR;
382 wndPtr = wndScope->child;
383 if( wndScope->flags & WIN_MANAGED )
385 /* this prevents mouse clicks from going "through" scrollbars in managed mode */
386 if( pt.x < wndScope->rectClient.left || pt.x >= wndScope->rectClient.right ||
387 pt.y < wndScope->rectClient.top || pt.y >= wndScope->rectClient.bottom )
390 MapWindowPoints16( GetDesktopWindow16(), wndScope->hwndSelf, &xy, 1 );
396 /* If point is in window, and window is visible, and it */
397 /* is enabled (or it's a top-level window), then explore */
398 /* its children. Otherwise, go to the next window. */
400 if ((wndPtr->dwStyle & WS_VISIBLE) &&
401 (!(wndPtr->dwStyle & WS_DISABLED) ||
402 ((wndPtr->dwStyle & (WS_POPUP | WS_CHILD)) != WS_CHILD)) &&
403 (xy.x >= wndPtr->rectWindow.left) &&
404 (xy.x < wndPtr->rectWindow.right) &&
405 (xy.y >= wndPtr->rectWindow.top) &&
406 (xy.y < wndPtr->rectWindow.bottom))
408 *ppWnd = wndPtr; /* Got a suitable window */
410 /* If window is minimized or disabled, return at once */
411 if (wndPtr->dwStyle & WS_MINIMIZE) return HTCAPTION;
412 if (wndPtr->dwStyle & WS_DISABLED) return HTERROR;
414 /* If point is not in client area, ignore the children */
415 if ((xy.x < wndPtr->rectClient.left) ||
416 (xy.x >= wndPtr->rectClient.right) ||
417 (xy.y < wndPtr->rectClient.top) ||
418 (xy.y >= wndPtr->rectClient.bottom)) break;
420 xy.x -= wndPtr->rectClient.left;
421 xy.y -= wndPtr->rectClient.top;
422 wndPtr = wndPtr->child;
424 else wndPtr = wndPtr->next;
428 /* If nothing found, try the scope window */
429 if (!*ppWnd) *ppWnd = wndScope;
431 /* Send the WM_NCHITTEST message (only if to the same task) */
432 if ((*ppWnd)->hmemTaskQ == GetFastQueue())
434 hittest = (INT16)SendMessage16( (*ppWnd)->hwndSelf, WM_NCHITTEST,
435 0, MAKELONG( pt.x, pt.y ) );
436 if (hittest != HTTRANSPARENT) return hittest; /* Found the window */
438 else return HTCLIENT;
440 /* If no children found in last search, make point relative to parent */
443 xy.x += (*ppWnd)->rectClient.left;
444 xy.y += (*ppWnd)->rectClient.top;
447 /* Restart the search from the next sibling */
448 wndPtr = (*ppWnd)->next;
449 *ppWnd = (*ppWnd)->parent;
454 /*******************************************************************
455 * WindowFromPoint16 (USER.30)
457 HWND16 WINAPI WindowFromPoint16( POINT16 pt )
460 WINPOS_WindowFromPoint( WIN_GetDesktop(), pt, &pWnd );
461 return pWnd->hwndSelf;
465 /*******************************************************************
466 * WindowFromPoint32 (USER32.582)
468 HWND32 WINAPI WindowFromPoint32( POINT32 pt )
472 CONV_POINT32TO16( &pt, &pt16 );
473 WINPOS_WindowFromPoint( WIN_GetDesktop(), pt16, &pWnd );
474 return (HWND32)pWnd->hwndSelf;
478 /*******************************************************************
479 * ChildWindowFromPoint16 (USER.191)
481 HWND16 WINAPI ChildWindowFromPoint16( HWND16 hwndParent, POINT16 pt )
484 CONV_POINT16TO32( &pt, &pt32 );
485 return (HWND16)ChildWindowFromPoint32( hwndParent, pt32 );
489 /*******************************************************************
490 * ChildWindowFromPoint32 (USER32.49)
492 HWND32 WINAPI ChildWindowFromPoint32( HWND32 hwndParent, POINT32 pt )
494 /* pt is in the client coordinates */
496 WND* wnd = WIN_FindWndPtr(hwndParent);
501 /* get client rect fast */
502 rect.top = rect.left = 0;
503 rect.right = wnd->rectClient.right - wnd->rectClient.left;
504 rect.bottom = wnd->rectClient.bottom - wnd->rectClient.top;
506 if (!PtInRect32( &rect, pt )) return 0;
511 if (PtInRect32( &wnd->rectWindow, pt )) return wnd->hwndSelf;
517 /*******************************************************************
518 * ChildWindowFromPointEx16 (USER.50)
520 HWND16 WINAPI ChildWindowFromPointEx16( HWND16 hwndParent, POINT16 pt, UINT16 uFlags)
523 CONV_POINT16TO32( &pt, &pt32 );
524 return (HWND16)ChildWindowFromPointEx32( hwndParent, pt32, uFlags );
528 /*******************************************************************
529 * ChildWindowFromPointEx32 (USER32.50)
531 HWND32 WINAPI ChildWindowFromPointEx32( HWND32 hwndParent, POINT32 pt,
534 /* pt is in the client coordinates */
536 WND* wnd = WIN_FindWndPtr(hwndParent);
541 /* get client rect fast */
542 rect.top = rect.left = 0;
543 rect.right = wnd->rectClient.right - wnd->rectClient.left;
544 rect.bottom = wnd->rectClient.bottom - wnd->rectClient.top;
546 if (!PtInRect32( &rect, pt )) return 0;
551 if (PtInRect32( &wnd->rectWindow, pt )) {
552 if ( (uFlags & CWP_SKIPINVISIBLE) &&
553 !(wnd->dwStyle & WS_VISIBLE) )
555 else if ( (uFlags & CWP_SKIPDISABLED) &&
556 (wnd->dwStyle & WS_DISABLED) )
558 else if ( (uFlags & CWP_SKIPTRANSPARENT) &&
559 (wnd->dwExStyle & WS_EX_TRANSPARENT) )
562 return wnd->hwndSelf;
569 /*******************************************************************
570 * WINPOS_GetWinOffset
572 * Calculate the offset between the origin of the two windows. Used
573 * to implement MapWindowPoints.
575 static void WINPOS_GetWinOffset( HWND32 hwndFrom, HWND32 hwndTo,
580 offset->x = offset->y = 0;
581 if (hwndFrom == hwndTo ) return;
583 /* Translate source window origin to screen coords */
586 if (!(wndPtr = WIN_FindWndPtr( hwndFrom )))
588 ERR(win,"bad hwndFrom = %04x\n",hwndFrom);
591 while (wndPtr->parent)
593 offset->x += wndPtr->rectClient.left;
594 offset->y += wndPtr->rectClient.top;
595 wndPtr = wndPtr->parent;
599 /* Translate origin to destination window coords */
602 if (!(wndPtr = WIN_FindWndPtr( hwndTo )))
604 ERR(win,"bad hwndTo = %04x\n", hwndTo );
607 while (wndPtr->parent)
609 offset->x -= wndPtr->rectClient.left;
610 offset->y -= wndPtr->rectClient.top;
611 wndPtr = wndPtr->parent;
617 /*******************************************************************
618 * MapWindowPoints16 (USER.258)
620 void WINAPI MapWindowPoints16( HWND16 hwndFrom, HWND16 hwndTo,
621 LPPOINT16 lppt, UINT16 count )
625 WINPOS_GetWinOffset( hwndFrom, hwndTo, &offset );
635 /*******************************************************************
636 * MapWindowPoints32 (USER32.386)
638 void WINAPI MapWindowPoints32( HWND32 hwndFrom, HWND32 hwndTo,
639 LPPOINT32 lppt, UINT32 count )
643 WINPOS_GetWinOffset( hwndFrom, hwndTo, &offset );
653 /***********************************************************************
654 * IsIconic16 (USER.31)
656 BOOL16 WINAPI IsIconic16(HWND16 hWnd)
658 return IsIconic32(hWnd);
662 /***********************************************************************
663 * IsIconic32 (USER32.345)
665 BOOL32 WINAPI IsIconic32(HWND32 hWnd)
667 WND * wndPtr = WIN_FindWndPtr(hWnd);
668 if (wndPtr == NULL) return FALSE;
669 return (wndPtr->dwStyle & WS_MINIMIZE) != 0;
673 /***********************************************************************
674 * IsZoomed (USER.272)
676 BOOL16 WINAPI IsZoomed16(HWND16 hWnd)
678 return IsZoomed32(hWnd);
682 /***********************************************************************
683 * IsZoomed (USER32.352)
685 BOOL32 WINAPI IsZoomed32(HWND32 hWnd)
687 WND * wndPtr = WIN_FindWndPtr(hWnd);
688 if (wndPtr == NULL) return FALSE;
689 return (wndPtr->dwStyle & WS_MAXIMIZE) != 0;
693 /*******************************************************************
694 * GetActiveWindow (USER.60)
696 HWND16 WINAPI GetActiveWindow16(void)
698 return (HWND16)GetActiveWindow32();
701 /*******************************************************************
702 * GetActiveWindow (USER32.205)
704 HWND32 WINAPI GetActiveWindow32(void)
706 MESSAGEQUEUE *pCurMsgQ = 0;
707 HWND32 hwndActive = 0;
709 /* Get the messageQ for the current thread */
710 if (!(pCurMsgQ = (MESSAGEQUEUE *)QUEUE_Lock( GetFastQueue() )))
712 WARN( win, "\tCurrent message queue not found. Exiting!\n" );
716 /* Return the current active window from the perQ data of the current message Q */
717 hwndActive = PERQDATA_GetActiveWnd( pCurMsgQ->pQData );
719 QUEUE_Unlock( pCurMsgQ );
724 /*******************************************************************
727 static BOOL32 WINPOS_CanActivate(WND* pWnd)
729 if( pWnd && ((pWnd->dwStyle & (WS_DISABLED | WS_VISIBLE | WS_CHILD))
730 == WS_VISIBLE) ) return TRUE;
735 /*******************************************************************
736 * SetActiveWindow16 (USER.59)
738 HWND16 WINAPI SetActiveWindow16( HWND16 hwnd )
740 return SetActiveWindow32(hwnd);
744 /*******************************************************************
745 * SetActiveWindow32 (USER32.463)
747 HWND32 WINAPI SetActiveWindow32( HWND32 hwnd )
750 WND *wndPtr = WIN_FindWndPtr( hwnd );
751 MESSAGEQUEUE *pMsgQ = 0, *pCurMsgQ = 0;
753 if ( !WINPOS_CanActivate(wndPtr) ) return 0;
755 /* Get the messageQ for the current thread */
756 if (!(pCurMsgQ = (MESSAGEQUEUE *)QUEUE_Lock( GetFastQueue() )))
758 WARN( win, "\tCurrent message queue not found. Exiting!\n" );
762 /* Retrieve the message queue associated with this window */
763 pMsgQ = (MESSAGEQUEUE *)QUEUE_Lock( wndPtr->hmemTaskQ );
766 WARN( win, "\tWindow message queue not found. Exiting!\n" );
770 /* Make sure that the window is associated with the calling threads
771 * message queue. It must share the same perQ data.
773 if ( pCurMsgQ->pQData != pMsgQ->pQData )
776 /* Save current active window */
777 prev = PERQDATA_GetActiveWnd( pMsgQ->pQData );
779 WINPOS_SetActiveWindow( hwnd, 0, 0 );
782 /* Unlock the queues before returning */
784 QUEUE_Unlock( pMsgQ );
786 QUEUE_Unlock( pCurMsgQ );
792 /*******************************************************************
793 * GetForegroundWindow16 (USER.608)
795 HWND16 WINAPI GetForegroundWindow16(void)
797 return (HWND16)GetForegroundWindow32();
801 /*******************************************************************
802 * SetForegroundWindow16 (USER.609)
804 BOOL16 WINAPI SetForegroundWindow16( HWND16 hwnd )
806 return SetForegroundWindow32( hwnd );
810 /*******************************************************************
811 * GetForegroundWindow32 (USER32.241)
813 HWND32 WINAPI GetForegroundWindow32(void)
815 return GetActiveWindow32();
819 /*******************************************************************
820 * SetForegroundWindow32 (USER32.482)
822 BOOL32 WINAPI SetForegroundWindow32( HWND32 hwnd )
824 SetActiveWindow32( hwnd );
829 /*******************************************************************
830 * GetShellWindow16 (USER.600)
832 HWND16 WINAPI GetShellWindow16(void)
834 return GetShellWindow32();
837 /*******************************************************************
838 * SetShellWindow32 (USER32.504)
840 HWND32 WINAPI SetShellWindow32(HWND32 hwndshell)
841 { WARN(win, "(hWnd=%08x) semi stub\n",hwndshell );
843 hGlobalShellWindow = hwndshell;
844 return hGlobalShellWindow;
848 /*******************************************************************
849 * GetShellWindow32 (USER32.287)
851 HWND32 WINAPI GetShellWindow32(void)
852 { WARN(win, "(hWnd=%x) semi stub\n",hGlobalShellWindow );
854 return hGlobalShellWindow;
858 /***********************************************************************
859 * BringWindowToTop16 (USER.45)
861 BOOL16 WINAPI BringWindowToTop16( HWND16 hwnd )
863 return BringWindowToTop32(hwnd);
867 /***********************************************************************
868 * BringWindowToTop32 (USER32.11)
870 BOOL32 WINAPI BringWindowToTop32( HWND32 hwnd )
872 return SetWindowPos32( hwnd, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE );
876 /***********************************************************************
877 * MoveWindow16 (USER.56)
879 BOOL16 WINAPI MoveWindow16( HWND16 hwnd, INT16 x, INT16 y, INT16 cx, INT16 cy,
882 return MoveWindow32(hwnd,x,y,cx,cy,repaint);
886 /***********************************************************************
887 * MoveWindow32 (USER32.399)
889 BOOL32 WINAPI MoveWindow32( HWND32 hwnd, INT32 x, INT32 y, INT32 cx, INT32 cy,
892 int flags = SWP_NOZORDER | SWP_NOACTIVATE;
893 if (!repaint) flags |= SWP_NOREDRAW;
894 TRACE(win, "%04x %d,%d %dx%d %d\n",
895 hwnd, x, y, cx, cy, repaint );
896 return SetWindowPos32( hwnd, 0, x, y, cx, cy, flags );
899 /***********************************************************************
900 * WINPOS_InitInternalPos
902 static LPINTERNALPOS WINPOS_InitInternalPos( WND* wnd, POINT32 pt,
903 LPRECT32 restoreRect )
905 LPINTERNALPOS lpPos = (LPINTERNALPOS) GetProp32A( wnd->hwndSelf,
909 /* this happens when the window is minimized/maximized
910 * for the first time (rectWindow is not adjusted yet) */
912 lpPos = HeapAlloc( SystemHeap, 0, sizeof(INTERNALPOS) );
913 if( !lpPos ) return NULL;
915 SetProp32A( wnd->hwndSelf, atomInternalPos, (HANDLE32)lpPos );
916 lpPos->hwndIconTitle = 0; /* defer until needs to be shown */
917 CONV_RECT32TO16( &wnd->rectWindow, &lpPos->rectNormal );
918 *(UINT32*)&lpPos->ptIconPos = *(UINT32*)&lpPos->ptMaxPos = 0xFFFFFFFF;
921 if( wnd->dwStyle & WS_MINIMIZE )
922 CONV_POINT32TO16( &pt, &lpPos->ptIconPos );
923 else if( wnd->dwStyle & WS_MAXIMIZE )
924 CONV_POINT32TO16( &pt, &lpPos->ptMaxPos );
925 else if( restoreRect )
926 CONV_RECT32TO16( restoreRect, &lpPos->rectNormal );
931 /***********************************************************************
932 * WINPOS_RedrawIconTitle
934 BOOL32 WINPOS_RedrawIconTitle( HWND32 hWnd )
936 LPINTERNALPOS lpPos = (LPINTERNALPOS)GetProp32A( hWnd, atomInternalPos );
939 if( lpPos->hwndIconTitle )
941 SendMessage32A( lpPos->hwndIconTitle, WM_SHOWWINDOW, TRUE, 0);
942 InvalidateRect32( lpPos->hwndIconTitle, NULL, TRUE );
949 /***********************************************************************
950 * WINPOS_ShowIconTitle
952 BOOL32 WINPOS_ShowIconTitle( WND* pWnd, BOOL32 bShow )
954 LPINTERNALPOS lpPos = (LPINTERNALPOS)GetProp32A( pWnd->hwndSelf, atomInternalPos );
956 if( lpPos && !(pWnd->flags & WIN_MANAGED))
958 HWND16 hWnd = lpPos->hwndIconTitle;
960 TRACE(win,"0x%04x %i\n", pWnd->hwndSelf, (bShow != 0) );
963 lpPos->hwndIconTitle = hWnd = ICONTITLE_Create( pWnd );
966 pWnd = WIN_FindWndPtr(hWnd);
968 if( !(pWnd->dwStyle & WS_VISIBLE) )
970 SendMessage32A( hWnd, WM_SHOWWINDOW, TRUE, 0 );
971 SetWindowPos32( hWnd, 0, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE |
972 SWP_NOACTIVATE | SWP_NOZORDER | SWP_SHOWWINDOW );
975 else ShowWindow32( hWnd, SW_HIDE );
980 /*******************************************************************
981 * WINPOS_GetMinMaxInfo
983 * Get the minimized and maximized information for a window.
985 void WINPOS_GetMinMaxInfo( WND *wndPtr, POINT32 *maxSize, POINT32 *maxPos,
986 POINT32 *minTrack, POINT32 *maxTrack )
992 /* Compute default values */
994 MinMax.ptMaxSize.x = SYSMETRICS_CXSCREEN;
995 MinMax.ptMaxSize.y = SYSMETRICS_CYSCREEN;
996 MinMax.ptMinTrackSize.x = SYSMETRICS_CXMINTRACK;
997 MinMax.ptMinTrackSize.y = SYSMETRICS_CYMINTRACK;
998 MinMax.ptMaxTrackSize.x = SYSMETRICS_CXSCREEN;
999 MinMax.ptMaxTrackSize.y = SYSMETRICS_CYSCREEN;
1001 if (wndPtr->flags & WIN_MANAGED) xinc = yinc = 0;
1002 else if (HAS_DLGFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
1004 xinc = SYSMETRICS_CXDLGFRAME;
1005 yinc = SYSMETRICS_CYDLGFRAME;
1010 if (HAS_THICKFRAME(wndPtr->dwStyle))
1012 xinc += SYSMETRICS_CXFRAME;
1013 yinc += SYSMETRICS_CYFRAME;
1015 if (wndPtr->dwStyle & WS_BORDER)
1017 xinc += SYSMETRICS_CXBORDER;
1018 yinc += SYSMETRICS_CYBORDER;
1021 MinMax.ptMaxSize.x += 2 * xinc;
1022 MinMax.ptMaxSize.y += 2 * yinc;
1024 lpPos = (LPINTERNALPOS)GetProp32A( wndPtr->hwndSelf, atomInternalPos );
1025 if( lpPos && !EMPTYPOINT(lpPos->ptMaxPos) )
1026 CONV_POINT16TO32( &lpPos->ptMaxPos, &MinMax.ptMaxPosition );
1029 MinMax.ptMaxPosition.x = -xinc;
1030 MinMax.ptMaxPosition.y = -yinc;
1033 SendMessage32A( wndPtr->hwndSelf, WM_GETMINMAXINFO, 0, (LPARAM)&MinMax );
1035 /* Some sanity checks */
1037 TRACE(win,"%d %d / %d %d / %d %d / %d %d\n",
1038 MinMax.ptMaxSize.x, MinMax.ptMaxSize.y,
1039 MinMax.ptMaxPosition.x, MinMax.ptMaxPosition.y,
1040 MinMax.ptMaxTrackSize.x, MinMax.ptMaxTrackSize.y,
1041 MinMax.ptMinTrackSize.x, MinMax.ptMinTrackSize.y);
1042 MinMax.ptMaxTrackSize.x = MAX( MinMax.ptMaxTrackSize.x,
1043 MinMax.ptMinTrackSize.x );
1044 MinMax.ptMaxTrackSize.y = MAX( MinMax.ptMaxTrackSize.y,
1045 MinMax.ptMinTrackSize.y );
1047 if (maxSize) *maxSize = MinMax.ptMaxSize;
1048 if (maxPos) *maxPos = MinMax.ptMaxPosition;
1049 if (minTrack) *minTrack = MinMax.ptMinTrackSize;
1050 if (maxTrack) *maxTrack = MinMax.ptMaxTrackSize;
1053 /***********************************************************************
1054 * WINPOS_MinMaximize
1056 * Fill in lpRect and return additional flags to be used with SetWindowPos().
1057 * This function assumes that 'cmd' is different from the current window
1060 UINT16 WINPOS_MinMaximize( WND* wndPtr, UINT16 cmd, LPRECT16 lpRect )
1062 UINT16 swpFlags = 0;
1064 POINT32 size = { wndPtr->rectWindow.left, wndPtr->rectWindow.top };
1065 LPINTERNALPOS lpPos = WINPOS_InitInternalPos( wndPtr, size,
1066 &wndPtr->rectWindow );
1068 TRACE(win,"0x%04x %u\n", wndPtr->hwndSelf, cmd );
1070 if (lpPos && !HOOK_CallHooks16(WH_CBT, HCBT_MINMAX, wndPtr->hwndSelf, cmd))
1072 if( wndPtr->dwStyle & WS_MINIMIZE )
1074 if( !SendMessage32A( wndPtr->hwndSelf, WM_QUERYOPEN, 0, 0L ) )
1075 return (SWP_NOSIZE | SWP_NOMOVE);
1076 swpFlags |= SWP_NOCOPYBITS;
1081 if( wndPtr->dwStyle & WS_MAXIMIZE)
1083 wndPtr->flags |= WIN_RESTORE_MAX;
1084 wndPtr->dwStyle &= ~WS_MAXIMIZE;
1087 wndPtr->flags &= ~WIN_RESTORE_MAX;
1088 wndPtr->dwStyle |= WS_MINIMIZE;
1090 lpPos->ptIconPos = WINPOS_FindIconPos( wndPtr, lpPos->ptIconPos );
1092 SetRect16( lpRect, lpPos->ptIconPos.x, lpPos->ptIconPos.y,
1093 SYSMETRICS_CXICON, SYSMETRICS_CYICON );
1094 swpFlags |= SWP_NOCOPYBITS;
1098 CONV_POINT16TO32( &lpPos->ptMaxPos, &pt );
1099 WINPOS_GetMinMaxInfo( wndPtr, &size, &pt, NULL, NULL );
1100 CONV_POINT32TO16( &pt, &lpPos->ptMaxPos );
1102 if( wndPtr->dwStyle & WS_MINIMIZE )
1104 WINPOS_ShowIconTitle( wndPtr, FALSE );
1105 wndPtr->dwStyle &= ~WS_MINIMIZE;
1107 wndPtr->dwStyle |= WS_MAXIMIZE;
1109 SetRect16( lpRect, lpPos->ptMaxPos.x, lpPos->ptMaxPos.y,
1114 if( wndPtr->dwStyle & WS_MINIMIZE )
1116 wndPtr->dwStyle &= ~WS_MINIMIZE;
1117 WINPOS_ShowIconTitle( wndPtr, FALSE );
1118 if( wndPtr->flags & WIN_RESTORE_MAX)
1120 /* Restore to maximized position */
1121 CONV_POINT16TO32( &lpPos->ptMaxPos, &pt );
1122 WINPOS_GetMinMaxInfo( wndPtr, &size, &pt, NULL, NULL);
1123 CONV_POINT32TO16( &pt, &lpPos->ptMaxPos );
1124 wndPtr->dwStyle |= WS_MAXIMIZE;
1125 SetRect16( lpRect, lpPos->ptMaxPos.x, lpPos->ptMaxPos.y, size.x, size.y );
1130 if( !(wndPtr->dwStyle & WS_MAXIMIZE) ) return (UINT16)(-1);
1131 else wndPtr->dwStyle &= ~WS_MAXIMIZE;
1133 /* Restore to normal position */
1135 *lpRect = lpPos->rectNormal;
1136 lpRect->right -= lpRect->left;
1137 lpRect->bottom -= lpRect->top;
1141 } else swpFlags |= SWP_NOSIZE | SWP_NOMOVE;
1145 /***********************************************************************
1146 * ShowWindowAsync32 (USER32.535)
1148 * doesn't wait; returns immediately.
1149 * used by threads to toggle windows in other (possibly hanging) threads
1151 BOOL32 WINAPI ShowWindowAsync32( HWND32 hwnd, INT32 cmd )
1153 /* FIXME: does ShowWindow32() return immediately ? */
1154 return ShowWindow32(hwnd, cmd);
1158 /***********************************************************************
1159 * ShowWindow16 (USER.42)
1161 BOOL16 WINAPI ShowWindow16( HWND16 hwnd, INT16 cmd )
1163 return ShowWindow32(hwnd,cmd);
1167 /***********************************************************************
1168 * ShowWindow32 (USER32.534)
1170 BOOL32 WINAPI ShowWindow32( HWND32 hwnd, INT32 cmd )
1172 WND* wndPtr = WIN_FindWndPtr( hwnd );
1173 BOOL32 wasVisible, showFlag;
1174 RECT16 newPos = {0, 0, 0, 0};
1177 if (!wndPtr) return FALSE;
1179 TRACE(win,"hwnd=%04x, cmd=%d\n", hwnd, cmd);
1181 wasVisible = (wndPtr->dwStyle & WS_VISIBLE) != 0;
1186 if (!wasVisible) return FALSE;
1187 swp |= SWP_HIDEWINDOW | SWP_NOSIZE | SWP_NOMOVE |
1188 SWP_NOACTIVATE | SWP_NOZORDER;
1189 if ((hwnd == GetFocus32()) || IsChild32( hwnd, GetFocus32()))
1191 /* Revert focus to parent */
1192 SetFocus32( GetParent32(hwnd) );
1196 case SW_SHOWMINNOACTIVE:
1197 swp |= SWP_NOACTIVATE | SWP_NOZORDER;
1199 case SW_SHOWMINIMIZED:
1200 swp |= SWP_SHOWWINDOW;
1203 swp |= SWP_FRAMECHANGED;
1204 if( !(wndPtr->dwStyle & WS_MINIMIZE) )
1205 swp |= WINPOS_MinMaximize( wndPtr, SW_MINIMIZE, &newPos );
1206 else swp |= SWP_NOSIZE | SWP_NOMOVE;
1209 case SW_SHOWMAXIMIZED: /* same as SW_MAXIMIZE */
1210 swp |= SWP_SHOWWINDOW | SWP_FRAMECHANGED;
1211 if( !(wndPtr->dwStyle & WS_MAXIMIZE) )
1212 swp |= WINPOS_MinMaximize( wndPtr, SW_MAXIMIZE, &newPos );
1213 else swp |= SWP_NOSIZE | SWP_NOMOVE;
1217 swp |= SWP_NOACTIVATE | SWP_NOZORDER;
1220 swp |= SWP_SHOWWINDOW | SWP_NOSIZE | SWP_NOMOVE;
1223 case SW_SHOWNOACTIVATE:
1224 swp |= SWP_NOZORDER;
1225 if (GetActiveWindow32()) swp |= SWP_NOACTIVATE;
1227 case SW_SHOWNORMAL: /* same as SW_NORMAL: */
1228 case SW_SHOWDEFAULT: /* FIXME: should have its own handler */
1230 swp |= SWP_SHOWWINDOW | SWP_FRAMECHANGED;
1232 if( wndPtr->dwStyle & (WS_MINIMIZE | WS_MAXIMIZE) )
1233 swp |= WINPOS_MinMaximize( wndPtr, SW_RESTORE, &newPos );
1234 else swp |= SWP_NOSIZE | SWP_NOMOVE;
1238 showFlag = (cmd != SW_HIDE);
1239 if (showFlag != wasVisible)
1241 SendMessage32A( hwnd, WM_SHOWWINDOW, showFlag, 0 );
1242 if (!IsWindow32( hwnd )) return wasVisible;
1245 if ((wndPtr->dwStyle & WS_CHILD) &&
1246 !IsWindowVisible32( wndPtr->parent->hwndSelf ) &&
1247 (swp & (SWP_NOSIZE | SWP_NOMOVE)) == (SWP_NOSIZE | SWP_NOMOVE) )
1249 /* Don't call SetWindowPos32() on invisible child windows */
1250 if (cmd == SW_HIDE) wndPtr->dwStyle &= ~WS_VISIBLE;
1251 else wndPtr->dwStyle |= WS_VISIBLE;
1255 /* We can't activate a child window */
1256 if (wndPtr->dwStyle & WS_CHILD) swp |= SWP_NOACTIVATE | SWP_NOZORDER;
1257 SetWindowPos32( hwnd, HWND_TOP,
1258 newPos.left, newPos.top, newPos.right, newPos.bottom, swp );
1259 if (!IsWindow32( hwnd )) return wasVisible;
1260 else if( wndPtr->dwStyle & WS_MINIMIZE ) WINPOS_ShowIconTitle( wndPtr, TRUE );
1263 if (wndPtr->flags & WIN_NEED_SIZE)
1265 /* should happen only in CreateWindowEx() */
1266 int wParam = SIZE_RESTORED;
1268 wndPtr->flags &= ~WIN_NEED_SIZE;
1269 if (wndPtr->dwStyle & WS_MAXIMIZE) wParam = SIZE_MAXIMIZED;
1270 else if (wndPtr->dwStyle & WS_MINIMIZE) wParam = SIZE_MINIMIZED;
1271 SendMessage32A( hwnd, WM_SIZE, wParam,
1272 MAKELONG(wndPtr->rectClient.right-wndPtr->rectClient.left,
1273 wndPtr->rectClient.bottom-wndPtr->rectClient.top));
1274 SendMessage32A( hwnd, WM_MOVE, 0,
1275 MAKELONG(wndPtr->rectClient.left, wndPtr->rectClient.top) );
1282 /***********************************************************************
1283 * GetInternalWindowPos16 (USER.460)
1285 UINT16 WINAPI GetInternalWindowPos16( HWND16 hwnd, LPRECT16 rectWnd,
1288 WINDOWPLACEMENT16 wndpl;
1289 if (GetWindowPlacement16( hwnd, &wndpl ))
1291 if (rectWnd) *rectWnd = wndpl.rcNormalPosition;
1292 if (ptIcon) *ptIcon = wndpl.ptMinPosition;
1293 return wndpl.showCmd;
1299 /***********************************************************************
1300 * GetInternalWindowPos32 (USER32.245)
1302 UINT32 WINAPI GetInternalWindowPos32( HWND32 hwnd, LPRECT32 rectWnd,
1305 WINDOWPLACEMENT32 wndpl;
1306 if (GetWindowPlacement32( hwnd, &wndpl ))
1308 if (rectWnd) *rectWnd = wndpl.rcNormalPosition;
1309 if (ptIcon) *ptIcon = wndpl.ptMinPosition;
1310 return wndpl.showCmd;
1315 /***********************************************************************
1316 * GetWindowPlacement16 (USER.370)
1318 BOOL16 WINAPI GetWindowPlacement16( HWND16 hwnd, WINDOWPLACEMENT16 *wndpl )
1320 WND *pWnd = WIN_FindWndPtr( hwnd );
1323 LPINTERNALPOS lpPos = (LPINTERNALPOS)WINPOS_InitInternalPos( pWnd,
1324 *(LPPOINT32)&pWnd->rectWindow.left, &pWnd->rectWindow );
1325 wndpl->length = sizeof(*wndpl);
1326 if( pWnd->dwStyle & WS_MINIMIZE )
1327 wndpl->showCmd = SW_SHOWMINIMIZED;
1329 wndpl->showCmd = ( pWnd->dwStyle & WS_MAXIMIZE )
1330 ? SW_SHOWMAXIMIZED : SW_SHOWNORMAL ;
1331 if( pWnd->flags & WIN_RESTORE_MAX )
1332 wndpl->flags = WPF_RESTORETOMAXIMIZED;
1335 wndpl->ptMinPosition = lpPos->ptIconPos;
1336 wndpl->ptMaxPosition = lpPos->ptMaxPos;
1337 wndpl->rcNormalPosition = lpPos->rectNormal;
1344 /***********************************************************************
1345 * GetWindowPlacement32 (USER32.307)
1348 * Fails if wndpl->length of Win95 (!) apps is invalid.
1350 BOOL32 WINAPI GetWindowPlacement32( HWND32 hwnd, WINDOWPLACEMENT32 *pwpl32 )
1354 WINDOWPLACEMENT16 wpl;
1355 wpl.length = sizeof(wpl);
1356 if( GetWindowPlacement16( hwnd, &wpl ) )
1358 pwpl32->length = sizeof(*pwpl32);
1359 pwpl32->flags = wpl.flags;
1360 pwpl32->showCmd = wpl.showCmd;
1361 CONV_POINT16TO32( &wpl.ptMinPosition, &pwpl32->ptMinPosition );
1362 CONV_POINT16TO32( &wpl.ptMaxPosition, &pwpl32->ptMaxPosition );
1363 CONV_RECT16TO32( &wpl.rcNormalPosition, &pwpl32->rcNormalPosition );
1371 /***********************************************************************
1372 * WINPOS_SetPlacement
1374 static BOOL32 WINPOS_SetPlacement( HWND32 hwnd, const WINDOWPLACEMENT16 *wndpl,
1377 WND *pWnd = WIN_FindWndPtr( hwnd );
1380 LPINTERNALPOS lpPos = (LPINTERNALPOS)WINPOS_InitInternalPos( pWnd,
1381 *(LPPOINT32)&pWnd->rectWindow.left, &pWnd->rectWindow );
1383 if( flags & PLACE_MIN ) lpPos->ptIconPos = wndpl->ptMinPosition;
1384 if( flags & PLACE_MAX ) lpPos->ptMaxPos = wndpl->ptMaxPosition;
1385 if( flags & PLACE_RECT) lpPos->rectNormal = wndpl->rcNormalPosition;
1387 if( pWnd->dwStyle & WS_MINIMIZE )
1389 WINPOS_ShowIconTitle( pWnd, FALSE );
1390 if( wndpl->flags & WPF_SETMINPOSITION && !EMPTYPOINT(lpPos->ptIconPos))
1391 SetWindowPos32( hwnd, 0, lpPos->ptIconPos.x, lpPos->ptIconPos.y,
1392 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE );
1394 else if( pWnd->dwStyle & WS_MAXIMIZE )
1396 if( !EMPTYPOINT(lpPos->ptMaxPos) )
1397 SetWindowPos32( hwnd, 0, lpPos->ptMaxPos.x, lpPos->ptMaxPos.y,
1398 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE );
1400 else if( flags & PLACE_RECT )
1401 SetWindowPos32( hwnd, 0, lpPos->rectNormal.left, lpPos->rectNormal.top,
1402 lpPos->rectNormal.right - lpPos->rectNormal.left,
1403 lpPos->rectNormal.bottom - lpPos->rectNormal.top,
1404 SWP_NOZORDER | SWP_NOACTIVATE );
1406 ShowWindow32( hwnd, wndpl->showCmd );
1407 if( IsWindow32(hwnd) && pWnd->dwStyle & WS_MINIMIZE )
1409 if( pWnd->dwStyle & WS_VISIBLE ) WINPOS_ShowIconTitle( pWnd, TRUE );
1411 /* SDK: ...valid only the next time... */
1412 if( wndpl->flags & WPF_RESTORETOMAXIMIZED ) pWnd->flags |= WIN_RESTORE_MAX;
1420 /***********************************************************************
1421 * SetWindowPlacement16 (USER.371)
1423 BOOL16 WINAPI SetWindowPlacement16(HWND16 hwnd, const WINDOWPLACEMENT16 *wndpl)
1425 return WINPOS_SetPlacement( hwnd, wndpl,
1426 PLACE_MIN | PLACE_MAX | PLACE_RECT );
1429 /***********************************************************************
1430 * SetWindowPlacement32 (USER32.519)
1433 * Fails if wndpl->length of Win95 (!) apps is invalid.
1435 BOOL32 WINAPI SetWindowPlacement32( HWND32 hwnd, const WINDOWPLACEMENT32 *pwpl32 )
1439 WINDOWPLACEMENT16 wpl = { sizeof(WINDOWPLACEMENT16),
1440 pwpl32->flags, pwpl32->showCmd, { pwpl32->ptMinPosition.x,
1441 pwpl32->ptMinPosition.y }, { pwpl32->ptMaxPosition.x,
1442 pwpl32->ptMaxPosition.y }, { pwpl32->rcNormalPosition.left,
1443 pwpl32->rcNormalPosition.top, pwpl32->rcNormalPosition.right,
1444 pwpl32->rcNormalPosition.bottom } };
1446 return WINPOS_SetPlacement( hwnd, &wpl, PLACE_MIN | PLACE_MAX | PLACE_RECT );
1452 /***********************************************************************
1453 * SetInternalWindowPos16 (USER.461)
1455 void WINAPI SetInternalWindowPos16( HWND16 hwnd, UINT16 showCmd,
1456 LPRECT16 rect, LPPOINT16 pt )
1458 if( IsWindow16(hwnd) )
1460 WINDOWPLACEMENT16 wndpl;
1463 wndpl.length = sizeof(wndpl);
1464 wndpl.showCmd = showCmd;
1465 wndpl.flags = flags = 0;
1470 wndpl.flags |= WPF_SETMINPOSITION;
1471 wndpl.ptMinPosition = *pt;
1475 flags |= PLACE_RECT;
1476 wndpl.rcNormalPosition = *rect;
1478 WINPOS_SetPlacement( hwnd, &wndpl, flags );
1483 /***********************************************************************
1484 * SetInternalWindowPos32 (USER32.483)
1486 void WINAPI SetInternalWindowPos32( HWND32 hwnd, UINT32 showCmd,
1487 LPRECT32 rect, LPPOINT32 pt )
1489 if( IsWindow32(hwnd) )
1491 WINDOWPLACEMENT16 wndpl;
1494 wndpl.length = sizeof(wndpl);
1495 wndpl.showCmd = showCmd;
1496 wndpl.flags = flags = 0;
1501 wndpl.flags |= WPF_SETMINPOSITION;
1502 CONV_POINT32TO16( pt, &wndpl.ptMinPosition );
1506 flags |= PLACE_RECT;
1507 CONV_RECT32TO16( rect, &wndpl.rcNormalPosition );
1509 WINPOS_SetPlacement( hwnd, &wndpl, flags );
1513 /*******************************************************************
1514 * WINPOS_SetActiveWindow
1516 * SetActiveWindow() back-end. This is the only function that
1517 * can assign active status to a window. It must be called only
1518 * for the top level windows.
1520 BOOL32 WINPOS_SetActiveWindow( HWND32 hWnd, BOOL32 fMouse, BOOL32 fChangeFocus)
1522 CBTACTIVATESTRUCT16* cbtStruct;
1523 WND* wndPtr, *wndTemp;
1524 HQUEUE16 hOldActiveQueue, hNewActiveQueue;
1525 MESSAGEQUEUE *pOldActiveQueue = 0, *pNewActiveQueue = 0;
1527 HWND32 hwndActive = 0;
1530 /* Get current active window from the active queue */
1533 pOldActiveQueue = QUEUE_Lock( hActiveQueue );
1534 if ( pOldActiveQueue )
1535 hwndActive = PERQDATA_GetActiveWnd( pOldActiveQueue->pQData );
1538 /* paranoid checks */
1539 if( hWnd == GetDesktopWindow32() || hWnd == hwndActive ) goto CLEANUP;
1541 /* if (wndPtr && (GetFastQueue() != wndPtr->hmemTaskQ))
1544 wndPtr = WIN_FindWndPtr(hWnd);
1545 hOldActiveQueue = hActiveQueue;
1547 if( (wndTemp = WIN_FindWndPtr(hwndActive)) )
1548 wIconized = HIWORD(wndTemp->dwStyle & WS_MINIMIZE);
1550 TRACE(win,"no current active window.\n");
1552 /* call CBT hook chain */
1553 if ((cbtStruct = SEGPTR_NEW(CBTACTIVATESTRUCT16)))
1556 cbtStruct->fMouse = fMouse;
1557 cbtStruct->hWndActive = hwndActive;
1558 wRet = HOOK_CallHooks16( WH_CBT, HCBT_ACTIVATE, (WPARAM16)hWnd,
1559 (LPARAM)SEGPTR_GET(cbtStruct) );
1560 SEGPTR_FREE(cbtStruct);
1563 /* Unlock the active queue before returning */
1564 if ( pOldActiveQueue )
1565 QUEUE_Unlock( pOldActiveQueue );
1570 /* set prev active wnd to current active wnd and send notification */
1571 if ((hwndPrevActive = hwndActive) && IsWindow32(hwndPrevActive))
1573 MESSAGEQUEUE *pTempActiveQueue = 0;
1575 if (!SendMessage32A( hwndPrevActive, WM_NCACTIVATE, FALSE, 0 ))
1577 if (GetSysModalWindow16() != hWnd) goto CLEANUP;
1578 /* disregard refusal if hWnd is sysmodal */
1582 SendMessage32A( hwndPrevActive, WM_ACTIVATE,
1583 MAKEWPARAM( WA_INACTIVE, wIconized ),
1586 /* FIXME: must be SendMessage16() because 32A doesn't do
1587 * intertask at this time */
1588 SendMessage16( hwndPrevActive, WM_ACTIVATE, WA_INACTIVE,
1589 MAKELPARAM( (HWND16)hWnd, wIconized ) );
1592 /* check if something happened during message processing
1593 * (global active queue may have changed)
1595 pTempActiveQueue = QUEUE_Lock( hActiveQueue );
1596 hwndActive = PERQDATA_GetActiveWnd( pTempActiveQueue->pQData );
1597 QUEUE_Unlock( pTempActiveQueue );
1598 if( hwndPrevActive != hwndActive )
1602 /* Set new active window in the message queue */
1606 pNewActiveQueue = QUEUE_Lock( wndPtr->hmemTaskQ );
1607 if ( pNewActiveQueue )
1608 PERQDATA_SetActiveWnd( pNewActiveQueue->pQData, hwndActive );
1611 /* send palette messages */
1612 if (hWnd && SendMessage16( hWnd, WM_QUERYNEWPALETTE, 0, 0L))
1613 SendMessage16((HWND16)-1, WM_PALETTEISCHANGING, (WPARAM16)hWnd, 0L );
1615 /* if prev wnd is minimized redraw icon title */
1616 if( IsIconic32( hwndPrevActive ) ) WINPOS_RedrawIconTitle(hwndPrevActive);
1618 /* managed windows will get ConfigureNotify event */
1619 if (wndPtr && !(wndPtr->dwStyle & WS_CHILD) && !(wndPtr->flags & WIN_MANAGED))
1621 /* check Z-order and bring hWnd to the top */
1622 for (wndTemp = WIN_GetDesktop()->child; wndTemp; wndTemp = wndTemp->next)
1623 if (wndTemp->dwStyle & WS_VISIBLE) break;
1625 if( wndTemp != wndPtr )
1626 SetWindowPos32(hWnd, HWND_TOP, 0,0,0,0,
1627 SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE );
1628 if (!IsWindow32(hWnd)) goto CLEANUP;
1631 /* Get a handle to the new active queue */
1632 hNewActiveQueue = wndPtr ? wndPtr->hmemTaskQ : 0;
1634 /* send WM_ACTIVATEAPP if necessary */
1635 if (hOldActiveQueue != hNewActiveQueue)
1637 WND **list, **ppWnd;
1639 if ((list = WIN_BuildWinArray( WIN_GetDesktop(), 0, NULL )))
1641 for (ppWnd = list; *ppWnd; ppWnd++)
1643 if (!IsWindow32( (*ppWnd)->hwndSelf )) continue;
1645 if ((*ppWnd)->hmemTaskQ == hOldActiveQueue)
1646 SendMessage16( (*ppWnd)->hwndSelf, WM_ACTIVATEAPP,
1647 0, QUEUE_GetQueueTask(hNewActiveQueue) );
1649 HeapFree( SystemHeap, 0, list );
1652 hActiveQueue = hNewActiveQueue;
1654 if ((list = WIN_BuildWinArray( WIN_GetDesktop(), 0, NULL )))
1656 for (ppWnd = list; *ppWnd; ppWnd++)
1658 if (!IsWindow32( (*ppWnd)->hwndSelf )) continue;
1660 if ((*ppWnd)->hmemTaskQ == hNewActiveQueue)
1661 SendMessage16( (*ppWnd)->hwndSelf, WM_ACTIVATEAPP,
1662 1, QUEUE_GetQueueTask( hOldActiveQueue ) );
1664 HeapFree( SystemHeap, 0, list );
1667 if (!IsWindow32(hWnd)) goto CLEANUP;
1672 /* walk up to the first unowned window */
1674 while (wndTemp->owner) wndTemp = wndTemp->owner;
1675 /* and set last active owned popup */
1676 wndTemp->hwndLastActive = hWnd;
1678 wIconized = HIWORD(wndTemp->dwStyle & WS_MINIMIZE);
1679 SendMessage32A( hWnd, WM_NCACTIVATE, TRUE, 0 );
1681 SendMessage32A( hWnd, WM_ACTIVATE,
1682 MAKEWPARAM( (fMouse) ? WA_CLICKACTIVE : WA_ACTIVE, wIconized),
1683 (LPARAM)hwndPrevActive );
1685 SendMessage16(hWnd, WM_ACTIVATE, (fMouse) ? WA_CLICKACTIVE : WA_ACTIVE,
1686 MAKELPARAM( (HWND16)hwndPrevActive, wIconized) );
1689 if( !IsWindow32(hWnd) ) goto CLEANUP;
1692 /* change focus if possible */
1693 if( fChangeFocus && GetFocus32() )
1694 if( WIN_GetTopParent(GetFocus32()) != hwndActive )
1695 FOCUS_SwitchFocus( pNewActiveQueue, GetFocus32(),
1696 (wndPtr && (wndPtr->dwStyle & WS_MINIMIZE))?
1701 if( !hwndPrevActive && wndPtr )
1702 (*wndPtr->pDriver->pForceWindowRaise)(wndPtr);
1704 /* if active wnd is minimized redraw icon title */
1705 if( IsIconic32(hwndActive) ) WINPOS_RedrawIconTitle(hwndActive);
1707 bRet = 1; // Success
1711 /* Unlock the message queues before returning */
1712 if ( pOldActiveQueue )
1713 QUEUE_Unlock( pOldActiveQueue );
1714 if ( pNewActiveQueue )
1715 QUEUE_Unlock( pNewActiveQueue );
1716 return bRet ? (hWnd == hwndActive) : 0;
1719 /*******************************************************************
1720 * WINPOS_ActivateOtherWindow
1722 * Activates window other than pWnd.
1724 BOOL32 WINPOS_ActivateOtherWindow(WND* pWnd)
1728 HWND32 hwndActive = 0;
1730 /* Get current active window from the active queue */
1733 MESSAGEQUEUE *pActiveQueue = QUEUE_Lock( hActiveQueue );
1736 hwndActive = PERQDATA_GetActiveWnd( pActiveQueue->pQData );
1737 QUEUE_Unlock( pActiveQueue );
1741 if( pWnd->hwndSelf == hwndPrevActive )
1744 if( hwndActive != pWnd->hwndSelf &&
1745 ( hwndActive || QUEUE_IsExitingQueue(pWnd->hmemTaskQ)) )
1748 if( !(pWnd->dwStyle & WS_POPUP) || !(pWnd->owner) ||
1749 !WINPOS_CanActivate((pWndTo = WIN_GetTopParentPtr(pWnd->owner))) )
1751 WND* pWndPtr = WIN_GetTopParentPtr(pWnd);
1753 pWndTo = WIN_FindWndPtr(hwndPrevActive);
1755 while( !WINPOS_CanActivate(pWndTo) )
1757 /* by now owned windows should've been taken care of */
1759 pWndTo = pWndPtr->next;
1761 if( !pWndTo ) break;
1765 bRet = WINPOS_SetActiveWindow( pWndTo ? pWndTo->hwndSelf : 0, FALSE, TRUE );
1767 /* switch desktop queue to current active */
1768 if( pWndTo ) WIN_GetDesktop()->hmemTaskQ = pWndTo->hmemTaskQ;
1774 /*******************************************************************
1775 * WINPOS_ChangeActiveWindow
1778 BOOL32 WINPOS_ChangeActiveWindow( HWND32 hWnd, BOOL32 mouseMsg )
1780 WND *wndPtr = WIN_FindWndPtr(hWnd);
1781 HWND32 hwndActive = 0;
1783 /* Get current active window from the active queue */
1786 MESSAGEQUEUE *pActiveQueue = QUEUE_Lock( hActiveQueue );
1789 hwndActive = PERQDATA_GetActiveWnd( pActiveQueue->pQData );
1790 QUEUE_Unlock( pActiveQueue );
1794 if (!hWnd) return WINPOS_SetActiveWindow( 0, mouseMsg, TRUE );
1796 if( !wndPtr ) return FALSE;
1798 /* child windows get WM_CHILDACTIVATE message */
1799 if( (wndPtr->dwStyle & (WS_CHILD | WS_POPUP)) == WS_CHILD )
1800 return SendMessage32A(hWnd, WM_CHILDACTIVATE, 0, 0L);
1802 /* owned popups imply owner activation - not sure */
1803 if ((wndPtr->dwStyle & WS_POPUP) && wndPtr->owner &&
1804 (wndPtr->owner->dwStyle & WS_VISIBLE ) &&
1805 !(wndPtr->owner->dwStyle & WS_DISABLED ))
1807 if (!(wndPtr = wndPtr->owner)) return FALSE;
1808 hWnd = wndPtr->hwndSelf;
1811 if( hWnd == hwndActive ) return FALSE;
1813 if( !WINPOS_SetActiveWindow(hWnd ,mouseMsg ,TRUE) )
1816 /* switch desktop queue to current active */
1817 if( wndPtr->parent == WIN_GetDesktop())
1818 WIN_GetDesktop()->hmemTaskQ = wndPtr->hmemTaskQ;
1824 /***********************************************************************
1825 * WINPOS_SendNCCalcSize
1827 * Send a WM_NCCALCSIZE message to a window.
1828 * All parameters are read-only except newClientRect.
1829 * oldWindowRect, oldClientRect and winpos must be non-NULL only
1830 * when calcValidRect is TRUE.
1832 LONG WINPOS_SendNCCalcSize( HWND32 hwnd, BOOL32 calcValidRect,
1833 RECT32 *newWindowRect, RECT32 *oldWindowRect,
1834 RECT32 *oldClientRect, WINDOWPOS32 *winpos,
1835 RECT32 *newClientRect )
1837 NCCALCSIZE_PARAMS32 params;
1838 WINDOWPOS32 winposCopy;
1841 params.rgrc[0] = *newWindowRect;
1844 winposCopy = *winpos;
1845 params.rgrc[1] = *oldWindowRect;
1846 params.rgrc[2] = *oldClientRect;
1847 params.lppos = &winposCopy;
1849 result = SendMessage32A( hwnd, WM_NCCALCSIZE, calcValidRect,
1851 TRACE(win, "%d,%d-%d,%d\n",
1852 params.rgrc[0].left, params.rgrc[0].top,
1853 params.rgrc[0].right, params.rgrc[0].bottom );
1854 *newClientRect = params.rgrc[0];
1859 /***********************************************************************
1860 * WINPOS_HandleWindowPosChanging16
1862 * Default handling for a WM_WINDOWPOSCHANGING. Called from DefWindowProc().
1864 LONG WINPOS_HandleWindowPosChanging16( WND *wndPtr, WINDOWPOS16 *winpos )
1866 POINT32 maxSize, minTrack;
1867 if (winpos->flags & SWP_NOSIZE) return 0;
1868 if ((wndPtr->dwStyle & WS_THICKFRAME) ||
1869 ((wndPtr->dwStyle & (WS_POPUP | WS_CHILD)) == 0))
1871 WINPOS_GetMinMaxInfo( wndPtr, &maxSize, NULL, &minTrack, NULL );
1872 if (maxSize.x < winpos->cx) winpos->cx = maxSize.x;
1873 if (maxSize.y < winpos->cy) winpos->cy = maxSize.y;
1874 if (!(wndPtr->dwStyle & WS_MINIMIZE))
1876 if (winpos->cx < minTrack.x ) winpos->cx = minTrack.x;
1877 if (winpos->cy < minTrack.y ) winpos->cy = minTrack.y;
1884 /***********************************************************************
1885 * WINPOS_HandleWindowPosChanging32
1887 * Default handling for a WM_WINDOWPOSCHANGING. Called from DefWindowProc().
1889 LONG WINPOS_HandleWindowPosChanging32( WND *wndPtr, WINDOWPOS32 *winpos )
1892 if (winpos->flags & SWP_NOSIZE) return 0;
1893 if ((wndPtr->dwStyle & WS_THICKFRAME) ||
1894 ((wndPtr->dwStyle & (WS_POPUP | WS_CHILD)) == 0))
1896 WINPOS_GetMinMaxInfo( wndPtr, &maxSize, NULL, NULL, NULL );
1897 winpos->cx = MIN( winpos->cx, maxSize.x );
1898 winpos->cy = MIN( winpos->cy, maxSize.y );
1904 /***********************************************************************
1905 * WINPOS_MoveWindowZOrder
1907 * Move a window in Z order, invalidating everything that needs it.
1908 * Only necessary for windows without associated X window.
1910 static void WINPOS_MoveWindowZOrder( HWND32 hwnd, HWND32 hwndAfter )
1913 WND *pWndAfter, *pWndCur, *wndPtr = WIN_FindWndPtr( hwnd );
1915 /* We have two possible cases:
1916 * - The window is moving up: we have to invalidate all areas
1917 * of the window that were covered by other windows
1918 * - The window is moving down: we have to invalidate areas
1919 * of other windows covered by this one.
1922 if (hwndAfter == HWND_TOP)
1926 else if (hwndAfter == HWND_BOTTOM)
1928 if (!wndPtr->next) return; /* Already at the bottom */
1933 if (!(pWndAfter = WIN_FindWndPtr( hwndAfter ))) return;
1934 if (wndPtr->next == pWndAfter) return; /* Already placed right */
1936 /* Determine which window we encounter first in Z-order */
1937 pWndCur = wndPtr->parent->child;
1938 while ((pWndCur != wndPtr) && (pWndCur != pWndAfter))
1939 pWndCur = pWndCur->next;
1940 movingUp = (pWndCur == pWndAfter);
1945 WND *pWndPrevAfter = wndPtr->next;
1946 WIN_UnlinkWindow( hwnd );
1947 WIN_LinkWindow( hwnd, hwndAfter );
1948 pWndCur = wndPtr->next;
1949 while (pWndCur != pWndPrevAfter)
1951 RECT32 rect = { pWndCur->rectWindow.left,
1952 pWndCur->rectWindow.top,
1953 pWndCur->rectWindow.right,
1954 pWndCur->rectWindow.bottom };
1955 OffsetRect32( &rect, -wndPtr->rectClient.left,
1956 -wndPtr->rectClient.top );
1957 PAINT_RedrawWindow( hwnd, &rect, 0, RDW_INVALIDATE | RDW_ALLCHILDREN |
1958 RDW_FRAME | RDW_ERASE, 0 );
1959 pWndCur = pWndCur->next;
1962 else /* Moving down */
1964 pWndCur = wndPtr->next;
1965 WIN_UnlinkWindow( hwnd );
1966 WIN_LinkWindow( hwnd, hwndAfter );
1967 while (pWndCur != wndPtr)
1969 RECT32 rect = { pWndCur->rectWindow.left,
1970 pWndCur->rectWindow.top,
1971 pWndCur->rectWindow.right,
1972 pWndCur->rectWindow.bottom };
1973 OffsetRect32( &rect, -pWndCur->rectClient.left,
1974 -pWndCur->rectClient.top );
1975 PAINT_RedrawWindow( pWndCur->hwndSelf, &rect, 0, RDW_INVALIDATE |
1976 RDW_ALLCHILDREN | RDW_FRAME | RDW_ERASE, 0 );
1977 pWndCur = pWndCur->next;
1982 /***********************************************************************
1983 * WINPOS_ReorderOwnedPopups
1985 * fix Z order taking into account owned popups -
1986 * basically we need to maintain them above the window that owns them
1988 HWND32 WINPOS_ReorderOwnedPopups(HWND32 hwndInsertAfter,WND* wndPtr,WORD flags)
1990 WND* w = WIN_GetDesktop()->child;
1992 if( wndPtr->dwStyle & WS_POPUP && wndPtr->owner )
1994 /* implement "local z-order" between the top and owner window */
1996 HWND32 hwndLocalPrev = HWND_TOP;
1998 if( hwndInsertAfter != HWND_TOP )
2000 while( w != wndPtr->owner )
2002 if (w != wndPtr) hwndLocalPrev = w->hwndSelf;
2003 if( hwndLocalPrev == hwndInsertAfter ) break;
2006 hwndInsertAfter = hwndLocalPrev;
2010 else if( wndPtr->dwStyle & WS_CHILD ) return hwndInsertAfter;
2012 w = WIN_GetDesktop()->child;
2015 if( w == wndPtr ) break;
2017 if( w->dwStyle & WS_POPUP && w->owner == wndPtr )
2019 SetWindowPos32(w->hwndSelf, hwndInsertAfter, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE |
2020 SWP_NOACTIVATE | SWP_NOSENDCHANGING | SWP_DEFERERASE);
2021 hwndInsertAfter = w->hwndSelf;
2026 return hwndInsertAfter;
2029 /***********************************************************************
2030 * WINPOS_SizeMoveClean
2032 * Make window look nice without excessive repainting
2036 * visible regions are in window coordinates
2037 * update regions are in window client coordinates
2038 * client and window rectangles are in parent client coordinates
2040 * FIXME: Move visible and update regions to the same coordinate system
2041 * (either parent client or window). This is a lot of work though.
2043 static UINT32 WINPOS_SizeMoveClean( WND* Wnd, HRGN32 oldVisRgn,
2044 LPRECT32 lpOldWndRect,
2045 LPRECT32 lpOldClientRect, UINT32 uFlags )
2047 HRGN32 newVisRgn = DCE_GetVisRgn(Wnd->hwndSelf,DCX_WINDOW | DCX_CLIPSIBLINGS);
2048 HRGN32 dirtyRgn = CreateRectRgn32(0,0,0,0);
2051 TRACE(win,"cleaning up...new wnd=(%i %i-%i %i) old wnd=(%i %i-%i %i)\n",
2052 Wnd->rectWindow.left, Wnd->rectWindow.top,
2053 Wnd->rectWindow.right, Wnd->rectWindow.bottom,
2054 lpOldWndRect->left, lpOldWndRect->top,
2055 lpOldWndRect->right, lpOldWndRect->bottom);
2056 TRACE(win,"\tnew client=(%i %i-%i %i) old client=(%i %i-%i %i)\n",
2057 Wnd->rectClient.left, Wnd->rectClient.top,
2058 Wnd->rectClient.right, Wnd->rectClient.bottom,
2059 lpOldClientRect->left, lpOldClientRect->top,
2060 lpOldClientRect->right,lpOldClientRect->bottom );
2062 if( (lpOldWndRect->right - lpOldWndRect->left) != (Wnd->rectWindow.right - Wnd->rectWindow.left) ||
2063 (lpOldWndRect->bottom - lpOldWndRect->top) != (Wnd->rectWindow.bottom - Wnd->rectWindow.top) )
2064 uFlags |= SMC_DRAWFRAME;
2066 CombineRgn32( dirtyRgn, newVisRgn, 0, RGN_COPY);
2068 if( !(uFlags & SMC_NOCOPY) )
2069 CombineRgn32( newVisRgn, newVisRgn, oldVisRgn, RGN_AND );
2071 /* map regions to the parent client area */
2073 OffsetRgn32( dirtyRgn, Wnd->rectWindow.left, Wnd->rectWindow.top );
2074 OffsetRgn32( oldVisRgn, lpOldWndRect->left, lpOldWndRect->top );
2076 /* compute invalidated region outside Wnd - (in client coordinates of the parent window) */
2078 other = CombineRgn32(dirtyRgn, oldVisRgn, dirtyRgn, RGN_DIFF);
2080 /* map visible region to the Wnd client area */
2082 OffsetRgn32( newVisRgn, Wnd->rectWindow.left - Wnd->rectClient.left,
2083 Wnd->rectWindow.top - Wnd->rectClient.top );
2085 /* substract previously invalidated region from the Wnd visible region */
2087 my = (Wnd->hrgnUpdate > 1) ? CombineRgn32( newVisRgn, newVisRgn,
2088 Wnd->hrgnUpdate, RGN_DIFF)
2091 if( uFlags & SMC_NOCOPY ) /* invalidate Wnd visible region */
2093 if (my != NULLREGION)
2094 PAINT_RedrawWindow( Wnd->hwndSelf, NULL, newVisRgn, RDW_INVALIDATE |
2095 RDW_FRAME | RDW_ALLCHILDREN | RDW_ERASE, RDW_C_USEHRGN );
2096 else if(uFlags & SMC_DRAWFRAME)
2097 Wnd->flags |= WIN_NEEDS_NCPAINT;
2099 else /* bitblt old client area */
2104 int xfrom,yfrom,xto,yto,width,height;
2106 if( uFlags & SMC_DRAWFRAME )
2108 /* copy only client area, frame will be redrawn anyway */
2110 xfrom = lpOldClientRect->left; yfrom = lpOldClientRect->top;
2111 xto = Wnd->rectClient.left; yto = Wnd->rectClient.top;
2112 width = lpOldClientRect->right - xfrom; height = lpOldClientRect->bottom - yfrom;
2113 updateRgn = CreateRectRgn32( 0, 0, width, height );
2114 CombineRgn32( newVisRgn, newVisRgn, updateRgn, RGN_AND );
2115 SetRectRgn32( updateRgn, 0, 0, Wnd->rectClient.right - xto,
2116 Wnd->rectClient.bottom - yto );
2120 xfrom = lpOldWndRect->left; yfrom = lpOldWndRect->top;
2121 xto = Wnd->rectWindow.left; yto = Wnd->rectWindow.top;
2122 width = lpOldWndRect->right - xfrom; height = lpOldWndRect->bottom - yfrom;
2123 updateRgn = CreateRectRgn32( xto - Wnd->rectClient.left,
2124 yto - Wnd->rectClient.top,
2125 Wnd->rectWindow.right - Wnd->rectClient.left,
2126 Wnd->rectWindow.bottom - Wnd->rectClient.top );
2129 CombineRgn32( newVisRgn, newVisRgn, updateRgn, RGN_AND );
2131 /* substract new visRgn from target rect to get a region that won't be copied */
2133 update = CombineRgn32( updateRgn, updateRgn, newVisRgn, RGN_DIFF );
2135 /* Blt valid bits using parent window DC */
2137 if( my != NULLREGION && (xfrom != xto || yfrom != yto) )
2140 /* compute clipping region in parent client coordinates */
2142 OffsetRgn32( newVisRgn, Wnd->rectClient.left, Wnd->rectClient.top );
2143 CombineRgn32( oldVisRgn, oldVisRgn, newVisRgn, RGN_OR );
2145 hDC = GetDCEx32( Wnd->parent->hwndSelf, oldVisRgn,
2146 DCX_KEEPCLIPRGN | DCX_INTERSECTRGN |
2147 DCX_CACHE | DCX_CLIPSIBLINGS);
2149 BitBlt32( hDC, xto, yto, width, height, hDC, xfrom, yfrom, SRCCOPY );
2150 ReleaseDC32( Wnd->parent->hwndSelf, hDC);
2153 if( update != NULLREGION )
2154 PAINT_RedrawWindow( Wnd->hwndSelf, NULL, updateRgn, RDW_INVALIDATE |
2155 RDW_FRAME | RDW_ALLCHILDREN | RDW_ERASE, RDW_C_USEHRGN );
2156 else if( uFlags & SMC_DRAWFRAME ) Wnd->flags |= WIN_NEEDS_NCPAINT;
2157 DeleteObject32( updateRgn );
2160 /* erase uncovered areas */
2162 if( !(uFlags & SMC_NOPARENTERASE) && (other != NULLREGION ) )
2163 PAINT_RedrawWindow( Wnd->parent->hwndSelf, NULL, dirtyRgn,
2164 RDW_INVALIDATE | RDW_ALLCHILDREN | RDW_ERASE, RDW_C_USEHRGN );
2165 DeleteObject32(dirtyRgn);
2166 DeleteObject32(newVisRgn);
2170 /***********************************************************************
2171 * SetWindowPos (USER.232)
2173 BOOL16 WINAPI SetWindowPos16( HWND16 hwnd, HWND16 hwndInsertAfter,
2174 INT16 x, INT16 y, INT16 cx, INT16 cy, WORD flags)
2176 return SetWindowPos32(hwnd,(INT32)(INT16)hwndInsertAfter,x,y,cx,cy,flags);
2179 /***********************************************************************
2180 * SetWindowPos (USER32.520)
2182 BOOL32 WINAPI SetWindowPos32( HWND32 hwnd, HWND32 hwndInsertAfter,
2183 INT32 x, INT32 y, INT32 cx, INT32 cy, WORD flags)
2187 RECT32 newWindowRect, newClientRect, oldWindowRect;
2189 HWND32 tempInsertAfter= 0;
2192 BOOL32 resync = FALSE;
2193 HWND32 hwndActive = 0;
2195 /* Get current active window from the active queue */
2198 MESSAGEQUEUE *pActiveQueue = QUEUE_Lock( hActiveQueue );
2201 hwndActive = PERQDATA_GetActiveWnd( pActiveQueue->pQData );
2202 QUEUE_Unlock( pActiveQueue );
2206 TRACE(win,"hwnd %04x, (%i,%i)-(%i,%i) flags %08x\n",
2207 hwnd, x, y, x+cx, y+cy, flags);
2208 /* Check window handle */
2210 if (hwnd == GetDesktopWindow32()) return FALSE;
2211 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return FALSE;
2213 if(wndPtr->dwStyle & WS_VISIBLE)
2214 flags &= ~SWP_SHOWWINDOW;
2217 uFlags |= SMC_NOPARENTERASE;
2218 flags &= ~SWP_HIDEWINDOW;
2219 if (!(flags & SWP_SHOWWINDOW)) flags |= SWP_NOREDRAW;
2222 /* Check for windows that may not be resized
2223 FIXME: this should be done only for Windows 3.0 programs
2224 if (flags & (SWP_SHOWWINDOW | SWP_HIDEWINDOW ) )
2225 flags |= SWP_NOSIZE | SWP_NOMOVE;
2227 /* Check dimensions */
2229 if (cx <= 0) cx = 1;
2230 if (cy <= 0) cy = 1;
2234 if (hwnd == hwndActive) flags |= SWP_NOACTIVATE; /* Already active */
2235 if ((wndPtr->rectWindow.right - wndPtr->rectWindow.left == cx) &&
2236 (wndPtr->rectWindow.bottom - wndPtr->rectWindow.top == cy))
2237 flags |= SWP_NOSIZE; /* Already the right size */
2238 if ((wndPtr->rectWindow.left == x) && (wndPtr->rectWindow.top == y))
2239 flags |= SWP_NOMOVE; /* Already the right position */
2241 /* Check hwndInsertAfter */
2243 if (!(flags & (SWP_NOZORDER | SWP_NOACTIVATE)))
2245 /* Ignore TOPMOST flags when activating a window */
2246 /* _and_ moving it in Z order. */
2247 if ((hwndInsertAfter == HWND_TOPMOST) ||
2248 (hwndInsertAfter == HWND_NOTOPMOST))
2249 hwndInsertAfter = HWND_TOP;
2251 /* TOPMOST not supported yet */
2252 if ((hwndInsertAfter == HWND_TOPMOST) ||
2253 (hwndInsertAfter == HWND_NOTOPMOST)) hwndInsertAfter = HWND_TOP;
2255 /* hwndInsertAfter must be a sibling of the window */
2256 if ((hwndInsertAfter != HWND_TOP) && (hwndInsertAfter != HWND_BOTTOM))
2258 WND* wnd = WIN_FindWndPtr(hwndInsertAfter);
2261 if( wnd->parent != wndPtr->parent ) return FALSE;
2262 if( wnd->next == wndPtr ) flags |= SWP_NOZORDER;
2265 else if (!X11DRV_WND_GetXWindow(wndPtr))
2267 /* FIXME: the following optimization is no good for "X-ed" windows */
2268 if (hwndInsertAfter == HWND_TOP)
2269 flags |= ( wndPtr->parent->child == wndPtr)? SWP_NOZORDER: 0;
2270 else /* HWND_BOTTOM */
2271 flags |= ( wndPtr->next )? 0: SWP_NOZORDER;
2274 /* Fill the WINDOWPOS structure */
2277 winpos.hwndInsertAfter = hwndInsertAfter;
2282 winpos.flags = flags;
2284 /* Send WM_WINDOWPOSCHANGING message */
2286 if (!(winpos.flags & SWP_NOSENDCHANGING))
2287 SendMessage32A( hwnd, WM_WINDOWPOSCHANGING, 0, (LPARAM)&winpos );
2289 /* Calculate new position and size */
2291 newWindowRect = wndPtr->rectWindow;
2292 newClientRect = (wndPtr->dwStyle & WS_MINIMIZE) ? wndPtr->rectWindow
2293 : wndPtr->rectClient;
2295 if (!(winpos.flags & SWP_NOSIZE))
2297 newWindowRect.right = newWindowRect.left + winpos.cx;
2298 newWindowRect.bottom = newWindowRect.top + winpos.cy;
2300 if (!(winpos.flags & SWP_NOMOVE))
2302 newWindowRect.left = winpos.x;
2303 newWindowRect.top = winpos.y;
2304 newWindowRect.right += winpos.x - wndPtr->rectWindow.left;
2305 newWindowRect.bottom += winpos.y - wndPtr->rectWindow.top;
2307 OffsetRect32( &newClientRect, winpos.x - wndPtr->rectWindow.left,
2308 winpos.y - wndPtr->rectWindow.top );
2311 winpos.flags |= SWP_NOCLIENTMOVE | SWP_NOCLIENTSIZE;
2313 /* Reposition window in Z order */
2315 if (!(winpos.flags & SWP_NOZORDER))
2317 /* reorder owned popups if hwnd is top-level window
2319 if( wndPtr->parent == WIN_GetDesktop() )
2320 hwndInsertAfter = WINPOS_ReorderOwnedPopups( hwndInsertAfter,
2321 wndPtr, winpos.flags );
2322 if (X11DRV_WND_GetXWindow(wndPtr))
2325 WIN_UnlinkWindow( winpos.hwnd );
2326 WIN_LinkWindow( winpos.hwnd, hwndInsertAfter );
2329 WINPOS_MoveWindowZOrder( winpos.hwnd, hwndInsertAfter );
2332 if ( !X11DRV_WND_GetXWindow(wndPtr) && !(winpos.flags & SWP_NOREDRAW) &&
2333 ((winpos.flags & (SWP_NOMOVE | SWP_NOSIZE | SWP_FRAMECHANGED))
2334 != (SWP_NOMOVE | SWP_NOSIZE)) )
2335 visRgn = DCE_GetVisRgn(hwnd, DCX_WINDOW | DCX_CLIPSIBLINGS);
2337 /* Send WM_NCCALCSIZE message to get new client area */
2338 if( (winpos.flags & (SWP_FRAMECHANGED | SWP_NOSIZE)) != SWP_NOSIZE )
2340 result = WINPOS_SendNCCalcSize( winpos.hwnd, TRUE, &newWindowRect,
2341 &wndPtr->rectWindow, &wndPtr->rectClient,
2342 &winpos, &newClientRect );
2344 /* FIXME: WVR_ALIGNxxx */
2346 if( newClientRect.left != wndPtr->rectClient.left ||
2347 newClientRect.top != wndPtr->rectClient.top )
2348 winpos.flags &= ~SWP_NOCLIENTMOVE;
2350 if( (newClientRect.right - newClientRect.left !=
2351 wndPtr->rectClient.right - wndPtr->rectClient.left) ||
2352 (newClientRect.bottom - newClientRect.top !=
2353 wndPtr->rectClient.bottom - wndPtr->rectClient.top) )
2354 winpos.flags &= ~SWP_NOCLIENTSIZE;
2357 if( !(flags & SWP_NOMOVE) && (newClientRect.left != wndPtr->rectClient.left ||
2358 newClientRect.top != wndPtr->rectClient.top) )
2359 winpos.flags &= ~SWP_NOCLIENTMOVE;
2361 /* Update active DCEs
2362 * TODO: Optimize conditions that trigger DCE update.
2365 if( (((winpos.flags & SWP_AGG_NOPOSCHANGE) != SWP_AGG_NOPOSCHANGE) &&
2366 wndPtr->dwStyle & WS_VISIBLE) ||
2367 (flags & (SWP_HIDEWINDOW | SWP_SHOWWINDOW)) )
2371 UnionRect32(&rect, &newWindowRect, &wndPtr->rectWindow);
2372 DCE_InvalidateDCE(wndPtr, &rect);
2375 /* change geometry */
2377 oldWindowRect = wndPtr->rectWindow;
2379 if (X11DRV_WND_GetXWindow(wndPtr))
2381 RECT32 oldClientRect = wndPtr->rectClient;
2383 tempInsertAfter = winpos.hwndInsertAfter;
2385 winpos.hwndInsertAfter = hwndInsertAfter;
2387 /* postpone geometry change */
2389 if( !(flags & (SWP_SHOWWINDOW | SWP_HIDEWINDOW)) )
2391 wndPtr->pDriver->pSetWindowPos(wndPtr, &winpos, TRUE);
2392 winpos.hwndInsertAfter = tempInsertAfter;
2394 else uFlags |= SMC_SETXPOS;
2396 wndPtr->rectWindow = newWindowRect;
2397 wndPtr->rectClient = newClientRect;
2399 if( !(flags & (SWP_SHOWWINDOW | SWP_HIDEWINDOW)) )
2401 if( (oldClientRect.left - oldWindowRect.left !=
2402 newClientRect.left - newWindowRect.left) ||
2403 (oldClientRect.top - oldWindowRect.top !=
2404 newClientRect.top - newWindowRect.top) ||
2405 (winpos.flags & SWP_NOCOPYBITS) )
2407 /* if the client area moved as a result of WM_NCCALCSIZE returning
2408 * obscure WVR_ALIGNxxx flags then we simply redraw the whole thing
2410 * TODO: use WINPOS_SizeMoveClean() if there is no SWP_NOCOPYBITS
2413 PAINT_RedrawWindow( wndPtr->hwndSelf, NULL, 0, RDW_INVALIDATE |
2414 RDW_ALLCHILDREN | RDW_FRAME | RDW_ERASE, 0 );
2417 if( winpos.flags & SWP_FRAMECHANGED )
2422 if( newClientRect.right > oldClientRect.right ) /* redraw exposed client area on the right */
2424 rect.top = 0; rect.bottom = newClientRect.bottom - newClientRect.top;
2425 rect.left = oldClientRect.right - newClientRect.left;
2426 rect.right = newClientRect.right - newClientRect.left;
2428 PAINT_RedrawWindow( wndPtr->hwndSelf, &rect, 0,
2429 RDW_INVALIDATE | RDW_FRAME | RDW_ERASE | RDW_ERASENOW | RDW_ALLCHILDREN, 0 );
2431 if( newClientRect.bottom > oldClientRect.bottom ) /* redraw exposed client area on the bottom */
2433 rect.left = 0; rect.right = ((wErase)?oldClientRect.right:newClientRect.right) - newClientRect.left;
2434 rect.top = oldClientRect.bottom - newClientRect.top;
2435 rect.bottom = newClientRect.bottom - newClientRect.top;
2437 PAINT_RedrawWindow( wndPtr->hwndSelf, &rect, 0,
2438 RDW_INVALIDATE | RDW_FRAME | RDW_ERASE | RDW_ERASENOW | RDW_ALLCHILDREN, 0 );
2440 if( !wErase ) /* just update the nonclient area */
2441 wndPtr->flags |= WIN_NEEDS_NCPAINT;
2444 uFlags |= SMC_NOPARENTERASE; /* X windows do not have eraseable parents */
2446 else /* not an X window */
2448 RECT32 oldClientRect = wndPtr->rectClient;
2450 wndPtr->rectWindow = newWindowRect;
2451 wndPtr->rectClient = newClientRect;
2453 if( oldClientRect.bottom - oldClientRect.top ==
2454 newClientRect.bottom - newClientRect.top ) result &= ~WVR_VREDRAW;
2456 if( oldClientRect.right - oldClientRect.left ==
2457 newClientRect.right - newClientRect.left ) result &= ~WVR_HREDRAW;
2459 if( !(flags & (SWP_NOREDRAW | SWP_HIDEWINDOW | SWP_SHOWWINDOW)) )
2461 uFlags |= ((winpos.flags & SWP_NOCOPYBITS) ||
2462 (result >= WVR_HREDRAW && result < WVR_VALIDRECTS)) ? SMC_NOCOPY : 0;
2463 uFlags |= (winpos.flags & SWP_FRAMECHANGED) ? SMC_DRAWFRAME : 0;
2465 if( (winpos.flags & SWP_AGG_NOGEOMETRYCHANGE) != SWP_AGG_NOGEOMETRYCHANGE )
2466 uFlags = WINPOS_SizeMoveClean(wndPtr, visRgn, &oldWindowRect,
2467 &oldClientRect, uFlags);
2470 /* adjust the frame and do not erase the parent */
2472 if( winpos.flags & SWP_FRAMECHANGED ) wndPtr->flags |= WIN_NEEDS_NCPAINT;
2473 if( winpos.flags & SWP_NOZORDER ) uFlags |= SMC_NOPARENTERASE;
2476 DeleteObject32(visRgn);
2479 if (flags & SWP_SHOWWINDOW)
2481 wndPtr->dwStyle |= WS_VISIBLE;
2482 if (X11DRV_WND_GetXWindow(wndPtr))
2486 wndPtr->pDriver->pSetWindowPos(wndPtr, &winpos, uFlags & SMC_SETXPOS );
2487 if( uFlags & SMC_SETXPOS )
2489 winpos.hwndInsertAfter = tempInsertAfter;
2492 if (wndPtr->flags & WIN_MANAGED) resync = TRUE;
2494 /* If focus was set to an unmapped window, reset X focus now */
2495 focus = curr = GetFocus32();
2499 SetFocus32( focus );
2502 curr = GetParent32(curr);
2507 if (!(flags & SWP_NOREDRAW))
2508 PAINT_RedrawWindow( winpos.hwnd, NULL, 0,
2509 RDW_INVALIDATE | RDW_ALLCHILDREN |
2510 RDW_FRAME | RDW_ERASENOW | RDW_ERASE, 0 );
2513 else if (flags & SWP_HIDEWINDOW)
2515 wndPtr->dwStyle &= ~WS_VISIBLE;
2516 if (X11DRV_WND_GetXWindow(wndPtr))
2518 wndPtr->pDriver->pSetWindowPos(wndPtr, &winpos, uFlags & SMC_SETXPOS );
2519 if( uFlags & SMC_SETXPOS )
2521 winpos.hwndInsertAfter = tempInsertAfter;
2526 if (!(flags & SWP_NOREDRAW))
2527 PAINT_RedrawWindow( wndPtr->parent->hwndSelf, &oldWindowRect,
2528 0, RDW_INVALIDATE | RDW_ALLCHILDREN |
2529 RDW_ERASE | RDW_ERASENOW, 0 );
2530 uFlags |= SMC_NOPARENTERASE;
2533 if (hwnd == CARET_GetHwnd()) DestroyCaret32();
2535 /* FIXME: This will cause the window to be activated irrespective
2536 * of whether it is owned by the same thread.
2537 * Should this behaviour be allowed in SetWindowPos?
2539 if (winpos.hwnd == hwndActive)
2540 WINPOS_ActivateOtherWindow( wndPtr );
2543 /* Activate the window */
2545 if (!(flags & SWP_NOACTIVATE))
2546 WINPOS_ChangeActiveWindow( winpos.hwnd, FALSE );
2548 /* Repaint the window */
2550 if (X11DRV_WND_GetXWindow(wndPtr))
2551 EVENT_Synchronize(); /* Wait for all expose events */
2553 if (!GetCapture32())
2554 EVENT_DummyMotionNotify(); /* Simulate a mouse event to set the cursor */
2556 if (!(flags & SWP_DEFERERASE) && !(uFlags & SMC_NOPARENTERASE) )
2557 PAINT_RedrawWindow( wndPtr->parent->hwndSelf, NULL, 0, RDW_ALLCHILDREN | RDW_ERASENOW, 0 );
2558 else if( wndPtr->parent == WIN_GetDesktop() && wndPtr->parent->flags & WIN_NEEDS_ERASEBKGND )
2559 PAINT_RedrawWindow( wndPtr->parent->hwndSelf, NULL, 0, RDW_NOCHILDREN | RDW_ERASENOW, 0 );
2561 /* And last, send the WM_WINDOWPOSCHANGED message */
2563 TRACE(win,"\tstatus flags = %04x\n", winpos.flags & SWP_AGG_STATUSFLAGS);
2566 (((winpos.flags & SWP_AGG_STATUSFLAGS) != SWP_AGG_NOPOSCHANGE) &&
2567 !(winpos.flags & SWP_NOSENDCHANGING)) )
2569 SendMessage32A( winpos.hwnd, WM_WINDOWPOSCHANGED, 0, (LPARAM)&winpos );
2570 if (resync) EVENT_Synchronize ();
2577 /***********************************************************************
2578 * BeginDeferWindowPos16 (USER.259)
2580 HDWP16 WINAPI BeginDeferWindowPos16( INT16 count )
2582 return BeginDeferWindowPos32( count );
2586 /***********************************************************************
2587 * BeginDeferWindowPos32 (USER32.9)
2589 HDWP32 WINAPI BeginDeferWindowPos32( INT32 count )
2594 if (count <= 0) return 0;
2595 handle = USER_HEAP_ALLOC( sizeof(DWP) + (count-1)*sizeof(WINDOWPOS32) );
2596 if (!handle) return 0;
2597 pDWP = (DWP *) USER_HEAP_LIN_ADDR( handle );
2598 pDWP->actualCount = 0;
2599 pDWP->suggestedCount = count;
2601 pDWP->wMagic = DWP_MAGIC;
2602 pDWP->hwndParent = 0;
2607 /***********************************************************************
2608 * DeferWindowPos16 (USER.260)
2610 HDWP16 WINAPI DeferWindowPos16( HDWP16 hdwp, HWND16 hwnd, HWND16 hwndAfter,
2611 INT16 x, INT16 y, INT16 cx, INT16 cy,
2614 return DeferWindowPos32( hdwp, hwnd, (INT32)(INT16)hwndAfter,
2615 x, y, cx, cy, flags );
2619 /***********************************************************************
2620 * DeferWindowPos32 (USER32.128)
2622 HDWP32 WINAPI DeferWindowPos32( HDWP32 hdwp, HWND32 hwnd, HWND32 hwndAfter,
2623 INT32 x, INT32 y, INT32 cx, INT32 cy,
2628 HDWP32 newhdwp = hdwp;
2629 /* HWND32 parent; */
2632 pDWP = (DWP *) USER_HEAP_LIN_ADDR( hdwp );
2633 if (!pDWP) return 0;
2634 if (hwnd == GetDesktopWindow32()) return 0;
2636 if (!(pWnd=WIN_FindWndPtr( hwnd ))) {
2637 USER_HEAP_FREE( hdwp );
2641 /* Numega Bounds Checker Demo dislikes the following code.
2642 In fact, I've not been able to find any "same parent" requirement in any docu
2646 /* All the windows of a DeferWindowPos() must have the same parent */
2647 parent = pWnd->parent->hwndSelf;
2648 if (pDWP->actualCount == 0) pDWP->hwndParent = parent;
2649 else if (parent != pDWP->hwndParent)
2651 USER_HEAP_FREE( hdwp );
2656 for (i = 0; i < pDWP->actualCount; i++)
2658 if (pDWP->winPos[i].hwnd == hwnd)
2660 /* Merge with the other changes */
2661 if (!(flags & SWP_NOZORDER))
2663 pDWP->winPos[i].hwndInsertAfter = hwndAfter;
2665 if (!(flags & SWP_NOMOVE))
2667 pDWP->winPos[i].x = x;
2668 pDWP->winPos[i].y = y;
2670 if (!(flags & SWP_NOSIZE))
2672 pDWP->winPos[i].cx = cx;
2673 pDWP->winPos[i].cy = cy;
2675 pDWP->winPos[i].flags &= flags | ~(SWP_NOSIZE | SWP_NOMOVE |
2676 SWP_NOZORDER | SWP_NOREDRAW |
2677 SWP_NOACTIVATE | SWP_NOCOPYBITS|
2679 pDWP->winPos[i].flags |= flags & (SWP_SHOWWINDOW | SWP_HIDEWINDOW |
2684 if (pDWP->actualCount >= pDWP->suggestedCount)
2686 newhdwp = USER_HEAP_REALLOC( hdwp,
2687 sizeof(DWP) + pDWP->suggestedCount*sizeof(WINDOWPOS32) );
2688 if (!newhdwp) return 0;
2689 pDWP = (DWP *) USER_HEAP_LIN_ADDR( newhdwp );
2690 pDWP->suggestedCount++;
2692 pDWP->winPos[pDWP->actualCount].hwnd = hwnd;
2693 pDWP->winPos[pDWP->actualCount].hwndInsertAfter = hwndAfter;
2694 pDWP->winPos[pDWP->actualCount].x = x;
2695 pDWP->winPos[pDWP->actualCount].y = y;
2696 pDWP->winPos[pDWP->actualCount].cx = cx;
2697 pDWP->winPos[pDWP->actualCount].cy = cy;
2698 pDWP->winPos[pDWP->actualCount].flags = flags;
2699 pDWP->actualCount++;
2704 /***********************************************************************
2705 * EndDeferWindowPos16 (USER.261)
2707 BOOL16 WINAPI EndDeferWindowPos16( HDWP16 hdwp )
2709 return EndDeferWindowPos32( hdwp );
2713 /***********************************************************************
2714 * EndDeferWindowPos32 (USER32.173)
2716 BOOL32 WINAPI EndDeferWindowPos32( HDWP32 hdwp )
2719 WINDOWPOS32 *winpos;
2723 pDWP = (DWP *) USER_HEAP_LIN_ADDR( hdwp );
2724 if (!pDWP) return FALSE;
2725 for (i = 0, winpos = pDWP->winPos; i < pDWP->actualCount; i++, winpos++)
2727 if (!(res = SetWindowPos32( winpos->hwnd, winpos->hwndInsertAfter,
2728 winpos->x, winpos->y, winpos->cx,
2729 winpos->cy, winpos->flags ))) break;
2731 USER_HEAP_FREE( hdwp );
2736 /***********************************************************************
2737 * TileChildWindows (USER.199)
2739 void WINAPI TileChildWindows( HWND16 parent, WORD action )
2741 FIXME(win, "(%04x, %d): stub\n", parent, action);
2744 /***********************************************************************
2745 * CascageChildWindows (USER.198)
2747 void WINAPI CascadeChildWindows( HWND16 parent, WORD action )
2749 FIXME(win, "(%04x, %d): stub\n", parent, action);
2751 /***********************************************************************
2752 * GetProgmanWindow [USER32.289]
2754 HRESULT WINAPI GetProgmanWindow ( )
2755 { FIXME(win,"stub\n");
2758 /***********************************************************************
2759 * GetTaskmanWindow [USER32.304]
2761 HRESULT WINAPI GetTaskmanWindow ( )
2762 { FIXME(win,"stub\n");
2765 /***********************************************************************
2766 * SetProgmanWindow [USER32.522]
2768 HRESULT WINAPI SetProgmanWindow ( DWORD x )
2769 { FIXME(win,"0x%08lx stub\n",x);
2772 /***********************************************************************
2773 * SetShellWindowEx [USER32.531]
2775 HRESULT WINAPI SetShellWindowEx ( DWORD x, DWORD y )
2776 { FIXME(win,"0x%08lx 0x%08lx stub\n",x,y);
2779 /***********************************************************************
2780 * SetTaskmanWindow [USER32.537]
2782 HRESULT WINAPI SetTaskmanWindow ( DWORD x )
2783 { FIXME(win,"0x%08lx stub\n",x);