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 HWND hwndPrevActive = 0; /* Previously active window */
57 static HWND hGlobalShellWindow=0; /*the shell*/
59 static LPCSTR atomInternalPos;
61 extern HQUEUE16 hActiveQueue;
63 /***********************************************************************
64 * WINPOS_CreateInternalPosAtom
66 BOOL WINPOS_CreateInternalPosAtom()
69 atomInternalPos = (LPCSTR)(DWORD)GlobalAddAtomA(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 HWND hwnd = wndPtr->hwndSelf;
84 lpPos = (LPINTERNALPOS) GetPropA( 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( IsWindow(lpPos->hwndIconTitle) )
105 DestroyWindow( 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 ArrangeIconicWindows(parent);
169 /***********************************************************************
170 * ArrangeIconicWindows32 (USER32.7)
172 UINT WINAPI ArrangeIconicWindows( HWND parent )
176 INT x, y, xspacing, yspacing;
178 GetClientRect( parent, &rectParent );
180 y = rectParent.bottom;
181 xspacing = SYSMETRICS_CXICONSPACING;
182 yspacing = SYSMETRICS_CYICONSPACING;
184 hwndChild = GetWindow( parent, GW_CHILD );
187 if( IsIconic( hwndChild ) )
189 WINPOS_ShowIconTitle( WIN_FindWndPtr(hwndChild), FALSE );
190 SetWindowPos( hwndChild, 0, x + (xspacing - SYSMETRICS_CXICON) / 2,
191 y - yspacing - SYSMETRICS_CYICON/2, 0, 0,
192 SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE );
193 if( IsWindow(hwndChild) )
194 WINPOS_ShowIconTitle( WIN_FindWndPtr(hwndChild), TRUE );
195 if (x <= rectParent.right - xspacing) x += xspacing;
202 hwndChild = GetWindow( hwndChild, GW_HWNDNEXT );
208 /***********************************************************************
209 * SwitchToThisWindow16 (USER.172)
211 void WINAPI SwitchToThisWindow16( HWND16 hwnd, BOOL16 restore )
213 SwitchToThisWindow( hwnd, restore );
217 /***********************************************************************
218 * SwitchToThisWindow32 (USER32.539)
220 void WINAPI SwitchToThisWindow( HWND hwnd, BOOL restore )
222 ShowWindow( 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 BOOL WINAPI GetWindowRect( HWND hwnd, LPRECT rect )
245 WND * wndPtr = WIN_FindWndPtr( hwnd );
246 if (!wndPtr) return FALSE;
248 *rect = wndPtr->rectWindow;
249 if (wndPtr->dwStyle & WS_CHILD)
250 MapWindowPoints( wndPtr->parent->hwndSelf, 0, (POINT *)rect, 2 );
255 /***********************************************************************
258 BOOL WINAPI GetWindowRgn ( HWND hwnd, HRGN 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 GetWindowRect ( hwnd, &rect );
271 FIXME (win, "Check whether a valid region here\n");
273 SetRectRgn ( hrgn, rect.left, rect.top, rect.right, rect.bottom );
275 return (SIMPLEREGION);
278 /***********************************************************************
281 INT WINAPI SetWindowRgn( HWND hwnd, HRGN hrgn,BOOL 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 BOOL WINAPI GetClientRect( HWND hwnd, LPRECT rect )
322 WND * wndPtr = WIN_FindWndPtr( hwnd );
324 rect->left = rect->top = rect->right = rect->bottom = 0;
325 if (!wndPtr) return FALSE;
326 rect->right = wndPtr->rectClient.right - wndPtr->rectClient.left;
327 rect->bottom = wndPtr->rectClient.bottom - wndPtr->rectClient.top;
332 /*******************************************************************
333 * ClientToScreen16 (USER.28)
335 void WINAPI ClientToScreen16( HWND16 hwnd, LPPOINT16 lppnt )
337 MapWindowPoints16( hwnd, 0, lppnt, 1 );
341 /*******************************************************************
342 * ClientToScreen32 (USER32.52)
344 BOOL WINAPI ClientToScreen( HWND hwnd, LPPOINT lppnt )
346 MapWindowPoints( hwnd, 0, lppnt, 1 );
351 /*******************************************************************
352 * ScreenToClient16 (USER.29)
354 void WINAPI ScreenToClient16( HWND16 hwnd, LPPOINT16 lppnt )
356 MapWindowPoints16( 0, hwnd, lppnt, 1 );
360 /*******************************************************************
361 * ScreenToClient32 (USER32.447)
363 BOOL WINAPI ScreenToClient( HWND hwnd, LPPOINT lppnt )
365 MapWindowPoints( 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 == GetFastQueue16())
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 HWND WINAPI WindowFromPoint( POINT pt )
472 CONV_POINT32TO16( &pt, &pt16 );
473 WINPOS_WindowFromPoint( WIN_GetDesktop(), pt16, &pWnd );
474 return (HWND)pWnd->hwndSelf;
478 /*******************************************************************
479 * ChildWindowFromPoint16 (USER.191)
481 HWND16 WINAPI ChildWindowFromPoint16( HWND16 hwndParent, POINT16 pt )
484 CONV_POINT16TO32( &pt, &pt32 );
485 return (HWND16)ChildWindowFromPoint( hwndParent, pt32 );
489 /*******************************************************************
490 * ChildWindowFromPoint32 (USER32.49)
492 HWND WINAPI ChildWindowFromPoint( HWND hwndParent, POINT 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 (!PtInRect( &rect, pt )) return 0;
511 if (PtInRect( &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)ChildWindowFromPointEx( hwndParent, pt32, uFlags );
528 /*******************************************************************
529 * ChildWindowFromPointEx32 (USER32.50)
531 HWND WINAPI ChildWindowFromPointEx( HWND hwndParent, POINT 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 (!PtInRect( &rect, pt )) return 0;
551 if (PtInRect( &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( HWND hwndFrom, HWND 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 INT WINAPI MapWindowPoints( HWND hwndFrom, HWND hwndTo,
639 LPPOINT lppt, UINT count )
643 WINPOS_GetWinOffset( hwndFrom, hwndTo, &offset );
650 return MAKELONG( LOWORD(offset.x), LOWORD(offset.y) );
654 /***********************************************************************
655 * IsIconic16 (USER.31)
657 BOOL16 WINAPI IsIconic16(HWND16 hWnd)
659 return IsIconic(hWnd);
663 /***********************************************************************
664 * IsIconic32 (USER32.345)
666 BOOL WINAPI IsIconic(HWND hWnd)
668 WND * wndPtr = WIN_FindWndPtr(hWnd);
669 if (wndPtr == NULL) return FALSE;
670 return (wndPtr->dwStyle & WS_MINIMIZE) != 0;
674 /***********************************************************************
675 * IsZoomed (USER.272)
677 BOOL16 WINAPI IsZoomed16(HWND16 hWnd)
679 return IsZoomed(hWnd);
683 /***********************************************************************
684 * IsZoomed (USER32.352)
686 BOOL WINAPI IsZoomed(HWND hWnd)
688 WND * wndPtr = WIN_FindWndPtr(hWnd);
689 if (wndPtr == NULL) return FALSE;
690 return (wndPtr->dwStyle & WS_MAXIMIZE) != 0;
694 /*******************************************************************
695 * GetActiveWindow (USER.60)
697 HWND16 WINAPI GetActiveWindow16(void)
699 return (HWND16)GetActiveWindow();
702 /*******************************************************************
703 * GetActiveWindow (USER32.205)
705 HWND WINAPI GetActiveWindow(void)
707 MESSAGEQUEUE *pCurMsgQ = 0;
710 /* Get the messageQ for the current thread */
711 if (!(pCurMsgQ = (MESSAGEQUEUE *)QUEUE_Lock( GetFastQueue16() )))
713 WARN( win, "\tCurrent message queue not found. Exiting!\n" );
717 /* Return the current active window from the perQ data of the current message Q */
718 hwndActive = PERQDATA_GetActiveWnd( pCurMsgQ->pQData );
720 QUEUE_Unlock( pCurMsgQ );
725 /*******************************************************************
728 static BOOL WINPOS_CanActivate(WND* pWnd)
730 if( pWnd && ((pWnd->dwStyle & (WS_DISABLED | WS_VISIBLE | WS_CHILD))
731 == WS_VISIBLE) ) return TRUE;
736 /*******************************************************************
737 * SetActiveWindow16 (USER.59)
739 HWND16 WINAPI SetActiveWindow16( HWND16 hwnd )
741 return SetActiveWindow(hwnd);
745 /*******************************************************************
746 * SetActiveWindow32 (USER32.463)
748 HWND WINAPI SetActiveWindow( HWND hwnd )
751 WND *wndPtr = WIN_FindWndPtr( hwnd );
752 MESSAGEQUEUE *pMsgQ = 0, *pCurMsgQ = 0;
754 if ( !WINPOS_CanActivate(wndPtr) ) return 0;
756 /* Get the messageQ for the current thread */
757 if (!(pCurMsgQ = (MESSAGEQUEUE *)QUEUE_Lock( GetFastQueue16() )))
759 WARN( win, "\tCurrent message queue not found. Exiting!\n" );
763 /* Retrieve the message queue associated with this window */
764 pMsgQ = (MESSAGEQUEUE *)QUEUE_Lock( wndPtr->hmemTaskQ );
767 WARN( win, "\tWindow message queue not found. Exiting!\n" );
771 /* Make sure that the window is associated with the calling threads
772 * message queue. It must share the same perQ data.
774 if ( pCurMsgQ->pQData != pMsgQ->pQData )
777 /* Save current active window */
778 prev = PERQDATA_GetActiveWnd( pMsgQ->pQData );
780 WINPOS_SetActiveWindow( hwnd, 0, 0 );
783 /* Unlock the queues before returning */
785 QUEUE_Unlock( pMsgQ );
787 QUEUE_Unlock( pCurMsgQ );
793 /*******************************************************************
794 * GetForegroundWindow16 (USER.608)
796 HWND16 WINAPI GetForegroundWindow16(void)
798 return (HWND16)GetForegroundWindow();
802 /*******************************************************************
803 * SetForegroundWindow16 (USER.609)
805 BOOL16 WINAPI SetForegroundWindow16( HWND16 hwnd )
807 return SetForegroundWindow( hwnd );
811 /*******************************************************************
812 * GetForegroundWindow32 (USER32.241)
814 HWND WINAPI GetForegroundWindow(void)
816 return GetActiveWindow();
820 /*******************************************************************
821 * SetForegroundWindow32 (USER32.482)
823 BOOL WINAPI SetForegroundWindow( HWND hwnd )
825 SetActiveWindow( hwnd );
830 /*******************************************************************
831 * GetShellWindow16 (USER.600)
833 HWND16 WINAPI GetShellWindow16(void)
835 return GetShellWindow();
838 /*******************************************************************
839 * SetShellWindow32 (USER32.504)
841 HWND WINAPI SetShellWindow(HWND hwndshell)
842 { WARN(win, "(hWnd=%08x) semi stub\n",hwndshell );
844 hGlobalShellWindow = hwndshell;
845 return hGlobalShellWindow;
849 /*******************************************************************
850 * GetShellWindow32 (USER32.287)
852 HWND WINAPI GetShellWindow(void)
853 { WARN(win, "(hWnd=%x) semi stub\n",hGlobalShellWindow );
855 return hGlobalShellWindow;
859 /***********************************************************************
860 * BringWindowToTop16 (USER.45)
862 BOOL16 WINAPI BringWindowToTop16( HWND16 hwnd )
864 return BringWindowToTop(hwnd);
868 /***********************************************************************
869 * BringWindowToTop32 (USER32.11)
871 BOOL WINAPI BringWindowToTop( HWND hwnd )
873 return SetWindowPos( hwnd, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE );
877 /***********************************************************************
878 * MoveWindow16 (USER.56)
880 BOOL16 WINAPI MoveWindow16( HWND16 hwnd, INT16 x, INT16 y, INT16 cx, INT16 cy,
883 return MoveWindow(hwnd,x,y,cx,cy,repaint);
887 /***********************************************************************
888 * MoveWindow32 (USER32.399)
890 BOOL WINAPI MoveWindow( HWND hwnd, INT x, INT y, INT cx, INT cy,
893 int flags = SWP_NOZORDER | SWP_NOACTIVATE;
894 if (!repaint) flags |= SWP_NOREDRAW;
895 TRACE(win, "%04x %d,%d %dx%d %d\n",
896 hwnd, x, y, cx, cy, repaint );
897 return SetWindowPos( hwnd, 0, x, y, cx, cy, flags );
900 /***********************************************************************
901 * WINPOS_InitInternalPos
903 static LPINTERNALPOS WINPOS_InitInternalPos( WND* wnd, POINT pt,
906 LPINTERNALPOS lpPos = (LPINTERNALPOS) GetPropA( wnd->hwndSelf,
910 /* this happens when the window is minimized/maximized
911 * for the first time (rectWindow is not adjusted yet) */
913 lpPos = HeapAlloc( SystemHeap, 0, sizeof(INTERNALPOS) );
914 if( !lpPos ) return NULL;
916 SetPropA( wnd->hwndSelf, atomInternalPos, (HANDLE)lpPos );
917 lpPos->hwndIconTitle = 0; /* defer until needs to be shown */
918 CONV_RECT32TO16( &wnd->rectWindow, &lpPos->rectNormal );
919 *(UINT*)&lpPos->ptIconPos = *(UINT*)&lpPos->ptMaxPos = 0xFFFFFFFF;
922 if( wnd->dwStyle & WS_MINIMIZE )
923 CONV_POINT32TO16( &pt, &lpPos->ptIconPos );
924 else if( wnd->dwStyle & WS_MAXIMIZE )
925 CONV_POINT32TO16( &pt, &lpPos->ptMaxPos );
926 else if( restoreRect )
927 CONV_RECT32TO16( restoreRect, &lpPos->rectNormal );
932 /***********************************************************************
933 * WINPOS_RedrawIconTitle
935 BOOL WINPOS_RedrawIconTitle( HWND hWnd )
937 LPINTERNALPOS lpPos = (LPINTERNALPOS)GetPropA( hWnd, atomInternalPos );
940 if( lpPos->hwndIconTitle )
942 SendMessageA( lpPos->hwndIconTitle, WM_SHOWWINDOW, TRUE, 0);
943 InvalidateRect( lpPos->hwndIconTitle, NULL, TRUE );
950 /***********************************************************************
951 * WINPOS_ShowIconTitle
953 BOOL WINPOS_ShowIconTitle( WND* pWnd, BOOL bShow )
955 LPINTERNALPOS lpPos = (LPINTERNALPOS)GetPropA( pWnd->hwndSelf, atomInternalPos );
957 if( lpPos && !(pWnd->flags & WIN_MANAGED))
959 HWND16 hWnd = lpPos->hwndIconTitle;
961 TRACE(win,"0x%04x %i\n", pWnd->hwndSelf, (bShow != 0) );
964 lpPos->hwndIconTitle = hWnd = ICONTITLE_Create( pWnd );
967 pWnd = WIN_FindWndPtr(hWnd);
969 if( !(pWnd->dwStyle & WS_VISIBLE) )
971 SendMessageA( hWnd, WM_SHOWWINDOW, TRUE, 0 );
972 SetWindowPos( hWnd, 0, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE |
973 SWP_NOACTIVATE | SWP_NOZORDER | SWP_SHOWWINDOW );
976 else ShowWindow( hWnd, SW_HIDE );
981 /*******************************************************************
982 * WINPOS_GetMinMaxInfo
984 * Get the minimized and maximized information for a window.
986 void WINPOS_GetMinMaxInfo( WND *wndPtr, POINT *maxSize, POINT *maxPos,
987 POINT *minTrack, POINT *maxTrack )
993 /* Compute default values */
995 MinMax.ptMaxSize.x = SYSMETRICS_CXSCREEN;
996 MinMax.ptMaxSize.y = SYSMETRICS_CYSCREEN;
997 MinMax.ptMinTrackSize.x = SYSMETRICS_CXMINTRACK;
998 MinMax.ptMinTrackSize.y = SYSMETRICS_CYMINTRACK;
999 MinMax.ptMaxTrackSize.x = SYSMETRICS_CXSCREEN;
1000 MinMax.ptMaxTrackSize.y = SYSMETRICS_CYSCREEN;
1002 if (wndPtr->flags & WIN_MANAGED) xinc = yinc = 0;
1003 else if (HAS_DLGFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
1005 xinc = SYSMETRICS_CXDLGFRAME;
1006 yinc = SYSMETRICS_CYDLGFRAME;
1011 if (HAS_THICKFRAME(wndPtr->dwStyle))
1013 xinc += SYSMETRICS_CXFRAME;
1014 yinc += SYSMETRICS_CYFRAME;
1016 if (wndPtr->dwStyle & WS_BORDER)
1018 xinc += SYSMETRICS_CXBORDER;
1019 yinc += SYSMETRICS_CYBORDER;
1022 MinMax.ptMaxSize.x += 2 * xinc;
1023 MinMax.ptMaxSize.y += 2 * yinc;
1025 lpPos = (LPINTERNALPOS)GetPropA( wndPtr->hwndSelf, atomInternalPos );
1026 if( lpPos && !EMPTYPOINT(lpPos->ptMaxPos) )
1027 CONV_POINT16TO32( &lpPos->ptMaxPos, &MinMax.ptMaxPosition );
1030 MinMax.ptMaxPosition.x = -xinc;
1031 MinMax.ptMaxPosition.y = -yinc;
1034 SendMessageA( wndPtr->hwndSelf, WM_GETMINMAXINFO, 0, (LPARAM)&MinMax );
1036 /* Some sanity checks */
1038 TRACE(win,"%ld %ld / %ld %ld / %ld %ld / %ld %ld\n",
1039 MinMax.ptMaxSize.x, MinMax.ptMaxSize.y,
1040 MinMax.ptMaxPosition.x, MinMax.ptMaxPosition.y,
1041 MinMax.ptMaxTrackSize.x, MinMax.ptMaxTrackSize.y,
1042 MinMax.ptMinTrackSize.x, MinMax.ptMinTrackSize.y);
1043 MinMax.ptMaxTrackSize.x = MAX( MinMax.ptMaxTrackSize.x,
1044 MinMax.ptMinTrackSize.x );
1045 MinMax.ptMaxTrackSize.y = MAX( MinMax.ptMaxTrackSize.y,
1046 MinMax.ptMinTrackSize.y );
1048 if (maxSize) *maxSize = MinMax.ptMaxSize;
1049 if (maxPos) *maxPos = MinMax.ptMaxPosition;
1050 if (minTrack) *minTrack = MinMax.ptMinTrackSize;
1051 if (maxTrack) *maxTrack = MinMax.ptMaxTrackSize;
1054 /***********************************************************************
1055 * WINPOS_MinMaximize
1057 * Fill in lpRect and return additional flags to be used with SetWindowPos().
1058 * This function assumes that 'cmd' is different from the current window
1061 UINT16 WINPOS_MinMaximize( WND* wndPtr, UINT16 cmd, LPRECT16 lpRect )
1063 UINT16 swpFlags = 0;
1065 POINT size = { wndPtr->rectWindow.left, wndPtr->rectWindow.top };
1066 LPINTERNALPOS lpPos = WINPOS_InitInternalPos( wndPtr, size,
1067 &wndPtr->rectWindow );
1069 TRACE(win,"0x%04x %u\n", wndPtr->hwndSelf, cmd );
1071 if (lpPos && !HOOK_CallHooks16(WH_CBT, HCBT_MINMAX, wndPtr->hwndSelf, cmd))
1073 if( wndPtr->dwStyle & WS_MINIMIZE )
1075 if( !SendMessageA( wndPtr->hwndSelf, WM_QUERYOPEN, 0, 0L ) )
1076 return (SWP_NOSIZE | SWP_NOMOVE);
1077 swpFlags |= SWP_NOCOPYBITS;
1082 if( wndPtr->dwStyle & WS_MAXIMIZE)
1084 wndPtr->flags |= WIN_RESTORE_MAX;
1085 wndPtr->dwStyle &= ~WS_MAXIMIZE;
1088 wndPtr->flags &= ~WIN_RESTORE_MAX;
1089 wndPtr->dwStyle |= WS_MINIMIZE;
1091 lpPos->ptIconPos = WINPOS_FindIconPos( wndPtr, lpPos->ptIconPos );
1093 SetRect16( lpRect, lpPos->ptIconPos.x, lpPos->ptIconPos.y,
1094 SYSMETRICS_CXICON, SYSMETRICS_CYICON );
1095 swpFlags |= SWP_NOCOPYBITS;
1099 CONV_POINT16TO32( &lpPos->ptMaxPos, &pt );
1100 WINPOS_GetMinMaxInfo( wndPtr, &size, &pt, NULL, NULL );
1101 CONV_POINT32TO16( &pt, &lpPos->ptMaxPos );
1103 if( wndPtr->dwStyle & WS_MINIMIZE )
1105 WINPOS_ShowIconTitle( wndPtr, FALSE );
1106 wndPtr->dwStyle &= ~WS_MINIMIZE;
1108 wndPtr->dwStyle |= WS_MAXIMIZE;
1110 SetRect16( lpRect, lpPos->ptMaxPos.x, lpPos->ptMaxPos.y,
1115 if( wndPtr->dwStyle & WS_MINIMIZE )
1117 wndPtr->dwStyle &= ~WS_MINIMIZE;
1118 WINPOS_ShowIconTitle( wndPtr, FALSE );
1119 if( wndPtr->flags & WIN_RESTORE_MAX)
1121 /* Restore to maximized position */
1122 CONV_POINT16TO32( &lpPos->ptMaxPos, &pt );
1123 WINPOS_GetMinMaxInfo( wndPtr, &size, &pt, NULL, NULL);
1124 CONV_POINT32TO16( &pt, &lpPos->ptMaxPos );
1125 wndPtr->dwStyle |= WS_MAXIMIZE;
1126 SetRect16( lpRect, lpPos->ptMaxPos.x, lpPos->ptMaxPos.y, size.x, size.y );
1131 if( !(wndPtr->dwStyle & WS_MAXIMIZE) ) return (UINT16)(-1);
1132 else wndPtr->dwStyle &= ~WS_MAXIMIZE;
1134 /* Restore to normal position */
1136 *lpRect = lpPos->rectNormal;
1137 lpRect->right -= lpRect->left;
1138 lpRect->bottom -= lpRect->top;
1142 } else swpFlags |= SWP_NOSIZE | SWP_NOMOVE;
1146 /***********************************************************************
1147 * ShowWindowAsync32 (USER32.535)
1149 * doesn't wait; returns immediately.
1150 * used by threads to toggle windows in other (possibly hanging) threads
1152 BOOL WINAPI ShowWindowAsync( HWND hwnd, INT cmd )
1154 /* FIXME: does ShowWindow32() return immediately ? */
1155 return ShowWindow(hwnd, cmd);
1159 /***********************************************************************
1160 * ShowWindow16 (USER.42)
1162 BOOL16 WINAPI ShowWindow16( HWND16 hwnd, INT16 cmd )
1164 return ShowWindow(hwnd,cmd);
1168 /***********************************************************************
1169 * ShowWindow32 (USER32.534)
1171 BOOL WINAPI ShowWindow( HWND hwnd, INT cmd )
1173 WND* wndPtr = WIN_FindWndPtr( hwnd );
1174 BOOL wasVisible, showFlag;
1175 RECT16 newPos = {0, 0, 0, 0};
1178 if (!wndPtr) return FALSE;
1180 TRACE(win,"hwnd=%04x, cmd=%d\n", hwnd, cmd);
1182 wasVisible = (wndPtr->dwStyle & WS_VISIBLE) != 0;
1187 if (!wasVisible) return FALSE;
1188 swp |= SWP_HIDEWINDOW | SWP_NOSIZE | SWP_NOMOVE |
1189 SWP_NOACTIVATE | SWP_NOZORDER;
1190 if ((hwnd == GetFocus()) || IsChild( hwnd, GetFocus()))
1192 /* Revert focus to parent */
1193 SetFocus( GetParent(hwnd) );
1197 case SW_SHOWMINNOACTIVE:
1198 swp |= SWP_NOACTIVATE | SWP_NOZORDER;
1200 case SW_SHOWMINIMIZED:
1201 swp |= SWP_SHOWWINDOW;
1204 swp |= SWP_FRAMECHANGED;
1205 if( !(wndPtr->dwStyle & WS_MINIMIZE) )
1206 swp |= WINPOS_MinMaximize( wndPtr, SW_MINIMIZE, &newPos );
1207 else swp |= SWP_NOSIZE | SWP_NOMOVE;
1210 case SW_SHOWMAXIMIZED: /* same as SW_MAXIMIZE */
1211 swp |= SWP_SHOWWINDOW | SWP_FRAMECHANGED;
1212 if( !(wndPtr->dwStyle & WS_MAXIMIZE) )
1213 swp |= WINPOS_MinMaximize( wndPtr, SW_MAXIMIZE, &newPos );
1214 else swp |= SWP_NOSIZE | SWP_NOMOVE;
1218 swp |= SWP_NOACTIVATE | SWP_NOZORDER;
1221 swp |= SWP_SHOWWINDOW | SWP_NOSIZE | SWP_NOMOVE;
1224 case SW_SHOWNOACTIVATE:
1225 swp |= SWP_NOZORDER;
1226 if (GetActiveWindow()) swp |= SWP_NOACTIVATE;
1228 case SW_SHOWNORMAL: /* same as SW_NORMAL: */
1229 case SW_SHOWDEFAULT: /* FIXME: should have its own handler */
1231 swp |= SWP_SHOWWINDOW | SWP_FRAMECHANGED;
1233 if( wndPtr->dwStyle & (WS_MINIMIZE | WS_MAXIMIZE) )
1234 swp |= WINPOS_MinMaximize( wndPtr, SW_RESTORE, &newPos );
1235 else swp |= SWP_NOSIZE | SWP_NOMOVE;
1239 showFlag = (cmd != SW_HIDE);
1240 if (showFlag != wasVisible)
1242 SendMessageA( hwnd, WM_SHOWWINDOW, showFlag, 0 );
1243 if (!IsWindow( hwnd )) return wasVisible;
1246 if ((wndPtr->dwStyle & WS_CHILD) &&
1247 !IsWindowVisible( wndPtr->parent->hwndSelf ) &&
1248 (swp & (SWP_NOSIZE | SWP_NOMOVE)) == (SWP_NOSIZE | SWP_NOMOVE) )
1250 /* Don't call SetWindowPos32() on invisible child windows */
1251 if (cmd == SW_HIDE) wndPtr->dwStyle &= ~WS_VISIBLE;
1252 else wndPtr->dwStyle |= WS_VISIBLE;
1256 /* We can't activate a child window */
1257 if (wndPtr->dwStyle & WS_CHILD) swp |= SWP_NOACTIVATE | SWP_NOZORDER;
1258 SetWindowPos( hwnd, HWND_TOP,
1259 newPos.left, newPos.top, newPos.right, newPos.bottom, swp );
1260 if (!IsWindow( hwnd )) return wasVisible;
1261 else if( wndPtr->dwStyle & WS_MINIMIZE ) WINPOS_ShowIconTitle( wndPtr, TRUE );
1264 if (wndPtr->flags & WIN_NEED_SIZE)
1266 /* should happen only in CreateWindowEx() */
1267 int wParam = SIZE_RESTORED;
1269 wndPtr->flags &= ~WIN_NEED_SIZE;
1270 if (wndPtr->dwStyle & WS_MAXIMIZE) wParam = SIZE_MAXIMIZED;
1271 else if (wndPtr->dwStyle & WS_MINIMIZE) wParam = SIZE_MINIMIZED;
1272 SendMessageA( hwnd, WM_SIZE, wParam,
1273 MAKELONG(wndPtr->rectClient.right-wndPtr->rectClient.left,
1274 wndPtr->rectClient.bottom-wndPtr->rectClient.top));
1275 SendMessageA( hwnd, WM_MOVE, 0,
1276 MAKELONG(wndPtr->rectClient.left, wndPtr->rectClient.top) );
1283 /***********************************************************************
1284 * GetInternalWindowPos16 (USER.460)
1286 UINT16 WINAPI GetInternalWindowPos16( HWND16 hwnd, LPRECT16 rectWnd,
1289 WINDOWPLACEMENT16 wndpl;
1290 if (GetWindowPlacement16( hwnd, &wndpl ))
1292 if (rectWnd) *rectWnd = wndpl.rcNormalPosition;
1293 if (ptIcon) *ptIcon = wndpl.ptMinPosition;
1294 return wndpl.showCmd;
1300 /***********************************************************************
1301 * GetInternalWindowPos32 (USER32.245)
1303 UINT WINAPI GetInternalWindowPos( HWND hwnd, LPRECT rectWnd,
1306 WINDOWPLACEMENT wndpl;
1307 if (GetWindowPlacement( hwnd, &wndpl ))
1309 if (rectWnd) *rectWnd = wndpl.rcNormalPosition;
1310 if (ptIcon) *ptIcon = wndpl.ptMinPosition;
1311 return wndpl.showCmd;
1316 /***********************************************************************
1317 * GetWindowPlacement16 (USER.370)
1319 BOOL16 WINAPI GetWindowPlacement16( HWND16 hwnd, WINDOWPLACEMENT16 *wndpl )
1321 WND *pWnd = WIN_FindWndPtr( hwnd );
1324 LPINTERNALPOS lpPos = (LPINTERNALPOS)WINPOS_InitInternalPos( pWnd,
1325 *(LPPOINT)&pWnd->rectWindow.left, &pWnd->rectWindow );
1326 wndpl->length = sizeof(*wndpl);
1327 if( pWnd->dwStyle & WS_MINIMIZE )
1328 wndpl->showCmd = SW_SHOWMINIMIZED;
1330 wndpl->showCmd = ( pWnd->dwStyle & WS_MAXIMIZE )
1331 ? SW_SHOWMAXIMIZED : SW_SHOWNORMAL ;
1332 if( pWnd->flags & WIN_RESTORE_MAX )
1333 wndpl->flags = WPF_RESTORETOMAXIMIZED;
1336 wndpl->ptMinPosition = lpPos->ptIconPos;
1337 wndpl->ptMaxPosition = lpPos->ptMaxPos;
1338 wndpl->rcNormalPosition = lpPos->rectNormal;
1345 /***********************************************************************
1346 * GetWindowPlacement32 (USER32.307)
1349 * Fails if wndpl->length of Win95 (!) apps is invalid.
1351 BOOL WINAPI GetWindowPlacement( HWND hwnd, WINDOWPLACEMENT *pwpl32 )
1355 WINDOWPLACEMENT16 wpl;
1356 wpl.length = sizeof(wpl);
1357 if( GetWindowPlacement16( hwnd, &wpl ) )
1359 pwpl32->length = sizeof(*pwpl32);
1360 pwpl32->flags = wpl.flags;
1361 pwpl32->showCmd = wpl.showCmd;
1362 CONV_POINT16TO32( &wpl.ptMinPosition, &pwpl32->ptMinPosition );
1363 CONV_POINT16TO32( &wpl.ptMaxPosition, &pwpl32->ptMaxPosition );
1364 CONV_RECT16TO32( &wpl.rcNormalPosition, &pwpl32->rcNormalPosition );
1372 /***********************************************************************
1373 * WINPOS_SetPlacement
1375 static BOOL WINPOS_SetPlacement( HWND hwnd, const WINDOWPLACEMENT16 *wndpl,
1378 WND *pWnd = WIN_FindWndPtr( hwnd );
1381 LPINTERNALPOS lpPos = (LPINTERNALPOS)WINPOS_InitInternalPos( pWnd,
1382 *(LPPOINT)&pWnd->rectWindow.left, &pWnd->rectWindow );
1384 if( flags & PLACE_MIN ) lpPos->ptIconPos = wndpl->ptMinPosition;
1385 if( flags & PLACE_MAX ) lpPos->ptMaxPos = wndpl->ptMaxPosition;
1386 if( flags & PLACE_RECT) lpPos->rectNormal = wndpl->rcNormalPosition;
1388 if( pWnd->dwStyle & WS_MINIMIZE )
1390 WINPOS_ShowIconTitle( pWnd, FALSE );
1391 if( wndpl->flags & WPF_SETMINPOSITION && !EMPTYPOINT(lpPos->ptIconPos))
1392 SetWindowPos( hwnd, 0, lpPos->ptIconPos.x, lpPos->ptIconPos.y,
1393 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE );
1395 else if( pWnd->dwStyle & WS_MAXIMIZE )
1397 if( !EMPTYPOINT(lpPos->ptMaxPos) )
1398 SetWindowPos( hwnd, 0, lpPos->ptMaxPos.x, lpPos->ptMaxPos.y,
1399 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE );
1401 else if( flags & PLACE_RECT )
1402 SetWindowPos( hwnd, 0, lpPos->rectNormal.left, lpPos->rectNormal.top,
1403 lpPos->rectNormal.right - lpPos->rectNormal.left,
1404 lpPos->rectNormal.bottom - lpPos->rectNormal.top,
1405 SWP_NOZORDER | SWP_NOACTIVATE );
1407 ShowWindow( hwnd, wndpl->showCmd );
1408 if( IsWindow(hwnd) && pWnd->dwStyle & WS_MINIMIZE )
1410 if( pWnd->dwStyle & WS_VISIBLE ) WINPOS_ShowIconTitle( pWnd, TRUE );
1412 /* SDK: ...valid only the next time... */
1413 if( wndpl->flags & WPF_RESTORETOMAXIMIZED ) pWnd->flags |= WIN_RESTORE_MAX;
1421 /***********************************************************************
1422 * SetWindowPlacement16 (USER.371)
1424 BOOL16 WINAPI SetWindowPlacement16(HWND16 hwnd, const WINDOWPLACEMENT16 *wndpl)
1426 return WINPOS_SetPlacement( hwnd, wndpl,
1427 PLACE_MIN | PLACE_MAX | PLACE_RECT );
1430 /***********************************************************************
1431 * SetWindowPlacement32 (USER32.519)
1434 * Fails if wndpl->length of Win95 (!) apps is invalid.
1436 BOOL WINAPI SetWindowPlacement( HWND hwnd, const WINDOWPLACEMENT *pwpl32 )
1440 WINDOWPLACEMENT16 wpl = { sizeof(WINDOWPLACEMENT16),
1441 pwpl32->flags, pwpl32->showCmd, { pwpl32->ptMinPosition.x,
1442 pwpl32->ptMinPosition.y }, { pwpl32->ptMaxPosition.x,
1443 pwpl32->ptMaxPosition.y }, { pwpl32->rcNormalPosition.left,
1444 pwpl32->rcNormalPosition.top, pwpl32->rcNormalPosition.right,
1445 pwpl32->rcNormalPosition.bottom } };
1447 return WINPOS_SetPlacement( hwnd, &wpl, PLACE_MIN | PLACE_MAX | PLACE_RECT );
1453 /***********************************************************************
1454 * SetInternalWindowPos16 (USER.461)
1456 void WINAPI SetInternalWindowPos16( HWND16 hwnd, UINT16 showCmd,
1457 LPRECT16 rect, LPPOINT16 pt )
1459 if( IsWindow16(hwnd) )
1461 WINDOWPLACEMENT16 wndpl;
1464 wndpl.length = sizeof(wndpl);
1465 wndpl.showCmd = showCmd;
1466 wndpl.flags = flags = 0;
1471 wndpl.flags |= WPF_SETMINPOSITION;
1472 wndpl.ptMinPosition = *pt;
1476 flags |= PLACE_RECT;
1477 wndpl.rcNormalPosition = *rect;
1479 WINPOS_SetPlacement( hwnd, &wndpl, flags );
1484 /***********************************************************************
1485 * SetInternalWindowPos32 (USER32.483)
1487 void WINAPI SetInternalWindowPos( HWND hwnd, UINT showCmd,
1488 LPRECT rect, LPPOINT pt )
1490 if( IsWindow(hwnd) )
1492 WINDOWPLACEMENT16 wndpl;
1495 wndpl.length = sizeof(wndpl);
1496 wndpl.showCmd = showCmd;
1497 wndpl.flags = flags = 0;
1502 wndpl.flags |= WPF_SETMINPOSITION;
1503 CONV_POINT32TO16( pt, &wndpl.ptMinPosition );
1507 flags |= PLACE_RECT;
1508 CONV_RECT32TO16( rect, &wndpl.rcNormalPosition );
1510 WINPOS_SetPlacement( hwnd, &wndpl, flags );
1514 /*******************************************************************
1515 * WINPOS_SetActiveWindow
1517 * SetActiveWindow() back-end. This is the only function that
1518 * can assign active status to a window. It must be called only
1519 * for the top level windows.
1521 BOOL WINPOS_SetActiveWindow( HWND hWnd, BOOL fMouse, BOOL fChangeFocus)
1523 CBTACTIVATESTRUCT16* cbtStruct;
1524 WND* wndPtr, *wndTemp;
1525 HQUEUE16 hOldActiveQueue, hNewActiveQueue;
1526 MESSAGEQUEUE *pOldActiveQueue = 0, *pNewActiveQueue = 0;
1528 HWND hwndActive = 0;
1531 /* Get current active window from the active queue */
1534 pOldActiveQueue = QUEUE_Lock( hActiveQueue );
1535 if ( pOldActiveQueue )
1536 hwndActive = PERQDATA_GetActiveWnd( pOldActiveQueue->pQData );
1539 /* paranoid checks */
1540 if( hWnd == GetDesktopWindow() || hWnd == hwndActive ) goto CLEANUP;
1542 /* if (wndPtr && (GetFastQueue() != wndPtr->hmemTaskQ))
1545 wndPtr = WIN_FindWndPtr(hWnd);
1546 hOldActiveQueue = hActiveQueue;
1548 if( (wndTemp = WIN_FindWndPtr(hwndActive)) )
1549 wIconized = HIWORD(wndTemp->dwStyle & WS_MINIMIZE);
1551 TRACE(win,"no current active window.\n");
1553 /* call CBT hook chain */
1554 if ((cbtStruct = SEGPTR_NEW(CBTACTIVATESTRUCT16)))
1557 cbtStruct->fMouse = fMouse;
1558 cbtStruct->hWndActive = hwndActive;
1559 wRet = HOOK_CallHooks16( WH_CBT, HCBT_ACTIVATE, (WPARAM16)hWnd,
1560 (LPARAM)SEGPTR_GET(cbtStruct) );
1561 SEGPTR_FREE(cbtStruct);
1564 /* Unlock the active queue before returning */
1565 if ( pOldActiveQueue )
1566 QUEUE_Unlock( pOldActiveQueue );
1571 /* set prev active wnd to current active wnd and send notification */
1572 if ((hwndPrevActive = hwndActive) && IsWindow(hwndPrevActive))
1574 MESSAGEQUEUE *pTempActiveQueue = 0;
1576 if (!SendMessageA( hwndPrevActive, WM_NCACTIVATE, FALSE, 0 ))
1578 if (GetSysModalWindow16() != hWnd) goto CLEANUP;
1579 /* disregard refusal if hWnd is sysmodal */
1583 SendMessageA( hwndPrevActive, WM_ACTIVATE,
1584 MAKEWPARAM( WA_INACTIVE, wIconized ),
1587 /* FIXME: must be SendMessage16() because 32A doesn't do
1588 * intertask at this time */
1589 SendMessage16( hwndPrevActive, WM_ACTIVATE, WA_INACTIVE,
1590 MAKELPARAM( (HWND16)hWnd, wIconized ) );
1593 /* check if something happened during message processing
1594 * (global active queue may have changed)
1596 if (hActiveQueue==0)
1599 pTempActiveQueue = QUEUE_Lock( hActiveQueue );
1600 hwndActive = PERQDATA_GetActiveWnd( pTempActiveQueue->pQData );
1601 QUEUE_Unlock( pTempActiveQueue );
1602 if( hwndPrevActive != hwndActive )
1606 /* Set new active window in the message queue */
1610 pNewActiveQueue = QUEUE_Lock( wndPtr->hmemTaskQ );
1611 if ( pNewActiveQueue )
1612 PERQDATA_SetActiveWnd( pNewActiveQueue->pQData, hwndActive );
1615 /* send palette messages */
1616 if (hWnd && SendMessage16( hWnd, WM_QUERYNEWPALETTE, 0, 0L))
1617 SendMessage16((HWND16)-1, WM_PALETTEISCHANGING, (WPARAM16)hWnd, 0L );
1619 /* if prev wnd is minimized redraw icon title */
1620 if( IsIconic( hwndPrevActive ) ) WINPOS_RedrawIconTitle(hwndPrevActive);
1622 /* managed windows will get ConfigureNotify event */
1623 if (wndPtr && !(wndPtr->dwStyle & WS_CHILD) && !(wndPtr->flags & WIN_MANAGED))
1625 /* check Z-order and bring hWnd to the top */
1626 for (wndTemp = WIN_GetDesktop()->child; wndTemp; wndTemp = wndTemp->next)
1627 if (wndTemp->dwStyle & WS_VISIBLE) break;
1629 if( wndTemp != wndPtr )
1630 SetWindowPos(hWnd, HWND_TOP, 0,0,0,0,
1631 SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE );
1632 if (!IsWindow(hWnd)) goto CLEANUP;
1635 /* Get a handle to the new active queue */
1636 hNewActiveQueue = wndPtr ? wndPtr->hmemTaskQ : 0;
1638 /* send WM_ACTIVATEAPP if necessary */
1639 if (hOldActiveQueue != hNewActiveQueue)
1641 WND **list, **ppWnd;
1643 if ( (hNewActiveQueue!=0) &&
1644 (list = WIN_BuildWinArray( WIN_GetDesktop(), 0, NULL )))
1646 for (ppWnd = list; *ppWnd; ppWnd++)
1648 if (!IsWindow( (*ppWnd)->hwndSelf )) continue;
1650 if ((*ppWnd)->hmemTaskQ == hOldActiveQueue)
1651 SendMessage16( (*ppWnd)->hwndSelf, WM_ACTIVATEAPP,
1652 0, QUEUE_GetQueueTask(hNewActiveQueue) );
1654 HeapFree( SystemHeap, 0, list );
1657 hActiveQueue = hNewActiveQueue;
1659 if ( (hOldActiveQueue!=0) &&
1660 (list = WIN_BuildWinArray( WIN_GetDesktop(), 0, NULL )))
1662 for (ppWnd = list; *ppWnd; ppWnd++)
1664 if (!IsWindow( (*ppWnd)->hwndSelf )) continue;
1666 if ((*ppWnd)->hmemTaskQ == hNewActiveQueue)
1667 SendMessage16( (*ppWnd)->hwndSelf, WM_ACTIVATEAPP,
1668 1, QUEUE_GetQueueTask( hOldActiveQueue ) );
1670 HeapFree( SystemHeap, 0, list );
1673 if (!IsWindow(hWnd)) goto CLEANUP;
1678 /* walk up to the first unowned window */
1680 while (wndTemp->owner) wndTemp = wndTemp->owner;
1681 /* and set last active owned popup */
1682 wndTemp->hwndLastActive = hWnd;
1684 wIconized = HIWORD(wndTemp->dwStyle & WS_MINIMIZE);
1685 SendMessageA( hWnd, WM_NCACTIVATE, TRUE, 0 );
1687 SendMessageA( hWnd, WM_ACTIVATE,
1688 MAKEWPARAM( (fMouse) ? WA_CLICKACTIVE : WA_ACTIVE, wIconized),
1689 (LPARAM)hwndPrevActive );
1691 SendMessage16(hWnd, WM_ACTIVATE, (fMouse) ? WA_CLICKACTIVE : WA_ACTIVE,
1692 MAKELPARAM( (HWND16)hwndPrevActive, wIconized) );
1695 if( !IsWindow(hWnd) ) goto CLEANUP;
1698 /* change focus if possible */
1699 if( fChangeFocus && GetFocus() )
1700 if( WIN_GetTopParent(GetFocus()) != hwndActive )
1701 FOCUS_SwitchFocus( pNewActiveQueue, GetFocus(),
1702 (wndPtr && (wndPtr->dwStyle & WS_MINIMIZE))?
1707 if( !hwndPrevActive && wndPtr )
1708 (*wndPtr->pDriver->pForceWindowRaise)(wndPtr);
1710 /* if active wnd is minimized redraw icon title */
1711 if( IsIconic(hwndActive) ) WINPOS_RedrawIconTitle(hwndActive);
1713 bRet = 1; // Success
1717 /* Unlock the message queues before returning */
1718 if ( pOldActiveQueue )
1719 QUEUE_Unlock( pOldActiveQueue );
1720 if ( pNewActiveQueue )
1721 QUEUE_Unlock( pNewActiveQueue );
1722 return bRet ? (hWnd == hwndActive) : 0;
1725 /*******************************************************************
1726 * WINPOS_ActivateOtherWindow
1728 * Activates window other than pWnd.
1730 BOOL WINPOS_ActivateOtherWindow(WND* pWnd)
1734 HWND hwndActive = 0;
1736 /* Get current active window from the active queue */
1739 MESSAGEQUEUE *pActiveQueue = QUEUE_Lock( hActiveQueue );
1742 hwndActive = PERQDATA_GetActiveWnd( pActiveQueue->pQData );
1743 QUEUE_Unlock( pActiveQueue );
1747 if( pWnd->hwndSelf == hwndPrevActive )
1750 if( hwndActive != pWnd->hwndSelf &&
1751 ( hwndActive || QUEUE_IsExitingQueue(pWnd->hmemTaskQ)) )
1754 if( !(pWnd->dwStyle & WS_POPUP) || !(pWnd->owner) ||
1755 !WINPOS_CanActivate((pWndTo = WIN_GetTopParentPtr(pWnd->owner))) )
1757 WND* pWndPtr = WIN_GetTopParentPtr(pWnd);
1759 pWndTo = WIN_FindWndPtr(hwndPrevActive);
1761 while( !WINPOS_CanActivate(pWndTo) )
1763 /* by now owned windows should've been taken care of */
1765 pWndTo = pWndPtr->next;
1767 if( !pWndTo ) break;
1771 bRet = WINPOS_SetActiveWindow( pWndTo ? pWndTo->hwndSelf : 0, FALSE, TRUE );
1773 /* switch desktop queue to current active */
1774 if( pWndTo ) WIN_GetDesktop()->hmemTaskQ = pWndTo->hmemTaskQ;
1780 /*******************************************************************
1781 * WINPOS_ChangeActiveWindow
1784 BOOL WINPOS_ChangeActiveWindow( HWND hWnd, BOOL mouseMsg )
1786 WND *wndPtr = WIN_FindWndPtr(hWnd);
1787 HWND hwndActive = 0;
1789 /* Get current active window from the active queue */
1792 MESSAGEQUEUE *pActiveQueue = QUEUE_Lock( hActiveQueue );
1795 hwndActive = PERQDATA_GetActiveWnd( pActiveQueue->pQData );
1796 QUEUE_Unlock( pActiveQueue );
1800 if (!hWnd) return WINPOS_SetActiveWindow( 0, mouseMsg, TRUE );
1802 if( !wndPtr ) return FALSE;
1804 /* child windows get WM_CHILDACTIVATE message */
1805 if( (wndPtr->dwStyle & (WS_CHILD | WS_POPUP)) == WS_CHILD )
1806 return SendMessageA(hWnd, WM_CHILDACTIVATE, 0, 0L);
1808 /* owned popups imply owner activation - not sure */
1809 if ((wndPtr->dwStyle & WS_POPUP) && wndPtr->owner &&
1810 (wndPtr->owner->dwStyle & WS_VISIBLE ) &&
1811 !(wndPtr->owner->dwStyle & WS_DISABLED ))
1813 if (!(wndPtr = wndPtr->owner)) return FALSE;
1814 hWnd = wndPtr->hwndSelf;
1817 if( hWnd == hwndActive ) return FALSE;
1819 if( !WINPOS_SetActiveWindow(hWnd ,mouseMsg ,TRUE) )
1822 /* switch desktop queue to current active */
1823 if( wndPtr->parent == WIN_GetDesktop())
1824 WIN_GetDesktop()->hmemTaskQ = wndPtr->hmemTaskQ;
1830 /***********************************************************************
1831 * WINPOS_SendNCCalcSize
1833 * Send a WM_NCCALCSIZE message to a window.
1834 * All parameters are read-only except newClientRect.
1835 * oldWindowRect, oldClientRect and winpos must be non-NULL only
1836 * when calcValidRect is TRUE.
1838 LONG WINPOS_SendNCCalcSize( HWND hwnd, BOOL calcValidRect,
1839 RECT *newWindowRect, RECT *oldWindowRect,
1840 RECT *oldClientRect, WINDOWPOS *winpos,
1841 RECT *newClientRect )
1843 NCCALCSIZE_PARAMS params;
1844 WINDOWPOS winposCopy;
1847 params.rgrc[0] = *newWindowRect;
1850 winposCopy = *winpos;
1851 params.rgrc[1] = *oldWindowRect;
1852 params.rgrc[2] = *oldClientRect;
1853 params.lppos = &winposCopy;
1855 result = SendMessageA( hwnd, WM_NCCALCSIZE, calcValidRect,
1857 TRACE(win, "%d,%d-%d,%d\n",
1858 params.rgrc[0].left, params.rgrc[0].top,
1859 params.rgrc[0].right, params.rgrc[0].bottom );
1860 *newClientRect = params.rgrc[0];
1865 /***********************************************************************
1866 * WINPOS_HandleWindowPosChanging16
1868 * Default handling for a WM_WINDOWPOSCHANGING. Called from DefWindowProc().
1870 LONG WINPOS_HandleWindowPosChanging16( WND *wndPtr, WINDOWPOS16 *winpos )
1872 POINT maxSize, minTrack;
1873 if (winpos->flags & SWP_NOSIZE) return 0;
1874 if ((wndPtr->dwStyle & WS_THICKFRAME) ||
1875 ((wndPtr->dwStyle & (WS_POPUP | WS_CHILD)) == 0))
1877 WINPOS_GetMinMaxInfo( wndPtr, &maxSize, NULL, &minTrack, NULL );
1878 if (maxSize.x < winpos->cx) winpos->cx = maxSize.x;
1879 if (maxSize.y < winpos->cy) winpos->cy = maxSize.y;
1880 if (!(wndPtr->dwStyle & WS_MINIMIZE))
1882 if (winpos->cx < minTrack.x ) winpos->cx = minTrack.x;
1883 if (winpos->cy < minTrack.y ) winpos->cy = minTrack.y;
1890 /***********************************************************************
1891 * WINPOS_HandleWindowPosChanging32
1893 * Default handling for a WM_WINDOWPOSCHANGING. Called from DefWindowProc().
1895 LONG WINPOS_HandleWindowPosChanging( WND *wndPtr, WINDOWPOS *winpos )
1898 if (winpos->flags & SWP_NOSIZE) return 0;
1899 if ((wndPtr->dwStyle & WS_THICKFRAME) ||
1900 ((wndPtr->dwStyle & (WS_POPUP | WS_CHILD)) == 0))
1902 WINPOS_GetMinMaxInfo( wndPtr, &maxSize, NULL, NULL, NULL );
1903 winpos->cx = MIN( winpos->cx, maxSize.x );
1904 winpos->cy = MIN( winpos->cy, maxSize.y );
1910 /***********************************************************************
1911 * WINPOS_MoveWindowZOrder
1913 * Move a window in Z order, invalidating everything that needs it.
1914 * Only necessary for windows without associated X window.
1916 static void WINPOS_MoveWindowZOrder( HWND hwnd, HWND hwndAfter )
1919 WND *pWndAfter, *pWndCur, *wndPtr = WIN_FindWndPtr( hwnd );
1921 /* We have two possible cases:
1922 * - The window is moving up: we have to invalidate all areas
1923 * of the window that were covered by other windows
1924 * - The window is moving down: we have to invalidate areas
1925 * of other windows covered by this one.
1928 if (hwndAfter == HWND_TOP)
1932 else if (hwndAfter == HWND_BOTTOM)
1934 if (!wndPtr->next) return; /* Already at the bottom */
1939 if (!(pWndAfter = WIN_FindWndPtr( hwndAfter ))) return;
1940 if (wndPtr->next == pWndAfter) return; /* Already placed right */
1942 /* Determine which window we encounter first in Z-order */
1943 pWndCur = wndPtr->parent->child;
1944 while ((pWndCur != wndPtr) && (pWndCur != pWndAfter))
1945 pWndCur = pWndCur->next;
1946 movingUp = (pWndCur == pWndAfter);
1951 WND *pWndPrevAfter = wndPtr->next;
1952 WIN_UnlinkWindow( hwnd );
1953 WIN_LinkWindow( hwnd, hwndAfter );
1954 pWndCur = wndPtr->next;
1955 while (pWndCur != pWndPrevAfter)
1957 RECT rect = { pWndCur->rectWindow.left,
1958 pWndCur->rectWindow.top,
1959 pWndCur->rectWindow.right,
1960 pWndCur->rectWindow.bottom };
1961 OffsetRect( &rect, -wndPtr->rectClient.left,
1962 -wndPtr->rectClient.top );
1963 PAINT_RedrawWindow( hwnd, &rect, 0, RDW_INVALIDATE | RDW_ALLCHILDREN |
1964 RDW_FRAME | RDW_ERASE, 0 );
1965 pWndCur = pWndCur->next;
1968 else /* Moving down */
1970 pWndCur = wndPtr->next;
1971 WIN_UnlinkWindow( hwnd );
1972 WIN_LinkWindow( hwnd, hwndAfter );
1973 while (pWndCur != wndPtr)
1975 RECT rect = { pWndCur->rectWindow.left,
1976 pWndCur->rectWindow.top,
1977 pWndCur->rectWindow.right,
1978 pWndCur->rectWindow.bottom };
1979 OffsetRect( &rect, -pWndCur->rectClient.left,
1980 -pWndCur->rectClient.top );
1981 PAINT_RedrawWindow( pWndCur->hwndSelf, &rect, 0, RDW_INVALIDATE |
1982 RDW_ALLCHILDREN | RDW_FRAME | RDW_ERASE, 0 );
1983 pWndCur = pWndCur->next;
1988 /***********************************************************************
1989 * WINPOS_ReorderOwnedPopups
1991 * fix Z order taking into account owned popups -
1992 * basically we need to maintain them above the window that owns them
1994 HWND WINPOS_ReorderOwnedPopups(HWND hwndInsertAfter,WND* wndPtr,WORD flags)
1996 WND* w = WIN_GetDesktop()->child;
1998 if( wndPtr->dwStyle & WS_POPUP && wndPtr->owner )
2000 /* implement "local z-order" between the top and owner window */
2002 HWND hwndLocalPrev = HWND_TOP;
2004 if( hwndInsertAfter != HWND_TOP )
2006 while( w != wndPtr->owner )
2008 if (w != wndPtr) hwndLocalPrev = w->hwndSelf;
2009 if( hwndLocalPrev == hwndInsertAfter ) break;
2012 hwndInsertAfter = hwndLocalPrev;
2016 else if( wndPtr->dwStyle & WS_CHILD ) return hwndInsertAfter;
2018 w = WIN_GetDesktop()->child;
2021 if( w == wndPtr ) break;
2023 if( w->dwStyle & WS_POPUP && w->owner == wndPtr )
2025 SetWindowPos(w->hwndSelf, hwndInsertAfter, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE |
2026 SWP_NOACTIVATE | SWP_NOSENDCHANGING | SWP_DEFERERASE);
2027 hwndInsertAfter = w->hwndSelf;
2032 return hwndInsertAfter;
2035 /***********************************************************************
2036 * WINPOS_SizeMoveClean
2038 * Make window look nice without excessive repainting
2042 * visible regions are in window coordinates
2043 * update regions are in window client coordinates
2044 * client and window rectangles are in parent client coordinates
2046 * FIXME: Move visible and update regions to the same coordinate system
2047 * (either parent client or window). This is a lot of work though.
2049 static UINT WINPOS_SizeMoveClean( WND* Wnd, HRGN oldVisRgn,
2050 LPRECT lpOldWndRect,
2051 LPRECT lpOldClientRect, UINT uFlags )
2053 HRGN newVisRgn = DCE_GetVisRgn(Wnd->hwndSelf,DCX_WINDOW | DCX_CLIPSIBLINGS,0,0);
2054 HRGN dirtyRgn = CreateRectRgn(0,0,0,0);
2057 TRACE(win,"cleaning up...new wnd=(%i %i-%i %i) old wnd=(%i %i-%i %i)\n",
2058 Wnd->rectWindow.left, Wnd->rectWindow.top,
2059 Wnd->rectWindow.right, Wnd->rectWindow.bottom,
2060 lpOldWndRect->left, lpOldWndRect->top,
2061 lpOldWndRect->right, lpOldWndRect->bottom);
2062 TRACE(win,"\tnew client=(%i %i-%i %i) old client=(%i %i-%i %i)\n",
2063 Wnd->rectClient.left, Wnd->rectClient.top,
2064 Wnd->rectClient.right, Wnd->rectClient.bottom,
2065 lpOldClientRect->left, lpOldClientRect->top,
2066 lpOldClientRect->right,lpOldClientRect->bottom );
2068 if( (lpOldWndRect->right - lpOldWndRect->left) != (Wnd->rectWindow.right - Wnd->rectWindow.left) ||
2069 (lpOldWndRect->bottom - lpOldWndRect->top) != (Wnd->rectWindow.bottom - Wnd->rectWindow.top) )
2070 uFlags |= SMC_DRAWFRAME;
2072 CombineRgn( dirtyRgn, newVisRgn, 0, RGN_COPY);
2074 if( !(uFlags & SMC_NOCOPY) )
2075 CombineRgn( newVisRgn, newVisRgn, oldVisRgn, RGN_AND );
2077 /* map regions to the parent client area */
2079 OffsetRgn( dirtyRgn, Wnd->rectWindow.left, Wnd->rectWindow.top );
2080 OffsetRgn( oldVisRgn, lpOldWndRect->left, lpOldWndRect->top );
2082 /* compute invalidated region outside Wnd - (in client coordinates of the parent window) */
2084 other = CombineRgn(dirtyRgn, oldVisRgn, dirtyRgn, RGN_DIFF);
2086 /* map visible region to the Wnd client area */
2088 OffsetRgn( newVisRgn, Wnd->rectWindow.left - Wnd->rectClient.left,
2089 Wnd->rectWindow.top - Wnd->rectClient.top );
2091 /* substract previously invalidated region from the Wnd visible region */
2093 my = (Wnd->hrgnUpdate > 1) ? CombineRgn( newVisRgn, newVisRgn,
2094 Wnd->hrgnUpdate, RGN_DIFF)
2097 if( uFlags & SMC_NOCOPY ) /* invalidate Wnd visible region */
2099 if (my != NULLREGION)
2100 PAINT_RedrawWindow( Wnd->hwndSelf, NULL, newVisRgn, RDW_INVALIDATE |
2101 RDW_FRAME | RDW_ALLCHILDREN | RDW_ERASE, RDW_C_USEHRGN );
2102 else if(uFlags & SMC_DRAWFRAME)
2103 Wnd->flags |= WIN_NEEDS_NCPAINT;
2105 else /* bitblt old client area */
2110 int xfrom,yfrom,xto,yto,width,height;
2112 if( uFlags & SMC_DRAWFRAME )
2114 /* copy only client area, frame will be redrawn anyway */
2116 xfrom = lpOldClientRect->left; yfrom = lpOldClientRect->top;
2117 xto = Wnd->rectClient.left; yto = Wnd->rectClient.top;
2118 width = lpOldClientRect->right - xfrom; height = lpOldClientRect->bottom - yfrom;
2119 updateRgn = CreateRectRgn( 0, 0, width, height );
2120 CombineRgn( newVisRgn, newVisRgn, updateRgn, RGN_AND );
2121 SetRectRgn( updateRgn, 0, 0, Wnd->rectClient.right - xto,
2122 Wnd->rectClient.bottom - yto );
2126 xfrom = lpOldWndRect->left; yfrom = lpOldWndRect->top;
2127 xto = Wnd->rectWindow.left; yto = Wnd->rectWindow.top;
2128 width = lpOldWndRect->right - xfrom; height = lpOldWndRect->bottom - yfrom;
2129 updateRgn = CreateRectRgn( xto - Wnd->rectClient.left,
2130 yto - Wnd->rectClient.top,
2131 Wnd->rectWindow.right - Wnd->rectClient.left,
2132 Wnd->rectWindow.bottom - Wnd->rectClient.top );
2135 CombineRgn( newVisRgn, newVisRgn, updateRgn, RGN_AND );
2137 /* substract new visRgn from target rect to get a region that won't be copied */
2139 update = CombineRgn( updateRgn, updateRgn, newVisRgn, RGN_DIFF );
2141 /* Blt valid bits using parent window DC */
2143 if( my != NULLREGION && (xfrom != xto || yfrom != yto) )
2146 /* compute clipping region in parent client coordinates */
2148 OffsetRgn( newVisRgn, Wnd->rectClient.left, Wnd->rectClient.top );
2149 CombineRgn( oldVisRgn, oldVisRgn, newVisRgn, RGN_OR );
2151 hDC = GetDCEx( Wnd->parent->hwndSelf, oldVisRgn,
2152 DCX_KEEPCLIPRGN | DCX_INTERSECTRGN |
2153 DCX_CACHE | DCX_CLIPSIBLINGS);
2155 BitBlt( hDC, xto, yto, width, height, hDC, xfrom, yfrom, SRCCOPY );
2156 ReleaseDC( Wnd->parent->hwndSelf, hDC);
2159 if( update != NULLREGION )
2160 PAINT_RedrawWindow( Wnd->hwndSelf, NULL, updateRgn, RDW_INVALIDATE |
2161 RDW_FRAME | RDW_ALLCHILDREN | RDW_ERASE, RDW_C_USEHRGN );
2162 else if( uFlags & SMC_DRAWFRAME ) Wnd->flags |= WIN_NEEDS_NCPAINT;
2163 DeleteObject( updateRgn );
2166 /* erase uncovered areas */
2168 if( !(uFlags & SMC_NOPARENTERASE) && (other != NULLREGION ) )
2169 PAINT_RedrawWindow( Wnd->parent->hwndSelf, NULL, dirtyRgn,
2170 RDW_INVALIDATE | RDW_ALLCHILDREN | RDW_ERASE, RDW_C_USEHRGN );
2171 DeleteObject(dirtyRgn);
2172 DeleteObject(newVisRgn);
2176 /***********************************************************************
2177 * SetWindowPos (USER.232)
2179 BOOL16 WINAPI SetWindowPos16( HWND16 hwnd, HWND16 hwndInsertAfter,
2180 INT16 x, INT16 y, INT16 cx, INT16 cy, WORD flags)
2182 return SetWindowPos(hwnd,(INT)(INT16)hwndInsertAfter,x,y,cx,cy,flags);
2185 /***********************************************************************
2186 * SetWindowPos (USER32.520)
2188 BOOL WINAPI SetWindowPos( HWND hwnd, HWND hwndInsertAfter,
2189 INT x, INT y, INT cx, INT cy, WORD flags)
2193 RECT newWindowRect, newClientRect, oldWindowRect;
2195 HWND tempInsertAfter= 0;
2198 BOOL resync = FALSE;
2199 HWND hwndActive = 0;
2201 /* Get current active window from the active queue */
2204 MESSAGEQUEUE *pActiveQueue = QUEUE_Lock( hActiveQueue );
2207 hwndActive = PERQDATA_GetActiveWnd( pActiveQueue->pQData );
2208 QUEUE_Unlock( pActiveQueue );
2212 TRACE(win,"hwnd %04x, (%i,%i)-(%i,%i) flags %08x\n",
2213 hwnd, x, y, x+cx, y+cy, flags);
2214 /* Check window handle */
2216 if (hwnd == GetDesktopWindow()) return FALSE;
2217 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return FALSE;
2219 if(wndPtr->dwStyle & WS_VISIBLE)
2220 flags &= ~SWP_SHOWWINDOW;
2223 uFlags |= SMC_NOPARENTERASE;
2224 flags &= ~SWP_HIDEWINDOW;
2225 if (!(flags & SWP_SHOWWINDOW)) flags |= SWP_NOREDRAW;
2228 /* Check for windows that may not be resized
2229 FIXME: this should be done only for Windows 3.0 programs
2230 if (flags & (SWP_SHOWWINDOW | SWP_HIDEWINDOW ) )
2231 flags |= SWP_NOSIZE | SWP_NOMOVE;
2233 /* Check dimensions */
2235 if (cx <= 0) cx = 1;
2236 if (cy <= 0) cy = 1;
2240 if (hwnd == hwndActive) flags |= SWP_NOACTIVATE; /* Already active */
2241 if ((wndPtr->rectWindow.right - wndPtr->rectWindow.left == cx) &&
2242 (wndPtr->rectWindow.bottom - wndPtr->rectWindow.top == cy))
2243 flags |= SWP_NOSIZE; /* Already the right size */
2244 if ((wndPtr->rectWindow.left == x) && (wndPtr->rectWindow.top == y))
2245 flags |= SWP_NOMOVE; /* Already the right position */
2247 /* Check hwndInsertAfter */
2249 if (!(flags & (SWP_NOZORDER | SWP_NOACTIVATE)))
2251 /* Ignore TOPMOST flags when activating a window */
2252 /* _and_ moving it in Z order. */
2253 if ((hwndInsertAfter == HWND_TOPMOST) ||
2254 (hwndInsertAfter == HWND_NOTOPMOST))
2255 hwndInsertAfter = HWND_TOP;
2257 /* TOPMOST not supported yet */
2258 if ((hwndInsertAfter == HWND_TOPMOST) ||
2259 (hwndInsertAfter == HWND_NOTOPMOST)) hwndInsertAfter = HWND_TOP;
2261 /* hwndInsertAfter must be a sibling of the window */
2262 if ((hwndInsertAfter != HWND_TOP) && (hwndInsertAfter != HWND_BOTTOM))
2264 WND* wnd = WIN_FindWndPtr(hwndInsertAfter);
2267 if( wnd->parent != wndPtr->parent ) return FALSE;
2268 if( wnd->next == wndPtr ) flags |= SWP_NOZORDER;
2271 else if (!X11DRV_WND_GetXWindow(wndPtr))
2273 /* FIXME: the following optimization is no good for "X-ed" windows */
2274 if (hwndInsertAfter == HWND_TOP)
2275 flags |= ( wndPtr->parent->child == wndPtr)? SWP_NOZORDER: 0;
2276 else /* HWND_BOTTOM */
2277 flags |= ( wndPtr->next )? 0: SWP_NOZORDER;
2280 /* Fill the WINDOWPOS structure */
2283 winpos.hwndInsertAfter = hwndInsertAfter;
2288 winpos.flags = flags;
2290 /* Send WM_WINDOWPOSCHANGING message */
2292 if (!(winpos.flags & SWP_NOSENDCHANGING))
2293 SendMessageA( hwnd, WM_WINDOWPOSCHANGING, 0, (LPARAM)&winpos );
2295 /* Calculate new position and size */
2297 newWindowRect = wndPtr->rectWindow;
2298 newClientRect = (wndPtr->dwStyle & WS_MINIMIZE) ? wndPtr->rectWindow
2299 : wndPtr->rectClient;
2301 if (!(winpos.flags & SWP_NOSIZE))
2303 newWindowRect.right = newWindowRect.left + winpos.cx;
2304 newWindowRect.bottom = newWindowRect.top + winpos.cy;
2306 if (!(winpos.flags & SWP_NOMOVE))
2308 newWindowRect.left = winpos.x;
2309 newWindowRect.top = winpos.y;
2310 newWindowRect.right += winpos.x - wndPtr->rectWindow.left;
2311 newWindowRect.bottom += winpos.y - wndPtr->rectWindow.top;
2313 OffsetRect( &newClientRect, winpos.x - wndPtr->rectWindow.left,
2314 winpos.y - wndPtr->rectWindow.top );
2317 winpos.flags |= SWP_NOCLIENTMOVE | SWP_NOCLIENTSIZE;
2319 /* Reposition window in Z order */
2321 if (!(winpos.flags & SWP_NOZORDER))
2323 /* reorder owned popups if hwnd is top-level window
2325 if( wndPtr->parent == WIN_GetDesktop() )
2326 hwndInsertAfter = WINPOS_ReorderOwnedPopups( hwndInsertAfter,
2327 wndPtr, winpos.flags );
2328 if (X11DRV_WND_GetXWindow(wndPtr))
2331 WIN_UnlinkWindow( winpos.hwnd );
2332 WIN_LinkWindow( winpos.hwnd, hwndInsertAfter );
2335 WINPOS_MoveWindowZOrder( winpos.hwnd, hwndInsertAfter );
2338 if ( !X11DRV_WND_GetXWindow(wndPtr) && !(winpos.flags & SWP_NOREDRAW) &&
2339 ((winpos.flags & (SWP_NOMOVE | SWP_NOSIZE | SWP_FRAMECHANGED))
2340 != (SWP_NOMOVE | SWP_NOSIZE)) )
2341 visRgn = DCE_GetVisRgn(hwnd, DCX_WINDOW | DCX_CLIPSIBLINGS, 0, 0);
2343 /* Send WM_NCCALCSIZE message to get new client area */
2344 if( (winpos.flags & (SWP_FRAMECHANGED | SWP_NOSIZE)) != SWP_NOSIZE )
2346 result = WINPOS_SendNCCalcSize( winpos.hwnd, TRUE, &newWindowRect,
2347 &wndPtr->rectWindow, &wndPtr->rectClient,
2348 &winpos, &newClientRect );
2350 /* FIXME: WVR_ALIGNxxx */
2352 if( newClientRect.left != wndPtr->rectClient.left ||
2353 newClientRect.top != wndPtr->rectClient.top )
2354 winpos.flags &= ~SWP_NOCLIENTMOVE;
2356 if( (newClientRect.right - newClientRect.left !=
2357 wndPtr->rectClient.right - wndPtr->rectClient.left) ||
2358 (newClientRect.bottom - newClientRect.top !=
2359 wndPtr->rectClient.bottom - wndPtr->rectClient.top) )
2360 winpos.flags &= ~SWP_NOCLIENTSIZE;
2363 if( !(flags & SWP_NOMOVE) && (newClientRect.left != wndPtr->rectClient.left ||
2364 newClientRect.top != wndPtr->rectClient.top) )
2365 winpos.flags &= ~SWP_NOCLIENTMOVE;
2367 /* Update active DCEs
2368 * TODO: Optimize conditions that trigger DCE update.
2371 if( (((winpos.flags & SWP_AGG_NOPOSCHANGE) != SWP_AGG_NOPOSCHANGE) &&
2372 wndPtr->dwStyle & WS_VISIBLE) ||
2373 (flags & (SWP_HIDEWINDOW | SWP_SHOWWINDOW)) )
2377 UnionRect(&rect, &newWindowRect, &wndPtr->rectWindow);
2378 DCE_InvalidateDCE(wndPtr, &rect);
2381 /* change geometry */
2383 oldWindowRect = wndPtr->rectWindow;
2385 if (X11DRV_WND_GetXWindow(wndPtr))
2387 RECT oldClientRect = wndPtr->rectClient;
2389 tempInsertAfter = winpos.hwndInsertAfter;
2391 winpos.hwndInsertAfter = hwndInsertAfter;
2393 /* postpone geometry change */
2395 if( !(flags & (SWP_SHOWWINDOW | SWP_HIDEWINDOW)) )
2397 wndPtr->pDriver->pSetWindowPos(wndPtr, &winpos, TRUE);
2398 winpos.hwndInsertAfter = tempInsertAfter;
2400 else uFlags |= SMC_SETXPOS;
2402 wndPtr->rectWindow = newWindowRect;
2403 wndPtr->rectClient = newClientRect;
2405 if( !(flags & (SWP_SHOWWINDOW | SWP_HIDEWINDOW)) )
2407 if( (oldClientRect.left - oldWindowRect.left !=
2408 newClientRect.left - newWindowRect.left) ||
2409 (oldClientRect.top - oldWindowRect.top !=
2410 newClientRect.top - newWindowRect.top) ||
2411 (winpos.flags & SWP_NOCOPYBITS) )
2413 /* if the client area moved as a result of WM_NCCALCSIZE returning
2414 * obscure WVR_ALIGNxxx flags then we simply redraw the whole thing
2416 * TODO: use WINPOS_SizeMoveClean() if there is no SWP_NOCOPYBITS
2419 PAINT_RedrawWindow( wndPtr->hwndSelf, NULL, 0, RDW_INVALIDATE |
2420 RDW_ALLCHILDREN | RDW_FRAME | RDW_ERASE, 0 );
2423 if( winpos.flags & SWP_FRAMECHANGED )
2428 if( newClientRect.right > oldClientRect.right ) /* redraw exposed client area on the right */
2430 rect.top = 0; rect.bottom = newClientRect.bottom - newClientRect.top;
2431 rect.left = oldClientRect.right - newClientRect.left;
2432 rect.right = newClientRect.right - newClientRect.left;
2434 PAINT_RedrawWindow( wndPtr->hwndSelf, &rect, 0,
2435 RDW_INVALIDATE | RDW_FRAME | RDW_ERASE | RDW_ERASENOW | RDW_ALLCHILDREN, 0 );
2437 if( newClientRect.bottom > oldClientRect.bottom ) /* redraw exposed client area on the bottom */
2439 rect.left = 0; rect.right = ((wErase)?oldClientRect.right:newClientRect.right) - newClientRect.left;
2440 rect.top = oldClientRect.bottom - newClientRect.top;
2441 rect.bottom = newClientRect.bottom - newClientRect.top;
2443 PAINT_RedrawWindow( wndPtr->hwndSelf, &rect, 0,
2444 RDW_INVALIDATE | RDW_FRAME | RDW_ERASE | RDW_ERASENOW | RDW_ALLCHILDREN, 0 );
2446 if( !wErase ) /* just update the nonclient area */
2447 // the previous command (wndPtr->flags |= WIN_NEEDS_NCPAINT)
2448 // was not enough. Absolutly need a non client update at this point
2449 // Cannot wait for the next WM_PAINT message, particularly in the menu-bar redrawing
2450 WIN_UpdateNCArea(wndPtr,TRUE);
2453 uFlags |= SMC_NOPARENTERASE; /* X windows do not have eraseable parents */
2455 else /* not an X window */
2457 RECT oldClientRect = wndPtr->rectClient;
2459 wndPtr->rectWindow = newWindowRect;
2460 wndPtr->rectClient = newClientRect;
2462 if( oldClientRect.bottom - oldClientRect.top ==
2463 newClientRect.bottom - newClientRect.top ) result &= ~WVR_VREDRAW;
2465 if( oldClientRect.right - oldClientRect.left ==
2466 newClientRect.right - newClientRect.left ) result &= ~WVR_HREDRAW;
2468 if( !(flags & (SWP_NOREDRAW | SWP_HIDEWINDOW | SWP_SHOWWINDOW)) )
2470 uFlags |= ((winpos.flags & SWP_NOCOPYBITS) ||
2471 (result >= WVR_HREDRAW && result < WVR_VALIDRECTS)) ? SMC_NOCOPY : 0;
2472 uFlags |= (winpos.flags & SWP_FRAMECHANGED) ? SMC_DRAWFRAME : 0;
2474 if( (winpos.flags & SWP_AGG_NOGEOMETRYCHANGE) != SWP_AGG_NOGEOMETRYCHANGE )
2475 uFlags = WINPOS_SizeMoveClean(wndPtr, visRgn, &oldWindowRect,
2476 &oldClientRect, uFlags);
2479 /* adjust the frame and do not erase the parent */
2481 if( winpos.flags & SWP_FRAMECHANGED ) wndPtr->flags |= WIN_NEEDS_NCPAINT;
2482 if( winpos.flags & SWP_NOZORDER ) uFlags |= SMC_NOPARENTERASE;
2485 DeleteObject(visRgn);
2488 if (flags & SWP_SHOWWINDOW)
2490 wndPtr->dwStyle |= WS_VISIBLE;
2491 if (X11DRV_WND_GetXWindow(wndPtr))
2495 wndPtr->pDriver->pSetWindowPos(wndPtr, &winpos, uFlags & SMC_SETXPOS );
2496 if( uFlags & SMC_SETXPOS )
2498 winpos.hwndInsertAfter = tempInsertAfter;
2501 if (wndPtr->flags & WIN_MANAGED) resync = TRUE;
2503 /* If focus was set to an unmapped window, reset X focus now */
2504 focus = curr = GetFocus();
2507 WND *pFocus = WIN_FindWndPtr( focus );
2509 pFocus->pDriver->pSetFocus(pFocus);
2512 curr = GetParent(curr);
2517 if (!(flags & SWP_NOREDRAW))
2518 PAINT_RedrawWindow( winpos.hwnd, NULL, 0,
2519 RDW_INVALIDATE | RDW_ALLCHILDREN |
2520 RDW_FRAME | RDW_ERASENOW | RDW_ERASE, 0 );
2523 else if (flags & SWP_HIDEWINDOW)
2525 wndPtr->dwStyle &= ~WS_VISIBLE;
2526 if (X11DRV_WND_GetXWindow(wndPtr))
2528 wndPtr->pDriver->pSetWindowPos(wndPtr, &winpos, uFlags & SMC_SETXPOS );
2529 if( uFlags & SMC_SETXPOS )
2531 winpos.hwndInsertAfter = tempInsertAfter;
2536 if (!(flags & SWP_NOREDRAW))
2537 PAINT_RedrawWindow( wndPtr->parent->hwndSelf, &oldWindowRect,
2538 0, RDW_INVALIDATE | RDW_ALLCHILDREN |
2539 RDW_ERASE | RDW_ERASENOW, 0 );
2540 uFlags |= SMC_NOPARENTERASE;
2543 if (hwnd == CARET_GetHwnd()) DestroyCaret();
2545 /* FIXME: This will cause the window to be activated irrespective
2546 * of whether it is owned by the same thread.
2547 * Should this behaviour be allowed in SetWindowPos?
2549 if (winpos.hwnd == hwndActive)
2550 WINPOS_ActivateOtherWindow( wndPtr );
2553 /* Activate the window */
2555 if (!(flags & SWP_NOACTIVATE))
2556 WINPOS_ChangeActiveWindow( winpos.hwnd, FALSE );
2558 /* Repaint the window */
2560 if (X11DRV_WND_GetXWindow(wndPtr))
2561 EVENT_Synchronize(); /* Wait for all expose events */
2563 if (!GetCapture() && ((wndPtr->dwStyle & WS_VISIBLE) || (flags & SWP_HIDEWINDOW)))
2564 EVENT_DummyMotionNotify(); /* Simulate a mouse event to set the cursor */
2566 if (!(flags & SWP_DEFERERASE) && !(uFlags & SMC_NOPARENTERASE) )
2567 PAINT_RedrawWindow( wndPtr->parent->hwndSelf, NULL, 0, RDW_ALLCHILDREN | RDW_ERASENOW, 0 );
2568 else if( wndPtr->parent == WIN_GetDesktop() && wndPtr->parent->flags & WIN_NEEDS_ERASEBKGND )
2569 PAINT_RedrawWindow( wndPtr->parent->hwndSelf, NULL, 0, RDW_NOCHILDREN | RDW_ERASENOW, 0 );
2571 /* And last, send the WM_WINDOWPOSCHANGED message */
2573 TRACE(win,"\tstatus flags = %04x\n", winpos.flags & SWP_AGG_STATUSFLAGS);
2576 (((winpos.flags & SWP_AGG_STATUSFLAGS) != SWP_AGG_NOPOSCHANGE) &&
2577 !(winpos.flags & SWP_NOSENDCHANGING)) )
2579 SendMessageA( winpos.hwnd, WM_WINDOWPOSCHANGED, 0, (LPARAM)&winpos );
2580 if (resync) EVENT_Synchronize ();
2587 /***********************************************************************
2588 * BeginDeferWindowPos16 (USER.259)
2590 HDWP16 WINAPI BeginDeferWindowPos16( INT16 count )
2592 return BeginDeferWindowPos( count );
2596 /***********************************************************************
2597 * BeginDeferWindowPos32 (USER32.9)
2599 HDWP WINAPI BeginDeferWindowPos( INT count )
2604 if (count <= 0) return 0;
2605 handle = USER_HEAP_ALLOC( sizeof(DWP) + (count-1)*sizeof(WINDOWPOS) );
2606 if (!handle) return 0;
2607 pDWP = (DWP *) USER_HEAP_LIN_ADDR( handle );
2608 pDWP->actualCount = 0;
2609 pDWP->suggestedCount = count;
2611 pDWP->wMagic = DWP_MAGIC;
2612 pDWP->hwndParent = 0;
2617 /***********************************************************************
2618 * DeferWindowPos16 (USER.260)
2620 HDWP16 WINAPI DeferWindowPos16( HDWP16 hdwp, HWND16 hwnd, HWND16 hwndAfter,
2621 INT16 x, INT16 y, INT16 cx, INT16 cy,
2624 return DeferWindowPos( hdwp, hwnd, (INT)(INT16)hwndAfter,
2625 x, y, cx, cy, flags );
2629 /***********************************************************************
2630 * DeferWindowPos32 (USER32.128)
2632 HDWP WINAPI DeferWindowPos( HDWP hdwp, HWND hwnd, HWND hwndAfter,
2633 INT x, INT y, INT cx, INT cy,
2638 HDWP newhdwp = hdwp;
2639 /* HWND32 parent; */
2642 pDWP = (DWP *) USER_HEAP_LIN_ADDR( hdwp );
2643 if (!pDWP) return 0;
2644 if (hwnd == GetDesktopWindow()) return 0;
2646 if (!(pWnd=WIN_FindWndPtr( hwnd ))) {
2647 USER_HEAP_FREE( hdwp );
2651 /* Numega Bounds Checker Demo dislikes the following code.
2652 In fact, I've not been able to find any "same parent" requirement in any docu
2656 /* All the windows of a DeferWindowPos() must have the same parent */
2657 parent = pWnd->parent->hwndSelf;
2658 if (pDWP->actualCount == 0) pDWP->hwndParent = parent;
2659 else if (parent != pDWP->hwndParent)
2661 USER_HEAP_FREE( hdwp );
2666 for (i = 0; i < pDWP->actualCount; i++)
2668 if (pDWP->winPos[i].hwnd == hwnd)
2670 /* Merge with the other changes */
2671 if (!(flags & SWP_NOZORDER))
2673 pDWP->winPos[i].hwndInsertAfter = hwndAfter;
2675 if (!(flags & SWP_NOMOVE))
2677 pDWP->winPos[i].x = x;
2678 pDWP->winPos[i].y = y;
2680 if (!(flags & SWP_NOSIZE))
2682 pDWP->winPos[i].cx = cx;
2683 pDWP->winPos[i].cy = cy;
2685 pDWP->winPos[i].flags &= flags | ~(SWP_NOSIZE | SWP_NOMOVE |
2686 SWP_NOZORDER | SWP_NOREDRAW |
2687 SWP_NOACTIVATE | SWP_NOCOPYBITS|
2689 pDWP->winPos[i].flags |= flags & (SWP_SHOWWINDOW | SWP_HIDEWINDOW |
2694 if (pDWP->actualCount >= pDWP->suggestedCount)
2696 newhdwp = USER_HEAP_REALLOC( hdwp,
2697 sizeof(DWP) + pDWP->suggestedCount*sizeof(WINDOWPOS) );
2698 if (!newhdwp) return 0;
2699 pDWP = (DWP *) USER_HEAP_LIN_ADDR( newhdwp );
2700 pDWP->suggestedCount++;
2702 pDWP->winPos[pDWP->actualCount].hwnd = hwnd;
2703 pDWP->winPos[pDWP->actualCount].hwndInsertAfter = hwndAfter;
2704 pDWP->winPos[pDWP->actualCount].x = x;
2705 pDWP->winPos[pDWP->actualCount].y = y;
2706 pDWP->winPos[pDWP->actualCount].cx = cx;
2707 pDWP->winPos[pDWP->actualCount].cy = cy;
2708 pDWP->winPos[pDWP->actualCount].flags = flags;
2709 pDWP->actualCount++;
2714 /***********************************************************************
2715 * EndDeferWindowPos16 (USER.261)
2717 BOOL16 WINAPI EndDeferWindowPos16( HDWP16 hdwp )
2719 return EndDeferWindowPos( hdwp );
2723 /***********************************************************************
2724 * EndDeferWindowPos32 (USER32.173)
2726 BOOL WINAPI EndDeferWindowPos( HDWP hdwp )
2733 pDWP = (DWP *) USER_HEAP_LIN_ADDR( hdwp );
2734 if (!pDWP) return FALSE;
2735 for (i = 0, winpos = pDWP->winPos; i < pDWP->actualCount; i++, winpos++)
2737 if (!(res = SetWindowPos( winpos->hwnd, winpos->hwndInsertAfter,
2738 winpos->x, winpos->y, winpos->cx,
2739 winpos->cy, winpos->flags ))) break;
2741 USER_HEAP_FREE( hdwp );
2746 /***********************************************************************
2747 * TileChildWindows (USER.199)
2749 void WINAPI TileChildWindows16( HWND16 parent, WORD action )
2751 FIXME(win, "(%04x, %d): stub\n", parent, action);
2754 /***********************************************************************
2755 * CascageChildWindows (USER.198)
2757 void WINAPI CascadeChildWindows16( HWND16 parent, WORD action )
2759 FIXME(win, "(%04x, %d): stub\n", parent, action);
2761 /***********************************************************************
2762 * GetProgmanWindow [USER32.289]
2764 HRESULT WINAPI GetProgmanWindow ( )
2765 { FIXME(win,"stub\n");
2768 /***********************************************************************
2769 * GetTaskmanWindow [USER32.304]
2771 HRESULT WINAPI GetTaskmanWindow ( )
2772 { FIXME(win,"stub\n");
2775 /***********************************************************************
2776 * SetProgmanWindow [USER32.522]
2778 HRESULT WINAPI SetProgmanWindow ( DWORD x )
2779 { FIXME(win,"0x%08lx stub\n",x);
2782 /***********************************************************************
2783 * SetShellWindowEx [USER32.531]
2785 HRESULT WINAPI SetShellWindowEx ( DWORD x, DWORD y )
2786 { FIXME(win,"0x%08lx 0x%08lx stub\n",x,y);
2789 /***********************************************************************
2790 * SetTaskmanWindow [USER32.537]
2792 HRESULT WINAPI SetTaskmanWindow ( DWORD x )
2793 { FIXME(win,"0x%08lx stub\n",x);