2 * Window position related functions.
4 * Copyright 1993, 1994, 1995 Alexandre Julliard
5 * 1995, 1996, 1999 Alex Korobka
13 #include "wine/winuser16.h"
24 #include "nonclient.h"
25 #include "debugtools.h"
28 DEFAULT_DEBUG_CHANNEL(win);
30 #define HAS_DLGFRAME(style,exStyle) \
31 (((exStyle) & WS_EX_DLGMODALFRAME) || \
32 (((style) & WS_DLGFRAME) && !((style) & WS_BORDER)))
34 #define HAS_THICKFRAME(style) \
35 (((style) & WS_THICKFRAME) && \
36 !(((style) & (WS_DLGFRAME|WS_BORDER)) == WS_DLGFRAME))
38 #define EMPTYPOINT(pt) ((*(LONG*)&(pt)) == -1)
40 #define PLACE_MIN 0x0001
41 #define PLACE_MAX 0x0002
42 #define PLACE_RECT 0x0004
45 #define DWP_MAGIC ((INT)('W' | ('P' << 8) | ('O' << 16) | ('S' << 24)))
57 /* ----- internal variables ----- */
59 static HWND hwndPrevActive = 0; /* Previously active window */
60 static HWND hGlobalShellWindow=0; /*the shell*/
61 static HWND hGlobalTaskmanWindow=0;
62 static HWND hGlobalProgmanWindow=0;
64 static LPCSTR atomInternalPos;
66 extern HQUEUE16 hActiveQueue;
68 /***********************************************************************
69 * WINPOS_CreateInternalPosAtom
71 BOOL WINPOS_CreateInternalPosAtom()
74 atomInternalPos = (LPCSTR)(DWORD)GlobalAddAtomA(str);
75 return (atomInternalPos) ? TRUE : FALSE;
78 /***********************************************************************
79 * WINPOS_CheckInternalPos
81 * Called when a window is destroyed.
83 void WINPOS_CheckInternalPos( WND* wndPtr )
86 MESSAGEQUEUE *pMsgQ = 0;
87 HWND hwnd = wndPtr->hwndSelf;
89 lpPos = (LPINTERNALPOS) GetPropA( hwnd, atomInternalPos );
91 /* Retrieve the message queue associated with this window */
92 pMsgQ = (MESSAGEQUEUE *)QUEUE_Lock( wndPtr->hmemTaskQ );
95 WARN("\tMessage queue not found. Exiting!\n" );
99 if( hwnd == hwndPrevActive ) hwndPrevActive = 0;
101 if( hwnd == PERQDATA_GetActiveWnd( pMsgQ->pQData ) )
103 PERQDATA_SetActiveWnd( pMsgQ->pQData, 0 );
104 WARN("\tattempt to activate destroyed window!\n");
109 if( IsWindow(lpPos->hwndIconTitle) )
110 DestroyWindow( lpPos->hwndIconTitle );
111 HeapFree( GetProcessHeap(), 0, lpPos );
114 QUEUE_Unlock( pMsgQ );
118 /***********************************************************************
119 * ArrangeIconicWindows (USER.170)
121 UINT16 WINAPI ArrangeIconicWindows16( HWND16 parent)
123 return ArrangeIconicWindows(parent);
125 /***********************************************************************
126 * ArrangeIconicWindows (USER32.@)
128 UINT WINAPI ArrangeIconicWindows( HWND parent )
132 INT x, y, xspacing, yspacing;
134 GetClientRect( parent, &rectParent );
136 y = rectParent.bottom;
137 xspacing = GetSystemMetrics(SM_CXICONSPACING);
138 yspacing = GetSystemMetrics(SM_CYICONSPACING);
140 hwndChild = GetWindow( parent, GW_CHILD );
143 if( IsIconic( hwndChild ) )
145 WND *wndPtr = WIN_FindWndPtr(hwndChild);
147 WINPOS_ShowIconTitle( wndPtr, FALSE );
149 SetWindowPos( hwndChild, 0, x + (xspacing - GetSystemMetrics(SM_CXICON)) / 2,
150 y - yspacing - GetSystemMetrics(SM_CYICON)/2, 0, 0,
151 SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE );
152 if( IsWindow(hwndChild) )
153 WINPOS_ShowIconTitle(wndPtr , TRUE );
154 WIN_ReleaseWndPtr(wndPtr);
156 if (x <= rectParent.right - xspacing) x += xspacing;
163 hwndChild = GetWindow( hwndChild, GW_HWNDNEXT );
169 /***********************************************************************
170 * SwitchToThisWindow (USER.172)
172 void WINAPI SwitchToThisWindow16( HWND16 hwnd, BOOL16 restore )
174 SwitchToThisWindow( hwnd, restore );
178 /***********************************************************************
179 * SwitchToThisWindow (USER32.@)
181 void WINAPI SwitchToThisWindow( HWND hwnd, BOOL restore )
183 ShowWindow( hwnd, restore ? SW_RESTORE : SW_SHOWMINIMIZED );
187 /***********************************************************************
188 * GetWindowRect (USER.32)
190 void WINAPI GetWindowRect16( HWND16 hwnd, LPRECT16 rect )
192 WND * wndPtr = WIN_FindWndPtr( hwnd );
195 CONV_RECT32TO16( &wndPtr->rectWindow, rect );
197 MapWindowPoints16( wndPtr->parent->hwndSelf, 0, (POINT16 *)rect, 2 );
198 WIN_ReleaseWndPtr(wndPtr);
202 /***********************************************************************
203 * GetWindowRect (USER32.@)
205 BOOL WINAPI GetWindowRect( HWND hwnd, LPRECT rect )
207 WND * wndPtr = WIN_FindWndPtr( hwnd );
208 if (!wndPtr) return FALSE;
210 *rect = wndPtr->rectWindow;
212 MapWindowPoints( wndPtr->parent->hwndSelf, 0, (POINT *)rect, 2 );
213 WIN_ReleaseWndPtr(wndPtr);
218 /***********************************************************************
219 * GetWindowRgn (USER32.@)
221 int WINAPI GetWindowRgn ( HWND hwnd, HRGN hrgn )
224 WND *wndPtr = WIN_FindWndPtr( hwnd );
227 if (wndPtr->hrgnWnd) nRet = CombineRgn( hrgn, wndPtr->hrgnWnd, 0, RGN_COPY );
228 WIN_ReleaseWndPtr(wndPtr);
233 /***********************************************************************
234 * SetWindowRgn (USER32.@)
236 int WINAPI SetWindowRgn( HWND hwnd, HRGN hrgn, BOOL bRedraw )
242 if (USER_Driver.pSetWindowRgn)
243 return USER_Driver.pSetWindowRgn( hwnd, hrgn, bRedraw );
245 if (!(wndPtr = WIN_FindWndPtr(hwnd))) return FALSE;
247 if (wndPtr->hrgnWnd == hrgn)
253 if (hrgn) /* verify that region really exists */
255 if (GetRgnBox( hrgn, &rect ) == ERROR) goto done;
260 /* delete previous region */
261 DeleteObject(wndPtr->hrgnWnd);
264 wndPtr->hrgnWnd = hrgn;
266 /* Size the window to the rectangle of the new region (if it isn't NULL) */
267 if (hrgn) SetWindowPos( hwnd, 0, rect.left, rect.top,
268 rect.right - rect.left, rect.bottom - rect.top,
269 SWP_NOSIZE | SWP_FRAMECHANGED | SWP_NOMOVE | SWP_NOACTIVATE |
270 SWP_NOZORDER | (bRedraw ? 0 : SWP_NOREDRAW) );
274 WIN_ReleaseWndPtr(wndPtr);
278 /***********************************************************************
279 * SetWindowRgn (USER.668)
281 INT16 WINAPI SetWindowRgn16( HWND16 hwnd, HRGN16 hrgn,BOOL16 bRedraw)
285 FIXME("SetWindowRgn16: stub\n");
290 /***********************************************************************
291 * GetClientRect (USER.33)
293 void WINAPI GetClientRect16( HWND16 hwnd, LPRECT16 rect )
295 WND * wndPtr = WIN_FindWndPtr( hwnd );
297 rect->left = rect->top = rect->right = rect->bottom = 0;
300 rect->right = wndPtr->rectClient.right - wndPtr->rectClient.left;
301 rect->bottom = wndPtr->rectClient.bottom - wndPtr->rectClient.top;
303 WIN_ReleaseWndPtr(wndPtr);
307 /***********************************************************************
308 * GetClientRect (USER32.@)
310 BOOL WINAPI GetClientRect( HWND hwnd, LPRECT rect )
312 WND * wndPtr = WIN_FindWndPtr( hwnd );
314 rect->left = rect->top = rect->right = rect->bottom = 0;
315 if (!wndPtr) return FALSE;
316 rect->right = wndPtr->rectClient.right - wndPtr->rectClient.left;
317 rect->bottom = wndPtr->rectClient.bottom - wndPtr->rectClient.top;
319 WIN_ReleaseWndPtr(wndPtr);
324 /*******************************************************************
325 * ClientToScreen (USER.28)
327 void WINAPI ClientToScreen16( HWND16 hwnd, LPPOINT16 lppnt )
329 MapWindowPoints16( hwnd, 0, lppnt, 1 );
333 /*******************************************************************
334 * ClientToScreen (USER32.@)
336 BOOL WINAPI ClientToScreen( HWND hwnd, LPPOINT lppnt )
338 MapWindowPoints( hwnd, 0, lppnt, 1 );
343 /*******************************************************************
344 * ScreenToClient (USER.29)
346 void WINAPI ScreenToClient16( HWND16 hwnd, LPPOINT16 lppnt )
348 MapWindowPoints16( 0, hwnd, lppnt, 1 );
352 /*******************************************************************
353 * ScreenToClient (USER32.@)
355 BOOL WINAPI ScreenToClient( HWND hwnd, LPPOINT lppnt )
357 MapWindowPoints( 0, hwnd, lppnt, 1 );
362 /***********************************************************************
363 * WINPOS_WindowFromPoint
365 * Find the window and hittest for a given point.
367 HWND WINPOS_WindowFromPoint( HWND hwndScope, POINT pt, INT *hittest )
369 WND *wndScope, *wndPtr, *wndTmp;
373 TRACE("scope %04x %ld,%ld\n", hwndScope, pt.x, pt.y);
375 if (!hwndScope) hwndScope = GetDesktopWindow();
376 if (!(wndScope = WIN_FindWndPtr( hwndScope ))) return 0;
379 wndPtr = WIN_LockWndPtr(wndScope->child);
381 if( wndScope->dwStyle & WS_DISABLED )
387 if (wndScope->parent)
388 MapWindowPoints( GetDesktopWindow(), wndScope->parent->hwndSelf, &xy, 1 );
390 if (xy.x < wndScope->rectClient.left || pt.x >= wndScope->rectClient.right ||
391 xy.y < wndScope->rectClient.top || pt.y >= wndScope->rectClient.bottom ||
392 wndScope->dwStyle & WS_MINIMIZE)
395 xy.x -= wndScope->rectClient.left;
396 xy.y -= wndScope->rectClient.top;
402 /* If point is in window, and window is visible, and it */
403 /* is enabled (or it's a top-level window), then explore */
404 /* its children. Otherwise, go to the next window. */
406 if ((wndPtr->dwStyle & WS_VISIBLE) &&
407 ((wndPtr->dwExStyle & (WS_EX_LAYERED | WS_EX_TRANSPARENT)) != (WS_EX_LAYERED | WS_EX_TRANSPARENT)) &&
408 (!(wndPtr->dwStyle & WS_DISABLED) ||
409 ((wndPtr->dwStyle & (WS_POPUP | WS_CHILD)) != WS_CHILD)) &&
411 PtInRegion(wndPtr->hrgnWnd, xy.x - wndPtr->rectWindow.left,
412 xy.y - wndPtr->rectWindow.top) :
413 ((xy.x >= wndPtr->rectWindow.left) &&
414 (xy.x < wndPtr->rectWindow.right) &&
415 (xy.y >= wndPtr->rectWindow.top) &&
416 (xy.y < wndPtr->rectWindow.bottom))))
418 TRACE("%ld,%ld is inside %04x\n", xy.x, xy.y, wndPtr->hwndSelf);
419 hwnd_ret = wndPtr->hwndSelf; /* Got a suitable window */
421 /* If window is minimized or disabled, return at once */
422 if (wndPtr->dwStyle & WS_MINIMIZE)
424 *hittest = HTCAPTION;
427 if (wndPtr->dwStyle & WS_DISABLED)
433 /* If point is not in client area, ignore the children */
434 if ((xy.x < wndPtr->rectClient.left) ||
435 (xy.x >= wndPtr->rectClient.right) ||
436 (xy.y < wndPtr->rectClient.top) ||
437 (xy.y >= wndPtr->rectClient.bottom)) break;
439 xy.x -= wndPtr->rectClient.left;
440 xy.y -= wndPtr->rectClient.top;
441 WIN_UpdateWndPtr(&wndPtr,wndPtr->child);
445 WIN_UpdateWndPtr(&wndPtr,wndPtr->next);
450 /* If nothing found, try the scope window */
451 if (!hwnd_ret) hwnd_ret = hwndScope;
453 /* Send the WM_NCHITTEST message (only if to the same task) */
454 if (GetWindowThreadProcessId( hwnd_ret, NULL ) == GetCurrentThreadId())
456 INT res = SendMessageA( hwnd_ret, WM_NCHITTEST, 0, MAKELONG( pt.x, pt.y ) );
457 if (res != HTTRANSPARENT)
459 *hittest = res; /* Found the window */
469 if (!(wndTmp = WIN_FindWndPtr( hwnd_ret ))) break;
471 /* If no children found in last search, make point relative to parent */
474 xy.x += wndTmp->rectClient.left;
475 xy.y += wndTmp->rectClient.top;
478 /* Restart the search from the next sibling */
479 WIN_UpdateWndPtr(&wndPtr,wndTmp->next);
480 hwnd_ret = wndTmp->parent ? wndTmp->parent->hwndSelf : 0;
481 WIN_ReleaseWndPtr( wndTmp );
485 WIN_ReleaseWndPtr(wndPtr);
486 WIN_ReleaseWndPtr(wndScope);
491 /*******************************************************************
492 * WindowFromPoint (USER.30)
494 HWND16 WINAPI WindowFromPoint16( POINT16 pt )
498 CONV_POINT16TO32( &pt, &pt32 );
499 return WindowFromPoint( pt32 );
503 /*******************************************************************
504 * WindowFromPoint (USER32.@)
506 HWND WINAPI WindowFromPoint( POINT pt )
509 return WINPOS_WindowFromPoint( 0, pt, &hittest );
513 /*******************************************************************
514 * ChildWindowFromPoint (USER.191)
516 HWND16 WINAPI ChildWindowFromPoint16( HWND16 hwndParent, POINT16 pt )
519 CONV_POINT16TO32( &pt, &pt32 );
520 return (HWND16)ChildWindowFromPoint( hwndParent, pt32 );
524 /*******************************************************************
525 * ChildWindowFromPoint (USER32.@)
527 HWND WINAPI ChildWindowFromPoint( HWND hwndParent, POINT pt )
529 /* pt is in the client coordinates */
531 WND* wnd = WIN_FindWndPtr(hwndParent);
537 /* get client rect fast */
538 rect.top = rect.left = 0;
539 rect.right = wnd->rectClient.right - wnd->rectClient.left;
540 rect.bottom = wnd->rectClient.bottom - wnd->rectClient.top;
542 if (!PtInRect( &rect, pt ))
547 WIN_UpdateWndPtr(&wnd,wnd->child);
550 if (PtInRect( &wnd->rectWindow, pt ))
552 retvalue = wnd->hwndSelf;
555 WIN_UpdateWndPtr(&wnd,wnd->next);
557 retvalue = hwndParent;
559 WIN_ReleaseWndPtr(wnd);
563 /*******************************************************************
564 * ChildWindowFromPointEx (USER.399)
566 HWND16 WINAPI ChildWindowFromPointEx16( HWND16 hwndParent, POINT16 pt, UINT16 uFlags)
569 CONV_POINT16TO32( &pt, &pt32 );
570 return (HWND16)ChildWindowFromPointEx( hwndParent, pt32, uFlags );
574 /*******************************************************************
575 * ChildWindowFromPointEx (USER32.@)
577 HWND WINAPI ChildWindowFromPointEx( HWND hwndParent, POINT pt,
580 /* pt is in the client coordinates */
582 WND* wnd = WIN_FindWndPtr(hwndParent);
588 /* get client rect fast */
589 rect.top = rect.left = 0;
590 rect.right = wnd->rectClient.right - wnd->rectClient.left;
591 rect.bottom = wnd->rectClient.bottom - wnd->rectClient.top;
593 if (!PtInRect( &rect, pt ))
598 WIN_UpdateWndPtr(&wnd,wnd->child);
602 if (PtInRect( &wnd->rectWindow, pt )) {
603 if ( (uFlags & CWP_SKIPINVISIBLE) &&
604 !(wnd->dwStyle & WS_VISIBLE) );
605 else if ( (uFlags & CWP_SKIPDISABLED) &&
606 (wnd->dwStyle & WS_DISABLED) );
607 else if ( (uFlags & CWP_SKIPTRANSPARENT) &&
608 (wnd->dwExStyle & WS_EX_TRANSPARENT) );
611 retvalue = wnd->hwndSelf;
616 WIN_UpdateWndPtr(&wnd,wnd->next);
618 retvalue = hwndParent;
620 WIN_ReleaseWndPtr(wnd);
625 /*******************************************************************
626 * WINPOS_GetWinOffset
628 * Calculate the offset between the origin of the two windows. Used
629 * to implement MapWindowPoints.
631 static void WINPOS_GetWinOffset( HWND hwndFrom, HWND hwndTo,
636 offset->x = offset->y = 0;
637 if (hwndFrom == hwndTo ) return;
639 /* Translate source window origin to screen coords */
642 if (!(wndPtr = WIN_FindWndPtr( hwndFrom )))
644 ERR("bad hwndFrom = %04x\n",hwndFrom);
647 while (wndPtr->parent)
649 offset->x += wndPtr->rectClient.left;
650 offset->y += wndPtr->rectClient.top;
651 WIN_UpdateWndPtr(&wndPtr,wndPtr->parent);
653 WIN_ReleaseWndPtr(wndPtr);
656 /* Translate origin to destination window coords */
659 if (!(wndPtr = WIN_FindWndPtr( hwndTo )))
661 ERR("bad hwndTo = %04x\n", hwndTo );
664 while (wndPtr->parent)
666 offset->x -= wndPtr->rectClient.left;
667 offset->y -= wndPtr->rectClient.top;
668 WIN_UpdateWndPtr(&wndPtr,wndPtr->parent);
670 WIN_ReleaseWndPtr(wndPtr);
675 /*******************************************************************
676 * MapWindowPoints (USER.258)
678 void WINAPI MapWindowPoints16( HWND16 hwndFrom, HWND16 hwndTo,
679 LPPOINT16 lppt, UINT16 count )
683 WINPOS_GetWinOffset( hwndFrom, hwndTo, &offset );
693 /*******************************************************************
694 * MapWindowPoints (USER32.@)
696 INT WINAPI MapWindowPoints( HWND hwndFrom, HWND hwndTo,
697 LPPOINT lppt, UINT count )
701 WINPOS_GetWinOffset( hwndFrom, hwndTo, &offset );
708 return MAKELONG( LOWORD(offset.x), LOWORD(offset.y) );
712 /***********************************************************************
715 BOOL16 WINAPI IsIconic16(HWND16 hWnd)
717 return IsIconic(hWnd);
721 /***********************************************************************
722 * IsIconic (USER32.@)
724 BOOL WINAPI IsIconic(HWND hWnd)
727 WND * wndPtr = WIN_FindWndPtr(hWnd);
728 if (wndPtr == NULL) return FALSE;
729 retvalue = (wndPtr->dwStyle & WS_MINIMIZE) != 0;
730 WIN_ReleaseWndPtr(wndPtr);
735 /***********************************************************************
736 * IsZoomed (USER.272)
738 BOOL16 WINAPI IsZoomed16(HWND16 hWnd)
740 return IsZoomed(hWnd);
744 /***********************************************************************
745 * IsZoomed (USER32.@)
747 BOOL WINAPI IsZoomed(HWND hWnd)
750 WND * wndPtr = WIN_FindWndPtr(hWnd);
751 if (wndPtr == NULL) return FALSE;
752 retvalue = (wndPtr->dwStyle & WS_MAXIMIZE) != 0;
753 WIN_ReleaseWndPtr(wndPtr);
758 /*******************************************************************
759 * GetActiveWindow (USER.60)
761 HWND16 WINAPI GetActiveWindow16(void)
763 return (HWND16)GetActiveWindow();
766 /*******************************************************************
767 * GetActiveWindow (USER32.@)
769 HWND WINAPI GetActiveWindow(void)
771 MESSAGEQUEUE *pCurMsgQ = 0;
774 /* Get the messageQ for the current thread */
775 if (!(pCurMsgQ = (MESSAGEQUEUE *)QUEUE_Lock( GetFastQueue16() )))
777 WARN("\tCurrent message queue not found. Exiting!\n" );
781 /* Return the current active window from the perQ data of the current message Q */
782 hwndActive = PERQDATA_GetActiveWnd( pCurMsgQ->pQData );
784 QUEUE_Unlock( pCurMsgQ );
789 /*******************************************************************
792 static BOOL WINPOS_CanActivate(WND* pWnd)
794 if( pWnd && ( (pWnd->dwStyle & (WS_DISABLED | WS_VISIBLE | WS_CHILD))
795 == WS_VISIBLE ) ) return TRUE;
800 /*******************************************************************
801 * SetActiveWindow (USER.59)
803 HWND16 WINAPI SetActiveWindow16( HWND16 hwnd )
805 return SetActiveWindow(hwnd);
809 /*******************************************************************
810 * SetActiveWindow (USER32.@)
812 HWND WINAPI SetActiveWindow( HWND hwnd )
815 WND *wndPtr = WIN_FindWndPtr( hwnd );
816 MESSAGEQUEUE *pMsgQ = 0, *pCurMsgQ = 0;
818 if (!wndPtr || (wndPtr->dwStyle & (WS_DISABLED | WS_CHILD)))
824 /* Get the messageQ for the current thread */
825 if (!(pCurMsgQ = (MESSAGEQUEUE *)QUEUE_Lock( GetFastQueue16() )))
827 WARN("\tCurrent message queue not found. Exiting!\n" );
831 /* Retrieve the message queue associated with this window */
832 pMsgQ = (MESSAGEQUEUE *)QUEUE_Lock( wndPtr->hmemTaskQ );
835 WARN("\tWindow message queue not found. Exiting!\n" );
839 /* Make sure that the window is associated with the calling threads
840 * message queue. It must share the same perQ data.
843 if ( pCurMsgQ->pQData != pMsgQ->pQData )
846 /* Save current active window */
847 prev = PERQDATA_GetActiveWnd( pMsgQ->pQData );
849 WINPOS_SetActiveWindow( hwnd, 0, 0 );
852 /* Unlock the queues before returning */
854 QUEUE_Unlock( pMsgQ );
856 QUEUE_Unlock( pCurMsgQ );
859 WIN_ReleaseWndPtr(wndPtr);
864 /*******************************************************************
865 * GetForegroundWindow (USER.608)
867 HWND16 WINAPI GetForegroundWindow16(void)
869 return (HWND16)GetForegroundWindow();
873 /*******************************************************************
874 * SetForegroundWindow (USER.609)
876 BOOL16 WINAPI SetForegroundWindow16( HWND16 hwnd )
878 return SetForegroundWindow( hwnd );
882 /*******************************************************************
883 * GetForegroundWindow (USER32.@)
885 HWND WINAPI GetForegroundWindow(void)
889 /* Get the foreground window (active window of hActiveQueue) */
892 MESSAGEQUEUE *pActiveQueue = QUEUE_Lock( hActiveQueue );
894 hwndActive = PERQDATA_GetActiveWnd( pActiveQueue->pQData );
896 QUEUE_Unlock( pActiveQueue );
902 /*******************************************************************
903 * SetForegroundWindow (USER32.@)
905 BOOL WINAPI SetForegroundWindow( HWND hwnd )
907 return WINPOS_ChangeActiveWindow( hwnd, FALSE );
911 /*******************************************************************
912 * AllowSetForegroundWindow (USER32.@)
914 BOOL WINAPI AllowSetForegroundWindow( DWORD procid )
916 /* FIXME: If Win98/2000 style SetForegroundWindow behavior is
917 * implemented, then fix this function. */
922 /*******************************************************************
923 * LockSetForegroundWindow (USER32.@)
925 BOOL WINAPI LockSetForegroundWindow( UINT lockcode )
927 /* FIXME: If Win98/2000 style SetForegroundWindow behavior is
928 * implemented, then fix this function. */
933 /*******************************************************************
934 * GetShellWindow (USER.600)
936 HWND16 WINAPI GetShellWindow16(void)
938 return GetShellWindow();
941 /*******************************************************************
942 * SetShellWindow (USER32.@)
944 HWND WINAPI SetShellWindow(HWND hwndshell)
945 { WARN("(hWnd=%08x) semi stub\n",hwndshell );
947 hGlobalShellWindow = hwndshell;
948 return hGlobalShellWindow;
952 /*******************************************************************
953 * GetShellWindow (USER32.@)
955 HWND WINAPI GetShellWindow(void)
956 { WARN("(hWnd=%x) semi stub\n",hGlobalShellWindow );
958 return hGlobalShellWindow;
962 /***********************************************************************
963 * BringWindowToTop (USER.45)
965 BOOL16 WINAPI BringWindowToTop16( HWND16 hwnd )
967 return BringWindowToTop(hwnd);
971 /***********************************************************************
972 * BringWindowToTop (USER32.@)
974 BOOL WINAPI BringWindowToTop( HWND hwnd )
976 return SetWindowPos( hwnd, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE );
980 /***********************************************************************
981 * MoveWindow (USER.56)
983 BOOL16 WINAPI MoveWindow16( HWND16 hwnd, INT16 x, INT16 y, INT16 cx, INT16 cy,
986 return MoveWindow(hwnd,x,y,cx,cy,repaint);
990 /***********************************************************************
991 * MoveWindow (USER32.@)
993 BOOL WINAPI MoveWindow( HWND hwnd, INT x, INT y, INT cx, INT cy,
996 int flags = SWP_NOZORDER | SWP_NOACTIVATE;
997 if (!repaint) flags |= SWP_NOREDRAW;
998 TRACE("%04x %d,%d %dx%d %d\n",
999 hwnd, x, y, cx, cy, repaint );
1000 return SetWindowPos( hwnd, 0, x, y, cx, cy, flags );
1003 /***********************************************************************
1004 * WINPOS_InitInternalPos
1006 static LPINTERNALPOS WINPOS_InitInternalPos( WND* wnd, POINT pt,
1007 LPRECT restoreRect )
1009 LPINTERNALPOS lpPos = (LPINTERNALPOS) GetPropA( wnd->hwndSelf,
1013 /* this happens when the window is minimized/maximized
1014 * for the first time (rectWindow is not adjusted yet) */
1016 lpPos = HeapAlloc( GetProcessHeap(), 0, sizeof(INTERNALPOS) );
1017 if( !lpPos ) return NULL;
1019 SetPropA( wnd->hwndSelf, atomInternalPos, (HANDLE)lpPos );
1020 lpPos->hwndIconTitle = 0; /* defer until needs to be shown */
1021 CONV_RECT32TO16( &wnd->rectWindow, &lpPos->rectNormal );
1022 *(UINT*)&lpPos->ptIconPos = *(UINT*)&lpPos->ptMaxPos = 0xFFFFFFFF;
1025 if( wnd->dwStyle & WS_MINIMIZE )
1026 CONV_POINT32TO16( &pt, &lpPos->ptIconPos );
1027 else if( wnd->dwStyle & WS_MAXIMIZE )
1028 CONV_POINT32TO16( &pt, &lpPos->ptMaxPos );
1029 else if( restoreRect )
1030 CONV_RECT32TO16( restoreRect, &lpPos->rectNormal );
1035 /***********************************************************************
1036 * WINPOS_RedrawIconTitle
1038 BOOL WINPOS_RedrawIconTitle( HWND hWnd )
1040 LPINTERNALPOS lpPos = (LPINTERNALPOS)GetPropA( hWnd, atomInternalPos );
1043 if( lpPos->hwndIconTitle )
1045 SendMessageA( lpPos->hwndIconTitle, WM_SHOWWINDOW, TRUE, 0);
1046 InvalidateRect( lpPos->hwndIconTitle, NULL, TRUE );
1053 /***********************************************************************
1054 * WINPOS_ShowIconTitle
1056 BOOL WINPOS_ShowIconTitle( WND* pWnd, BOOL bShow )
1058 LPINTERNALPOS lpPos = (LPINTERNALPOS)GetPropA( pWnd->hwndSelf, atomInternalPos );
1060 if( lpPos && !(pWnd->dwExStyle & WS_EX_MANAGED))
1062 HWND16 hWnd = lpPos->hwndIconTitle;
1064 TRACE("0x%04x %i\n", pWnd->hwndSelf, (bShow != 0) );
1067 lpPos->hwndIconTitle = hWnd = ICONTITLE_Create( pWnd );
1070 if( ( pWnd = WIN_FindWndPtr(hWnd) ) != NULL)
1072 if( !(pWnd->dwStyle & WS_VISIBLE) )
1074 SendMessageA( hWnd, WM_SHOWWINDOW, TRUE, 0 );
1075 SetWindowPos( hWnd, 0, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE |
1076 SWP_NOACTIVATE | SWP_NOZORDER | SWP_SHOWWINDOW );
1078 WIN_ReleaseWndPtr(pWnd);
1081 else ShowWindow( hWnd, SW_HIDE );
1086 /*******************************************************************
1087 * WINPOS_GetMinMaxInfo
1089 * Get the minimized and maximized information for a window.
1091 void WINPOS_GetMinMaxInfo( WND *wndPtr, POINT *maxSize, POINT *maxPos,
1092 POINT *minTrack, POINT *maxTrack )
1094 LPINTERNALPOS lpPos;
1098 /* Compute default values */
1100 MinMax.ptMaxSize.x = GetSystemMetrics(SM_CXSCREEN);
1101 MinMax.ptMaxSize.y = GetSystemMetrics(SM_CYSCREEN);
1102 MinMax.ptMinTrackSize.x = GetSystemMetrics(SM_CXMINTRACK);
1103 MinMax.ptMinTrackSize.y = GetSystemMetrics(SM_CYMINTRACK);
1104 MinMax.ptMaxTrackSize.x = GetSystemMetrics(SM_CXSCREEN);
1105 MinMax.ptMaxTrackSize.y = GetSystemMetrics(SM_CYSCREEN);
1107 if (HAS_DLGFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
1109 xinc = GetSystemMetrics(SM_CXDLGFRAME);
1110 yinc = GetSystemMetrics(SM_CYDLGFRAME);
1115 if (HAS_THICKFRAME(wndPtr->dwStyle))
1117 xinc += GetSystemMetrics(SM_CXFRAME);
1118 yinc += GetSystemMetrics(SM_CYFRAME);
1120 if (wndPtr->dwStyle & WS_BORDER)
1122 xinc += GetSystemMetrics(SM_CXBORDER);
1123 yinc += GetSystemMetrics(SM_CYBORDER);
1126 MinMax.ptMaxSize.x += 2 * xinc;
1127 MinMax.ptMaxSize.y += 2 * yinc;
1129 lpPos = (LPINTERNALPOS)GetPropA( wndPtr->hwndSelf, atomInternalPos );
1130 if( lpPos && !EMPTYPOINT(lpPos->ptMaxPos) )
1131 CONV_POINT16TO32( &lpPos->ptMaxPos, &MinMax.ptMaxPosition );
1134 MinMax.ptMaxPosition.x = -xinc;
1135 MinMax.ptMaxPosition.y = -yinc;
1138 SendMessageA( wndPtr->hwndSelf, WM_GETMINMAXINFO, 0, (LPARAM)&MinMax );
1140 /* Some sanity checks */
1142 TRACE("%ld %ld / %ld %ld / %ld %ld / %ld %ld\n",
1143 MinMax.ptMaxSize.x, MinMax.ptMaxSize.y,
1144 MinMax.ptMaxPosition.x, MinMax.ptMaxPosition.y,
1145 MinMax.ptMaxTrackSize.x, MinMax.ptMaxTrackSize.y,
1146 MinMax.ptMinTrackSize.x, MinMax.ptMinTrackSize.y);
1147 MinMax.ptMaxTrackSize.x = max( MinMax.ptMaxTrackSize.x,
1148 MinMax.ptMinTrackSize.x );
1149 MinMax.ptMaxTrackSize.y = max( MinMax.ptMaxTrackSize.y,
1150 MinMax.ptMinTrackSize.y );
1152 if (maxSize) *maxSize = MinMax.ptMaxSize;
1153 if (maxPos) *maxPos = MinMax.ptMaxPosition;
1154 if (minTrack) *minTrack = MinMax.ptMinTrackSize;
1155 if (maxTrack) *maxTrack = MinMax.ptMaxTrackSize;
1158 /***********************************************************************
1159 * ShowWindowAsync (USER32.@)
1161 * doesn't wait; returns immediately.
1162 * used by threads to toggle windows in other (possibly hanging) threads
1164 BOOL WINAPI ShowWindowAsync( HWND hwnd, INT cmd )
1166 /* FIXME: does ShowWindow() return immediately ? */
1167 return ShowWindow(hwnd, cmd);
1171 /***********************************************************************
1172 * ShowWindow (USER.42)
1174 BOOL16 WINAPI ShowWindow16( HWND16 hwnd, INT16 cmd )
1176 return ShowWindow(hwnd,cmd);
1180 /***********************************************************************
1181 * ShowWindow (USER32.@)
1183 BOOL WINAPI ShowWindow( HWND hwnd, INT cmd )
1185 return USER_Driver.pShowWindow( hwnd, cmd );
1189 /***********************************************************************
1190 * GetInternalWindowPos (USER.460)
1192 UINT16 WINAPI GetInternalWindowPos16( HWND16 hwnd, LPRECT16 rectWnd,
1195 WINDOWPLACEMENT16 wndpl;
1196 if (GetWindowPlacement16( hwnd, &wndpl ))
1198 if (rectWnd) *rectWnd = wndpl.rcNormalPosition;
1199 if (ptIcon) *ptIcon = wndpl.ptMinPosition;
1200 return wndpl.showCmd;
1206 /***********************************************************************
1207 * GetInternalWindowPos (USER32.@)
1209 UINT WINAPI GetInternalWindowPos( HWND hwnd, LPRECT rectWnd,
1212 WINDOWPLACEMENT wndpl;
1213 if (GetWindowPlacement( hwnd, &wndpl ))
1215 if (rectWnd) *rectWnd = wndpl.rcNormalPosition;
1216 if (ptIcon) *ptIcon = wndpl.ptMinPosition;
1217 return wndpl.showCmd;
1222 /***********************************************************************
1223 * GetWindowPlacement (USER.370)
1225 BOOL16 WINAPI GetWindowPlacement16( HWND16 hwnd, WINDOWPLACEMENT16 *wndpl )
1227 WND *pWnd = WIN_FindWndPtr( hwnd );
1228 LPINTERNALPOS lpPos;
1230 if(!pWnd ) return FALSE;
1232 lpPos = (LPINTERNALPOS)WINPOS_InitInternalPos( pWnd,
1233 *(LPPOINT)&pWnd->rectWindow.left, &pWnd->rectWindow );
1234 wndpl->length = sizeof(*wndpl);
1235 if( pWnd->dwStyle & WS_MINIMIZE )
1236 wndpl->showCmd = SW_SHOWMINIMIZED;
1238 wndpl->showCmd = ( pWnd->dwStyle & WS_MAXIMIZE )
1239 ? SW_SHOWMAXIMIZED : SW_SHOWNORMAL ;
1240 if( pWnd->flags & WIN_RESTORE_MAX )
1241 wndpl->flags = WPF_RESTORETOMAXIMIZED;
1244 wndpl->ptMinPosition = lpPos->ptIconPos;
1245 wndpl->ptMaxPosition = lpPos->ptMaxPos;
1246 wndpl->rcNormalPosition = lpPos->rectNormal;
1248 WIN_ReleaseWndPtr(pWnd);
1253 /***********************************************************************
1254 * GetWindowPlacement (USER32.@)
1257 * Fails if wndpl->length of Win95 (!) apps is invalid.
1259 BOOL WINAPI GetWindowPlacement( HWND hwnd, WINDOWPLACEMENT *pwpl32 )
1263 WINDOWPLACEMENT16 wpl;
1264 wpl.length = sizeof(wpl);
1265 if( GetWindowPlacement16( hwnd, &wpl ) )
1267 pwpl32->length = sizeof(*pwpl32);
1268 pwpl32->flags = wpl.flags;
1269 pwpl32->showCmd = wpl.showCmd;
1270 CONV_POINT16TO32( &wpl.ptMinPosition, &pwpl32->ptMinPosition );
1271 CONV_POINT16TO32( &wpl.ptMaxPosition, &pwpl32->ptMaxPosition );
1272 CONV_RECT16TO32( &wpl.rcNormalPosition, &pwpl32->rcNormalPosition );
1280 /***********************************************************************
1281 * WINPOS_SetPlacement
1283 static BOOL WINPOS_SetPlacement( HWND hwnd, const WINDOWPLACEMENT16 *wndpl,
1286 WND *pWnd = WIN_FindWndPtr( hwnd );
1289 LPINTERNALPOS lpPos = (LPINTERNALPOS)WINPOS_InitInternalPos( pWnd,
1290 *(LPPOINT)&pWnd->rectWindow.left, &pWnd->rectWindow );
1292 if( flags & PLACE_MIN ) lpPos->ptIconPos = wndpl->ptMinPosition;
1293 if( flags & PLACE_MAX ) lpPos->ptMaxPos = wndpl->ptMaxPosition;
1294 if( flags & PLACE_RECT) lpPos->rectNormal = wndpl->rcNormalPosition;
1296 if( pWnd->dwStyle & WS_MINIMIZE )
1298 WINPOS_ShowIconTitle( pWnd, FALSE );
1299 if( wndpl->flags & WPF_SETMINPOSITION && !EMPTYPOINT(lpPos->ptIconPos))
1300 SetWindowPos( hwnd, 0, lpPos->ptIconPos.x, lpPos->ptIconPos.y,
1301 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE );
1303 else if( pWnd->dwStyle & WS_MAXIMIZE )
1305 if( !EMPTYPOINT(lpPos->ptMaxPos) )
1306 SetWindowPos( hwnd, 0, lpPos->ptMaxPos.x, lpPos->ptMaxPos.y,
1307 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE );
1309 else if( flags & PLACE_RECT )
1310 SetWindowPos( hwnd, 0, lpPos->rectNormal.left, lpPos->rectNormal.top,
1311 lpPos->rectNormal.right - lpPos->rectNormal.left,
1312 lpPos->rectNormal.bottom - lpPos->rectNormal.top,
1313 SWP_NOZORDER | SWP_NOACTIVATE );
1315 ShowWindow( hwnd, wndpl->showCmd );
1316 if( IsWindow(hwnd) && pWnd->dwStyle & WS_MINIMIZE )
1318 if( pWnd->dwStyle & WS_VISIBLE ) WINPOS_ShowIconTitle( pWnd, TRUE );
1320 /* SDK: ...valid only the next time... */
1321 if( wndpl->flags & WPF_RESTORETOMAXIMIZED ) pWnd->flags |= WIN_RESTORE_MAX;
1323 WIN_ReleaseWndPtr(pWnd);
1330 /***********************************************************************
1331 * SetWindowPlacement (USER.371)
1333 BOOL16 WINAPI SetWindowPlacement16(HWND16 hwnd, const WINDOWPLACEMENT16 *wndpl)
1335 return WINPOS_SetPlacement( hwnd, wndpl,
1336 PLACE_MIN | PLACE_MAX | PLACE_RECT );
1339 /***********************************************************************
1340 * SetWindowPlacement (USER32.@)
1343 * Fails if wndpl->length of Win95 (!) apps is invalid.
1345 BOOL WINAPI SetWindowPlacement( HWND hwnd, const WINDOWPLACEMENT *pwpl32 )
1349 WINDOWPLACEMENT16 wpl;
1351 wpl.length = sizeof(WINDOWPLACEMENT16);
1352 wpl.flags = pwpl32->flags;
1353 wpl.showCmd = pwpl32->showCmd;
1354 wpl.ptMinPosition.x = pwpl32->ptMinPosition.x;
1355 wpl.ptMinPosition.y = pwpl32->ptMinPosition.y;
1356 wpl.ptMaxPosition.x = pwpl32->ptMaxPosition.x;
1357 wpl.ptMaxPosition.y = pwpl32->ptMaxPosition.y;
1358 wpl.rcNormalPosition.left = pwpl32->rcNormalPosition.left;
1359 wpl.rcNormalPosition.top = pwpl32->rcNormalPosition.top;
1360 wpl.rcNormalPosition.right = pwpl32->rcNormalPosition.right;
1361 wpl.rcNormalPosition.bottom = pwpl32->rcNormalPosition.bottom;
1363 return WINPOS_SetPlacement( hwnd, &wpl, PLACE_MIN | PLACE_MAX | PLACE_RECT );
1369 /***********************************************************************
1370 * SetInternalWindowPos (USER.461)
1372 void WINAPI SetInternalWindowPos16( HWND16 hwnd, UINT16 showCmd,
1373 LPRECT16 rect, LPPOINT16 pt )
1375 if( IsWindow16(hwnd) )
1377 WINDOWPLACEMENT16 wndpl;
1380 wndpl.length = sizeof(wndpl);
1381 wndpl.showCmd = showCmd;
1382 wndpl.flags = flags = 0;
1387 wndpl.flags |= WPF_SETMINPOSITION;
1388 wndpl.ptMinPosition = *pt;
1392 flags |= PLACE_RECT;
1393 wndpl.rcNormalPosition = *rect;
1395 WINPOS_SetPlacement( hwnd, &wndpl, flags );
1399 /***********************************************************************
1400 * AnimateWindow (USER32.@)
1401 * Shows/Hides a window with an animation
1404 BOOL WINAPI AnimateWindow(HWND hwnd, DWORD dwTime, DWORD dwFlags)
1406 FIXME("partial stub\n");
1408 /* If trying to show/hide and it's already *
1409 * shown/hidden or invalid window, fail with *
1410 * invalid parameter */
1411 if(!IsWindow(hwnd) ||
1412 (IsWindowVisible(hwnd) && !(dwFlags & AW_HIDE)) ||
1413 (!IsWindowVisible(hwnd) && (dwFlags & AW_HIDE)))
1415 SetLastError(ERROR_INVALID_PARAMETER);
1419 ShowWindow(hwnd, (dwFlags & AW_HIDE) ? SW_HIDE : ((dwFlags & AW_ACTIVATE) ? SW_SHOW : SW_SHOWNA));
1424 /***********************************************************************
1425 * SetInternalWindowPos (USER32.@)
1427 void WINAPI SetInternalWindowPos( HWND hwnd, UINT showCmd,
1428 LPRECT rect, LPPOINT pt )
1430 if( IsWindow(hwnd) )
1432 WINDOWPLACEMENT16 wndpl;
1435 wndpl.length = sizeof(wndpl);
1436 wndpl.showCmd = showCmd;
1437 wndpl.flags = flags = 0;
1442 wndpl.flags |= WPF_SETMINPOSITION;
1443 CONV_POINT32TO16( pt, &wndpl.ptMinPosition );
1447 flags |= PLACE_RECT;
1448 CONV_RECT32TO16( rect, &wndpl.rcNormalPosition );
1450 WINPOS_SetPlacement( hwnd, &wndpl, flags );
1454 /*******************************************************************
1455 * WINPOS_SetActiveWindow
1457 * SetActiveWindow() back-end. This is the only function that
1458 * can assign active status to a window. It must be called only
1459 * for the top level windows.
1461 BOOL WINPOS_SetActiveWindow( HWND hWnd, BOOL fMouse, BOOL fChangeFocus)
1463 WND* wndPtr=0, *wndTemp;
1464 HQUEUE16 hOldActiveQueue, hNewActiveQueue;
1465 MESSAGEQUEUE *pOldActiveQueue = 0, *pNewActiveQueue = 0;
1467 HWND hwndActive = 0;
1470 TRACE("(%04x, %d, %d)\n", hWnd, fMouse, fChangeFocus );
1472 /* Get current active window from the active queue */
1475 pOldActiveQueue = QUEUE_Lock( hActiveQueue );
1476 if ( pOldActiveQueue )
1477 hwndActive = PERQDATA_GetActiveWnd( pOldActiveQueue->pQData );
1480 /* paranoid checks */
1481 if( hWnd == GetDesktopWindow() || (bRet = (hWnd == hwndActive)) )
1484 /* if (wndPtr && (GetFastQueue16() != wndPtr->hmemTaskQ))
1487 wndPtr = WIN_FindWndPtr(hWnd);
1488 hOldActiveQueue = hActiveQueue;
1490 if( (wndTemp = WIN_FindWndPtr(hwndActive)) )
1492 wIconized = HIWORD(wndTemp->dwStyle & WS_MINIMIZE);
1493 WIN_ReleaseWndPtr(wndTemp);
1496 TRACE("no current active window.\n");
1498 /* call CBT hook chain */
1499 if (HOOK_IsHooked( WH_CBT ))
1501 CBTACTIVATESTRUCT cbt;
1502 cbt.fMouse = fMouse;
1503 cbt.hWndActive = hwndActive;
1504 if (HOOK_CallHooksA( WH_CBT, HCBT_ACTIVATE, hWnd, (LPARAM)&cbt )) goto CLEANUP_END;
1507 /* set prev active wnd to current active wnd and send notification */
1508 if ((hwndPrevActive = hwndActive) && IsWindow(hwndPrevActive))
1510 MESSAGEQUEUE *pTempActiveQueue = 0;
1512 if (!SendMessageA( hwndPrevActive, WM_NCACTIVATE, FALSE, 0 ))
1514 if (GetSysModalWindow16() != hWnd)
1516 /* disregard refusal if hWnd is sysmodal */
1519 SendMessageA( hwndPrevActive, WM_ACTIVATE,
1520 MAKEWPARAM( WA_INACTIVE, wIconized ),
1523 /* check if something happened during message processing
1524 * (global active queue may have changed)
1526 pTempActiveQueue = QUEUE_Lock( hActiveQueue );
1527 if(!pTempActiveQueue)
1530 hwndActive = PERQDATA_GetActiveWnd( pTempActiveQueue->pQData );
1531 QUEUE_Unlock( pTempActiveQueue );
1532 if( hwndPrevActive != hwndActive )
1536 /* Set new active window in the message queue */
1540 pNewActiveQueue = QUEUE_Lock( wndPtr->hmemTaskQ );
1541 if ( pNewActiveQueue )
1542 PERQDATA_SetActiveWnd( pNewActiveQueue->pQData, hwndActive );
1544 else /* have to do this or MDI frame activation goes to hell */
1545 if( pOldActiveQueue )
1546 PERQDATA_SetActiveWnd( pOldActiveQueue->pQData, 0 );
1548 /* send palette messages */
1549 if (hWnd && SendMessage16( hWnd, WM_QUERYNEWPALETTE, 0, 0L))
1550 SendMessage16((HWND16)-1, WM_PALETTEISCHANGING, (WPARAM16)hWnd, 0L );
1552 /* if prev wnd is minimized redraw icon title */
1553 if( IsIconic( hwndPrevActive ) ) WINPOS_RedrawIconTitle(hwndPrevActive);
1555 /* managed windows will get ConfigureNotify event */
1556 if (wndPtr && !(wndPtr->dwStyle & WS_CHILD) && !(wndPtr->dwExStyle & WS_EX_MANAGED))
1558 /* check Z-order and bring hWnd to the top */
1559 for (wndTemp = WIN_LockWndPtr(WIN_GetDesktop()->child); wndTemp; WIN_UpdateWndPtr(&wndTemp,wndTemp->next))
1561 if (wndTemp->dwStyle & WS_VISIBLE) break;
1563 WIN_ReleaseDesktop();
1564 WIN_ReleaseWndPtr(wndTemp);
1566 if( wndTemp != wndPtr )
1567 SetWindowPos(hWnd, HWND_TOP, 0,0,0,0,
1568 SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE );
1569 if (!IsWindow(hWnd))
1573 /* Get a handle to the new active queue */
1574 hNewActiveQueue = wndPtr ? wndPtr->hmemTaskQ : 0;
1576 /* send WM_ACTIVATEAPP if necessary */
1577 if (hOldActiveQueue != hNewActiveQueue)
1579 WND **list, **ppWnd;
1580 WND *pDesktop = WIN_GetDesktop();
1582 if ((list = WIN_BuildWinArray( pDesktop, 0, NULL )))
1584 DWORD new_thread = GetWindowThreadProcessId( hwndActive, NULL );
1585 for (ppWnd = list; *ppWnd; ppWnd++)
1587 if (!IsWindow( (*ppWnd)->hwndSelf )) continue;
1589 if ((*ppWnd)->hmemTaskQ == hOldActiveQueue)
1590 SendMessageW( (*ppWnd)->hwndSelf, WM_ACTIVATEAPP, 0, new_thread );
1592 WIN_ReleaseWinArray(list);
1595 hActiveQueue = hNewActiveQueue;
1597 if ((list = WIN_BuildWinArray(pDesktop, 0, NULL )))
1599 DWORD old_thread = GetWindowThreadProcessId( hwndPrevActive, NULL );
1600 for (ppWnd = list; *ppWnd; ppWnd++)
1602 if (!IsWindow( (*ppWnd)->hwndSelf )) continue;
1604 if ((*ppWnd)->hmemTaskQ == hNewActiveQueue)
1605 SendMessageW( (*ppWnd)->hwndSelf, WM_ACTIVATEAPP, 1, old_thread );
1607 WIN_ReleaseWinArray(list);
1609 WIN_ReleaseDesktop();
1611 if (hWnd && !IsWindow(hWnd)) goto CLEANUP;
1616 /* walk up to the first unowned window */
1617 wndTemp = WIN_LockWndPtr(wndPtr);
1618 while (wndTemp->owner)
1620 WIN_UpdateWndPtr(&wndTemp,wndTemp->owner);
1622 /* and set last active owned popup */
1623 wndTemp->hwndLastActive = hWnd;
1625 wIconized = HIWORD(wndTemp->dwStyle & WS_MINIMIZE);
1626 WIN_ReleaseWndPtr(wndTemp);
1627 SendMessageA( hWnd, WM_NCACTIVATE, TRUE, 0 );
1628 SendMessageA( hWnd, WM_ACTIVATE,
1629 MAKEWPARAM( (fMouse) ? WA_CLICKACTIVE : WA_ACTIVE, wIconized),
1630 (LPARAM)hwndPrevActive );
1631 if( !IsWindow(hWnd) ) goto CLEANUP;
1634 /* change focus if possible */
1637 if ( pNewActiveQueue )
1639 HWND hOldFocus = PERQDATA_GetFocusWnd( pNewActiveQueue->pQData );
1641 if ( hOldFocus && WIN_GetTopParent( hOldFocus ) != hwndActive )
1642 FOCUS_SwitchFocus( pNewActiveQueue, hOldFocus,
1643 (wndPtr && (wndPtr->dwStyle & WS_MINIMIZE))?
1647 if ( pOldActiveQueue &&
1648 ( !pNewActiveQueue ||
1649 pNewActiveQueue->pQData != pOldActiveQueue->pQData ) )
1651 HWND hOldFocus = PERQDATA_GetFocusWnd( pOldActiveQueue->pQData );
1653 FOCUS_SwitchFocus( pOldActiveQueue, hOldFocus, 0 );
1657 if( !hwndPrevActive && wndPtr )
1659 if (USER_Driver.pForceWindowRaise) USER_Driver.pForceWindowRaise( wndPtr->hwndSelf );
1662 /* if active wnd is minimized redraw icon title */
1663 if( IsIconic(hwndActive) ) WINPOS_RedrawIconTitle(hwndActive);
1665 bRet = (hWnd == hwndActive); /* Success? */
1667 CLEANUP: /* Unlock the message queues before returning */
1669 if ( pNewActiveQueue )
1670 QUEUE_Unlock( pNewActiveQueue );
1674 if ( pOldActiveQueue )
1675 QUEUE_Unlock( pOldActiveQueue );
1677 WIN_ReleaseWndPtr(wndPtr);
1681 /*******************************************************************
1682 * WINPOS_ActivateOtherWindow
1684 * Activates window other than pWnd.
1686 BOOL WINPOS_ActivateOtherWindow(WND* pWnd)
1690 HWND hwndActive = 0;
1692 /* Get current active window from the active queue */
1695 MESSAGEQUEUE *pActiveQueue = QUEUE_Lock( hActiveQueue );
1698 hwndActive = PERQDATA_GetActiveWnd( pActiveQueue->pQData );
1699 QUEUE_Unlock( pActiveQueue );
1703 if( pWnd->hwndSelf == hwndPrevActive )
1706 if( hwndActive != pWnd->hwndSelf &&
1707 ( hwndActive || QUEUE_IsExitingQueue(pWnd->hmemTaskQ)) )
1710 if( !(pWnd->dwStyle & WS_POPUP) || !(pWnd->owner) ||
1711 !WINPOS_CanActivate((pWndTo = WIN_GetTopParentPtr(pWnd->owner))) )
1713 WND* pWndPtr = WIN_GetTopParentPtr(pWnd);
1715 WIN_ReleaseWndPtr(pWndTo);
1716 pWndTo = WIN_FindWndPtr(hwndPrevActive);
1718 while( !WINPOS_CanActivate(pWndTo) )
1720 /* by now owned windows should've been taken care of */
1721 WIN_UpdateWndPtr(&pWndTo,pWndPtr->next);
1722 WIN_UpdateWndPtr(&pWndPtr,pWndTo);
1723 if( !pWndTo ) break;
1725 WIN_ReleaseWndPtr(pWndPtr);
1728 bRet = WINPOS_SetActiveWindow( pWndTo ? pWndTo->hwndSelf : 0, FALSE, TRUE );
1730 if( pWndTo ) WIN_ReleaseWndPtr(pWndTo);
1736 /*******************************************************************
1737 * WINPOS_ChangeActiveWindow
1740 BOOL WINPOS_ChangeActiveWindow( HWND hWnd, BOOL mouseMsg )
1744 HWND hwndActive = 0;
1746 /* Get current active window from the active queue */
1749 MESSAGEQUEUE *pActiveQueue = QUEUE_Lock( hActiveQueue );
1752 hwndActive = PERQDATA_GetActiveWnd( pActiveQueue->pQData );
1753 QUEUE_Unlock( pActiveQueue );
1758 return WINPOS_SetActiveWindow( 0, mouseMsg, TRUE );
1760 wndPtr = WIN_FindWndPtr(hWnd);
1761 if( !wndPtr ) return FALSE;
1763 /* child windows get WM_CHILDACTIVATE message */
1764 if( (wndPtr->dwStyle & (WS_CHILD | WS_POPUP)) == WS_CHILD )
1766 retvalue = SendMessageA(hWnd, WM_CHILDACTIVATE, 0, 0L);
1770 if( hWnd == hwndActive )
1776 if( !WINPOS_SetActiveWindow(hWnd ,mouseMsg ,TRUE) )
1784 WIN_ReleaseWndPtr(wndPtr);
1789 /***********************************************************************
1790 * WINPOS_SendNCCalcSize
1792 * Send a WM_NCCALCSIZE message to a window.
1793 * All parameters are read-only except newClientRect.
1794 * oldWindowRect, oldClientRect and winpos must be non-NULL only
1795 * when calcValidRect is TRUE.
1797 LONG WINPOS_SendNCCalcSize( HWND hwnd, BOOL calcValidRect,
1798 RECT *newWindowRect, RECT *oldWindowRect,
1799 RECT *oldClientRect, WINDOWPOS *winpos,
1800 RECT *newClientRect )
1802 NCCALCSIZE_PARAMS params;
1803 WINDOWPOS winposCopy;
1806 params.rgrc[0] = *newWindowRect;
1809 winposCopy = *winpos;
1810 params.rgrc[1] = *oldWindowRect;
1811 params.rgrc[2] = *oldClientRect;
1812 params.lppos = &winposCopy;
1814 result = SendMessageA( hwnd, WM_NCCALCSIZE, calcValidRect,
1816 TRACE("%d,%d-%d,%d\n",
1817 params.rgrc[0].left, params.rgrc[0].top,
1818 params.rgrc[0].right, params.rgrc[0].bottom );
1820 /* If the application send back garbage, ignore it */
1821 if (params.rgrc[0].left <= params.rgrc[0].right && params.rgrc[0].top <= params.rgrc[0].bottom)
1822 *newClientRect = params.rgrc[0];
1828 /***********************************************************************
1829 * WINPOS_HandleWindowPosChanging16
1831 * Default handling for a WM_WINDOWPOSCHANGING. Called from DefWindowProc().
1833 LONG WINPOS_HandleWindowPosChanging16( WND *wndPtr, WINDOWPOS16 *winpos )
1835 POINT maxSize, minTrack;
1836 if (winpos->flags & SWP_NOSIZE) return 0;
1837 if ((wndPtr->dwStyle & WS_THICKFRAME) ||
1838 ((wndPtr->dwStyle & (WS_POPUP | WS_CHILD)) == 0))
1840 WINPOS_GetMinMaxInfo( wndPtr, &maxSize, NULL, &minTrack, NULL );
1841 if (maxSize.x < winpos->cx) winpos->cx = maxSize.x;
1842 if (maxSize.y < winpos->cy) winpos->cy = maxSize.y;
1843 if (!(wndPtr->dwStyle & WS_MINIMIZE))
1845 if (winpos->cx < minTrack.x ) winpos->cx = minTrack.x;
1846 if (winpos->cy < minTrack.y ) winpos->cy = minTrack.y;
1853 /***********************************************************************
1854 * WINPOS_HandleWindowPosChanging
1856 * Default handling for a WM_WINDOWPOSCHANGING. Called from DefWindowProc().
1858 LONG WINPOS_HandleWindowPosChanging( WND *wndPtr, WINDOWPOS *winpos )
1860 POINT maxSize, minTrack;
1861 if (winpos->flags & SWP_NOSIZE) return 0;
1862 if ((wndPtr->dwStyle & WS_THICKFRAME) ||
1863 ((wndPtr->dwStyle & (WS_POPUP | WS_CHILD)) == 0))
1865 WINPOS_GetMinMaxInfo( wndPtr, &maxSize, NULL, &minTrack, NULL );
1866 winpos->cx = min( winpos->cx, maxSize.x );
1867 winpos->cy = min( winpos->cy, maxSize.y );
1868 if (!(wndPtr->dwStyle & WS_MINIMIZE))
1870 if (winpos->cx < minTrack.x ) winpos->cx = minTrack.x;
1871 if (winpos->cy < minTrack.y ) winpos->cy = minTrack.y;
1877 /***********************************************************************
1878 * SetWindowPos (USER.232)
1880 BOOL16 WINAPI SetWindowPos16( HWND16 hwnd, HWND16 hwndInsertAfter,
1881 INT16 x, INT16 y, INT16 cx, INT16 cy, WORD flags)
1883 return SetWindowPos(hwnd,(INT)(INT16)hwndInsertAfter,x,y,cx,cy,flags);
1886 /***********************************************************************
1887 * SetWindowPos (USER32.@)
1889 BOOL WINAPI SetWindowPos( HWND hwnd, HWND hwndInsertAfter,
1890 INT x, INT y, INT cx, INT cy, UINT flags )
1895 winpos.hwndInsertAfter = hwndInsertAfter;
1900 winpos.flags = flags;
1901 return USER_Driver.pSetWindowPos( &winpos );
1905 /***********************************************************************
1906 * BeginDeferWindowPos (USER.259)
1908 HDWP16 WINAPI BeginDeferWindowPos16( INT16 count )
1910 return BeginDeferWindowPos( count );
1914 /***********************************************************************
1915 * BeginDeferWindowPos (USER32.@)
1917 HDWP WINAPI BeginDeferWindowPos( INT count )
1924 SetLastError(ERROR_INVALID_PARAMETER);
1927 /* Windows allows zero count, in which case it allocates context for 8 moves */
1928 if (count == 0) count = 8;
1930 handle = USER_HEAP_ALLOC( sizeof(DWP) + (count-1)*sizeof(WINDOWPOS) );
1931 if (!handle) return 0;
1932 pDWP = (DWP *) USER_HEAP_LIN_ADDR( handle );
1933 pDWP->actualCount = 0;
1934 pDWP->suggestedCount = count;
1936 pDWP->wMagic = DWP_MAGIC;
1937 pDWP->hwndParent = 0;
1942 /***********************************************************************
1943 * DeferWindowPos (USER.260)
1945 HDWP16 WINAPI DeferWindowPos16( HDWP16 hdwp, HWND16 hwnd, HWND16 hwndAfter,
1946 INT16 x, INT16 y, INT16 cx, INT16 cy,
1949 return DeferWindowPos( hdwp, hwnd, (INT)(INT16)hwndAfter,
1950 x, y, cx, cy, flags );
1954 /***********************************************************************
1955 * DeferWindowPos (USER32.@)
1957 HDWP WINAPI DeferWindowPos( HDWP hdwp, HWND hwnd, HWND hwndAfter,
1958 INT x, INT y, INT cx, INT cy,
1963 HDWP newhdwp = hdwp,retvalue;
1967 pDWP = (DWP *) USER_HEAP_LIN_ADDR( hdwp );
1968 if (!pDWP) return 0;
1969 if (hwnd == GetDesktopWindow()) return 0;
1971 if (!(pWnd=WIN_FindWndPtr( hwnd ))) {
1972 USER_HEAP_FREE( hdwp );
1976 /* Numega Bounds Checker Demo dislikes the following code.
1977 In fact, I've not been able to find any "same parent" requirement in any docu
1981 /* All the windows of a DeferWindowPos() must have the same parent */
1982 parent = pWnd->parent->hwndSelf;
1983 if (pDWP->actualCount == 0) pDWP->hwndParent = parent;
1984 else if (parent != pDWP->hwndParent)
1986 USER_HEAP_FREE( hdwp );
1992 for (i = 0; i < pDWP->actualCount; i++)
1994 if (pDWP->winPos[i].hwnd == hwnd)
1996 /* Merge with the other changes */
1997 if (!(flags & SWP_NOZORDER))
1999 pDWP->winPos[i].hwndInsertAfter = hwndAfter;
2001 if (!(flags & SWP_NOMOVE))
2003 pDWP->winPos[i].x = x;
2004 pDWP->winPos[i].y = y;
2006 if (!(flags & SWP_NOSIZE))
2008 pDWP->winPos[i].cx = cx;
2009 pDWP->winPos[i].cy = cy;
2011 pDWP->winPos[i].flags &= flags | ~(SWP_NOSIZE | SWP_NOMOVE |
2012 SWP_NOZORDER | SWP_NOREDRAW |
2013 SWP_NOACTIVATE | SWP_NOCOPYBITS|
2015 pDWP->winPos[i].flags |= flags & (SWP_SHOWWINDOW | SWP_HIDEWINDOW |
2021 if (pDWP->actualCount >= pDWP->suggestedCount)
2023 newhdwp = USER_HEAP_REALLOC( hdwp,
2024 sizeof(DWP) + pDWP->suggestedCount*sizeof(WINDOWPOS) );
2030 pDWP = (DWP *) USER_HEAP_LIN_ADDR( newhdwp );
2031 pDWP->suggestedCount++;
2033 pDWP->winPos[pDWP->actualCount].hwnd = hwnd;
2034 pDWP->winPos[pDWP->actualCount].hwndInsertAfter = hwndAfter;
2035 pDWP->winPos[pDWP->actualCount].x = x;
2036 pDWP->winPos[pDWP->actualCount].y = y;
2037 pDWP->winPos[pDWP->actualCount].cx = cx;
2038 pDWP->winPos[pDWP->actualCount].cy = cy;
2039 pDWP->winPos[pDWP->actualCount].flags = flags;
2040 pDWP->actualCount++;
2043 WIN_ReleaseWndPtr(pWnd);
2048 /***********************************************************************
2049 * EndDeferWindowPos (USER.261)
2051 BOOL16 WINAPI EndDeferWindowPos16( HDWP16 hdwp )
2053 return EndDeferWindowPos( hdwp );
2057 /***********************************************************************
2058 * EndDeferWindowPos (USER32.@)
2060 BOOL WINAPI EndDeferWindowPos( HDWP hdwp )
2067 pDWP = (DWP *) USER_HEAP_LIN_ADDR( hdwp );
2068 if (!pDWP) return FALSE;
2069 for (i = 0, winpos = pDWP->winPos; i < pDWP->actualCount; i++, winpos++)
2071 if (!(res = USER_Driver.pSetWindowPos( winpos ))) break;
2073 USER_HEAP_FREE( hdwp );
2078 /***********************************************************************
2079 * TileChildWindows (USER.199)
2081 void WINAPI TileChildWindows16( HWND16 parent, WORD action )
2083 FIXME("(%04x, %d): stub\n", parent, action);
2086 /***********************************************************************
2087 * CascadeChildWindows (USER.198)
2089 void WINAPI CascadeChildWindows16( HWND16 parent, WORD action )
2091 FIXME("(%04x, %d): stub\n", parent, action);
2094 /***********************************************************************
2095 * SetProgmanWindow (USER32.@)
2097 HRESULT WINAPI SetProgmanWindow ( HWND hwnd )
2099 hGlobalProgmanWindow = hwnd;
2100 return hGlobalProgmanWindow;
2103 /***********************************************************************
2104 * GetProgmanWindow (USER32.@)
2106 HRESULT WINAPI GetProgmanWindow ( )
2108 return hGlobalProgmanWindow;
2111 /***********************************************************************
2112 * SetShellWindowEx (USER32.@)
2113 * hwndProgman = Progman[Program Manager]
2114 * |-> SHELLDLL_DefView
2115 * hwndListView = | |-> SysListView32
2116 * | | |-> tooltips_class32
2122 HRESULT WINAPI SetShellWindowEx ( HWND hwndProgman, HWND hwndListView )
2124 FIXME("0x%08x 0x%08x stub\n",hwndProgman ,hwndListView );
2125 hGlobalShellWindow = hwndProgman;
2126 return hGlobalShellWindow;
2130 /***********************************************************************
2131 * SetTaskmanWindow (USER32.@)
2133 * hwnd = MSTaskSwWClass
2134 * |-> SysTabControl32
2136 HRESULT WINAPI SetTaskmanWindow ( HWND hwnd )
2138 hGlobalTaskmanWindow = hwnd;
2139 return hGlobalTaskmanWindow;
2142 /***********************************************************************
2143 * GetTaskmanWindow (USER32.@)
2145 HRESULT WINAPI GetTaskmanWindow ( )
2147 return hGlobalTaskmanWindow;