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_CallHooks16(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 CBTACTIVATESTRUCT16
* cbtStruct
;
1726 WND
* wndPtr
=0, *wndTemp
;
1727 HQUEUE16 hOldActiveQueue
, hNewActiveQueue
;
1728 MESSAGEQUEUE
*pOldActiveQueue
= 0, *pNewActiveQueue
= 0;
1730 HWND hwndActive
= 0;
1733 TRACE("(%04x, %d, %d)\n", hWnd
, fMouse
, fChangeFocus
);
1735 /* Get current active window from the active queue */
1738 pOldActiveQueue
= QUEUE_Lock( hActiveQueue
);
1739 if ( pOldActiveQueue
)
1740 hwndActive
= PERQDATA_GetActiveWnd( pOldActiveQueue
->pQData
);
1743 /* paranoid checks */
1744 if( hWnd
== GetDesktopWindow() || (bRet
= (hWnd
== hwndActive
)) )
1747 /* if (wndPtr && (GetFastQueue16() != wndPtr->hmemTaskQ))
1750 wndPtr
= WIN_FindWndPtr(hWnd
);
1751 hOldActiveQueue
= hActiveQueue
;
1753 if( (wndTemp
= WIN_FindWndPtr(hwndActive
)) )
1755 wIconized
= HIWORD(wndTemp
->dwStyle
& WS_MINIMIZE
);
1756 WIN_ReleaseWndPtr(wndTemp
);
1759 TRACE("no current active window.\n");
1761 /* call CBT hook chain */
1762 if ((cbtStruct
= SEGPTR_NEW(CBTACTIVATESTRUCT16
)))
1764 cbtStruct
->fMouse
= fMouse
;
1765 cbtStruct
->hWndActive
= hwndActive
;
1766 bRet
= (BOOL
)HOOK_CallHooks16( WH_CBT
, HCBT_ACTIVATE
, (WPARAM16
)hWnd
,
1767 (LPARAM
)SEGPTR_GET(cbtStruct
) );
1768 SEGPTR_FREE(cbtStruct
);
1769 if (bRet
) goto CLEANUP_END
;
1772 /* set prev active wnd to current active wnd and send notification */
1773 if ((hwndPrevActive
= hwndActive
) && IsWindow(hwndPrevActive
))
1775 MESSAGEQUEUE
*pTempActiveQueue
= 0;
1777 if (!SendMessageA( hwndPrevActive
, WM_NCACTIVATE
, FALSE
, 0 ))
1779 if (GetSysModalWindow16() != hWnd
)
1781 /* disregard refusal if hWnd is sysmodal */
1784 SendMessageA( hwndPrevActive
, WM_ACTIVATE
,
1785 MAKEWPARAM( WA_INACTIVE
, wIconized
),
1788 /* check if something happened during message processing
1789 * (global active queue may have changed)
1791 pTempActiveQueue
= QUEUE_Lock( hActiveQueue
);
1792 if(!pTempActiveQueue
)
1795 hwndActive
= PERQDATA_GetActiveWnd( pTempActiveQueue
->pQData
);
1796 QUEUE_Unlock( pTempActiveQueue
);
1797 if( hwndPrevActive
!= hwndActive
)
1801 /* Set new active window in the message queue */
1805 pNewActiveQueue
= QUEUE_Lock( wndPtr
->hmemTaskQ
);
1806 if ( pNewActiveQueue
)
1807 PERQDATA_SetActiveWnd( pNewActiveQueue
->pQData
, hwndActive
);
1809 else /* have to do this or MDI frame activation goes to hell */
1810 if( pOldActiveQueue
)
1811 PERQDATA_SetActiveWnd( pOldActiveQueue
->pQData
, 0 );
1813 /* send palette messages */
1814 if (hWnd
&& SendMessage16( hWnd
, WM_QUERYNEWPALETTE
, 0, 0L))
1815 SendMessage16((HWND16
)-1, WM_PALETTEISCHANGING
, (WPARAM16
)hWnd
, 0L );
1817 /* if prev wnd is minimized redraw icon title */
1818 if( IsIconic( hwndPrevActive
) ) WINPOS_RedrawIconTitle(hwndPrevActive
);
1820 /* managed windows will get ConfigureNotify event */
1821 if (wndPtr
&& !(wndPtr
->dwStyle
& WS_CHILD
) && !(wndPtr
->dwExStyle
& WS_EX_MANAGED
))
1823 /* check Z-order and bring hWnd to the top */
1824 for (wndTemp
= WIN_LockWndPtr(WIN_GetDesktop()->child
); wndTemp
; WIN_UpdateWndPtr(&wndTemp
,wndTemp
->next
))
1826 if (wndTemp
->dwStyle
& WS_VISIBLE
) break;
1828 WIN_ReleaseDesktop();
1829 WIN_ReleaseWndPtr(wndTemp
);
1831 if( wndTemp
!= wndPtr
)
1832 SetWindowPos(hWnd
, HWND_TOP
, 0,0,0,0,
1833 SWP_NOSIZE
| SWP_NOMOVE
| SWP_NOACTIVATE
);
1834 if (!IsWindow(hWnd
))
1838 /* Get a handle to the new active queue */
1839 hNewActiveQueue
= wndPtr
? wndPtr
->hmemTaskQ
: 0;
1841 /* send WM_ACTIVATEAPP if necessary */
1842 if (hOldActiveQueue
!= hNewActiveQueue
)
1844 WND
**list
, **ppWnd
;
1845 WND
*pDesktop
= WIN_GetDesktop();
1847 if ((list
= WIN_BuildWinArray( pDesktop
, 0, NULL
)))
1849 for (ppWnd
= list
; *ppWnd
; ppWnd
++)
1851 if (!IsWindow( (*ppWnd
)->hwndSelf
)) continue;
1853 if ((*ppWnd
)->hmemTaskQ
== hOldActiveQueue
)
1854 SendMessage16( (*ppWnd
)->hwndSelf
, WM_ACTIVATEAPP
,
1855 0, QUEUE_GetQueueTask(hNewActiveQueue
) );
1857 WIN_ReleaseWinArray(list
);
1860 hActiveQueue
= hNewActiveQueue
;
1862 if ((list
= WIN_BuildWinArray(pDesktop
, 0, NULL
)))
1864 for (ppWnd
= list
; *ppWnd
; ppWnd
++)
1866 if (!IsWindow( (*ppWnd
)->hwndSelf
)) continue;
1868 if ((*ppWnd
)->hmemTaskQ
== hNewActiveQueue
)
1869 SendMessage16( (*ppWnd
)->hwndSelf
, WM_ACTIVATEAPP
,
1870 1, QUEUE_GetQueueTask( hOldActiveQueue
) );
1872 WIN_ReleaseWinArray(list
);
1874 WIN_ReleaseDesktop();
1876 if (hWnd
&& !IsWindow(hWnd
)) goto CLEANUP
;
1881 /* walk up to the first unowned window */
1882 wndTemp
= WIN_LockWndPtr(wndPtr
);
1883 while (wndTemp
->owner
)
1885 WIN_UpdateWndPtr(&wndTemp
,wndTemp
->owner
);
1887 /* and set last active owned popup */
1888 wndTemp
->hwndLastActive
= hWnd
;
1890 wIconized
= HIWORD(wndTemp
->dwStyle
& WS_MINIMIZE
);
1891 WIN_ReleaseWndPtr(wndTemp
);
1892 SendMessageA( hWnd
, WM_NCACTIVATE
, TRUE
, 0 );
1893 SendMessageA( hWnd
, WM_ACTIVATE
,
1894 MAKEWPARAM( (fMouse
) ? WA_CLICKACTIVE
: WA_ACTIVE
, wIconized
),
1895 (LPARAM
)hwndPrevActive
);
1896 if( !IsWindow(hWnd
) ) goto CLEANUP
;
1899 /* change focus if possible */
1902 if ( pNewActiveQueue
)
1904 HWND hOldFocus
= PERQDATA_GetFocusWnd( pNewActiveQueue
->pQData
);
1906 if ( hOldFocus
&& WIN_GetTopParent( hOldFocus
) != hwndActive
)
1907 FOCUS_SwitchFocus( pNewActiveQueue
, hOldFocus
,
1908 (wndPtr
&& (wndPtr
->dwStyle
& WS_MINIMIZE
))?
1912 if ( pOldActiveQueue
&&
1913 ( !pNewActiveQueue
||
1914 pNewActiveQueue
->pQData
!= pOldActiveQueue
->pQData
) )
1916 HWND hOldFocus
= PERQDATA_GetFocusWnd( pOldActiveQueue
->pQData
);
1918 FOCUS_SwitchFocus( pOldActiveQueue
, hOldFocus
, 0 );
1922 if( !hwndPrevActive
&& wndPtr
)
1923 (*wndPtr
->pDriver
->pForceWindowRaise
)(wndPtr
);
1925 /* if active wnd is minimized redraw icon title */
1926 if( IsIconic(hwndActive
) ) WINPOS_RedrawIconTitle(hwndActive
);
1928 bRet
= (hWnd
== hwndActive
); /* Success? */
1930 CLEANUP
: /* Unlock the message queues before returning */
1932 if ( pNewActiveQueue
)
1933 QUEUE_Unlock( pNewActiveQueue
);
1937 if ( pOldActiveQueue
)
1938 QUEUE_Unlock( pOldActiveQueue
);
1940 WIN_ReleaseWndPtr(wndPtr
);
1944 /*******************************************************************
1945 * WINPOS_ActivateOtherWindow
1947 * Activates window other than pWnd.
1949 BOOL
WINPOS_ActivateOtherWindow(WND
* pWnd
)
1953 HWND hwndActive
= 0;
1955 /* Get current active window from the active queue */
1958 MESSAGEQUEUE
*pActiveQueue
= QUEUE_Lock( hActiveQueue
);
1961 hwndActive
= PERQDATA_GetActiveWnd( pActiveQueue
->pQData
);
1962 QUEUE_Unlock( pActiveQueue
);
1966 if( pWnd
->hwndSelf
== hwndPrevActive
)
1969 if( hwndActive
!= pWnd
->hwndSelf
&&
1970 ( hwndActive
|| QUEUE_IsExitingQueue(pWnd
->hmemTaskQ
)) )
1973 if( !(pWnd
->dwStyle
& WS_POPUP
) || !(pWnd
->owner
) ||
1974 !WINPOS_CanActivate((pWndTo
= WIN_GetTopParentPtr(pWnd
->owner
))) )
1976 WND
* pWndPtr
= WIN_GetTopParentPtr(pWnd
);
1978 WIN_ReleaseWndPtr(pWndTo
);
1979 pWndTo
= WIN_FindWndPtr(hwndPrevActive
);
1981 while( !WINPOS_CanActivate(pWndTo
) )
1983 /* by now owned windows should've been taken care of */
1984 WIN_UpdateWndPtr(&pWndTo
,pWndPtr
->next
);
1985 WIN_UpdateWndPtr(&pWndPtr
,pWndTo
);
1986 if( !pWndTo
) break;
1988 WIN_ReleaseWndPtr(pWndPtr
);
1991 bRet
= WINPOS_SetActiveWindow( pWndTo
? pWndTo
->hwndSelf
: 0, FALSE
, TRUE
);
1993 /* switch desktop queue to current active */
1996 WIN_GetDesktop()->hmemTaskQ
= pWndTo
->hmemTaskQ
;
1997 WIN_ReleaseWndPtr(pWndTo
);
1998 WIN_ReleaseDesktop();
2005 /*******************************************************************
2006 * WINPOS_ChangeActiveWindow
2009 BOOL
WINPOS_ChangeActiveWindow( HWND hWnd
, BOOL mouseMsg
)
2011 WND
*wndPtr
, *wndTemp
;
2013 HWND hwndActive
= 0;
2015 /* Get current active window from the active queue */
2018 MESSAGEQUEUE
*pActiveQueue
= QUEUE_Lock( hActiveQueue
);
2021 hwndActive
= PERQDATA_GetActiveWnd( pActiveQueue
->pQData
);
2022 QUEUE_Unlock( pActiveQueue
);
2027 return WINPOS_SetActiveWindow( 0, mouseMsg
, TRUE
);
2029 wndPtr
= WIN_FindWndPtr(hWnd
);
2030 if( !wndPtr
) return FALSE
;
2032 /* child windows get WM_CHILDACTIVATE message */
2033 if( (wndPtr
->dwStyle
& (WS_CHILD
| WS_POPUP
)) == WS_CHILD
)
2035 retvalue
= SendMessageA(hWnd
, WM_CHILDACTIVATE
, 0, 0L);
2039 if( hWnd
== hwndActive
)
2045 if( !WINPOS_SetActiveWindow(hWnd
,mouseMsg
,TRUE
) )
2051 /* switch desktop queue to current active */
2052 wndTemp
= WIN_GetDesktop();
2053 if( wndPtr
->parent
== wndTemp
)
2054 wndTemp
->hmemTaskQ
= wndPtr
->hmemTaskQ
;
2055 WIN_ReleaseDesktop();
2059 WIN_ReleaseWndPtr(wndPtr
);
2064 /***********************************************************************
2065 * WINPOS_SendNCCalcSize
2067 * Send a WM_NCCALCSIZE message to a window.
2068 * All parameters are read-only except newClientRect.
2069 * oldWindowRect, oldClientRect and winpos must be non-NULL only
2070 * when calcValidRect is TRUE.
2072 LONG
WINPOS_SendNCCalcSize( HWND hwnd
, BOOL calcValidRect
,
2073 RECT
*newWindowRect
, RECT
*oldWindowRect
,
2074 RECT
*oldClientRect
, WINDOWPOS
*winpos
,
2075 RECT
*newClientRect
)
2077 NCCALCSIZE_PARAMS params
;
2078 WINDOWPOS winposCopy
;
2081 params
.rgrc
[0] = *newWindowRect
;
2084 winposCopy
= *winpos
;
2085 params
.rgrc
[1] = *oldWindowRect
;
2086 params
.rgrc
[2] = *oldClientRect
;
2087 params
.lppos
= &winposCopy
;
2089 result
= SendMessageA( hwnd
, WM_NCCALCSIZE
, calcValidRect
,
2091 TRACE("%d,%d-%d,%d\n",
2092 params
.rgrc
[0].left
, params
.rgrc
[0].top
,
2093 params
.rgrc
[0].right
, params
.rgrc
[0].bottom
);
2095 /* If the application send back garbage, ignore it */
2096 if (params
.rgrc
[0].left
<= params
.rgrc
[0].right
&& params
.rgrc
[0].top
<= params
.rgrc
[0].bottom
)
2097 *newClientRect
= params
.rgrc
[0];
2103 /***********************************************************************
2104 * WINPOS_HandleWindowPosChanging16
2106 * Default handling for a WM_WINDOWPOSCHANGING. Called from DefWindowProc().
2108 LONG
WINPOS_HandleWindowPosChanging16( WND
*wndPtr
, WINDOWPOS16
*winpos
)
2110 POINT maxSize
, minTrack
;
2111 if (winpos
->flags
& SWP_NOSIZE
) return 0;
2112 if ((wndPtr
->dwStyle
& WS_THICKFRAME
) ||
2113 ((wndPtr
->dwStyle
& (WS_POPUP
| WS_CHILD
)) == 0))
2115 WINPOS_GetMinMaxInfo( wndPtr
, &maxSize
, NULL
, &minTrack
, NULL
);
2116 if (maxSize
.x
< winpos
->cx
) winpos
->cx
= maxSize
.x
;
2117 if (maxSize
.y
< winpos
->cy
) winpos
->cy
= maxSize
.y
;
2118 if (!(wndPtr
->dwStyle
& WS_MINIMIZE
))
2120 if (winpos
->cx
< minTrack
.x
) winpos
->cx
= minTrack
.x
;
2121 if (winpos
->cy
< minTrack
.y
) winpos
->cy
= minTrack
.y
;
2128 /***********************************************************************
2129 * WINPOS_HandleWindowPosChanging
2131 * Default handling for a WM_WINDOWPOSCHANGING. Called from DefWindowProc().
2133 LONG
WINPOS_HandleWindowPosChanging( WND
*wndPtr
, WINDOWPOS
*winpos
)
2135 POINT maxSize
, minTrack
;
2136 if (winpos
->flags
& SWP_NOSIZE
) return 0;
2137 if ((wndPtr
->dwStyle
& WS_THICKFRAME
) ||
2138 ((wndPtr
->dwStyle
& (WS_POPUP
| WS_CHILD
)) == 0))
2140 WINPOS_GetMinMaxInfo( wndPtr
, &maxSize
, NULL
, &minTrack
, NULL
);
2141 winpos
->cx
= min( winpos
->cx
, maxSize
.x
);
2142 winpos
->cy
= min( winpos
->cy
, maxSize
.y
);
2143 if (!(wndPtr
->dwStyle
& WS_MINIMIZE
))
2145 if (winpos
->cx
< minTrack
.x
) winpos
->cx
= minTrack
.x
;
2146 if (winpos
->cy
< minTrack
.y
) winpos
->cy
= minTrack
.y
;
2152 /***********************************************************************
2153 * SetWindowPos (USER.232)
2155 BOOL16 WINAPI
SetWindowPos16( HWND16 hwnd
, HWND16 hwndInsertAfter
,
2156 INT16 x
, INT16 y
, INT16 cx
, INT16 cy
, WORD flags
)
2158 return SetWindowPos(hwnd
,(INT
)(INT16
)hwndInsertAfter
,x
,y
,cx
,cy
,flags
);
2161 /***********************************************************************
2162 * SetWindowPos (USER32.@)
2164 BOOL WINAPI
SetWindowPos( HWND hwnd
, HWND hwndInsertAfter
,
2165 INT x
, INT y
, INT cx
, INT cy
, UINT flags
)
2170 winpos
.hwndInsertAfter
= hwndInsertAfter
;
2175 winpos
.flags
= flags
;
2176 return USER_Driver
.pSetWindowPos( &winpos
);
2180 /***********************************************************************
2181 * BeginDeferWindowPos (USER.259)
2183 HDWP16 WINAPI
BeginDeferWindowPos16( INT16 count
)
2185 return BeginDeferWindowPos( count
);
2189 /***********************************************************************
2190 * BeginDeferWindowPos (USER32.@)
2192 HDWP WINAPI
BeginDeferWindowPos( INT count
)
2199 SetLastError(ERROR_INVALID_PARAMETER
);
2202 /* Windows allows zero count, in which case it allocates context for 8 moves */
2203 if (count
== 0) count
= 8;
2205 handle
= USER_HEAP_ALLOC( sizeof(DWP
) + (count
-1)*sizeof(WINDOWPOS
) );
2206 if (!handle
) return 0;
2207 pDWP
= (DWP
*) USER_HEAP_LIN_ADDR( handle
);
2208 pDWP
->actualCount
= 0;
2209 pDWP
->suggestedCount
= count
;
2211 pDWP
->wMagic
= DWP_MAGIC
;
2212 pDWP
->hwndParent
= 0;
2217 /***********************************************************************
2218 * DeferWindowPos (USER.260)
2220 HDWP16 WINAPI
DeferWindowPos16( HDWP16 hdwp
, HWND16 hwnd
, HWND16 hwndAfter
,
2221 INT16 x
, INT16 y
, INT16 cx
, INT16 cy
,
2224 return DeferWindowPos( hdwp
, hwnd
, (INT
)(INT16
)hwndAfter
,
2225 x
, y
, cx
, cy
, flags
);
2229 /***********************************************************************
2230 * DeferWindowPos (USER32.@)
2232 HDWP WINAPI
DeferWindowPos( HDWP hdwp
, HWND hwnd
, HWND hwndAfter
,
2233 INT x
, INT y
, INT cx
, INT cy
,
2238 HDWP newhdwp
= hdwp
,retvalue
;
2242 pDWP
= (DWP
*) USER_HEAP_LIN_ADDR( hdwp
);
2243 if (!pDWP
) return 0;
2244 if (hwnd
== GetDesktopWindow()) return 0;
2246 if (!(pWnd
=WIN_FindWndPtr( hwnd
))) {
2247 USER_HEAP_FREE( hdwp
);
2251 /* Numega Bounds Checker Demo dislikes the following code.
2252 In fact, I've not been able to find any "same parent" requirement in any docu
2256 /* All the windows of a DeferWindowPos() must have the same parent */
2257 parent
= pWnd
->parent
->hwndSelf
;
2258 if (pDWP
->actualCount
== 0) pDWP
->hwndParent
= parent
;
2259 else if (parent
!= pDWP
->hwndParent
)
2261 USER_HEAP_FREE( hdwp
);
2267 for (i
= 0; i
< pDWP
->actualCount
; i
++)
2269 if (pDWP
->winPos
[i
].hwnd
== hwnd
)
2271 /* Merge with the other changes */
2272 if (!(flags
& SWP_NOZORDER
))
2274 pDWP
->winPos
[i
].hwndInsertAfter
= hwndAfter
;
2276 if (!(flags
& SWP_NOMOVE
))
2278 pDWP
->winPos
[i
].x
= x
;
2279 pDWP
->winPos
[i
].y
= y
;
2281 if (!(flags
& SWP_NOSIZE
))
2283 pDWP
->winPos
[i
].cx
= cx
;
2284 pDWP
->winPos
[i
].cy
= cy
;
2286 pDWP
->winPos
[i
].flags
&= flags
| ~(SWP_NOSIZE
| SWP_NOMOVE
|
2287 SWP_NOZORDER
| SWP_NOREDRAW
|
2288 SWP_NOACTIVATE
| SWP_NOCOPYBITS
|
2290 pDWP
->winPos
[i
].flags
|= flags
& (SWP_SHOWWINDOW
| SWP_HIDEWINDOW
|
2296 if (pDWP
->actualCount
>= pDWP
->suggestedCount
)
2298 newhdwp
= USER_HEAP_REALLOC( hdwp
,
2299 sizeof(DWP
) + pDWP
->suggestedCount
*sizeof(WINDOWPOS
) );
2305 pDWP
= (DWP
*) USER_HEAP_LIN_ADDR( newhdwp
);
2306 pDWP
->suggestedCount
++;
2308 pDWP
->winPos
[pDWP
->actualCount
].hwnd
= hwnd
;
2309 pDWP
->winPos
[pDWP
->actualCount
].hwndInsertAfter
= hwndAfter
;
2310 pDWP
->winPos
[pDWP
->actualCount
].x
= x
;
2311 pDWP
->winPos
[pDWP
->actualCount
].y
= y
;
2312 pDWP
->winPos
[pDWP
->actualCount
].cx
= cx
;
2313 pDWP
->winPos
[pDWP
->actualCount
].cy
= cy
;
2314 pDWP
->winPos
[pDWP
->actualCount
].flags
= flags
;
2315 pDWP
->actualCount
++;
2318 WIN_ReleaseWndPtr(pWnd
);
2323 /***********************************************************************
2324 * EndDeferWindowPos (USER.261)
2326 BOOL16 WINAPI
EndDeferWindowPos16( HDWP16 hdwp
)
2328 return EndDeferWindowPos( hdwp
);
2332 /***********************************************************************
2333 * EndDeferWindowPos (USER32.@)
2335 BOOL WINAPI
EndDeferWindowPos( HDWP hdwp
)
2342 pDWP
= (DWP
*) USER_HEAP_LIN_ADDR( hdwp
);
2343 if (!pDWP
) return FALSE
;
2344 for (i
= 0, winpos
= pDWP
->winPos
; i
< pDWP
->actualCount
; i
++, winpos
++)
2346 if (!(res
= USER_Driver
.pSetWindowPos( winpos
))) break;
2348 USER_HEAP_FREE( hdwp
);
2353 /***********************************************************************
2354 * TileChildWindows (USER.199)
2356 void WINAPI
TileChildWindows16( HWND16 parent
, WORD action
)
2358 FIXME("(%04x, %d): stub\n", parent
, action
);
2361 /***********************************************************************
2362 * CascadeChildWindows (USER.198)
2364 void WINAPI
CascadeChildWindows16( HWND16 parent
, WORD action
)
2366 FIXME("(%04x, %d): stub\n", parent
, action
);
2369 /***********************************************************************
2370 * SetProgmanWindow (USER32.@)
2372 HRESULT WINAPI
SetProgmanWindow ( HWND hwnd
)
2374 hGlobalProgmanWindow
= hwnd
;
2375 return hGlobalProgmanWindow
;
2378 /***********************************************************************
2379 * GetProgmanWindow (USER32.@)
2381 HRESULT WINAPI
GetProgmanWindow ( )
2383 return hGlobalProgmanWindow
;
2386 /***********************************************************************
2387 * SetShellWindowEx (USER32.@)
2388 * hwndProgman = Progman[Program Manager]
2389 * |-> SHELLDLL_DefView
2390 * hwndListView = | |-> SysListView32
2391 * | | |-> tooltips_class32
2397 HRESULT WINAPI
SetShellWindowEx ( HWND hwndProgman
, HWND hwndListView
)
2399 FIXME("0x%08x 0x%08x stub\n",hwndProgman
,hwndListView
);
2400 hGlobalShellWindow
= hwndProgman
;
2401 return hGlobalShellWindow
;
2405 /***********************************************************************
2406 * SetTaskmanWindow (USER32.@)
2408 * hwnd = MSTaskSwWClass
2409 * |-> SysTabControl32
2411 HRESULT WINAPI
SetTaskmanWindow ( HWND hwnd
)
2413 hGlobalTaskmanWindow
= hwnd
;
2414 return hGlobalTaskmanWindow
;
2417 /***********************************************************************
2418 * GetTaskmanWindow (USER32.@)
2420 HRESULT WINAPI
GetTaskmanWindow ( )
2422 return hGlobalTaskmanWindow
;