2 * Window position related functions.
4 * Copyright 1993, 1994, 1995 Alexandre Julliard
5 * 1995, 1996, 1999 Alex Korobka
13 #include "wine/winuser16.h"
25 #include "nonclient.h"
26 #include "debugtools.h"
29 DEFAULT_DEBUG_CHANNEL(win);
31 #define HAS_DLGFRAME(style,exStyle) \
32 (((exStyle) & WS_EX_DLGMODALFRAME) || \
33 (((style) & WS_DLGFRAME) && !((style) & WS_BORDER)))
35 #define HAS_THICKFRAME(style) \
36 (((style) & WS_THICKFRAME) && \
37 !(((style) & (WS_DLGFRAME|WS_BORDER)) == WS_DLGFRAME))
39 #define EMPTYPOINT(pt) ((*(LONG*)&(pt)) == -1)
41 #define PLACE_MIN 0x0001
42 #define PLACE_MAX 0x0002
43 #define PLACE_RECT 0x0004
45 #define MINMAX_NOSWP 0x00010000
48 #define DWP_MAGIC ((INT)('W' | ('P' << 8) | ('O' << 16) | ('S' << 24)))
60 /* ----- internal variables ----- */
62 static HWND hwndPrevActive = 0; /* Previously active window */
63 static HWND hGlobalShellWindow=0; /*the shell*/
64 static HWND hGlobalTaskmanWindow=0;
65 static HWND hGlobalProgmanWindow=0;
67 static LPCSTR atomInternalPos;
69 extern HQUEUE16 hActiveQueue;
71 /***********************************************************************
72 * WINPOS_CreateInternalPosAtom
74 BOOL WINPOS_CreateInternalPosAtom()
77 atomInternalPos = (LPCSTR)(DWORD)GlobalAddAtomA(str);
78 return (atomInternalPos) ? TRUE : FALSE;
81 /***********************************************************************
82 * WINPOS_CheckInternalPos
84 * Called when a window is destroyed.
86 void WINPOS_CheckInternalPos( WND* wndPtr )
89 MESSAGEQUEUE *pMsgQ = 0;
90 HWND hwnd = wndPtr->hwndSelf;
92 lpPos = (LPINTERNALPOS) GetPropA( hwnd, atomInternalPos );
94 /* Retrieve the message queue associated with this window */
95 pMsgQ = (MESSAGEQUEUE *)QUEUE_Lock( wndPtr->hmemTaskQ );
98 WARN("\tMessage queue not found. Exiting!\n" );
102 if( hwnd == hwndPrevActive ) hwndPrevActive = 0;
104 if( hwnd == PERQDATA_GetActiveWnd( pMsgQ->pQData ) )
106 PERQDATA_SetActiveWnd( pMsgQ->pQData, 0 );
107 WARN("\tattempt to activate destroyed window!\n");
112 if( IsWindow(lpPos->hwndIconTitle) )
113 DestroyWindow( lpPos->hwndIconTitle );
114 HeapFree( GetProcessHeap(), 0, lpPos );
117 QUEUE_Unlock( pMsgQ );
121 /***********************************************************************
124 * Find a suitable place for an iconic window.
126 static POINT16 WINPOS_FindIconPos( WND* wndPtr, POINT16 pt )
129 short x, y, xspacing, yspacing;
131 GetClientRect16( wndPtr->parent->hwndSelf, &rectParent );
132 if ((pt.x >= rectParent.left) && (pt.x + GetSystemMetrics(SM_CXICON) < rectParent.right) &&
133 (pt.y >= rectParent.top) && (pt.y + GetSystemMetrics(SM_CYICON) < rectParent.bottom))
134 return pt; /* The icon already has a suitable position */
136 xspacing = GetSystemMetrics(SM_CXICONSPACING);
137 yspacing = GetSystemMetrics(SM_CYICONSPACING);
139 y = rectParent.bottom;
145 /* Check if another icon already occupies this spot */
146 WND *childPtr = WIN_LockWndPtr(wndPtr->parent->child);
149 if ((childPtr->dwStyle & WS_MINIMIZE) && (childPtr != wndPtr))
151 if ((childPtr->rectWindow.left < x + xspacing) &&
152 (childPtr->rectWindow.right >= x) &&
153 (childPtr->rectWindow.top <= y) &&
154 (childPtr->rectWindow.bottom > y - yspacing))
155 break; /* There's a window in there */
157 WIN_UpdateWndPtr(&childPtr,childPtr->next);
159 WIN_ReleaseWndPtr(childPtr);
160 if (!childPtr) /* No window was found, so it's OK for us */
162 pt.x = x + (xspacing - GetSystemMetrics(SM_CXICON)) / 2;
163 pt.y = y - (yspacing + GetSystemMetrics(SM_CYICON)) / 2;
167 } while(x <= rectParent.right-xspacing);
173 /***********************************************************************
174 * ArrangeIconicWindows (USER.170)
176 UINT16 WINAPI ArrangeIconicWindows16( HWND16 parent)
178 return ArrangeIconicWindows(parent);
180 /***********************************************************************
181 * ArrangeIconicWindows (USER32.@)
183 UINT WINAPI ArrangeIconicWindows( HWND parent )
187 INT x, y, xspacing, yspacing;
189 GetClientRect( parent, &rectParent );
191 y = rectParent.bottom;
192 xspacing = GetSystemMetrics(SM_CXICONSPACING);
193 yspacing = GetSystemMetrics(SM_CYICONSPACING);
195 hwndChild = GetWindow( parent, GW_CHILD );
198 if( IsIconic( hwndChild ) )
200 WND *wndPtr = WIN_FindWndPtr(hwndChild);
202 WINPOS_ShowIconTitle( wndPtr, FALSE );
204 SetWindowPos( hwndChild, 0, x + (xspacing - GetSystemMetrics(SM_CXICON)) / 2,
205 y - yspacing - GetSystemMetrics(SM_CYICON)/2, 0, 0,
206 SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE );
207 if( IsWindow(hwndChild) )
208 WINPOS_ShowIconTitle(wndPtr , TRUE );
209 WIN_ReleaseWndPtr(wndPtr);
211 if (x <= rectParent.right - xspacing) x += xspacing;
218 hwndChild = GetWindow( hwndChild, GW_HWNDNEXT );
224 /***********************************************************************
225 * SwitchToThisWindow (USER.172)
227 void WINAPI SwitchToThisWindow16( HWND16 hwnd, BOOL16 restore )
229 SwitchToThisWindow( hwnd, restore );
233 /***********************************************************************
234 * SwitchToThisWindow (USER32.@)
236 void WINAPI SwitchToThisWindow( HWND hwnd, BOOL restore )
238 ShowWindow( hwnd, restore ? SW_RESTORE : SW_SHOWMINIMIZED );
242 /***********************************************************************
243 * GetWindowRect (USER.32)
245 void WINAPI GetWindowRect16( HWND16 hwnd, LPRECT16 rect )
247 WND * wndPtr = WIN_FindWndPtr( hwnd );
250 CONV_RECT32TO16( &wndPtr->rectWindow, rect );
252 MapWindowPoints16( wndPtr->parent->hwndSelf, 0, (POINT16 *)rect, 2 );
253 WIN_ReleaseWndPtr(wndPtr);
257 /***********************************************************************
258 * GetWindowRect (USER32.@)
260 BOOL WINAPI GetWindowRect( HWND hwnd, LPRECT rect )
262 WND * wndPtr = WIN_FindWndPtr( hwnd );
263 if (!wndPtr) return FALSE;
265 *rect = wndPtr->rectWindow;
267 MapWindowPoints( wndPtr->parent->hwndSelf, 0, (POINT *)rect, 2 );
268 WIN_ReleaseWndPtr(wndPtr);
273 /***********************************************************************
274 * GetWindowRgn (USER32.@)
276 int WINAPI GetWindowRgn ( HWND hwnd, HRGN hrgn )
279 WND *wndPtr = WIN_FindWndPtr( hwnd );
282 if (wndPtr->hrgnWnd) nRet = CombineRgn( hrgn, wndPtr->hrgnWnd, 0, RGN_COPY );
283 WIN_ReleaseWndPtr(wndPtr);
288 /***********************************************************************
289 * SetWindowRgn (USER32.@)
291 int WINAPI SetWindowRgn( HWND hwnd, HRGN hrgn, BOOL bRedraw )
297 if (USER_Driver.pSetWindowRgn)
298 return USER_Driver.pSetWindowRgn( hwnd, hrgn, bRedraw );
300 if (!(wndPtr = WIN_FindWndPtr(hwnd))) return FALSE;
302 if (wndPtr->hrgnWnd == hrgn)
308 if (hrgn) /* verify that region really exists */
310 if (GetRgnBox( hrgn, &rect ) == ERROR) goto done;
315 /* delete previous region */
316 DeleteObject(wndPtr->hrgnWnd);
319 wndPtr->hrgnWnd = hrgn;
321 /* Size the window to the rectangle of the new region (if it isn't NULL) */
322 if (hrgn) SetWindowPos( hwnd, 0, rect.left, rect.top,
323 rect.right - rect.left, rect.bottom - rect.top,
324 SWP_NOSIZE | SWP_FRAMECHANGED | SWP_NOMOVE | SWP_NOACTIVATE |
325 SWP_NOZORDER | (bRedraw ? 0 : SWP_NOREDRAW) );
329 WIN_ReleaseWndPtr(wndPtr);
333 /***********************************************************************
334 * SetWindowRgn (USER.668)
336 INT16 WINAPI SetWindowRgn16( HWND16 hwnd, HRGN16 hrgn,BOOL16 bRedraw)
340 FIXME("SetWindowRgn16: stub\n");
345 /***********************************************************************
346 * GetClientRect (USER.33)
348 void WINAPI GetClientRect16( HWND16 hwnd, LPRECT16 rect )
350 WND * wndPtr = WIN_FindWndPtr( hwnd );
352 rect->left = rect->top = rect->right = rect->bottom = 0;
355 rect->right = wndPtr->rectClient.right - wndPtr->rectClient.left;
356 rect->bottom = wndPtr->rectClient.bottom - wndPtr->rectClient.top;
358 WIN_ReleaseWndPtr(wndPtr);
362 /***********************************************************************
363 * GetClientRect (USER32.@)
365 BOOL WINAPI GetClientRect( HWND hwnd, LPRECT rect )
367 WND * wndPtr = WIN_FindWndPtr( hwnd );
369 rect->left = rect->top = rect->right = rect->bottom = 0;
370 if (!wndPtr) return FALSE;
371 rect->right = wndPtr->rectClient.right - wndPtr->rectClient.left;
372 rect->bottom = wndPtr->rectClient.bottom - wndPtr->rectClient.top;
374 WIN_ReleaseWndPtr(wndPtr);
379 /*******************************************************************
380 * ClientToScreen (USER.28)
382 void WINAPI ClientToScreen16( HWND16 hwnd, LPPOINT16 lppnt )
384 MapWindowPoints16( hwnd, 0, lppnt, 1 );
388 /*******************************************************************
389 * ClientToScreen (USER32.@)
391 BOOL WINAPI ClientToScreen( HWND hwnd, LPPOINT lppnt )
393 MapWindowPoints( hwnd, 0, lppnt, 1 );
398 /*******************************************************************
399 * ScreenToClient (USER.29)
401 void WINAPI ScreenToClient16( HWND16 hwnd, LPPOINT16 lppnt )
403 MapWindowPoints16( 0, hwnd, lppnt, 1 );
407 /*******************************************************************
408 * ScreenToClient (USER32.@)
410 BOOL WINAPI ScreenToClient( HWND hwnd, LPPOINT lppnt )
412 MapWindowPoints( 0, hwnd, lppnt, 1 );
417 /***********************************************************************
418 * WINPOS_WindowFromPoint
420 * Find the window and hittest for a given point.
422 INT16 WINPOS_WindowFromPoint( WND* wndScope, POINT16 pt, WND **ppWnd )
425 INT16 hittest = HTERROR;
429 TRACE("scope %04x %d,%d\n", wndScope->hwndSelf, pt.x, pt.y);
431 wndPtr = WIN_LockWndPtr(wndScope->child);
433 if( wndScope->dwStyle & WS_DISABLED )
439 if( wndScope->dwExStyle & WS_EX_MANAGED)
441 /* In managed mode we have to check wndScope first as it is also
442 * a window which received the mouse event. */
444 if( pt.x < wndScope->rectClient.left || pt.x >= wndScope->rectClient.right ||
445 pt.y < wndScope->rectClient.top || pt.y >= wndScope->rectClient.bottom )
448 MapWindowPoints16( GetDesktopWindow16(), wndScope->hwndSelf, &xy, 1 );
454 /* If point is in window, and window is visible, and it */
455 /* is enabled (or it's a top-level window), then explore */
456 /* its children. Otherwise, go to the next window. */
458 if ((wndPtr->dwStyle & WS_VISIBLE) &&
459 ((wndPtr->dwExStyle & (WS_EX_LAYERED | WS_EX_TRANSPARENT)) != (WS_EX_LAYERED | WS_EX_TRANSPARENT)) &&
460 (!(wndPtr->dwStyle & WS_DISABLED) ||
461 ((wndPtr->dwStyle & (WS_POPUP | WS_CHILD)) != WS_CHILD)) &&
463 PtInRegion(wndPtr->hrgnWnd, xy.x - wndPtr->rectWindow.left,
464 xy.y - wndPtr->rectWindow.top) :
465 ((xy.x >= wndPtr->rectWindow.left) &&
466 (xy.x < wndPtr->rectWindow.right) &&
467 (xy.y >= wndPtr->rectWindow.top) &&
468 (xy.y < wndPtr->rectWindow.bottom))))
470 TRACE("%d,%d is inside %04x\n", xy.x, xy.y, wndPtr->hwndSelf);
471 *ppWnd = wndPtr; /* Got a suitable window */
473 /* If window is minimized or disabled, return at once */
474 if (wndPtr->dwStyle & WS_MINIMIZE)
476 retvalue = HTCAPTION;
479 if (wndPtr->dwStyle & WS_DISABLED)
485 /* If point is not in client area, ignore the children */
486 if ((xy.x < wndPtr->rectClient.left) ||
487 (xy.x >= wndPtr->rectClient.right) ||
488 (xy.y < wndPtr->rectClient.top) ||
489 (xy.y >= wndPtr->rectClient.bottom)) break;
491 xy.x -= wndPtr->rectClient.left;
492 xy.y -= wndPtr->rectClient.top;
493 WIN_UpdateWndPtr(&wndPtr,wndPtr->child);
497 WIN_UpdateWndPtr(&wndPtr,wndPtr->next);
502 /* If nothing found, try the scope window */
503 if (!*ppWnd) *ppWnd = wndScope;
505 /* Send the WM_NCHITTEST message (only if to the same task) */
506 if ((*ppWnd)->hmemTaskQ == GetFastQueue16())
508 hittest = (INT16)SendMessage16( (*ppWnd)->hwndSelf, WM_NCHITTEST,
509 0, MAKELONG( pt.x, pt.y ) );
510 if (hittest != HTTRANSPARENT)
512 retvalue = hittest; /* Found the window */
522 /* If no children found in last search, make point relative to parent */
525 xy.x += (*ppWnd)->rectClient.left;
526 xy.y += (*ppWnd)->rectClient.top;
529 /* Restart the search from the next sibling */
530 WIN_UpdateWndPtr(&wndPtr,(*ppWnd)->next);
531 *ppWnd = (*ppWnd)->parent;
535 WIN_ReleaseWndPtr(wndPtr);
540 /*******************************************************************
541 * WindowFromPoint (USER.30)
543 HWND16 WINAPI WindowFromPoint16( POINT16 pt )
546 WINPOS_WindowFromPoint( WIN_GetDesktop(), pt, &pWnd );
547 WIN_ReleaseDesktop();
548 return pWnd->hwndSelf;
552 /*******************************************************************
553 * WindowFromPoint (USER32.@)
555 HWND WINAPI WindowFromPoint( POINT pt )
559 CONV_POINT32TO16( &pt, &pt16 );
560 WINPOS_WindowFromPoint( WIN_GetDesktop(), pt16, &pWnd );
561 WIN_ReleaseDesktop();
562 return (HWND)pWnd->hwndSelf;
566 /*******************************************************************
567 * ChildWindowFromPoint (USER.191)
569 HWND16 WINAPI ChildWindowFromPoint16( HWND16 hwndParent, POINT16 pt )
572 CONV_POINT16TO32( &pt, &pt32 );
573 return (HWND16)ChildWindowFromPoint( hwndParent, pt32 );
577 /*******************************************************************
578 * ChildWindowFromPoint (USER32.@)
580 HWND WINAPI ChildWindowFromPoint( HWND hwndParent, POINT pt )
582 /* pt is in the client coordinates */
584 WND* wnd = WIN_FindWndPtr(hwndParent);
590 /* get client rect fast */
591 rect.top = rect.left = 0;
592 rect.right = wnd->rectClient.right - wnd->rectClient.left;
593 rect.bottom = wnd->rectClient.bottom - wnd->rectClient.top;
595 if (!PtInRect( &rect, pt ))
600 WIN_UpdateWndPtr(&wnd,wnd->child);
603 if (PtInRect( &wnd->rectWindow, pt ))
605 retvalue = wnd->hwndSelf;
608 WIN_UpdateWndPtr(&wnd,wnd->next);
610 retvalue = hwndParent;
612 WIN_ReleaseWndPtr(wnd);
616 /*******************************************************************
617 * ChildWindowFromPointEx (USER.399)
619 HWND16 WINAPI ChildWindowFromPointEx16( HWND16 hwndParent, POINT16 pt, UINT16 uFlags)
622 CONV_POINT16TO32( &pt, &pt32 );
623 return (HWND16)ChildWindowFromPointEx( hwndParent, pt32, uFlags );
627 /*******************************************************************
628 * ChildWindowFromPointEx (USER32.@)
630 HWND WINAPI ChildWindowFromPointEx( HWND hwndParent, POINT pt,
633 /* pt is in the client coordinates */
635 WND* wnd = WIN_FindWndPtr(hwndParent);
641 /* get client rect fast */
642 rect.top = rect.left = 0;
643 rect.right = wnd->rectClient.right - wnd->rectClient.left;
644 rect.bottom = wnd->rectClient.bottom - wnd->rectClient.top;
646 if (!PtInRect( &rect, pt ))
651 WIN_UpdateWndPtr(&wnd,wnd->child);
655 if (PtInRect( &wnd->rectWindow, pt )) {
656 if ( (uFlags & CWP_SKIPINVISIBLE) &&
657 !(wnd->dwStyle & WS_VISIBLE) );
658 else if ( (uFlags & CWP_SKIPDISABLED) &&
659 (wnd->dwStyle & WS_DISABLED) );
660 else if ( (uFlags & CWP_SKIPTRANSPARENT) &&
661 (wnd->dwExStyle & WS_EX_TRANSPARENT) );
664 retvalue = wnd->hwndSelf;
669 WIN_UpdateWndPtr(&wnd,wnd->next);
671 retvalue = hwndParent;
673 WIN_ReleaseWndPtr(wnd);
678 /*******************************************************************
679 * WINPOS_GetWinOffset
681 * Calculate the offset between the origin of the two windows. Used
682 * to implement MapWindowPoints.
684 static void WINPOS_GetWinOffset( HWND hwndFrom, HWND hwndTo,
689 offset->x = offset->y = 0;
690 if (hwndFrom == hwndTo ) return;
692 /* Translate source window origin to screen coords */
695 if (!(wndPtr = WIN_FindWndPtr( hwndFrom )))
697 ERR("bad hwndFrom = %04x\n",hwndFrom);
700 while (wndPtr->parent)
702 offset->x += wndPtr->rectClient.left;
703 offset->y += wndPtr->rectClient.top;
704 WIN_UpdateWndPtr(&wndPtr,wndPtr->parent);
706 WIN_ReleaseWndPtr(wndPtr);
709 /* Translate origin to destination window coords */
712 if (!(wndPtr = WIN_FindWndPtr( hwndTo )))
714 ERR("bad hwndTo = %04x\n", hwndTo );
717 while (wndPtr->parent)
719 offset->x -= wndPtr->rectClient.left;
720 offset->y -= wndPtr->rectClient.top;
721 WIN_UpdateWndPtr(&wndPtr,wndPtr->parent);
723 WIN_ReleaseWndPtr(wndPtr);
728 /*******************************************************************
729 * MapWindowPoints (USER.258)
731 void WINAPI MapWindowPoints16( HWND16 hwndFrom, HWND16 hwndTo,
732 LPPOINT16 lppt, UINT16 count )
736 WINPOS_GetWinOffset( hwndFrom, hwndTo, &offset );
746 /*******************************************************************
747 * MapWindowPoints (USER32.@)
749 INT WINAPI MapWindowPoints( HWND hwndFrom, HWND hwndTo,
750 LPPOINT lppt, UINT count )
754 WINPOS_GetWinOffset( hwndFrom, hwndTo, &offset );
761 return MAKELONG( LOWORD(offset.x), LOWORD(offset.y) );
765 /***********************************************************************
768 BOOL16 WINAPI IsIconic16(HWND16 hWnd)
770 return IsIconic(hWnd);
774 /***********************************************************************
775 * IsIconic (USER32.@)
777 BOOL WINAPI IsIconic(HWND hWnd)
780 WND * wndPtr = WIN_FindWndPtr(hWnd);
781 if (wndPtr == NULL) return FALSE;
782 retvalue = (wndPtr->dwStyle & WS_MINIMIZE) != 0;
783 WIN_ReleaseWndPtr(wndPtr);
788 /***********************************************************************
789 * IsZoomed (USER.272)
791 BOOL16 WINAPI IsZoomed16(HWND16 hWnd)
793 return IsZoomed(hWnd);
797 /***********************************************************************
798 * IsZoomed (USER32.@)
800 BOOL WINAPI IsZoomed(HWND hWnd)
803 WND * wndPtr = WIN_FindWndPtr(hWnd);
804 if (wndPtr == NULL) return FALSE;
805 retvalue = (wndPtr->dwStyle & WS_MAXIMIZE) != 0;
806 WIN_ReleaseWndPtr(wndPtr);
811 /*******************************************************************
812 * GetActiveWindow (USER.60)
814 HWND16 WINAPI GetActiveWindow16(void)
816 return (HWND16)GetActiveWindow();
819 /*******************************************************************
820 * GetActiveWindow (USER32.@)
822 HWND WINAPI GetActiveWindow(void)
824 MESSAGEQUEUE *pCurMsgQ = 0;
827 /* Get the messageQ for the current thread */
828 if (!(pCurMsgQ = (MESSAGEQUEUE *)QUEUE_Lock( GetFastQueue16() )))
830 WARN("\tCurrent message queue not found. Exiting!\n" );
834 /* Return the current active window from the perQ data of the current message Q */
835 hwndActive = PERQDATA_GetActiveWnd( pCurMsgQ->pQData );
837 QUEUE_Unlock( pCurMsgQ );
842 /*******************************************************************
845 static BOOL WINPOS_CanActivate(WND* pWnd)
847 if( pWnd && ( (pWnd->dwStyle & (WS_DISABLED | WS_VISIBLE | WS_CHILD))
848 == WS_VISIBLE ) ) return TRUE;
853 /*******************************************************************
854 * SetActiveWindow (USER.59)
856 HWND16 WINAPI SetActiveWindow16( HWND16 hwnd )
858 return SetActiveWindow(hwnd);
862 /*******************************************************************
863 * SetActiveWindow (USER32.@)
865 HWND WINAPI SetActiveWindow( HWND hwnd )
868 WND *wndPtr = WIN_FindWndPtr( hwnd );
869 MESSAGEQUEUE *pMsgQ = 0, *pCurMsgQ = 0;
871 if (!wndPtr || (wndPtr->dwStyle & (WS_DISABLED | WS_CHILD)))
877 /* Get the messageQ for the current thread */
878 if (!(pCurMsgQ = (MESSAGEQUEUE *)QUEUE_Lock( GetFastQueue16() )))
880 WARN("\tCurrent message queue not found. Exiting!\n" );
884 /* Retrieve the message queue associated with this window */
885 pMsgQ = (MESSAGEQUEUE *)QUEUE_Lock( wndPtr->hmemTaskQ );
888 WARN("\tWindow message queue not found. Exiting!\n" );
892 /* Make sure that the window is associated with the calling threads
893 * message queue. It must share the same perQ data.
896 if ( pCurMsgQ->pQData != pMsgQ->pQData )
899 /* Save current active window */
900 prev = PERQDATA_GetActiveWnd( pMsgQ->pQData );
902 WINPOS_SetActiveWindow( hwnd, 0, 0 );
905 /* Unlock the queues before returning */
907 QUEUE_Unlock( pMsgQ );
909 QUEUE_Unlock( pCurMsgQ );
912 WIN_ReleaseWndPtr(wndPtr);
917 /*******************************************************************
918 * GetForegroundWindow (USER.608)
920 HWND16 WINAPI GetForegroundWindow16(void)
922 return (HWND16)GetForegroundWindow();
926 /*******************************************************************
927 * SetForegroundWindow (USER.609)
929 BOOL16 WINAPI SetForegroundWindow16( HWND16 hwnd )
931 return SetForegroundWindow( hwnd );
935 /*******************************************************************
936 * GetForegroundWindow (USER32.@)
938 HWND WINAPI GetForegroundWindow(void)
942 /* Get the foreground window (active window of hActiveQueue) */
945 MESSAGEQUEUE *pActiveQueue = QUEUE_Lock( hActiveQueue );
947 hwndActive = PERQDATA_GetActiveWnd( pActiveQueue->pQData );
949 QUEUE_Unlock( pActiveQueue );
955 /*******************************************************************
956 * SetForegroundWindow (USER32.@)
958 BOOL WINAPI SetForegroundWindow( HWND hwnd )
960 return WINPOS_ChangeActiveWindow( hwnd, FALSE );
964 /*******************************************************************
965 * AllowSetForegroundWindow (USER32.@)
967 BOOL WINAPI AllowSetForegroundWindow( DWORD procid )
969 /* FIXME: If Win98/2000 style SetForegroundWindow behavior is
970 * implemented, then fix this function. */
975 /*******************************************************************
976 * LockSetForegroundWindow (USER32.@)
978 BOOL WINAPI LockSetForegroundWindow( UINT lockcode )
980 /* FIXME: If Win98/2000 style SetForegroundWindow behavior is
981 * implemented, then fix this function. */
986 /*******************************************************************
987 * GetShellWindow (USER.600)
989 HWND16 WINAPI GetShellWindow16(void)
991 return GetShellWindow();
994 /*******************************************************************
995 * SetShellWindow (USER32.@)
997 HWND WINAPI SetShellWindow(HWND hwndshell)
998 { WARN("(hWnd=%08x) semi stub\n",hwndshell );
1000 hGlobalShellWindow = hwndshell;
1001 return hGlobalShellWindow;
1005 /*******************************************************************
1006 * GetShellWindow (USER32.@)
1008 HWND WINAPI GetShellWindow(void)
1009 { WARN("(hWnd=%x) semi stub\n",hGlobalShellWindow );
1011 return hGlobalShellWindow;
1015 /***********************************************************************
1016 * BringWindowToTop (USER.45)
1018 BOOL16 WINAPI BringWindowToTop16( HWND16 hwnd )
1020 return BringWindowToTop(hwnd);
1024 /***********************************************************************
1025 * BringWindowToTop (USER32.@)
1027 BOOL WINAPI BringWindowToTop( HWND hwnd )
1029 return SetWindowPos( hwnd, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE );
1033 /***********************************************************************
1034 * MoveWindow (USER.56)
1036 BOOL16 WINAPI MoveWindow16( HWND16 hwnd, INT16 x, INT16 y, INT16 cx, INT16 cy,
1039 return MoveWindow(hwnd,x,y,cx,cy,repaint);
1043 /***********************************************************************
1044 * MoveWindow (USER32.@)
1046 BOOL WINAPI MoveWindow( HWND hwnd, INT x, INT y, INT cx, INT cy,
1049 int flags = SWP_NOZORDER | SWP_NOACTIVATE;
1050 if (!repaint) flags |= SWP_NOREDRAW;
1051 TRACE("%04x %d,%d %dx%d %d\n",
1052 hwnd, x, y, cx, cy, repaint );
1053 return SetWindowPos( hwnd, 0, x, y, cx, cy, flags );
1056 /***********************************************************************
1057 * WINPOS_InitInternalPos
1059 static LPINTERNALPOS WINPOS_InitInternalPos( WND* wnd, POINT pt,
1060 LPRECT restoreRect )
1062 LPINTERNALPOS lpPos = (LPINTERNALPOS) GetPropA( wnd->hwndSelf,
1066 /* this happens when the window is minimized/maximized
1067 * for the first time (rectWindow is not adjusted yet) */
1069 lpPos = HeapAlloc( GetProcessHeap(), 0, sizeof(INTERNALPOS) );
1070 if( !lpPos ) return NULL;
1072 SetPropA( wnd->hwndSelf, atomInternalPos, (HANDLE)lpPos );
1073 lpPos->hwndIconTitle = 0; /* defer until needs to be shown */
1074 CONV_RECT32TO16( &wnd->rectWindow, &lpPos->rectNormal );
1075 *(UINT*)&lpPos->ptIconPos = *(UINT*)&lpPos->ptMaxPos = 0xFFFFFFFF;
1078 if( wnd->dwStyle & WS_MINIMIZE )
1079 CONV_POINT32TO16( &pt, &lpPos->ptIconPos );
1080 else if( wnd->dwStyle & WS_MAXIMIZE )
1081 CONV_POINT32TO16( &pt, &lpPos->ptMaxPos );
1082 else if( restoreRect )
1083 CONV_RECT32TO16( restoreRect, &lpPos->rectNormal );
1088 /***********************************************************************
1089 * WINPOS_RedrawIconTitle
1091 BOOL WINPOS_RedrawIconTitle( HWND hWnd )
1093 LPINTERNALPOS lpPos = (LPINTERNALPOS)GetPropA( hWnd, atomInternalPos );
1096 if( lpPos->hwndIconTitle )
1098 SendMessageA( lpPos->hwndIconTitle, WM_SHOWWINDOW, TRUE, 0);
1099 InvalidateRect( lpPos->hwndIconTitle, NULL, TRUE );
1106 /***********************************************************************
1107 * WINPOS_ShowIconTitle
1109 BOOL WINPOS_ShowIconTitle( WND* pWnd, BOOL bShow )
1111 LPINTERNALPOS lpPos = (LPINTERNALPOS)GetPropA( pWnd->hwndSelf, atomInternalPos );
1113 if( lpPos && !(pWnd->dwExStyle & WS_EX_MANAGED))
1115 HWND16 hWnd = lpPos->hwndIconTitle;
1117 TRACE("0x%04x %i\n", pWnd->hwndSelf, (bShow != 0) );
1120 lpPos->hwndIconTitle = hWnd = ICONTITLE_Create( pWnd );
1123 if( ( pWnd = WIN_FindWndPtr(hWnd) ) != NULL)
1125 if( !(pWnd->dwStyle & WS_VISIBLE) )
1127 SendMessageA( hWnd, WM_SHOWWINDOW, TRUE, 0 );
1128 SetWindowPos( hWnd, 0, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE |
1129 SWP_NOACTIVATE | SWP_NOZORDER | SWP_SHOWWINDOW );
1131 WIN_ReleaseWndPtr(pWnd);
1134 else ShowWindow( hWnd, SW_HIDE );
1139 /*******************************************************************
1140 * WINPOS_GetMinMaxInfo
1142 * Get the minimized and maximized information for a window.
1144 void WINPOS_GetMinMaxInfo( WND *wndPtr, POINT *maxSize, POINT *maxPos,
1145 POINT *minTrack, POINT *maxTrack )
1147 LPINTERNALPOS lpPos;
1151 /* Compute default values */
1153 MinMax.ptMaxSize.x = GetSystemMetrics(SM_CXSCREEN);
1154 MinMax.ptMaxSize.y = GetSystemMetrics(SM_CYSCREEN);
1155 MinMax.ptMinTrackSize.x = GetSystemMetrics(SM_CXMINTRACK);
1156 MinMax.ptMinTrackSize.y = GetSystemMetrics(SM_CYMINTRACK);
1157 MinMax.ptMaxTrackSize.x = GetSystemMetrics(SM_CXSCREEN);
1158 MinMax.ptMaxTrackSize.y = GetSystemMetrics(SM_CYSCREEN);
1160 if (wndPtr->dwExStyle & WS_EX_MANAGED) xinc = yinc = 0;
1161 else if (HAS_DLGFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
1163 xinc = GetSystemMetrics(SM_CXDLGFRAME);
1164 yinc = GetSystemMetrics(SM_CYDLGFRAME);
1169 if (HAS_THICKFRAME(wndPtr->dwStyle))
1171 xinc += GetSystemMetrics(SM_CXFRAME);
1172 yinc += GetSystemMetrics(SM_CYFRAME);
1174 if (wndPtr->dwStyle & WS_BORDER)
1176 xinc += GetSystemMetrics(SM_CXBORDER);
1177 yinc += GetSystemMetrics(SM_CYBORDER);
1180 MinMax.ptMaxSize.x += 2 * xinc;
1181 MinMax.ptMaxSize.y += 2 * yinc;
1183 lpPos = (LPINTERNALPOS)GetPropA( wndPtr->hwndSelf, atomInternalPos );
1184 if( lpPos && !EMPTYPOINT(lpPos->ptMaxPos) )
1185 CONV_POINT16TO32( &lpPos->ptMaxPos, &MinMax.ptMaxPosition );
1188 MinMax.ptMaxPosition.x = -xinc;
1189 MinMax.ptMaxPosition.y = -yinc;
1192 SendMessageA( wndPtr->hwndSelf, WM_GETMINMAXINFO, 0, (LPARAM)&MinMax );
1194 /* Some sanity checks */
1196 TRACE("%ld %ld / %ld %ld / %ld %ld / %ld %ld\n",
1197 MinMax.ptMaxSize.x, MinMax.ptMaxSize.y,
1198 MinMax.ptMaxPosition.x, MinMax.ptMaxPosition.y,
1199 MinMax.ptMaxTrackSize.x, MinMax.ptMaxTrackSize.y,
1200 MinMax.ptMinTrackSize.x, MinMax.ptMinTrackSize.y);
1201 MinMax.ptMaxTrackSize.x = max( MinMax.ptMaxTrackSize.x,
1202 MinMax.ptMinTrackSize.x );
1203 MinMax.ptMaxTrackSize.y = max( MinMax.ptMaxTrackSize.y,
1204 MinMax.ptMinTrackSize.y );
1206 if (maxSize) *maxSize = MinMax.ptMaxSize;
1207 if (maxPos) *maxPos = MinMax.ptMaxPosition;
1208 if (minTrack) *minTrack = MinMax.ptMinTrackSize;
1209 if (maxTrack) *maxTrack = MinMax.ptMaxTrackSize;
1212 /***********************************************************************
1213 * WINPOS_MinMaximize
1215 * Fill in lpRect and return additional flags to be used with SetWindowPos().
1216 * This function assumes that 'cmd' is different from the current window
1219 UINT WINPOS_MinMaximize( WND* wndPtr, UINT16 cmd, LPRECT16 lpRect )
1223 LPINTERNALPOS lpPos;
1225 TRACE("0x%04x %u\n", wndPtr->hwndSelf, cmd );
1227 size.x = wndPtr->rectWindow.left; size.y = wndPtr->rectWindow.top;
1228 lpPos = WINPOS_InitInternalPos( wndPtr, size, &wndPtr->rectWindow );
1230 if (lpPos && !HOOK_CallHooksA(WH_CBT, HCBT_MINMAX, wndPtr->hwndSelf, cmd))
1232 if( wndPtr->dwStyle & WS_MINIMIZE )
1234 if( !SendMessageA( wndPtr->hwndSelf, WM_QUERYOPEN, 0, 0L ) )
1235 return (SWP_NOSIZE | SWP_NOMOVE);
1236 swpFlags |= SWP_NOCOPYBITS;
1241 if( wndPtr->dwStyle & WS_MAXIMIZE)
1243 wndPtr->flags |= WIN_RESTORE_MAX;
1244 wndPtr->dwStyle &= ~WS_MAXIMIZE;
1247 wndPtr->flags &= ~WIN_RESTORE_MAX;
1248 wndPtr->dwStyle |= WS_MINIMIZE;
1250 if( wndPtr->pDriver->pSetHostAttr( wndPtr, HAK_ICONICSTATE, TRUE ) )
1251 swpFlags |= MINMAX_NOSWP;
1253 lpPos->ptIconPos = WINPOS_FindIconPos( wndPtr, lpPos->ptIconPos );
1255 SetRect16( lpRect, lpPos->ptIconPos.x, lpPos->ptIconPos.y,
1256 GetSystemMetrics(SM_CXICON), GetSystemMetrics(SM_CYICON) );
1257 swpFlags |= SWP_NOCOPYBITS;
1261 CONV_POINT16TO32( &lpPos->ptMaxPos, &pt );
1262 WINPOS_GetMinMaxInfo( wndPtr, &size, &pt, NULL, NULL );
1263 CONV_POINT32TO16( &pt, &lpPos->ptMaxPos );
1265 if( wndPtr->dwStyle & WS_MINIMIZE )
1267 wndPtr->pDriver->pSetHostAttr( wndPtr, HAK_ICONICSTATE, FALSE );
1269 WINPOS_ShowIconTitle( wndPtr, FALSE );
1270 wndPtr->dwStyle &= ~WS_MINIMIZE;
1272 wndPtr->dwStyle |= WS_MAXIMIZE;
1274 SetRect16( lpRect, lpPos->ptMaxPos.x, lpPos->ptMaxPos.y,
1279 if( wndPtr->dwStyle & WS_MINIMIZE )
1281 wndPtr->pDriver->pSetHostAttr( wndPtr, HAK_ICONICSTATE, FALSE );
1283 wndPtr->dwStyle &= ~WS_MINIMIZE;
1284 WINPOS_ShowIconTitle( wndPtr, FALSE );
1286 if( wndPtr->flags & WIN_RESTORE_MAX)
1288 /* Restore to maximized position */
1289 CONV_POINT16TO32( &lpPos->ptMaxPos, &pt );
1290 WINPOS_GetMinMaxInfo( wndPtr, &size, &pt, NULL, NULL);
1291 CONV_POINT32TO16( &pt, &lpPos->ptMaxPos );
1292 wndPtr->dwStyle |= WS_MAXIMIZE;
1293 SetRect16( lpRect, lpPos->ptMaxPos.x, lpPos->ptMaxPos.y, size.x, size.y );
1298 if( !(wndPtr->dwStyle & WS_MAXIMIZE) ) return (UINT16)(-1);
1299 else wndPtr->dwStyle &= ~WS_MAXIMIZE;
1301 /* Restore to normal position */
1303 *lpRect = lpPos->rectNormal;
1304 lpRect->right -= lpRect->left;
1305 lpRect->bottom -= lpRect->top;
1309 } else swpFlags |= SWP_NOSIZE | SWP_NOMOVE;
1313 /***********************************************************************
1314 * ShowWindowAsync (USER32.@)
1316 * doesn't wait; returns immediately.
1317 * used by threads to toggle windows in other (possibly hanging) threads
1319 BOOL WINAPI ShowWindowAsync( HWND hwnd, INT cmd )
1321 /* FIXME: does ShowWindow() return immediately ? */
1322 return ShowWindow(hwnd, cmd);
1326 /***********************************************************************
1327 * ShowWindow (USER.42)
1329 BOOL16 WINAPI ShowWindow16( HWND16 hwnd, INT16 cmd )
1331 return ShowWindow(hwnd,cmd);
1335 /***********************************************************************
1336 * ShowWindow (USER32.@)
1338 BOOL WINAPI ShowWindow( HWND hwnd, INT cmd )
1340 WND* wndPtr = WIN_FindWndPtr( hwnd );
1341 BOOL wasVisible, showFlag;
1342 RECT16 newPos = {0, 0, 0, 0};
1345 if (!wndPtr) return FALSE;
1347 TRACE("hwnd=%04x, cmd=%d\n", hwnd, cmd);
1349 wasVisible = (wndPtr->dwStyle & WS_VISIBLE) != 0;
1354 if (!wasVisible) goto END;;
1355 swp |= SWP_HIDEWINDOW | SWP_NOSIZE | SWP_NOMOVE |
1356 SWP_NOACTIVATE | SWP_NOZORDER;
1359 case SW_SHOWMINNOACTIVE:
1360 swp |= SWP_NOACTIVATE | SWP_NOZORDER;
1362 case SW_SHOWMINIMIZED:
1363 swp |= SWP_SHOWWINDOW;
1366 swp |= SWP_FRAMECHANGED;
1367 if( !(wndPtr->dwStyle & WS_MINIMIZE) )
1368 swp |= WINPOS_MinMaximize( wndPtr, SW_MINIMIZE, &newPos );
1369 else swp |= SWP_NOSIZE | SWP_NOMOVE;
1372 case SW_SHOWMAXIMIZED: /* same as SW_MAXIMIZE */
1373 swp |= SWP_SHOWWINDOW | SWP_FRAMECHANGED;
1374 if( !(wndPtr->dwStyle & WS_MAXIMIZE) )
1375 swp |= WINPOS_MinMaximize( wndPtr, SW_MAXIMIZE, &newPos );
1376 else swp |= SWP_NOSIZE | SWP_NOMOVE;
1380 swp |= SWP_NOACTIVATE | SWP_NOZORDER;
1383 swp |= SWP_SHOWWINDOW | SWP_NOSIZE | SWP_NOMOVE;
1386 * ShowWindow has a little peculiar behavior that if the
1387 * window is already the topmost window, it will not
1390 if (GetTopWindow((HWND)0)==hwnd && (wasVisible || GetActiveWindow() == hwnd))
1391 swp |= SWP_NOACTIVATE;
1395 case SW_SHOWNOACTIVATE:
1396 swp |= SWP_NOZORDER;
1397 if (GetActiveWindow()) swp |= SWP_NOACTIVATE;
1399 case SW_SHOWNORMAL: /* same as SW_NORMAL: */
1400 case SW_SHOWDEFAULT: /* FIXME: should have its own handler */
1402 swp |= SWP_SHOWWINDOW | SWP_FRAMECHANGED;
1404 if( wndPtr->dwStyle & (WS_MINIMIZE | WS_MAXIMIZE) )
1405 swp |= WINPOS_MinMaximize( wndPtr, SW_RESTORE, &newPos );
1406 else swp |= SWP_NOSIZE | SWP_NOMOVE;
1410 showFlag = (cmd != SW_HIDE);
1411 if (showFlag != wasVisible)
1413 SendMessageA( hwnd, WM_SHOWWINDOW, showFlag, 0 );
1414 if (!IsWindow( hwnd )) goto END;
1417 if ((wndPtr->dwStyle & WS_CHILD) &&
1418 !IsWindowVisible( wndPtr->parent->hwndSelf ) &&
1419 (swp & (SWP_NOSIZE | SWP_NOMOVE)) == (SWP_NOSIZE | SWP_NOMOVE) )
1421 /* Don't call SetWindowPos() on invisible child windows */
1422 if (cmd == SW_HIDE) wndPtr->dwStyle &= ~WS_VISIBLE;
1423 else wndPtr->dwStyle |= WS_VISIBLE;
1427 /* We can't activate a child window */
1428 if ((wndPtr->dwStyle & WS_CHILD) &&
1429 !(wndPtr->dwExStyle & WS_EX_MDICHILD))
1430 swp |= SWP_NOACTIVATE | SWP_NOZORDER;
1431 if (!(swp & MINMAX_NOSWP))
1433 SetWindowPos( hwnd, HWND_TOP, newPos.left, newPos.top,
1434 newPos.right, newPos.bottom, LOWORD(swp) );
1437 /* FIXME: This will cause the window to be activated irrespective
1438 * of whether it is owned by the same thread. Has to be done
1442 if (hwnd == GetActiveWindow())
1443 WINPOS_ActivateOtherWindow(wndPtr);
1445 /* Revert focus to parent */
1446 if (hwnd == GetFocus() || IsChild(hwnd, GetFocus()))
1447 SetFocus( GetParent(hwnd) );
1450 if (!IsWindow( hwnd )) goto END;
1451 else if( wndPtr->dwStyle & WS_MINIMIZE ) WINPOS_ShowIconTitle( wndPtr, TRUE );
1454 if (wndPtr->flags & WIN_NEED_SIZE)
1456 /* should happen only in CreateWindowEx() */
1457 int wParam = SIZE_RESTORED;
1459 wndPtr->flags &= ~WIN_NEED_SIZE;
1460 if (wndPtr->dwStyle & WS_MAXIMIZE) wParam = SIZE_MAXIMIZED;
1461 else if (wndPtr->dwStyle & WS_MINIMIZE) wParam = SIZE_MINIMIZED;
1462 SendMessageA( hwnd, WM_SIZE, wParam,
1463 MAKELONG(wndPtr->rectClient.right-wndPtr->rectClient.left,
1464 wndPtr->rectClient.bottom-wndPtr->rectClient.top));
1465 SendMessageA( hwnd, WM_MOVE, 0,
1466 MAKELONG(wndPtr->rectClient.left, wndPtr->rectClient.top) );
1470 WIN_ReleaseWndPtr(wndPtr);
1475 /***********************************************************************
1476 * GetInternalWindowPos (USER.460)
1478 UINT16 WINAPI GetInternalWindowPos16( HWND16 hwnd, LPRECT16 rectWnd,
1481 WINDOWPLACEMENT16 wndpl;
1482 if (GetWindowPlacement16( hwnd, &wndpl ))
1484 if (rectWnd) *rectWnd = wndpl.rcNormalPosition;
1485 if (ptIcon) *ptIcon = wndpl.ptMinPosition;
1486 return wndpl.showCmd;
1492 /***********************************************************************
1493 * GetInternalWindowPos (USER32.@)
1495 UINT WINAPI GetInternalWindowPos( HWND hwnd, LPRECT rectWnd,
1498 WINDOWPLACEMENT wndpl;
1499 if (GetWindowPlacement( hwnd, &wndpl ))
1501 if (rectWnd) *rectWnd = wndpl.rcNormalPosition;
1502 if (ptIcon) *ptIcon = wndpl.ptMinPosition;
1503 return wndpl.showCmd;
1508 /***********************************************************************
1509 * GetWindowPlacement (USER.370)
1511 BOOL16 WINAPI GetWindowPlacement16( HWND16 hwnd, WINDOWPLACEMENT16 *wndpl )
1513 WND *pWnd = WIN_FindWndPtr( hwnd );
1514 LPINTERNALPOS lpPos;
1516 if(!pWnd ) return FALSE;
1518 lpPos = (LPINTERNALPOS)WINPOS_InitInternalPos( pWnd,
1519 *(LPPOINT)&pWnd->rectWindow.left, &pWnd->rectWindow );
1520 wndpl->length = sizeof(*wndpl);
1521 if( pWnd->dwStyle & WS_MINIMIZE )
1522 wndpl->showCmd = SW_SHOWMINIMIZED;
1524 wndpl->showCmd = ( pWnd->dwStyle & WS_MAXIMIZE )
1525 ? SW_SHOWMAXIMIZED : SW_SHOWNORMAL ;
1526 if( pWnd->flags & WIN_RESTORE_MAX )
1527 wndpl->flags = WPF_RESTORETOMAXIMIZED;
1530 wndpl->ptMinPosition = lpPos->ptIconPos;
1531 wndpl->ptMaxPosition = lpPos->ptMaxPos;
1532 wndpl->rcNormalPosition = lpPos->rectNormal;
1534 WIN_ReleaseWndPtr(pWnd);
1539 /***********************************************************************
1540 * GetWindowPlacement (USER32.@)
1543 * Fails if wndpl->length of Win95 (!) apps is invalid.
1545 BOOL WINAPI GetWindowPlacement( HWND hwnd, WINDOWPLACEMENT *pwpl32 )
1549 WINDOWPLACEMENT16 wpl;
1550 wpl.length = sizeof(wpl);
1551 if( GetWindowPlacement16( hwnd, &wpl ) )
1553 pwpl32->length = sizeof(*pwpl32);
1554 pwpl32->flags = wpl.flags;
1555 pwpl32->showCmd = wpl.showCmd;
1556 CONV_POINT16TO32( &wpl.ptMinPosition, &pwpl32->ptMinPosition );
1557 CONV_POINT16TO32( &wpl.ptMaxPosition, &pwpl32->ptMaxPosition );
1558 CONV_RECT16TO32( &wpl.rcNormalPosition, &pwpl32->rcNormalPosition );
1566 /***********************************************************************
1567 * WINPOS_SetPlacement
1569 static BOOL WINPOS_SetPlacement( HWND hwnd, const WINDOWPLACEMENT16 *wndpl,
1572 WND *pWnd = WIN_FindWndPtr( hwnd );
1575 LPINTERNALPOS lpPos = (LPINTERNALPOS)WINPOS_InitInternalPos( pWnd,
1576 *(LPPOINT)&pWnd->rectWindow.left, &pWnd->rectWindow );
1578 if( flags & PLACE_MIN ) lpPos->ptIconPos = wndpl->ptMinPosition;
1579 if( flags & PLACE_MAX ) lpPos->ptMaxPos = wndpl->ptMaxPosition;
1580 if( flags & PLACE_RECT) lpPos->rectNormal = wndpl->rcNormalPosition;
1582 if( pWnd->dwStyle & WS_MINIMIZE )
1584 WINPOS_ShowIconTitle( pWnd, FALSE );
1585 if( wndpl->flags & WPF_SETMINPOSITION && !EMPTYPOINT(lpPos->ptIconPos))
1586 SetWindowPos( hwnd, 0, lpPos->ptIconPos.x, lpPos->ptIconPos.y,
1587 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE );
1589 else if( pWnd->dwStyle & WS_MAXIMIZE )
1591 if( !EMPTYPOINT(lpPos->ptMaxPos) )
1592 SetWindowPos( hwnd, 0, lpPos->ptMaxPos.x, lpPos->ptMaxPos.y,
1593 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE );
1595 else if( flags & PLACE_RECT )
1596 SetWindowPos( hwnd, 0, lpPos->rectNormal.left, lpPos->rectNormal.top,
1597 lpPos->rectNormal.right - lpPos->rectNormal.left,
1598 lpPos->rectNormal.bottom - lpPos->rectNormal.top,
1599 SWP_NOZORDER | SWP_NOACTIVATE );
1601 ShowWindow( hwnd, wndpl->showCmd );
1602 if( IsWindow(hwnd) && pWnd->dwStyle & WS_MINIMIZE )
1604 if( pWnd->dwStyle & WS_VISIBLE ) WINPOS_ShowIconTitle( pWnd, TRUE );
1606 /* SDK: ...valid only the next time... */
1607 if( wndpl->flags & WPF_RESTORETOMAXIMIZED ) pWnd->flags |= WIN_RESTORE_MAX;
1609 WIN_ReleaseWndPtr(pWnd);
1616 /***********************************************************************
1617 * SetWindowPlacement (USER.371)
1619 BOOL16 WINAPI SetWindowPlacement16(HWND16 hwnd, const WINDOWPLACEMENT16 *wndpl)
1621 return WINPOS_SetPlacement( hwnd, wndpl,
1622 PLACE_MIN | PLACE_MAX | PLACE_RECT );
1625 /***********************************************************************
1626 * SetWindowPlacement (USER32.@)
1629 * Fails if wndpl->length of Win95 (!) apps is invalid.
1631 BOOL WINAPI SetWindowPlacement( HWND hwnd, const WINDOWPLACEMENT *pwpl32 )
1635 WINDOWPLACEMENT16 wpl;
1637 wpl.length = sizeof(WINDOWPLACEMENT16);
1638 wpl.flags = pwpl32->flags;
1639 wpl.showCmd = pwpl32->showCmd;
1640 wpl.ptMinPosition.x = pwpl32->ptMinPosition.x;
1641 wpl.ptMinPosition.y = pwpl32->ptMinPosition.y;
1642 wpl.ptMaxPosition.x = pwpl32->ptMaxPosition.x;
1643 wpl.ptMaxPosition.y = pwpl32->ptMaxPosition.y;
1644 wpl.rcNormalPosition.left = pwpl32->rcNormalPosition.left;
1645 wpl.rcNormalPosition.top = pwpl32->rcNormalPosition.top;
1646 wpl.rcNormalPosition.right = pwpl32->rcNormalPosition.right;
1647 wpl.rcNormalPosition.bottom = pwpl32->rcNormalPosition.bottom;
1649 return WINPOS_SetPlacement( hwnd, &wpl, PLACE_MIN | PLACE_MAX | PLACE_RECT );
1655 /***********************************************************************
1656 * SetInternalWindowPos (USER.461)
1658 void WINAPI SetInternalWindowPos16( HWND16 hwnd, UINT16 showCmd,
1659 LPRECT16 rect, LPPOINT16 pt )
1661 if( IsWindow16(hwnd) )
1663 WINDOWPLACEMENT16 wndpl;
1666 wndpl.length = sizeof(wndpl);
1667 wndpl.showCmd = showCmd;
1668 wndpl.flags = flags = 0;
1673 wndpl.flags |= WPF_SETMINPOSITION;
1674 wndpl.ptMinPosition = *pt;
1678 flags |= PLACE_RECT;
1679 wndpl.rcNormalPosition = *rect;
1681 WINPOS_SetPlacement( hwnd, &wndpl, flags );
1686 /***********************************************************************
1687 * SetInternalWindowPos (USER32.@)
1689 void WINAPI SetInternalWindowPos( HWND hwnd, UINT showCmd,
1690 LPRECT rect, LPPOINT pt )
1692 if( IsWindow(hwnd) )
1694 WINDOWPLACEMENT16 wndpl;
1697 wndpl.length = sizeof(wndpl);
1698 wndpl.showCmd = showCmd;
1699 wndpl.flags = flags = 0;
1704 wndpl.flags |= WPF_SETMINPOSITION;
1705 CONV_POINT32TO16( pt, &wndpl.ptMinPosition );
1709 flags |= PLACE_RECT;
1710 CONV_RECT32TO16( rect, &wndpl.rcNormalPosition );
1712 WINPOS_SetPlacement( hwnd, &wndpl, flags );
1716 /*******************************************************************
1717 * WINPOS_SetActiveWindow
1719 * SetActiveWindow() back-end. This is the only function that
1720 * can assign active status to a window. It must be called only
1721 * for the top level windows.
1723 BOOL WINPOS_SetActiveWindow( HWND hWnd, BOOL fMouse, BOOL fChangeFocus)
1725 WND* wndPtr=0, *wndTemp;
1726 HQUEUE16 hOldActiveQueue, hNewActiveQueue;
1727 MESSAGEQUEUE *pOldActiveQueue = 0, *pNewActiveQueue = 0;
1729 HWND hwndActive = 0;
1732 TRACE("(%04x, %d, %d)\n", hWnd, fMouse, fChangeFocus );
1734 /* Get current active window from the active queue */
1737 pOldActiveQueue = QUEUE_Lock( hActiveQueue );
1738 if ( pOldActiveQueue )
1739 hwndActive = PERQDATA_GetActiveWnd( pOldActiveQueue->pQData );
1742 /* paranoid checks */
1743 if( hWnd == GetDesktopWindow() || (bRet = (hWnd == hwndActive)) )
1746 /* if (wndPtr && (GetFastQueue16() != wndPtr->hmemTaskQ))
1749 wndPtr = WIN_FindWndPtr(hWnd);
1750 hOldActiveQueue = hActiveQueue;
1752 if( (wndTemp = WIN_FindWndPtr(hwndActive)) )
1754 wIconized = HIWORD(wndTemp->dwStyle & WS_MINIMIZE);
1755 WIN_ReleaseWndPtr(wndTemp);
1758 TRACE("no current active window.\n");
1760 /* call CBT hook chain */
1761 if (HOOK_IsHooked( WH_CBT ))
1763 CBTACTIVATESTRUCT cbt;
1764 cbt.fMouse = fMouse;
1765 cbt.hWndActive = hwndActive;
1766 if (HOOK_CallHooksA( WH_CBT, HCBT_ACTIVATE, hWnd, (LPARAM)&cbt )) goto CLEANUP_END;
1769 /* set prev active wnd to current active wnd and send notification */
1770 if ((hwndPrevActive = hwndActive) && IsWindow(hwndPrevActive))
1772 MESSAGEQUEUE *pTempActiveQueue = 0;
1774 if (!SendMessageA( hwndPrevActive, WM_NCACTIVATE, FALSE, 0 ))
1776 if (GetSysModalWindow16() != hWnd)
1778 /* disregard refusal if hWnd is sysmodal */
1781 SendMessageA( hwndPrevActive, WM_ACTIVATE,
1782 MAKEWPARAM( WA_INACTIVE, wIconized ),
1785 /* check if something happened during message processing
1786 * (global active queue may have changed)
1788 pTempActiveQueue = QUEUE_Lock( hActiveQueue );
1789 if(!pTempActiveQueue)
1792 hwndActive = PERQDATA_GetActiveWnd( pTempActiveQueue->pQData );
1793 QUEUE_Unlock( pTempActiveQueue );
1794 if( hwndPrevActive != hwndActive )
1798 /* Set new active window in the message queue */
1802 pNewActiveQueue = QUEUE_Lock( wndPtr->hmemTaskQ );
1803 if ( pNewActiveQueue )
1804 PERQDATA_SetActiveWnd( pNewActiveQueue->pQData, hwndActive );
1806 else /* have to do this or MDI frame activation goes to hell */
1807 if( pOldActiveQueue )
1808 PERQDATA_SetActiveWnd( pOldActiveQueue->pQData, 0 );
1810 /* send palette messages */
1811 if (hWnd && SendMessage16( hWnd, WM_QUERYNEWPALETTE, 0, 0L))
1812 SendMessage16((HWND16)-1, WM_PALETTEISCHANGING, (WPARAM16)hWnd, 0L );
1814 /* if prev wnd is minimized redraw icon title */
1815 if( IsIconic( hwndPrevActive ) ) WINPOS_RedrawIconTitle(hwndPrevActive);
1817 /* managed windows will get ConfigureNotify event */
1818 if (wndPtr && !(wndPtr->dwStyle & WS_CHILD) && !(wndPtr->dwExStyle & WS_EX_MANAGED))
1820 /* check Z-order and bring hWnd to the top */
1821 for (wndTemp = WIN_LockWndPtr(WIN_GetDesktop()->child); wndTemp; WIN_UpdateWndPtr(&wndTemp,wndTemp->next))
1823 if (wndTemp->dwStyle & WS_VISIBLE) break;
1825 WIN_ReleaseDesktop();
1826 WIN_ReleaseWndPtr(wndTemp);
1828 if( wndTemp != wndPtr )
1829 SetWindowPos(hWnd, HWND_TOP, 0,0,0,0,
1830 SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE );
1831 if (!IsWindow(hWnd))
1835 /* Get a handle to the new active queue */
1836 hNewActiveQueue = wndPtr ? wndPtr->hmemTaskQ : 0;
1838 /* send WM_ACTIVATEAPP if necessary */
1839 if (hOldActiveQueue != hNewActiveQueue)
1841 WND **list, **ppWnd;
1842 WND *pDesktop = WIN_GetDesktop();
1844 if ((list = WIN_BuildWinArray( pDesktop, 0, NULL )))
1846 for (ppWnd = list; *ppWnd; ppWnd++)
1848 if (!IsWindow( (*ppWnd)->hwndSelf )) continue;
1850 if ((*ppWnd)->hmemTaskQ == hOldActiveQueue)
1851 SendMessage16( (*ppWnd)->hwndSelf, WM_ACTIVATEAPP,
1852 0, QUEUE_GetQueueTask(hNewActiveQueue) );
1854 WIN_ReleaseWinArray(list);
1857 hActiveQueue = hNewActiveQueue;
1859 if ((list = WIN_BuildWinArray(pDesktop, 0, NULL )))
1861 for (ppWnd = list; *ppWnd; ppWnd++)
1863 if (!IsWindow( (*ppWnd)->hwndSelf )) continue;
1865 if ((*ppWnd)->hmemTaskQ == hNewActiveQueue)
1866 SendMessage16( (*ppWnd)->hwndSelf, WM_ACTIVATEAPP,
1867 1, QUEUE_GetQueueTask( hOldActiveQueue ) );
1869 WIN_ReleaseWinArray(list);
1871 WIN_ReleaseDesktop();
1873 if (hWnd && !IsWindow(hWnd)) goto CLEANUP;
1878 /* walk up to the first unowned window */
1879 wndTemp = WIN_LockWndPtr(wndPtr);
1880 while (wndTemp->owner)
1882 WIN_UpdateWndPtr(&wndTemp,wndTemp->owner);
1884 /* and set last active owned popup */
1885 wndTemp->hwndLastActive = hWnd;
1887 wIconized = HIWORD(wndTemp->dwStyle & WS_MINIMIZE);
1888 WIN_ReleaseWndPtr(wndTemp);
1889 SendMessageA( hWnd, WM_NCACTIVATE, TRUE, 0 );
1890 SendMessageA( hWnd, WM_ACTIVATE,
1891 MAKEWPARAM( (fMouse) ? WA_CLICKACTIVE : WA_ACTIVE, wIconized),
1892 (LPARAM)hwndPrevActive );
1893 if( !IsWindow(hWnd) ) goto CLEANUP;
1896 /* change focus if possible */
1899 if ( pNewActiveQueue )
1901 HWND hOldFocus = PERQDATA_GetFocusWnd( pNewActiveQueue->pQData );
1903 if ( hOldFocus && WIN_GetTopParent( hOldFocus ) != hwndActive )
1904 FOCUS_SwitchFocus( pNewActiveQueue, hOldFocus,
1905 (wndPtr && (wndPtr->dwStyle & WS_MINIMIZE))?
1909 if ( pOldActiveQueue &&
1910 ( !pNewActiveQueue ||
1911 pNewActiveQueue->pQData != pOldActiveQueue->pQData ) )
1913 HWND hOldFocus = PERQDATA_GetFocusWnd( pOldActiveQueue->pQData );
1915 FOCUS_SwitchFocus( pOldActiveQueue, hOldFocus, 0 );
1919 if( !hwndPrevActive && wndPtr )
1920 (*wndPtr->pDriver->pForceWindowRaise)(wndPtr);
1922 /* if active wnd is minimized redraw icon title */
1923 if( IsIconic(hwndActive) ) WINPOS_RedrawIconTitle(hwndActive);
1925 bRet = (hWnd == hwndActive); /* Success? */
1927 CLEANUP: /* Unlock the message queues before returning */
1929 if ( pNewActiveQueue )
1930 QUEUE_Unlock( pNewActiveQueue );
1934 if ( pOldActiveQueue )
1935 QUEUE_Unlock( pOldActiveQueue );
1937 WIN_ReleaseWndPtr(wndPtr);
1941 /*******************************************************************
1942 * WINPOS_ActivateOtherWindow
1944 * Activates window other than pWnd.
1946 BOOL WINPOS_ActivateOtherWindow(WND* pWnd)
1950 HWND hwndActive = 0;
1952 /* Get current active window from the active queue */
1955 MESSAGEQUEUE *pActiveQueue = QUEUE_Lock( hActiveQueue );
1958 hwndActive = PERQDATA_GetActiveWnd( pActiveQueue->pQData );
1959 QUEUE_Unlock( pActiveQueue );
1963 if( pWnd->hwndSelf == hwndPrevActive )
1966 if( hwndActive != pWnd->hwndSelf &&
1967 ( hwndActive || QUEUE_IsExitingQueue(pWnd->hmemTaskQ)) )
1970 if( !(pWnd->dwStyle & WS_POPUP) || !(pWnd->owner) ||
1971 !WINPOS_CanActivate((pWndTo = WIN_GetTopParentPtr(pWnd->owner))) )
1973 WND* pWndPtr = WIN_GetTopParentPtr(pWnd);
1975 WIN_ReleaseWndPtr(pWndTo);
1976 pWndTo = WIN_FindWndPtr(hwndPrevActive);
1978 while( !WINPOS_CanActivate(pWndTo) )
1980 /* by now owned windows should've been taken care of */
1981 WIN_UpdateWndPtr(&pWndTo,pWndPtr->next);
1982 WIN_UpdateWndPtr(&pWndPtr,pWndTo);
1983 if( !pWndTo ) break;
1985 WIN_ReleaseWndPtr(pWndPtr);
1988 bRet = WINPOS_SetActiveWindow( pWndTo ? pWndTo->hwndSelf : 0, FALSE, TRUE );
1990 /* switch desktop queue to current active */
1993 WIN_GetDesktop()->hmemTaskQ = pWndTo->hmemTaskQ;
1994 WIN_ReleaseWndPtr(pWndTo);
1995 WIN_ReleaseDesktop();
2002 /*******************************************************************
2003 * WINPOS_ChangeActiveWindow
2006 BOOL WINPOS_ChangeActiveWindow( HWND hWnd, BOOL mouseMsg )
2008 WND *wndPtr, *wndTemp;
2010 HWND hwndActive = 0;
2012 /* Get current active window from the active queue */
2015 MESSAGEQUEUE *pActiveQueue = QUEUE_Lock( hActiveQueue );
2018 hwndActive = PERQDATA_GetActiveWnd( pActiveQueue->pQData );
2019 QUEUE_Unlock( pActiveQueue );
2024 return WINPOS_SetActiveWindow( 0, mouseMsg, TRUE );
2026 wndPtr = WIN_FindWndPtr(hWnd);
2027 if( !wndPtr ) return FALSE;
2029 /* child windows get WM_CHILDACTIVATE message */
2030 if( (wndPtr->dwStyle & (WS_CHILD | WS_POPUP)) == WS_CHILD )
2032 retvalue = SendMessageA(hWnd, WM_CHILDACTIVATE, 0, 0L);
2036 if( hWnd == hwndActive )
2042 if( !WINPOS_SetActiveWindow(hWnd ,mouseMsg ,TRUE) )
2048 /* switch desktop queue to current active */
2049 wndTemp = WIN_GetDesktop();
2050 if( wndPtr->parent == wndTemp)
2051 wndTemp->hmemTaskQ = wndPtr->hmemTaskQ;
2052 WIN_ReleaseDesktop();
2056 WIN_ReleaseWndPtr(wndPtr);
2061 /***********************************************************************
2062 * WINPOS_SendNCCalcSize
2064 * Send a WM_NCCALCSIZE message to a window.
2065 * All parameters are read-only except newClientRect.
2066 * oldWindowRect, oldClientRect and winpos must be non-NULL only
2067 * when calcValidRect is TRUE.
2069 LONG WINPOS_SendNCCalcSize( HWND hwnd, BOOL calcValidRect,
2070 RECT *newWindowRect, RECT *oldWindowRect,
2071 RECT *oldClientRect, WINDOWPOS *winpos,
2072 RECT *newClientRect )
2074 NCCALCSIZE_PARAMS params;
2075 WINDOWPOS winposCopy;
2078 params.rgrc[0] = *newWindowRect;
2081 winposCopy = *winpos;
2082 params.rgrc[1] = *oldWindowRect;
2083 params.rgrc[2] = *oldClientRect;
2084 params.lppos = &winposCopy;
2086 result = SendMessageA( hwnd, WM_NCCALCSIZE, calcValidRect,
2088 TRACE("%d,%d-%d,%d\n",
2089 params.rgrc[0].left, params.rgrc[0].top,
2090 params.rgrc[0].right, params.rgrc[0].bottom );
2092 /* If the application send back garbage, ignore it */
2093 if (params.rgrc[0].left <= params.rgrc[0].right && params.rgrc[0].top <= params.rgrc[0].bottom)
2094 *newClientRect = params.rgrc[0];
2100 /***********************************************************************
2101 * WINPOS_HandleWindowPosChanging16
2103 * Default handling for a WM_WINDOWPOSCHANGING. Called from DefWindowProc().
2105 LONG WINPOS_HandleWindowPosChanging16( WND *wndPtr, WINDOWPOS16 *winpos )
2107 POINT maxSize, minTrack;
2108 if (winpos->flags & SWP_NOSIZE) return 0;
2109 if ((wndPtr->dwStyle & WS_THICKFRAME) ||
2110 ((wndPtr->dwStyle & (WS_POPUP | WS_CHILD)) == 0))
2112 WINPOS_GetMinMaxInfo( wndPtr, &maxSize, NULL, &minTrack, NULL );
2113 if (maxSize.x < winpos->cx) winpos->cx = maxSize.x;
2114 if (maxSize.y < winpos->cy) winpos->cy = maxSize.y;
2115 if (!(wndPtr->dwStyle & WS_MINIMIZE))
2117 if (winpos->cx < minTrack.x ) winpos->cx = minTrack.x;
2118 if (winpos->cy < minTrack.y ) winpos->cy = minTrack.y;
2125 /***********************************************************************
2126 * WINPOS_HandleWindowPosChanging
2128 * Default handling for a WM_WINDOWPOSCHANGING. Called from DefWindowProc().
2130 LONG WINPOS_HandleWindowPosChanging( WND *wndPtr, WINDOWPOS *winpos )
2132 POINT maxSize, minTrack;
2133 if (winpos->flags & SWP_NOSIZE) return 0;
2134 if ((wndPtr->dwStyle & WS_THICKFRAME) ||
2135 ((wndPtr->dwStyle & (WS_POPUP | WS_CHILD)) == 0))
2137 WINPOS_GetMinMaxInfo( wndPtr, &maxSize, NULL, &minTrack, NULL );
2138 winpos->cx = min( winpos->cx, maxSize.x );
2139 winpos->cy = min( winpos->cy, maxSize.y );
2140 if (!(wndPtr->dwStyle & WS_MINIMIZE))
2142 if (winpos->cx < minTrack.x ) winpos->cx = minTrack.x;
2143 if (winpos->cy < minTrack.y ) winpos->cy = minTrack.y;
2149 /***********************************************************************
2150 * SetWindowPos (USER.232)
2152 BOOL16 WINAPI SetWindowPos16( HWND16 hwnd, HWND16 hwndInsertAfter,
2153 INT16 x, INT16 y, INT16 cx, INT16 cy, WORD flags)
2155 return SetWindowPos(hwnd,(INT)(INT16)hwndInsertAfter,x,y,cx,cy,flags);
2158 /***********************************************************************
2159 * SetWindowPos (USER32.@)
2161 BOOL WINAPI SetWindowPos( HWND hwnd, HWND hwndInsertAfter,
2162 INT x, INT y, INT cx, INT cy, UINT flags )
2167 winpos.hwndInsertAfter = hwndInsertAfter;
2172 winpos.flags = flags;
2173 return USER_Driver.pSetWindowPos( &winpos );
2177 /***********************************************************************
2178 * BeginDeferWindowPos (USER.259)
2180 HDWP16 WINAPI BeginDeferWindowPos16( INT16 count )
2182 return BeginDeferWindowPos( count );
2186 /***********************************************************************
2187 * BeginDeferWindowPos (USER32.@)
2189 HDWP WINAPI BeginDeferWindowPos( INT count )
2196 SetLastError(ERROR_INVALID_PARAMETER);
2199 /* Windows allows zero count, in which case it allocates context for 8 moves */
2200 if (count == 0) count = 8;
2202 handle = USER_HEAP_ALLOC( sizeof(DWP) + (count-1)*sizeof(WINDOWPOS) );
2203 if (!handle) return 0;
2204 pDWP = (DWP *) USER_HEAP_LIN_ADDR( handle );
2205 pDWP->actualCount = 0;
2206 pDWP->suggestedCount = count;
2208 pDWP->wMagic = DWP_MAGIC;
2209 pDWP->hwndParent = 0;
2214 /***********************************************************************
2215 * DeferWindowPos (USER.260)
2217 HDWP16 WINAPI DeferWindowPos16( HDWP16 hdwp, HWND16 hwnd, HWND16 hwndAfter,
2218 INT16 x, INT16 y, INT16 cx, INT16 cy,
2221 return DeferWindowPos( hdwp, hwnd, (INT)(INT16)hwndAfter,
2222 x, y, cx, cy, flags );
2226 /***********************************************************************
2227 * DeferWindowPos (USER32.@)
2229 HDWP WINAPI DeferWindowPos( HDWP hdwp, HWND hwnd, HWND hwndAfter,
2230 INT x, INT y, INT cx, INT cy,
2235 HDWP newhdwp = hdwp,retvalue;
2239 pDWP = (DWP *) USER_HEAP_LIN_ADDR( hdwp );
2240 if (!pDWP) return 0;
2241 if (hwnd == GetDesktopWindow()) return 0;
2243 if (!(pWnd=WIN_FindWndPtr( hwnd ))) {
2244 USER_HEAP_FREE( hdwp );
2248 /* Numega Bounds Checker Demo dislikes the following code.
2249 In fact, I've not been able to find any "same parent" requirement in any docu
2253 /* All the windows of a DeferWindowPos() must have the same parent */
2254 parent = pWnd->parent->hwndSelf;
2255 if (pDWP->actualCount == 0) pDWP->hwndParent = parent;
2256 else if (parent != pDWP->hwndParent)
2258 USER_HEAP_FREE( hdwp );
2264 for (i = 0; i < pDWP->actualCount; i++)
2266 if (pDWP->winPos[i].hwnd == hwnd)
2268 /* Merge with the other changes */
2269 if (!(flags & SWP_NOZORDER))
2271 pDWP->winPos[i].hwndInsertAfter = hwndAfter;
2273 if (!(flags & SWP_NOMOVE))
2275 pDWP->winPos[i].x = x;
2276 pDWP->winPos[i].y = y;
2278 if (!(flags & SWP_NOSIZE))
2280 pDWP->winPos[i].cx = cx;
2281 pDWP->winPos[i].cy = cy;
2283 pDWP->winPos[i].flags &= flags | ~(SWP_NOSIZE | SWP_NOMOVE |
2284 SWP_NOZORDER | SWP_NOREDRAW |
2285 SWP_NOACTIVATE | SWP_NOCOPYBITS|
2287 pDWP->winPos[i].flags |= flags & (SWP_SHOWWINDOW | SWP_HIDEWINDOW |
2293 if (pDWP->actualCount >= pDWP->suggestedCount)
2295 newhdwp = USER_HEAP_REALLOC( hdwp,
2296 sizeof(DWP) + pDWP->suggestedCount*sizeof(WINDOWPOS) );
2302 pDWP = (DWP *) USER_HEAP_LIN_ADDR( newhdwp );
2303 pDWP->suggestedCount++;
2305 pDWP->winPos[pDWP->actualCount].hwnd = hwnd;
2306 pDWP->winPos[pDWP->actualCount].hwndInsertAfter = hwndAfter;
2307 pDWP->winPos[pDWP->actualCount].x = x;
2308 pDWP->winPos[pDWP->actualCount].y = y;
2309 pDWP->winPos[pDWP->actualCount].cx = cx;
2310 pDWP->winPos[pDWP->actualCount].cy = cy;
2311 pDWP->winPos[pDWP->actualCount].flags = flags;
2312 pDWP->actualCount++;
2315 WIN_ReleaseWndPtr(pWnd);
2320 /***********************************************************************
2321 * EndDeferWindowPos (USER.261)
2323 BOOL16 WINAPI EndDeferWindowPos16( HDWP16 hdwp )
2325 return EndDeferWindowPos( hdwp );
2329 /***********************************************************************
2330 * EndDeferWindowPos (USER32.@)
2332 BOOL WINAPI EndDeferWindowPos( HDWP hdwp )
2339 pDWP = (DWP *) USER_HEAP_LIN_ADDR( hdwp );
2340 if (!pDWP) return FALSE;
2341 for (i = 0, winpos = pDWP->winPos; i < pDWP->actualCount; i++, winpos++)
2343 if (!(res = USER_Driver.pSetWindowPos( winpos ))) break;
2345 USER_HEAP_FREE( hdwp );
2350 /***********************************************************************
2351 * TileChildWindows (USER.199)
2353 void WINAPI TileChildWindows16( HWND16 parent, WORD action )
2355 FIXME("(%04x, %d): stub\n", parent, action);
2358 /***********************************************************************
2359 * CascadeChildWindows (USER.198)
2361 void WINAPI CascadeChildWindows16( HWND16 parent, WORD action )
2363 FIXME("(%04x, %d): stub\n", parent, action);
2366 /***********************************************************************
2367 * SetProgmanWindow (USER32.@)
2369 HRESULT WINAPI SetProgmanWindow ( HWND hwnd )
2371 hGlobalProgmanWindow = hwnd;
2372 return hGlobalProgmanWindow;
2375 /***********************************************************************
2376 * GetProgmanWindow (USER32.@)
2378 HRESULT WINAPI GetProgmanWindow ( )
2380 return hGlobalProgmanWindow;
2383 /***********************************************************************
2384 * SetShellWindowEx (USER32.@)
2385 * hwndProgman = Progman[Program Manager]
2386 * |-> SHELLDLL_DefView
2387 * hwndListView = | |-> SysListView32
2388 * | | |-> tooltips_class32
2394 HRESULT WINAPI SetShellWindowEx ( HWND hwndProgman, HWND hwndListView )
2396 FIXME("0x%08x 0x%08x stub\n",hwndProgman ,hwndListView );
2397 hGlobalShellWindow = hwndProgman;
2398 return hGlobalShellWindow;
2402 /***********************************************************************
2403 * SetTaskmanWindow (USER32.@)
2405 * hwnd = MSTaskSwWClass
2406 * |-> SysTabControl32
2408 HRESULT WINAPI SetTaskmanWindow ( HWND hwnd )
2410 hGlobalTaskmanWindow = hwnd;
2411 return hGlobalTaskmanWindow;
2414 /***********************************************************************
2415 * GetTaskmanWindow (USER32.@)
2417 HRESULT WINAPI GetTaskmanWindow ( )
2419 return hGlobalTaskmanWindow;