blob: ba42028bac46e1dd3c544599e325e25e4605f2aa [file] [log] [blame]
Alexandre Julliard5f721f81994-01-04 20:14:34 +00001/*
2 * Window position related functions.
3 *
Alexandre Julliard22945d51995-03-02 17:44:29 +00004 * Copyright 1993, 1994, 1995 Alexandre Julliard
Alex Korobka4f1ac051999-03-28 09:37:57 +00005 * 1995, 1996, 1999 Alex Korobka
Alexandre Julliard5f721f81994-01-04 20:14:34 +00006 */
7
Alexandre Julliarddadf78f1998-05-17 17:13:43 +00008#include <string.h>
Jeremy Whited3e22d92000-02-10 19:03:02 +00009#include "windef.h"
10#include "wingdi.h"
Michael Veksler9d14a001999-05-08 12:40:24 +000011#include "wine/winuser16.h"
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +000012#include "heap.h"
Alexandre Julliardc981d0b1996-03-31 16:40:13 +000013#include "module.h"
Alexandre Julliarddba420a1994-02-02 06:48:31 +000014#include "user.h"
Alex Korobka4f1ac051999-03-28 09:37:57 +000015#include "region.h"
Alexandre Julliard5f721f81994-01-04 20:14:34 +000016#include "win.h"
Alexandre Julliardd4719651995-12-12 18:49:11 +000017#include "hook.h"
Alexandre Julliard8d24ae61994-04-05 21:42:43 +000018#include "message.h"
Alexandre Julliardb817f4f1996-03-14 18:08:34 +000019#include "queue.h"
Alexandre Julliard18f92e71996-07-17 20:02:21 +000020#include "options.h"
Ulrich Weigand1babe5b1998-12-24 15:16:08 +000021#include "task.h"
Alexandre Julliardaca05781994-10-17 18:12:41 +000022#include "winpos.h"
Alexandre Julliard1e9ac791996-06-06 18:38:27 +000023#include "dce.h"
Alexandre Julliard22945d51995-03-02 17:44:29 +000024#include "nonclient.h"
Alexandre Julliard359f497e1999-07-04 16:02:24 +000025#include "debugtools.h"
Patrik Stridvall8d8703c1999-02-04 14:05:38 +000026#include "local.h"
27#include "ldt.h"
Lionel Ulmeracc74671999-11-07 21:25:57 +000028#include "input.h"
Alexandre Julliard5f721f81994-01-04 20:14:34 +000029
Patrik Stridvallb4b9fae1999-04-19 14:56:29 +000030DEFAULT_DEBUG_CHANNEL(win)
31
Alexandre Julliard23946ad1997-06-16 17:43:53 +000032#define HAS_DLGFRAME(style,exStyle) \
33 (((exStyle) & WS_EX_DLGMODALFRAME) || \
34 (((style) & WS_DLGFRAME) && !((style) & WS_BORDER)))
35
36#define HAS_THICKFRAME(style) \
37 (((style) & WS_THICKFRAME) && \
38 !(((style) & (WS_DLGFRAME|WS_BORDER)) == WS_DLGFRAME))
39
Alexandre Julliard18f92e71996-07-17 20:02:21 +000040#define SWP_AGG_NOGEOMETRYCHANGE \
41 (SWP_NOSIZE | SWP_NOMOVE | SWP_NOCLIENTSIZE | SWP_NOCLIENTMOVE)
42#define SWP_AGG_NOPOSCHANGE \
43 (SWP_AGG_NOGEOMETRYCHANGE | SWP_NOZORDER)
44#define SWP_AGG_STATUSFLAGS \
45 (SWP_AGG_NOPOSCHANGE | SWP_FRAMECHANGED | SWP_HIDEWINDOW | SWP_SHOWWINDOW)
Alexandre Julliardcdcdede1996-04-21 14:57:41 +000046
Alexandre Julliard23946ad1997-06-16 17:43:53 +000047#define EMPTYPOINT(pt) ((*(LONG*)&(pt)) == -1)
48
49#define PLACE_MIN 0x0001
50#define PLACE_MAX 0x0002
51#define PLACE_RECT 0x0004
52
Alex Korobka4f1ac051999-03-28 09:37:57 +000053#define SWP_EX_NOCOPY 0x0001
54#define SWP_EX_PAINTSELF 0x0002
Alex Korobka98447491999-05-08 17:57:09 +000055#define SWP_EX_NONCLIENT 0x0004
Alexandre Julliard1e37a181996-08-18 16:21:52 +000056
Alex Korobka44a1b591999-04-01 12:03:52 +000057#define MINMAX_NOSWP 0x00010000
58
Alexandre Julliardd4719651995-12-12 18:49:11 +000059/* ----- internal variables ----- */
60
Alexandre Julliarda3960291999-02-26 11:11:13 +000061static HWND hwndPrevActive = 0; /* Previously active window */
62static HWND hGlobalShellWindow=0; /*the shell*/
Juergen Schmiedddb2e291999-05-02 09:19:19 +000063static HWND hGlobalTaskmanWindow=0;
64static HWND hGlobalProgmanWindow=0;
Alexandre Julliardd4719651995-12-12 18:49:11 +000065
Alexandre Julliard23946ad1997-06-16 17:43:53 +000066static LPCSTR atomInternalPos;
67
Stephane Lussier1c4786f1999-01-28 10:54:11 +000068extern HQUEUE16 hActiveQueue;
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +000069
70/***********************************************************************
Alexandre Julliard23946ad1997-06-16 17:43:53 +000071 * WINPOS_CreateInternalPosAtom
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +000072 */
Alexandre Julliarda3960291999-02-26 11:11:13 +000073BOOL WINPOS_CreateInternalPosAtom()
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +000074{
Alexandre Julliard23946ad1997-06-16 17:43:53 +000075 LPSTR str = "SysIP";
Alexandre Julliarda3960291999-02-26 11:11:13 +000076 atomInternalPos = (LPCSTR)(DWORD)GlobalAddAtomA(str);
Alexandre Julliard23946ad1997-06-16 17:43:53 +000077 return (atomInternalPos) ? TRUE : FALSE;
78}
79
80/***********************************************************************
81 * WINPOS_CheckInternalPos
82 *
83 * Called when a window is destroyed.
84 */
Noel Borthwickb4278561999-02-05 10:37:53 +000085void WINPOS_CheckInternalPos( WND* wndPtr )
Alexandre Julliard23946ad1997-06-16 17:43:53 +000086{
Noel Borthwickb4278561999-02-05 10:37:53 +000087 LPINTERNALPOS lpPos;
88 MESSAGEQUEUE *pMsgQ = 0;
Alexandre Julliarda3960291999-02-26 11:11:13 +000089 HWND hwnd = wndPtr->hwndSelf;
Noel Borthwickb4278561999-02-05 10:37:53 +000090
Alexandre Julliarda3960291999-02-26 11:11:13 +000091 lpPos = (LPINTERNALPOS) GetPropA( hwnd, atomInternalPos );
Noel Borthwickb4278561999-02-05 10:37:53 +000092
93 /* Retrieve the message queue associated with this window */
94 pMsgQ = (MESSAGEQUEUE *)QUEUE_Lock( wndPtr->hmemTaskQ );
95 if ( !pMsgQ )
96 {
Alexandre Julliard359f497e1999-07-04 16:02:24 +000097 WARN("\tMessage queue not found. Exiting!\n" );
Noel Borthwickb4278561999-02-05 10:37:53 +000098 return;
99 }
Alexandre Julliard23946ad1997-06-16 17:43:53 +0000100
101 if( hwnd == hwndPrevActive ) hwndPrevActive = 0;
Noel Borthwickb4278561999-02-05 10:37:53 +0000102
103 if( hwnd == PERQDATA_GetActiveWnd( pMsgQ->pQData ) )
Alexandre Julliard23946ad1997-06-16 17:43:53 +0000104 {
Noel Borthwickb4278561999-02-05 10:37:53 +0000105 PERQDATA_SetActiveWnd( pMsgQ->pQData, 0 );
Alexandre Julliard359f497e1999-07-04 16:02:24 +0000106 WARN("\tattempt to activate destroyed window!\n");
Alexandre Julliard23946ad1997-06-16 17:43:53 +0000107 }
108
109 if( lpPos )
110 {
Alexandre Julliarda3960291999-02-26 11:11:13 +0000111 if( IsWindow(lpPos->hwndIconTitle) )
112 DestroyWindow( lpPos->hwndIconTitle );
Alexandre Julliard23946ad1997-06-16 17:43:53 +0000113 HeapFree( SystemHeap, 0, lpPos );
114 }
Noel Borthwickb4278561999-02-05 10:37:53 +0000115
116 QUEUE_Unlock( pMsgQ );
117 return;
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +0000118}
119
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000120/***********************************************************************
Alexandre Julliard22945d51995-03-02 17:44:29 +0000121 * WINPOS_FindIconPos
122 *
123 * Find a suitable place for an iconic window.
Alexandre Julliard22945d51995-03-02 17:44:29 +0000124 */
Alexandre Julliard23946ad1997-06-16 17:43:53 +0000125static POINT16 WINPOS_FindIconPos( WND* wndPtr, POINT16 pt )
Alexandre Julliard22945d51995-03-02 17:44:29 +0000126{
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000127 RECT16 rectParent;
Alexandre Julliard22945d51995-03-02 17:44:29 +0000128 short x, y, xspacing, yspacing;
Alexandre Julliard22945d51995-03-02 17:44:29 +0000129
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000130 GetClientRect16( wndPtr->parent->hwndSelf, &rectParent );
Marcus Meissnerddca3151999-05-22 11:33:23 +0000131 if ((pt.x >= rectParent.left) && (pt.x + GetSystemMetrics(SM_CXICON) < rectParent.right) &&
132 (pt.y >= rectParent.top) && (pt.y + GetSystemMetrics(SM_CYICON) < rectParent.bottom))
Alexandre Julliard23946ad1997-06-16 17:43:53 +0000133 return pt; /* The icon already has a suitable position */
Alexandre Julliard22945d51995-03-02 17:44:29 +0000134
Marcus Meissnerddca3151999-05-22 11:33:23 +0000135 xspacing = GetSystemMetrics(SM_CXICONSPACING);
136 yspacing = GetSystemMetrics(SM_CYICONSPACING);
Alexandre Julliard23946ad1997-06-16 17:43:53 +0000137
Alexandre Julliard22945d51995-03-02 17:44:29 +0000138 y = rectParent.bottom;
139 for (;;)
140 {
Huw D M Daviesbe898161999-12-25 22:51:19 +0000141 x = rectParent.left;
142 do
Alexandre Julliard22945d51995-03-02 17:44:29 +0000143 {
144 /* Check if another icon already occupies this spot */
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000145 WND *childPtr = WIN_LockWndPtr(wndPtr->parent->child);
Alexandre Julliard59730ae1996-03-24 16:20:51 +0000146 while (childPtr)
Alexandre Julliard22945d51995-03-02 17:44:29 +0000147 {
Alexandre Julliard59730ae1996-03-24 16:20:51 +0000148 if ((childPtr->dwStyle & WS_MINIMIZE) && (childPtr != wndPtr))
Alexandre Julliard22945d51995-03-02 17:44:29 +0000149 {
150 if ((childPtr->rectWindow.left < x + xspacing) &&
151 (childPtr->rectWindow.right >= x) &&
152 (childPtr->rectWindow.top <= y) &&
153 (childPtr->rectWindow.bottom > y - yspacing))
154 break; /* There's a window in there */
155 }
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000156 WIN_UpdateWndPtr(&childPtr,childPtr->next);
Alexandre Julliard22945d51995-03-02 17:44:29 +0000157 }
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000158 WIN_ReleaseWndPtr(childPtr);
Alexandre Julliard23946ad1997-06-16 17:43:53 +0000159 if (!childPtr) /* No window was found, so it's OK for us */
Alexandre Julliard22945d51995-03-02 17:44:29 +0000160 {
Marcus Meissnerddca3151999-05-22 11:33:23 +0000161 pt.x = x + (xspacing - GetSystemMetrics(SM_CXICON)) / 2;
162 pt.y = y - (yspacing + GetSystemMetrics(SM_CYICON)) / 2;
Alexandre Julliard23946ad1997-06-16 17:43:53 +0000163 return pt;
Alexandre Julliard22945d51995-03-02 17:44:29 +0000164 }
Huw D M Daviesbe898161999-12-25 22:51:19 +0000165 x += xspacing;
166 } while(x <= rectParent.right-xspacing);
Alexandre Julliard22945d51995-03-02 17:44:29 +0000167 y -= yspacing;
168 }
169}
170
171
172/***********************************************************************
Alexandre Julliard23946ad1997-06-16 17:43:53 +0000173 * ArrangeIconicWindows16 (USER.170)
Alexandre Julliard01d63461997-01-20 19:43:45 +0000174 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000175UINT16 WINAPI ArrangeIconicWindows16( HWND16 parent)
Alexandre Julliard23946ad1997-06-16 17:43:53 +0000176{
Alexandre Julliarda3960291999-02-26 11:11:13 +0000177 return ArrangeIconicWindows(parent);
Alexandre Julliard01d63461997-01-20 19:43:45 +0000178}
179/***********************************************************************
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000180 * ArrangeIconicWindows (USER32.7)
Alexandre Julliard22945d51995-03-02 17:44:29 +0000181 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000182UINT WINAPI ArrangeIconicWindows( HWND parent )
Alexandre Julliard22945d51995-03-02 17:44:29 +0000183{
Alexandre Julliarda3960291999-02-26 11:11:13 +0000184 RECT rectParent;
185 HWND hwndChild;
186 INT x, y, xspacing, yspacing;
Alexandre Julliard22945d51995-03-02 17:44:29 +0000187
Alexandre Julliarda3960291999-02-26 11:11:13 +0000188 GetClientRect( parent, &rectParent );
Alexandre Julliard22945d51995-03-02 17:44:29 +0000189 x = rectParent.left;
190 y = rectParent.bottom;
Marcus Meissnerddca3151999-05-22 11:33:23 +0000191 xspacing = GetSystemMetrics(SM_CXICONSPACING);
192 yspacing = GetSystemMetrics(SM_CYICONSPACING);
Alexandre Julliard23946ad1997-06-16 17:43:53 +0000193
Alexandre Julliarda3960291999-02-26 11:11:13 +0000194 hwndChild = GetWindow( parent, GW_CHILD );
Alexandre Julliard22945d51995-03-02 17:44:29 +0000195 while (hwndChild)
196 {
Alexandre Julliarda3960291999-02-26 11:11:13 +0000197 if( IsIconic( hwndChild ) )
Alexandre Julliard22945d51995-03-02 17:44:29 +0000198 {
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000199 WND *wndPtr = WIN_FindWndPtr(hwndChild);
200
201 WINPOS_ShowIconTitle( wndPtr, FALSE );
202
Marcus Meissnerddca3151999-05-22 11:33:23 +0000203 SetWindowPos( hwndChild, 0, x + (xspacing - GetSystemMetrics(SM_CXICON)) / 2,
204 y - yspacing - GetSystemMetrics(SM_CYICON)/2, 0, 0,
Alexandre Julliard23946ad1997-06-16 17:43:53 +0000205 SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE );
Alexandre Julliarda3960291999-02-26 11:11:13 +0000206 if( IsWindow(hwndChild) )
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000207 WINPOS_ShowIconTitle(wndPtr , TRUE );
208 WIN_ReleaseWndPtr(wndPtr);
209
Alexandre Julliard22945d51995-03-02 17:44:29 +0000210 if (x <= rectParent.right - xspacing) x += xspacing;
211 else
212 {
213 x = rectParent.left;
214 y -= yspacing;
215 }
216 }
Alexandre Julliarda3960291999-02-26 11:11:13 +0000217 hwndChild = GetWindow( hwndChild, GW_HWNDNEXT );
Alexandre Julliard22945d51995-03-02 17:44:29 +0000218 }
219 return yspacing;
220}
221
222
223/***********************************************************************
Alexandre Julliarddf2673b1997-03-29 17:20:20 +0000224 * SwitchToThisWindow16 (USER.172)
225 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000226void WINAPI SwitchToThisWindow16( HWND16 hwnd, BOOL16 restore )
Alexandre Julliarddf2673b1997-03-29 17:20:20 +0000227{
Alexandre Julliarda3960291999-02-26 11:11:13 +0000228 SwitchToThisWindow( hwnd, restore );
Alexandre Julliarddf2673b1997-03-29 17:20:20 +0000229}
230
231
232/***********************************************************************
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000233 * SwitchToThisWindow (USER32.539)
Alexandre Julliarddf2673b1997-03-29 17:20:20 +0000234 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000235void WINAPI SwitchToThisWindow( HWND hwnd, BOOL restore )
Alexandre Julliarddf2673b1997-03-29 17:20:20 +0000236{
Alexandre Julliarda3960291999-02-26 11:11:13 +0000237 ShowWindow( hwnd, restore ? SW_RESTORE : SW_SHOWMINIMIZED );
Alexandre Julliarddf2673b1997-03-29 17:20:20 +0000238}
239
240
241/***********************************************************************
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000242 * GetWindowRect16 (USER.32)
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000243 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000244void WINAPI GetWindowRect16( HWND16 hwnd, LPRECT16 rect )
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000245{
246 WND * wndPtr = WIN_FindWndPtr( hwnd );
247 if (!wndPtr) return;
248
Alexandre Julliardd37eb361997-07-20 16:23:21 +0000249 CONV_RECT32TO16( &wndPtr->rectWindow, rect );
Alexandre Julliardfb9a9191994-03-01 19:48:04 +0000250 if (wndPtr->dwStyle & WS_CHILD)
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000251 MapWindowPoints16( wndPtr->parent->hwndSelf, 0, (POINT16 *)rect, 2 );
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000252 WIN_ReleaseWndPtr(wndPtr);
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000253}
254
255
256/***********************************************************************
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000257 * GetWindowRect (USER32.308)
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000258 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000259BOOL WINAPI GetWindowRect( HWND hwnd, LPRECT rect )
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000260{
261 WND * wndPtr = WIN_FindWndPtr( hwnd );
Alexandre Julliardd30dfd21998-09-27 18:28:36 +0000262 if (!wndPtr) return FALSE;
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000263
Alexandre Julliardd37eb361997-07-20 16:23:21 +0000264 *rect = wndPtr->rectWindow;
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000265 if (wndPtr->dwStyle & WS_CHILD)
Alexandre Julliarda3960291999-02-26 11:11:13 +0000266 MapWindowPoints( wndPtr->parent->hwndSelf, 0, (POINT *)rect, 2 );
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000267 WIN_ReleaseWndPtr(wndPtr);
Alexandre Julliardd30dfd21998-09-27 18:28:36 +0000268 return TRUE;
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000269}
270
271
272/***********************************************************************
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000273 * GetWindowRgn
Alexandre Julliard46ea8b31998-05-03 19:01:20 +0000274 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000275BOOL WINAPI GetWindowRgn ( HWND hwnd, HRGN hrgn )
Alexandre Julliard46ea8b31998-05-03 19:01:20 +0000276
277{
Alexandre Julliarda3960291999-02-26 11:11:13 +0000278 RECT rect;
Alexandre Julliard46ea8b31998-05-03 19:01:20 +0000279 WND * wndPtr = WIN_FindWndPtr( hwnd );
280 if (!wndPtr) return (ERROR);
281
Alexandre Julliard359f497e1999-07-04 16:02:24 +0000282 FIXME("GetWindowRgn: doesn't really do regions\n");
Alexandre Julliard46ea8b31998-05-03 19:01:20 +0000283
284 memset (&rect, 0, sizeof(rect));
285
Alexandre Julliarda3960291999-02-26 11:11:13 +0000286 GetWindowRect ( hwnd, &rect );
Alexandre Julliard46ea8b31998-05-03 19:01:20 +0000287
Alexandre Julliard359f497e1999-07-04 16:02:24 +0000288 FIXME("Check whether a valid region here\n");
Alexandre Julliard46ea8b31998-05-03 19:01:20 +0000289
Alexandre Julliarda3960291999-02-26 11:11:13 +0000290 SetRectRgn ( hrgn, rect.left, rect.top, rect.right, rect.bottom );
Alexandre Julliard46ea8b31998-05-03 19:01:20 +0000291
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000292 WIN_ReleaseWndPtr(wndPtr);
Alexandre Julliard46ea8b31998-05-03 19:01:20 +0000293 return (SIMPLEREGION);
294}
295
296/***********************************************************************
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000297 * SetWindowRgn
Alexandre Julliard46ea8b31998-05-03 19:01:20 +0000298 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000299INT WINAPI SetWindowRgn( HWND hwnd, HRGN hrgn,BOOL bRedraw)
Alexandre Julliard46ea8b31998-05-03 19:01:20 +0000300
301{
302
Alexandre Julliard359f497e1999-07-04 16:02:24 +0000303 FIXME("SetWindowRgn: stub\n");
Alexandre Julliard46ea8b31998-05-03 19:01:20 +0000304 return TRUE;
305}
306
Alexandre Julliarda0d77311998-09-13 16:32:00 +0000307/***********************************************************************
308 * SetWindowRgn16
309 */
310INT16 WINAPI SetWindowRgn16( HWND16 hwnd, HRGN16 hrgn,BOOL16 bRedraw)
311
312{
313
Alexandre Julliard359f497e1999-07-04 16:02:24 +0000314 FIXME("SetWindowRgn16: stub\n");
Alexandre Julliarda0d77311998-09-13 16:32:00 +0000315 return TRUE;
316}
317
Alexandre Julliard46ea8b31998-05-03 19:01:20 +0000318
319/***********************************************************************
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000320 * GetClientRect16 (USER.33)
321 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000322void WINAPI GetClientRect16( HWND16 hwnd, LPRECT16 rect )
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000323{
324 WND * wndPtr = WIN_FindWndPtr( hwnd );
325
326 rect->left = rect->top = rect->right = rect->bottom = 0;
327 if (wndPtr)
328 {
329 rect->right = wndPtr->rectClient.right - wndPtr->rectClient.left;
330 rect->bottom = wndPtr->rectClient.bottom - wndPtr->rectClient.top;
331 }
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000332 WIN_ReleaseWndPtr(wndPtr);
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000333}
334
335
336/***********************************************************************
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000337 * GetClientRect (USER.220)
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000338 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000339BOOL WINAPI GetClientRect( HWND hwnd, LPRECT rect )
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000340{
341 WND * wndPtr = WIN_FindWndPtr( hwnd );
342
343 rect->left = rect->top = rect->right = rect->bottom = 0;
Eric Pouechb9544f11999-02-14 14:09:42 +0000344 if (!wndPtr) return FALSE;
345 rect->right = wndPtr->rectClient.right - wndPtr->rectClient.left;
346 rect->bottom = wndPtr->rectClient.bottom - wndPtr->rectClient.top;
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000347
348 WIN_ReleaseWndPtr(wndPtr);
Eric Pouechb9544f11999-02-14 14:09:42 +0000349 return TRUE;
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000350}
351
352
353/*******************************************************************
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000354 * ClientToScreen16 (USER.28)
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000355 */
Alexandre Julliard77b99181997-09-14 17:17:23 +0000356void WINAPI ClientToScreen16( HWND16 hwnd, LPPOINT16 lppnt )
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000357{
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000358 MapWindowPoints16( hwnd, 0, lppnt, 1 );
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000359}
360
361
362/*******************************************************************
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000363 * ClientToScreen (USER32.52)
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000364 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000365BOOL WINAPI ClientToScreen( HWND hwnd, LPPOINT lppnt )
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000366{
Alexandre Julliarda3960291999-02-26 11:11:13 +0000367 MapWindowPoints( hwnd, 0, lppnt, 1 );
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000368 return TRUE;
369}
370
371
372/*******************************************************************
373 * ScreenToClient16 (USER.29)
374 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000375void WINAPI ScreenToClient16( HWND16 hwnd, LPPOINT16 lppnt )
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000376{
377 MapWindowPoints16( 0, hwnd, lppnt, 1 );
378}
379
380
381/*******************************************************************
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000382 * ScreenToClient (USER32.447)
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000383 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000384BOOL WINAPI ScreenToClient( HWND hwnd, LPPOINT lppnt )
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000385{
Alexandre Julliarda3960291999-02-26 11:11:13 +0000386 MapWindowPoints( 0, hwnd, lppnt, 1 );
Eric Pouechb9544f11999-02-14 14:09:42 +0000387 return TRUE;
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000388}
389
390
Alexandre Julliard0c126c71996-02-18 18:44:41 +0000391/***********************************************************************
392 * WINPOS_WindowFromPoint
Alexandre Julliard7e56f681996-01-31 19:02:28 +0000393 *
Alexandre Julliard0c126c71996-02-18 18:44:41 +0000394 * Find the window and hittest for a given point.
Alexandre Julliard7e56f681996-01-31 19:02:28 +0000395 */
Alexandre Julliard75d86e11996-11-17 18:59:11 +0000396INT16 WINPOS_WindowFromPoint( WND* wndScope, POINT16 pt, WND **ppWnd )
Alexandre Julliard7e56f681996-01-31 19:02:28 +0000397{
Alexandre Julliard0c126c71996-02-18 18:44:41 +0000398 WND *wndPtr;
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000399 INT16 hittest = HTERROR;
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000400 INT16 retvalue;
Alexandre Julliard84c70f51997-05-09 08:40:27 +0000401 POINT16 xy = pt;
Alexandre Julliard7e56f681996-01-31 19:02:28 +0000402
Alexandre Julliarda0d77311998-09-13 16:32:00 +0000403 *ppWnd = NULL;
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000404 wndPtr = WIN_LockWndPtr(wndScope->child);
405
Alexandre Julliarda0d77311998-09-13 16:32:00 +0000406 if( wndScope->flags & WIN_MANAGED )
407 {
Alex Korobka4f1ac051999-03-28 09:37:57 +0000408 /* In managed mode we have to check wndScope first as it is also
409 * a window which received the mouse event. */
410
411 if( wndScope->dwStyle & WS_DISABLED )
412 {
413 retvalue = HTERROR;
414 goto end;
415 }
Alexandre Julliarda0d77311998-09-13 16:32:00 +0000416 if( pt.x < wndScope->rectClient.left || pt.x >= wndScope->rectClient.right ||
417 pt.y < wndScope->rectClient.top || pt.y >= wndScope->rectClient.bottom )
418 goto hittest;
419 }
Alexandre Julliard84c70f51997-05-09 08:40:27 +0000420 MapWindowPoints16( GetDesktopWindow16(), wndScope->hwndSelf, &xy, 1 );
421
Alexandre Julliard0c126c71996-02-18 18:44:41 +0000422 for (;;)
423 {
Alexandre Julliard59730ae1996-03-24 16:20:51 +0000424 while (wndPtr)
Alexandre Julliard0c126c71996-02-18 18:44:41 +0000425 {
426 /* If point is in window, and window is visible, and it */
427 /* is enabled (or it's a top-level window), then explore */
428 /* its children. Otherwise, go to the next window. */
Alexandre Julliard7e56f681996-01-31 19:02:28 +0000429
Alexandre Julliard0c126c71996-02-18 18:44:41 +0000430 if ((wndPtr->dwStyle & WS_VISIBLE) &&
431 (!(wndPtr->dwStyle & WS_DISABLED) ||
432 ((wndPtr->dwStyle & (WS_POPUP | WS_CHILD)) != WS_CHILD)) &&
Alexandre Julliard84c70f51997-05-09 08:40:27 +0000433 (xy.x >= wndPtr->rectWindow.left) &&
434 (xy.x < wndPtr->rectWindow.right) &&
435 (xy.y >= wndPtr->rectWindow.top) &&
436 (xy.y < wndPtr->rectWindow.bottom))
Alexandre Julliard0c126c71996-02-18 18:44:41 +0000437 {
Alexandre Julliard59730ae1996-03-24 16:20:51 +0000438 *ppWnd = wndPtr; /* Got a suitable window */
Alexandre Julliard7e56f681996-01-31 19:02:28 +0000439
Alexandre Julliard0c126c71996-02-18 18:44:41 +0000440 /* If window is minimized or disabled, return at once */
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000441 if (wndPtr->dwStyle & WS_MINIMIZE)
442 {
443 retvalue = HTCAPTION;
444 goto end;
445 }
446 if (wndPtr->dwStyle & WS_DISABLED)
447 {
448 retvalue = HTERROR;
449 goto end;
450 }
Alexandre Julliard7e56f681996-01-31 19:02:28 +0000451
Alexandre Julliard0c126c71996-02-18 18:44:41 +0000452 /* If point is not in client area, ignore the children */
Alexandre Julliard84c70f51997-05-09 08:40:27 +0000453 if ((xy.x < wndPtr->rectClient.left) ||
454 (xy.x >= wndPtr->rectClient.right) ||
455 (xy.y < wndPtr->rectClient.top) ||
456 (xy.y >= wndPtr->rectClient.bottom)) break;
Alexandre Julliard7e56f681996-01-31 19:02:28 +0000457
Alexandre Julliard84c70f51997-05-09 08:40:27 +0000458 xy.x -= wndPtr->rectClient.left;
459 xy.y -= wndPtr->rectClient.top;
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000460 WIN_UpdateWndPtr(&wndPtr,wndPtr->child);
Alexandre Julliard0c126c71996-02-18 18:44:41 +0000461 }
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000462 else
463 {
464 WIN_UpdateWndPtr(&wndPtr,wndPtr->next);
465 }
Alexandre Julliard0c126c71996-02-18 18:44:41 +0000466 }
Alexandre Julliard7e56f681996-01-31 19:02:28 +0000467
Alexandre Julliarda0d77311998-09-13 16:32:00 +0000468hittest:
Alexandre Julliard84c70f51997-05-09 08:40:27 +0000469 /* If nothing found, try the scope window */
470 if (!*ppWnd) *ppWnd = wndScope;
Alexandre Julliard7e56f681996-01-31 19:02:28 +0000471
Alexandre Julliard0c126c71996-02-18 18:44:41 +0000472 /* Send the WM_NCHITTEST message (only if to the same task) */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000473 if ((*ppWnd)->hmemTaskQ == GetFastQueue16())
Alexandre Julliard84c70f51997-05-09 08:40:27 +0000474 {
475 hittest = (INT16)SendMessage16( (*ppWnd)->hwndSelf, WM_NCHITTEST,
476 0, MAKELONG( pt.x, pt.y ) );
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000477 if (hittest != HTTRANSPARENT)
478 {
479 retvalue = hittest; /* Found the window */
480 goto end;
Alexandre Julliard84c70f51997-05-09 08:40:27 +0000481 }
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000482 }
483 else
484 {
485 retvalue = HTCLIENT;
486 goto end;
487 }
Alexandre Julliard7e56f681996-01-31 19:02:28 +0000488
Alexandre Julliard84c70f51997-05-09 08:40:27 +0000489 /* If no children found in last search, make point relative to parent */
Alexandre Julliard59730ae1996-03-24 16:20:51 +0000490 if (!wndPtr)
Alexandre Julliard0c126c71996-02-18 18:44:41 +0000491 {
Alexandre Julliard84c70f51997-05-09 08:40:27 +0000492 xy.x += (*ppWnd)->rectClient.left;
493 xy.y += (*ppWnd)->rectClient.top;
Alexandre Julliard0c126c71996-02-18 18:44:41 +0000494 }
Alexandre Julliard7e56f681996-01-31 19:02:28 +0000495
Alexandre Julliard0c126c71996-02-18 18:44:41 +0000496 /* Restart the search from the next sibling */
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000497 WIN_UpdateWndPtr(&wndPtr,(*ppWnd)->next);
Alexandre Julliardc981d0b1996-03-31 16:40:13 +0000498 *ppWnd = (*ppWnd)->parent;
Alexandre Julliard0c126c71996-02-18 18:44:41 +0000499 }
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000500
501end:
502 WIN_ReleaseWndPtr(wndPtr);
503 return retvalue;
Alexandre Julliard7e56f681996-01-31 19:02:28 +0000504}
505
506
507/*******************************************************************
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000508 * WindowFromPoint16 (USER.30)
Alexandre Julliard86a8d0f1994-01-18 23:04:40 +0000509 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000510HWND16 WINAPI WindowFromPoint16( POINT16 pt )
Alexandre Julliard86a8d0f1994-01-18 23:04:40 +0000511{
Alexandre Julliard59730ae1996-03-24 16:20:51 +0000512 WND *pWnd;
Alexandre Julliard75d86e11996-11-17 18:59:11 +0000513 WINPOS_WindowFromPoint( WIN_GetDesktop(), pt, &pWnd );
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000514 WIN_ReleaseDesktop();
Alexandre Julliard59730ae1996-03-24 16:20:51 +0000515 return pWnd->hwndSelf;
Alexandre Julliard86a8d0f1994-01-18 23:04:40 +0000516}
517
Alexandre Julliard22945d51995-03-02 17:44:29 +0000518
Alexandre Julliard86a8d0f1994-01-18 23:04:40 +0000519/*******************************************************************
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000520 * WindowFromPoint (USER32.582)
Alexandre Julliard86a8d0f1994-01-18 23:04:40 +0000521 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000522HWND WINAPI WindowFromPoint( POINT pt )
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000523{
524 WND *pWnd;
525 POINT16 pt16;
526 CONV_POINT32TO16( &pt, &pt16 );
Alexandre Julliard75d86e11996-11-17 18:59:11 +0000527 WINPOS_WindowFromPoint( WIN_GetDesktop(), pt16, &pWnd );
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000528 WIN_ReleaseDesktop();
Alexandre Julliarda3960291999-02-26 11:11:13 +0000529 return (HWND)pWnd->hwndSelf;
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000530}
531
532
533/*******************************************************************
534 * ChildWindowFromPoint16 (USER.191)
535 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000536HWND16 WINAPI ChildWindowFromPoint16( HWND16 hwndParent, POINT16 pt )
Alexandre Julliard86a8d0f1994-01-18 23:04:40 +0000537{
Alexandre Julliarda3960291999-02-26 11:11:13 +0000538 POINT pt32;
Alexandre Julliardd37eb361997-07-20 16:23:21 +0000539 CONV_POINT16TO32( &pt, &pt32 );
Alexandre Julliarda3960291999-02-26 11:11:13 +0000540 return (HWND16)ChildWindowFromPoint( hwndParent, pt32 );
Alexandre Julliardd37eb361997-07-20 16:23:21 +0000541}
542
543
544/*******************************************************************
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000545 * ChildWindowFromPoint (USER32.49)
Alexandre Julliardd37eb361997-07-20 16:23:21 +0000546 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000547HWND WINAPI ChildWindowFromPoint( HWND hwndParent, POINT pt )
Alexandre Julliardd37eb361997-07-20 16:23:21 +0000548{
Alexandre Julliardc981d0b1996-03-31 16:40:13 +0000549 /* pt is in the client coordinates */
550
551 WND* wnd = WIN_FindWndPtr(hwndParent);
Alexandre Julliarda3960291999-02-26 11:11:13 +0000552 RECT rect;
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000553 HWND retvalue;
Alexandre Julliardc981d0b1996-03-31 16:40:13 +0000554
555 if( !wnd ) return 0;
556
557 /* get client rect fast */
558 rect.top = rect.left = 0;
559 rect.right = wnd->rectClient.right - wnd->rectClient.left;
560 rect.bottom = wnd->rectClient.bottom - wnd->rectClient.top;
561
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000562 if (!PtInRect( &rect, pt ))
563 {
564 retvalue = 0;
565 goto end;
566 }
567 WIN_UpdateWndPtr(&wnd,wnd->child);
Alexandre Julliardc981d0b1996-03-31 16:40:13 +0000568 while ( wnd )
Alexandre Julliard86a8d0f1994-01-18 23:04:40 +0000569 {
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000570 if (PtInRect( &wnd->rectWindow, pt ))
571 {
572 retvalue = wnd->hwndSelf;
573 goto end;
574 }
575 WIN_UpdateWndPtr(&wnd,wnd->next);
Alexandre Julliard86a8d0f1994-01-18 23:04:40 +0000576 }
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000577 retvalue = hwndParent;
578end:
579 WIN_ReleaseWndPtr(wnd);
580 return retvalue;
Alexandre Julliard86a8d0f1994-01-18 23:04:40 +0000581}
582
Paul Quinneede6b01998-11-30 13:15:36 +0000583/*******************************************************************
584 * ChildWindowFromPointEx16 (USER.50)
585 */
586HWND16 WINAPI ChildWindowFromPointEx16( HWND16 hwndParent, POINT16 pt, UINT16 uFlags)
587{
Alexandre Julliarda3960291999-02-26 11:11:13 +0000588 POINT pt32;
Paul Quinneede6b01998-11-30 13:15:36 +0000589 CONV_POINT16TO32( &pt, &pt32 );
Alexandre Julliarda3960291999-02-26 11:11:13 +0000590 return (HWND16)ChildWindowFromPointEx( hwndParent, pt32, uFlags );
Paul Quinneede6b01998-11-30 13:15:36 +0000591}
592
593
594/*******************************************************************
595 * ChildWindowFromPointEx32 (USER32.50)
596 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000597HWND WINAPI ChildWindowFromPointEx( HWND hwndParent, POINT pt,
598 UINT uFlags)
Paul Quinneede6b01998-11-30 13:15:36 +0000599{
600 /* pt is in the client coordinates */
601
602 WND* wnd = WIN_FindWndPtr(hwndParent);
Alexandre Julliarda3960291999-02-26 11:11:13 +0000603 RECT rect;
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000604 HWND retvalue;
Paul Quinneede6b01998-11-30 13:15:36 +0000605
606 if( !wnd ) return 0;
607
608 /* get client rect fast */
609 rect.top = rect.left = 0;
610 rect.right = wnd->rectClient.right - wnd->rectClient.left;
611 rect.bottom = wnd->rectClient.bottom - wnd->rectClient.top;
612
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000613 if (!PtInRect( &rect, pt ))
614 {
615 retvalue = 0;
616 goto end;
617 }
618 WIN_UpdateWndPtr(&wnd,wnd->child);
Paul Quinneede6b01998-11-30 13:15:36 +0000619
Paul Quinneede6b01998-11-30 13:15:36 +0000620 while ( wnd )
621 {
Alexandre Julliarda3960291999-02-26 11:11:13 +0000622 if (PtInRect( &wnd->rectWindow, pt )) {
Paul Quinneede6b01998-11-30 13:15:36 +0000623 if ( (uFlags & CWP_SKIPINVISIBLE) &&
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000624 !(wnd->dwStyle & WS_VISIBLE) );
Paul Quinneede6b01998-11-30 13:15:36 +0000625 else if ( (uFlags & CWP_SKIPDISABLED) &&
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000626 (wnd->dwStyle & WS_DISABLED) );
Paul Quinneede6b01998-11-30 13:15:36 +0000627 else if ( (uFlags & CWP_SKIPTRANSPARENT) &&
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000628 (wnd->dwExStyle & WS_EX_TRANSPARENT) );
Paul Quinneede6b01998-11-30 13:15:36 +0000629 else
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000630 {
631 retvalue = wnd->hwndSelf;
632 goto end;
633 }
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000634
Paul Quinneede6b01998-11-30 13:15:36 +0000635 }
Francis Beaudetd9a3d701999-05-13 18:43:15 +0000636 WIN_UpdateWndPtr(&wnd,wnd->next);
Paul Quinneede6b01998-11-30 13:15:36 +0000637 }
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000638 retvalue = hwndParent;
639end:
640 WIN_ReleaseWndPtr(wnd);
641 return retvalue;
Paul Quinneede6b01998-11-30 13:15:36 +0000642}
643
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000644
Alexandre Julliard86a8d0f1994-01-18 23:04:40 +0000645/*******************************************************************
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000646 * WINPOS_GetWinOffset
647 *
648 * Calculate the offset between the origin of the two windows. Used
649 * to implement MapWindowPoints.
650 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000651static void WINPOS_GetWinOffset( HWND hwndFrom, HWND hwndTo,
652 POINT *offset )
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000653{
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000654 WND * wndPtr = 0;
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000655
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000656 offset->x = offset->y = 0;
657 if (hwndFrom == hwndTo ) return;
Alexandre Julliard7e56f681996-01-31 19:02:28 +0000658
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000659 /* Translate source window origin to screen coords */
Alexandre Julliard59730ae1996-03-24 16:20:51 +0000660 if (hwndFrom)
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000661 {
Alexandre Julliard59730ae1996-03-24 16:20:51 +0000662 if (!(wndPtr = WIN_FindWndPtr( hwndFrom )))
663 {
Alexandre Julliard359f497e1999-07-04 16:02:24 +0000664 ERR("bad hwndFrom = %04x\n",hwndFrom);
Alexandre Julliard59730ae1996-03-24 16:20:51 +0000665 return;
666 }
667 while (wndPtr->parent)
668 {
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000669 offset->x += wndPtr->rectClient.left;
670 offset->y += wndPtr->rectClient.top;
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000671 WIN_UpdateWndPtr(&wndPtr,wndPtr->parent);
Alexandre Julliard59730ae1996-03-24 16:20:51 +0000672 }
Francois Boisvert3a3cd9f1999-03-28 12:42:52 +0000673 WIN_ReleaseWndPtr(wndPtr);
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000674 }
675
676 /* Translate origin to destination window coords */
Alexandre Julliard59730ae1996-03-24 16:20:51 +0000677 if (hwndTo)
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000678 {
Alexandre Julliard59730ae1996-03-24 16:20:51 +0000679 if (!(wndPtr = WIN_FindWndPtr( hwndTo )))
680 {
Alexandre Julliard359f497e1999-07-04 16:02:24 +0000681 ERR("bad hwndTo = %04x\n", hwndTo );
Alexandre Julliard59730ae1996-03-24 16:20:51 +0000682 return;
683 }
684 while (wndPtr->parent)
685 {
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000686 offset->x -= wndPtr->rectClient.left;
687 offset->y -= wndPtr->rectClient.top;
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000688 WIN_UpdateWndPtr(&wndPtr,wndPtr->parent);
Alexandre Julliard59730ae1996-03-24 16:20:51 +0000689 }
Francois Boisvert3a3cd9f1999-03-28 12:42:52 +0000690 WIN_ReleaseWndPtr(wndPtr);
Alexandre Julliard59730ae1996-03-24 16:20:51 +0000691 }
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000692}
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000693
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000694
695/*******************************************************************
696 * MapWindowPoints16 (USER.258)
697 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000698void WINAPI MapWindowPoints16( HWND16 hwndFrom, HWND16 hwndTo,
699 LPPOINT16 lppt, UINT16 count )
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000700{
Alexandre Julliarda3960291999-02-26 11:11:13 +0000701 POINT offset;
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000702
703 WINPOS_GetWinOffset( hwndFrom, hwndTo, &offset );
704 while (count--)
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000705 {
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000706 lppt->x += offset.x;
707 lppt->y += offset.y;
708 lppt++;
709 }
710}
711
712
713/*******************************************************************
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000714 * MapWindowPoints (USER32.386)
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000715 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000716INT WINAPI MapWindowPoints( HWND hwndFrom, HWND hwndTo,
717 LPPOINT lppt, UINT count )
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000718{
Alexandre Julliarda3960291999-02-26 11:11:13 +0000719 POINT offset;
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000720
721 WINPOS_GetWinOffset( hwndFrom, hwndTo, &offset );
722 while (count--)
723 {
724 lppt->x += offset.x;
725 lppt->y += offset.y;
726 lppt++;
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000727 }
Eric Pouechb9544f11999-02-14 14:09:42 +0000728 return MAKELONG( LOWORD(offset.x), LOWORD(offset.y) );
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000729}
730
731
732/***********************************************************************
Alexandre Julliard23946ad1997-06-16 17:43:53 +0000733 * IsIconic16 (USER.31)
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000734 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000735BOOL16 WINAPI IsIconic16(HWND16 hWnd)
Alexandre Julliard01d63461997-01-20 19:43:45 +0000736{
Alexandre Julliarda3960291999-02-26 11:11:13 +0000737 return IsIconic(hWnd);
Alexandre Julliard01d63461997-01-20 19:43:45 +0000738}
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000739
740
Alexandre Julliard01d63461997-01-20 19:43:45 +0000741/***********************************************************************
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000742 * IsIconic (USER32.345)
Alexandre Julliard01d63461997-01-20 19:43:45 +0000743 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000744BOOL WINAPI IsIconic(HWND hWnd)
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000745{
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000746 BOOL retvalue;
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000747 WND * wndPtr = WIN_FindWndPtr(hWnd);
748 if (wndPtr == NULL) return FALSE;
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000749 retvalue = (wndPtr->dwStyle & WS_MINIMIZE) != 0;
750 WIN_ReleaseWndPtr(wndPtr);
751 return retvalue;
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000752}
753
754
755/***********************************************************************
756 * IsZoomed (USER.272)
757 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000758BOOL16 WINAPI IsZoomed16(HWND16 hWnd)
Alexandre Julliard01d63461997-01-20 19:43:45 +0000759{
Alexandre Julliarda3960291999-02-26 11:11:13 +0000760 return IsZoomed(hWnd);
Alexandre Julliard01d63461997-01-20 19:43:45 +0000761}
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000762
763
Alexandre Julliard01d63461997-01-20 19:43:45 +0000764/***********************************************************************
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000765 * IsZoomed (USER.352)
Alexandre Julliard01d63461997-01-20 19:43:45 +0000766 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000767BOOL WINAPI IsZoomed(HWND hWnd)
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000768{
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000769 BOOL retvalue;
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000770 WND * wndPtr = WIN_FindWndPtr(hWnd);
771 if (wndPtr == NULL) return FALSE;
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000772 retvalue = (wndPtr->dwStyle & WS_MAXIMIZE) != 0;
773 WIN_ReleaseWndPtr(wndPtr);
774 return retvalue;
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000775}
776
777
Alexandre Julliarddba420a1994-02-02 06:48:31 +0000778/*******************************************************************
779 * GetActiveWindow (USER.60)
780 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000781HWND16 WINAPI GetActiveWindow16(void)
Alexandre Julliard01d63461997-01-20 19:43:45 +0000782{
Alexandre Julliarda3960291999-02-26 11:11:13 +0000783 return (HWND16)GetActiveWindow();
Alexandre Julliard01d63461997-01-20 19:43:45 +0000784}
Alexandre Julliard23946ad1997-06-16 17:43:53 +0000785
Alexandre Julliard01d63461997-01-20 19:43:45 +0000786/*******************************************************************
Alexandre Julliardc7c217b1998-04-13 12:21:30 +0000787 * GetActiveWindow (USER32.205)
Alexandre Julliard01d63461997-01-20 19:43:45 +0000788 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000789HWND WINAPI GetActiveWindow(void)
Alexandre Julliarddba420a1994-02-02 06:48:31 +0000790{
Noel Borthwickb4278561999-02-05 10:37:53 +0000791 MESSAGEQUEUE *pCurMsgQ = 0;
Alexandre Julliarda3960291999-02-26 11:11:13 +0000792 HWND hwndActive = 0;
Noel Borthwickb4278561999-02-05 10:37:53 +0000793
794 /* Get the messageQ for the current thread */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000795 if (!(pCurMsgQ = (MESSAGEQUEUE *)QUEUE_Lock( GetFastQueue16() )))
Noel Borthwickb4278561999-02-05 10:37:53 +0000796{
Alexandre Julliard359f497e1999-07-04 16:02:24 +0000797 WARN("\tCurrent message queue not found. Exiting!\n" );
Noel Borthwickb4278561999-02-05 10:37:53 +0000798 return 0;
799 }
800
801 /* Return the current active window from the perQ data of the current message Q */
802 hwndActive = PERQDATA_GetActiveWnd( pCurMsgQ->pQData );
803
804 QUEUE_Unlock( pCurMsgQ );
805 return hwndActive;
Alexandre Julliarddba420a1994-02-02 06:48:31 +0000806}
807
Alexandre Julliard22945d51995-03-02 17:44:29 +0000808
Alexandre Julliarddba420a1994-02-02 06:48:31 +0000809/*******************************************************************
Alexandre Julliard23946ad1997-06-16 17:43:53 +0000810 * WINPOS_CanActivate
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +0000811 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000812static BOOL WINPOS_CanActivate(WND* pWnd)
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +0000813{
Abey George983f90a1999-10-13 15:43:45 +0000814 if( pWnd && !(pWnd->dwStyle & (WS_DISABLED | WS_CHILD)) ) return TRUE;
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000815 return FALSE;
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +0000816}
817
818
819/*******************************************************************
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000820 * SetActiveWindow16 (USER.59)
Alexandre Julliarddba420a1994-02-02 06:48:31 +0000821 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000822HWND16 WINAPI SetActiveWindow16( HWND16 hwnd )
Alexandre Julliarddba420a1994-02-02 06:48:31 +0000823{
Alexandre Julliarda3960291999-02-26 11:11:13 +0000824 return SetActiveWindow(hwnd);
Alexandre Julliard01d63461997-01-20 19:43:45 +0000825}
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000826
827
Alexandre Julliard01d63461997-01-20 19:43:45 +0000828/*******************************************************************
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000829 * SetActiveWindow (USER32.463)
Alexandre Julliard01d63461997-01-20 19:43:45 +0000830 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000831HWND WINAPI SetActiveWindow( HWND hwnd )
Alexandre Julliard01d63461997-01-20 19:43:45 +0000832{
Alexandre Julliarda3960291999-02-26 11:11:13 +0000833 HWND prev = 0;
Alexandre Julliarddba420a1994-02-02 06:48:31 +0000834 WND *wndPtr = WIN_FindWndPtr( hwnd );
Noel Borthwickb4278561999-02-05 10:37:53 +0000835 MESSAGEQUEUE *pMsgQ = 0, *pCurMsgQ = 0;
Alexandre Julliardd4719651995-12-12 18:49:11 +0000836
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000837 if ( !WINPOS_CanActivate(wndPtr) )
838 {
839 prev = 0;
840 goto end;
841 }
Alexandre Julliardd4719651995-12-12 18:49:11 +0000842
Noel Borthwickb4278561999-02-05 10:37:53 +0000843 /* Get the messageQ for the current thread */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000844 if (!(pCurMsgQ = (MESSAGEQUEUE *)QUEUE_Lock( GetFastQueue16() )))
Noel Borthwickb4278561999-02-05 10:37:53 +0000845 {
Alexandre Julliard359f497e1999-07-04 16:02:24 +0000846 WARN("\tCurrent message queue not found. Exiting!\n" );
Noel Borthwickb4278561999-02-05 10:37:53 +0000847 goto CLEANUP;
848 }
849
850 /* Retrieve the message queue associated with this window */
851 pMsgQ = (MESSAGEQUEUE *)QUEUE_Lock( wndPtr->hmemTaskQ );
852 if ( !pMsgQ )
853 {
Alexandre Julliard359f497e1999-07-04 16:02:24 +0000854 WARN("\tWindow message queue not found. Exiting!\n" );
Noel Borthwickb4278561999-02-05 10:37:53 +0000855 goto CLEANUP;
856 }
857
858 /* Make sure that the window is associated with the calling threads
859 * message queue. It must share the same perQ data.
860 */
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000861
Noel Borthwickb4278561999-02-05 10:37:53 +0000862 if ( pCurMsgQ->pQData != pMsgQ->pQData )
863 goto CLEANUP;
864
865 /* Save current active window */
866 prev = PERQDATA_GetActiveWnd( pMsgQ->pQData );
867
Alexandre Julliardd4719651995-12-12 18:49:11 +0000868 WINPOS_SetActiveWindow( hwnd, 0, 0 );
Noel Borthwickb4278561999-02-05 10:37:53 +0000869
870CLEANUP:
871 /* Unlock the queues before returning */
872 if ( pMsgQ )
873 QUEUE_Unlock( pMsgQ );
874 if ( pCurMsgQ )
875 QUEUE_Unlock( pCurMsgQ );
876
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000877end:
878 WIN_ReleaseWndPtr(wndPtr);
Alexandre Julliarddba420a1994-02-02 06:48:31 +0000879 return prev;
880}
881
882
Alexandre Julliard17216f51997-10-12 16:30:17 +0000883/*******************************************************************
884 * GetForegroundWindow16 (USER.608)
885 */
886HWND16 WINAPI GetForegroundWindow16(void)
887{
Alexandre Julliarda3960291999-02-26 11:11:13 +0000888 return (HWND16)GetForegroundWindow();
Alexandre Julliard17216f51997-10-12 16:30:17 +0000889}
890
891
892/*******************************************************************
893 * SetForegroundWindow16 (USER.609)
894 */
895BOOL16 WINAPI SetForegroundWindow16( HWND16 hwnd )
896{
Alexandre Julliarda3960291999-02-26 11:11:13 +0000897 return SetForegroundWindow( hwnd );
Alexandre Julliard17216f51997-10-12 16:30:17 +0000898}
899
900
901/*******************************************************************
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000902 * GetForegroundWindow (USER32.241)
Alexandre Julliard17216f51997-10-12 16:30:17 +0000903 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000904HWND WINAPI GetForegroundWindow(void)
Alexandre Julliard17216f51997-10-12 16:30:17 +0000905{
Ulrich Weigandb38e1de1999-06-12 06:42:20 +0000906 HWND hwndActive = 0;
Alexandre Julliard17216f51997-10-12 16:30:17 +0000907
Ulrich Weigandb38e1de1999-06-12 06:42:20 +0000908 /* Get the foreground window (active window of hActiveQueue) */
909 if ( hActiveQueue )
910 {
911 MESSAGEQUEUE *pActiveQueue = QUEUE_Lock( hActiveQueue );
912 if ( pActiveQueue )
913 hwndActive = PERQDATA_GetActiveWnd( pActiveQueue->pQData );
914
915 QUEUE_Unlock( pActiveQueue );
916 }
917
918 return hwndActive;
919}
Alexandre Julliard17216f51997-10-12 16:30:17 +0000920
921/*******************************************************************
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000922 * SetForegroundWindow (USER32.482)
Alexandre Julliard17216f51997-10-12 16:30:17 +0000923 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000924BOOL WINAPI SetForegroundWindow( HWND hwnd )
Alexandre Julliard17216f51997-10-12 16:30:17 +0000925{
Ulrich Weigandb38e1de1999-06-12 06:42:20 +0000926 return WINPOS_ChangeActiveWindow( hwnd, FALSE );
Alexandre Julliard17216f51997-10-12 16:30:17 +0000927}
928
929
930/*******************************************************************
931 * GetShellWindow16 (USER.600)
932 */
933HWND16 WINAPI GetShellWindow16(void)
934{
Alexandre Julliarda3960291999-02-26 11:11:13 +0000935 return GetShellWindow();
Alexandre Julliard17216f51997-10-12 16:30:17 +0000936}
937
Alexandre Julliarde658d821997-11-30 17:45:40 +0000938/*******************************************************************
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000939 * SetShellWindow (USER32.504)
Alexandre Julliarde658d821997-11-30 17:45:40 +0000940 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000941HWND WINAPI SetShellWindow(HWND hwndshell)
Alexandre Julliard359f497e1999-07-04 16:02:24 +0000942{ WARN("(hWnd=%08x) semi stub\n",hwndshell );
Alexandre Julliard85ed45e1998-08-22 19:03:56 +0000943
944 hGlobalShellWindow = hwndshell;
945 return hGlobalShellWindow;
Alexandre Julliarde658d821997-11-30 17:45:40 +0000946}
947
Alexandre Julliard17216f51997-10-12 16:30:17 +0000948
949/*******************************************************************
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000950 * GetShellWindow (USER32.287)
Alexandre Julliard17216f51997-10-12 16:30:17 +0000951 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000952HWND WINAPI GetShellWindow(void)
Alexandre Julliard359f497e1999-07-04 16:02:24 +0000953{ WARN("(hWnd=%x) semi stub\n",hGlobalShellWindow );
Alexandre Julliard85ed45e1998-08-22 19:03:56 +0000954
955 return hGlobalShellWindow;
Alexandre Julliard17216f51997-10-12 16:30:17 +0000956}
957
958
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000959/***********************************************************************
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000960 * BringWindowToTop16 (USER.45)
Alexandre Julliard86a8d0f1994-01-18 23:04:40 +0000961 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000962BOOL16 WINAPI BringWindowToTop16( HWND16 hwnd )
Alexandre Julliard86a8d0f1994-01-18 23:04:40 +0000963{
Alexandre Julliarda3960291999-02-26 11:11:13 +0000964 return BringWindowToTop(hwnd);
Alexandre Julliard01d63461997-01-20 19:43:45 +0000965}
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000966
967
Alexandre Julliard01d63461997-01-20 19:43:45 +0000968/***********************************************************************
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000969 * BringWindowToTop (USER32.11)
Alexandre Julliard01d63461997-01-20 19:43:45 +0000970 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000971BOOL WINAPI BringWindowToTop( HWND hwnd )
Alexandre Julliard01d63461997-01-20 19:43:45 +0000972{
Alexandre Julliarda3960291999-02-26 11:11:13 +0000973 return SetWindowPos( hwnd, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE );
Alexandre Julliard86a8d0f1994-01-18 23:04:40 +0000974}
975
976
977/***********************************************************************
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000978 * MoveWindow16 (USER.56)
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000979 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000980BOOL16 WINAPI MoveWindow16( HWND16 hwnd, INT16 x, INT16 y, INT16 cx, INT16 cy,
981 BOOL16 repaint )
982{
Alexandre Julliarda3960291999-02-26 11:11:13 +0000983 return MoveWindow(hwnd,x,y,cx,cy,repaint);
Alexandre Julliard01d63461997-01-20 19:43:45 +0000984}
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000985
986
Alexandre Julliard01d63461997-01-20 19:43:45 +0000987/***********************************************************************
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000988 * MoveWindow (USER32.399)
Alexandre Julliard01d63461997-01-20 19:43:45 +0000989 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000990BOOL WINAPI MoveWindow( HWND hwnd, INT x, INT y, INT cx, INT cy,
991 BOOL repaint )
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000992{
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000993 int flags = SWP_NOZORDER | SWP_NOACTIVATE;
994 if (!repaint) flags |= SWP_NOREDRAW;
Alexandre Julliard359f497e1999-07-04 16:02:24 +0000995 TRACE("%04x %d,%d %dx%d %d\n",
Alexandre Julliardaca05781994-10-17 18:12:41 +0000996 hwnd, x, y, cx, cy, repaint );
Alexandre Julliarda3960291999-02-26 11:11:13 +0000997 return SetWindowPos( hwnd, 0, x, y, cx, cy, flags );
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000998}
999
Alexandre Julliard5f721f81994-01-04 20:14:34 +00001000/***********************************************************************
Alexandre Julliard23946ad1997-06-16 17:43:53 +00001001 * WINPOS_InitInternalPos
1002 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001003static LPINTERNALPOS WINPOS_InitInternalPos( WND* wnd, POINT pt,
1004 LPRECT restoreRect )
Alexandre Julliard23946ad1997-06-16 17:43:53 +00001005{
Alexandre Julliarda3960291999-02-26 11:11:13 +00001006 LPINTERNALPOS lpPos = (LPINTERNALPOS) GetPropA( wnd->hwndSelf,
Alexandre Julliardd37eb361997-07-20 16:23:21 +00001007 atomInternalPos );
Alexandre Julliard23946ad1997-06-16 17:43:53 +00001008 if( !lpPos )
1009 {
1010 /* this happens when the window is minimized/maximized
1011 * for the first time (rectWindow is not adjusted yet) */
1012
1013 lpPos = HeapAlloc( SystemHeap, 0, sizeof(INTERNALPOS) );
1014 if( !lpPos ) return NULL;
1015
Alexandre Julliarda3960291999-02-26 11:11:13 +00001016 SetPropA( wnd->hwndSelf, atomInternalPos, (HANDLE)lpPos );
Alexandre Julliard23946ad1997-06-16 17:43:53 +00001017 lpPos->hwndIconTitle = 0; /* defer until needs to be shown */
Alexandre Julliardd37eb361997-07-20 16:23:21 +00001018 CONV_RECT32TO16( &wnd->rectWindow, &lpPos->rectNormal );
Alexandre Julliarda3960291999-02-26 11:11:13 +00001019 *(UINT*)&lpPos->ptIconPos = *(UINT*)&lpPos->ptMaxPos = 0xFFFFFFFF;
Alexandre Julliard23946ad1997-06-16 17:43:53 +00001020 }
1021
1022 if( wnd->dwStyle & WS_MINIMIZE )
Alexandre Julliardd37eb361997-07-20 16:23:21 +00001023 CONV_POINT32TO16( &pt, &lpPos->ptIconPos );
Alexandre Julliard23946ad1997-06-16 17:43:53 +00001024 else if( wnd->dwStyle & WS_MAXIMIZE )
Alexandre Julliardd37eb361997-07-20 16:23:21 +00001025 CONV_POINT32TO16( &pt, &lpPos->ptMaxPos );
Alexandre Julliard23946ad1997-06-16 17:43:53 +00001026 else if( restoreRect )
Alexandre Julliardd37eb361997-07-20 16:23:21 +00001027 CONV_RECT32TO16( restoreRect, &lpPos->rectNormal );
Alexandre Julliard23946ad1997-06-16 17:43:53 +00001028
1029 return lpPos;
1030}
1031
1032/***********************************************************************
1033 * WINPOS_RedrawIconTitle
1034 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001035BOOL WINPOS_RedrawIconTitle( HWND hWnd )
Alexandre Julliard23946ad1997-06-16 17:43:53 +00001036{
Alexandre Julliarda3960291999-02-26 11:11:13 +00001037 LPINTERNALPOS lpPos = (LPINTERNALPOS)GetPropA( hWnd, atomInternalPos );
Alexandre Julliard23946ad1997-06-16 17:43:53 +00001038 if( lpPos )
1039 {
1040 if( lpPos->hwndIconTitle )
1041 {
Alexandre Julliarda3960291999-02-26 11:11:13 +00001042 SendMessageA( lpPos->hwndIconTitle, WM_SHOWWINDOW, TRUE, 0);
1043 InvalidateRect( lpPos->hwndIconTitle, NULL, TRUE );
Alexandre Julliard23946ad1997-06-16 17:43:53 +00001044 return TRUE;
1045 }
1046 }
1047 return FALSE;
1048}
1049
1050/***********************************************************************
1051 * WINPOS_ShowIconTitle
1052 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001053BOOL WINPOS_ShowIconTitle( WND* pWnd, BOOL bShow )
Alexandre Julliard23946ad1997-06-16 17:43:53 +00001054{
Alexandre Julliarda3960291999-02-26 11:11:13 +00001055 LPINTERNALPOS lpPos = (LPINTERNALPOS)GetPropA( pWnd->hwndSelf, atomInternalPos );
Alexandre Julliard23946ad1997-06-16 17:43:53 +00001056
1057 if( lpPos && !(pWnd->flags & WIN_MANAGED))
1058 {
1059 HWND16 hWnd = lpPos->hwndIconTitle;
1060
Alexandre Julliard359f497e1999-07-04 16:02:24 +00001061 TRACE("0x%04x %i\n", pWnd->hwndSelf, (bShow != 0) );
Alexandre Julliard23946ad1997-06-16 17:43:53 +00001062
1063 if( !hWnd )
1064 lpPos->hwndIconTitle = hWnd = ICONTITLE_Create( pWnd );
1065 if( bShow )
1066 {
Eric Pouech6cf348d1999-05-22 19:20:02 +00001067 if( ( pWnd = WIN_FindWndPtr(hWnd) ) != NULL)
Alexandre Julliard23946ad1997-06-16 17:43:53 +00001068 {
Eric Pouech6cf348d1999-05-22 19:20:02 +00001069 if( !(pWnd->dwStyle & WS_VISIBLE) )
1070 {
1071 SendMessageA( hWnd, WM_SHOWWINDOW, TRUE, 0 );
1072 SetWindowPos( hWnd, 0, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE |
1073 SWP_NOACTIVATE | SWP_NOZORDER | SWP_SHOWWINDOW );
1074 }
1075 WIN_ReleaseWndPtr(pWnd);
Alexandre Julliard23946ad1997-06-16 17:43:53 +00001076 }
1077 }
Alexandre Julliarda3960291999-02-26 11:11:13 +00001078 else ShowWindow( hWnd, SW_HIDE );
Alexandre Julliard23946ad1997-06-16 17:43:53 +00001079 }
1080 return FALSE;
1081}
1082
1083/*******************************************************************
1084 * WINPOS_GetMinMaxInfo
1085 *
1086 * Get the minimized and maximized information for a window.
1087 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001088void WINPOS_GetMinMaxInfo( WND *wndPtr, POINT *maxSize, POINT *maxPos,
1089 POINT *minTrack, POINT *maxTrack )
Alexandre Julliard23946ad1997-06-16 17:43:53 +00001090{
1091 LPINTERNALPOS lpPos;
Alexandre Julliarda3960291999-02-26 11:11:13 +00001092 MINMAXINFO MinMax;
1093 INT xinc, yinc;
Alexandre Julliard23946ad1997-06-16 17:43:53 +00001094
Alexandre Julliardd37eb361997-07-20 16:23:21 +00001095 /* Compute default values */
Alexandre Julliard23946ad1997-06-16 17:43:53 +00001096
Marcus Meissnerddca3151999-05-22 11:33:23 +00001097 MinMax.ptMaxSize.x = GetSystemMetrics(SM_CXSCREEN);
1098 MinMax.ptMaxSize.y = GetSystemMetrics(SM_CYSCREEN);
1099 MinMax.ptMinTrackSize.x = GetSystemMetrics(SM_CXMINTRACK);
1100 MinMax.ptMinTrackSize.y = GetSystemMetrics(SM_CYMINTRACK);
1101 MinMax.ptMaxTrackSize.x = GetSystemMetrics(SM_CXSCREEN);
1102 MinMax.ptMaxTrackSize.y = GetSystemMetrics(SM_CYSCREEN);
Alexandre Julliard23946ad1997-06-16 17:43:53 +00001103
1104 if (wndPtr->flags & WIN_MANAGED) xinc = yinc = 0;
1105 else if (HAS_DLGFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
1106 {
Marcus Meissnerddca3151999-05-22 11:33:23 +00001107 xinc = GetSystemMetrics(SM_CXDLGFRAME);
1108 yinc = GetSystemMetrics(SM_CYDLGFRAME);
Alexandre Julliard23946ad1997-06-16 17:43:53 +00001109 }
1110 else
1111 {
1112 xinc = yinc = 0;
1113 if (HAS_THICKFRAME(wndPtr->dwStyle))
1114 {
Marcus Meissnerddca3151999-05-22 11:33:23 +00001115 xinc += GetSystemMetrics(SM_CXFRAME);
1116 yinc += GetSystemMetrics(SM_CYFRAME);
Alexandre Julliard23946ad1997-06-16 17:43:53 +00001117 }
1118 if (wndPtr->dwStyle & WS_BORDER)
1119 {
Marcus Meissnerddca3151999-05-22 11:33:23 +00001120 xinc += GetSystemMetrics(SM_CXBORDER);
1121 yinc += GetSystemMetrics(SM_CYBORDER);
Alexandre Julliard23946ad1997-06-16 17:43:53 +00001122 }
1123 }
Alexandre Julliardd37eb361997-07-20 16:23:21 +00001124 MinMax.ptMaxSize.x += 2 * xinc;
1125 MinMax.ptMaxSize.y += 2 * yinc;
Alexandre Julliard23946ad1997-06-16 17:43:53 +00001126
Alexandre Julliarda3960291999-02-26 11:11:13 +00001127 lpPos = (LPINTERNALPOS)GetPropA( wndPtr->hwndSelf, atomInternalPos );
Alexandre Julliard23946ad1997-06-16 17:43:53 +00001128 if( lpPos && !EMPTYPOINT(lpPos->ptMaxPos) )
Alexandre Julliardd37eb361997-07-20 16:23:21 +00001129 CONV_POINT16TO32( &lpPos->ptMaxPos, &MinMax.ptMaxPosition );
Alexandre Julliard23946ad1997-06-16 17:43:53 +00001130 else
1131 {
Alexandre Julliardd37eb361997-07-20 16:23:21 +00001132 MinMax.ptMaxPosition.x = -xinc;
1133 MinMax.ptMaxPosition.y = -yinc;
Alexandre Julliard23946ad1997-06-16 17:43:53 +00001134 }
1135
Alexandre Julliarda3960291999-02-26 11:11:13 +00001136 SendMessageA( wndPtr->hwndSelf, WM_GETMINMAXINFO, 0, (LPARAM)&MinMax );
Alexandre Julliard23946ad1997-06-16 17:43:53 +00001137
1138 /* Some sanity checks */
1139
Alexandre Julliard359f497e1999-07-04 16:02:24 +00001140 TRACE("%ld %ld / %ld %ld / %ld %ld / %ld %ld\n",
Alexandre Julliardd37eb361997-07-20 16:23:21 +00001141 MinMax.ptMaxSize.x, MinMax.ptMaxSize.y,
1142 MinMax.ptMaxPosition.x, MinMax.ptMaxPosition.y,
1143 MinMax.ptMaxTrackSize.x, MinMax.ptMaxTrackSize.y,
1144 MinMax.ptMinTrackSize.x, MinMax.ptMinTrackSize.y);
1145 MinMax.ptMaxTrackSize.x = MAX( MinMax.ptMaxTrackSize.x,
1146 MinMax.ptMinTrackSize.x );
1147 MinMax.ptMaxTrackSize.y = MAX( MinMax.ptMaxTrackSize.y,
1148 MinMax.ptMinTrackSize.y );
Alexandre Julliard23946ad1997-06-16 17:43:53 +00001149
Alexandre Julliardd37eb361997-07-20 16:23:21 +00001150 if (maxSize) *maxSize = MinMax.ptMaxSize;
1151 if (maxPos) *maxPos = MinMax.ptMaxPosition;
1152 if (minTrack) *minTrack = MinMax.ptMinTrackSize;
1153 if (maxTrack) *maxTrack = MinMax.ptMaxTrackSize;
Alexandre Julliard23946ad1997-06-16 17:43:53 +00001154}
1155
1156/***********************************************************************
1157 * WINPOS_MinMaximize
1158 *
1159 * Fill in lpRect and return additional flags to be used with SetWindowPos().
1160 * This function assumes that 'cmd' is different from the current window
1161 * state.
1162 */
Alex Korobka44a1b591999-04-01 12:03:52 +00001163UINT WINPOS_MinMaximize( WND* wndPtr, UINT16 cmd, LPRECT16 lpRect )
Alexandre Julliard23946ad1997-06-16 17:43:53 +00001164{
Alex Korobka44a1b591999-04-01 12:03:52 +00001165 UINT swpFlags = 0;
Alex Korobka98447491999-05-08 17:57:09 +00001166 POINT pt, size;
Patrik Stridvalla9a671d1999-04-25 19:01:52 +00001167 LPINTERNALPOS lpPos;
Alexandre Julliard23946ad1997-06-16 17:43:53 +00001168
Alexandre Julliard359f497e1999-07-04 16:02:24 +00001169 TRACE("0x%04x %u\n", wndPtr->hwndSelf, cmd );
Alexandre Julliard23946ad1997-06-16 17:43:53 +00001170
Alex Korobka98447491999-05-08 17:57:09 +00001171 size.x = wndPtr->rectWindow.left; size.y = wndPtr->rectWindow.top;
Patrik Stridvalla9a671d1999-04-25 19:01:52 +00001172 lpPos = WINPOS_InitInternalPos( wndPtr, size, &wndPtr->rectWindow );
1173
Alexandre Julliardd37eb361997-07-20 16:23:21 +00001174 if (lpPos && !HOOK_CallHooks16(WH_CBT, HCBT_MINMAX, wndPtr->hwndSelf, cmd))
Alexandre Julliard23946ad1997-06-16 17:43:53 +00001175 {
1176 if( wndPtr->dwStyle & WS_MINIMIZE )
1177 {
Alexandre Julliarda3960291999-02-26 11:11:13 +00001178 if( !SendMessageA( wndPtr->hwndSelf, WM_QUERYOPEN, 0, 0L ) )
Alexandre Julliard23946ad1997-06-16 17:43:53 +00001179 return (SWP_NOSIZE | SWP_NOMOVE);
1180 swpFlags |= SWP_NOCOPYBITS;
1181 }
1182 switch( cmd )
1183 {
1184 case SW_MINIMIZE:
1185 if( wndPtr->dwStyle & WS_MAXIMIZE)
1186 {
1187 wndPtr->flags |= WIN_RESTORE_MAX;
1188 wndPtr->dwStyle &= ~WS_MAXIMIZE;
1189 }
1190 else
1191 wndPtr->flags &= ~WIN_RESTORE_MAX;
1192 wndPtr->dwStyle |= WS_MINIMIZE;
1193
Alex Korobka44a1b591999-04-01 12:03:52 +00001194 if( wndPtr->flags & WIN_NATIVE )
1195 if( wndPtr->pDriver->pSetHostAttr( wndPtr, HAK_ICONICSTATE, TRUE ) )
1196 swpFlags |= MINMAX_NOSWP;
1197
Alexandre Julliard23946ad1997-06-16 17:43:53 +00001198 lpPos->ptIconPos = WINPOS_FindIconPos( wndPtr, lpPos->ptIconPos );
1199
1200 SetRect16( lpRect, lpPos->ptIconPos.x, lpPos->ptIconPos.y,
Marcus Meissnerddca3151999-05-22 11:33:23 +00001201 GetSystemMetrics(SM_CXICON), GetSystemMetrics(SM_CYICON) );
Alexandre Julliard23946ad1997-06-16 17:43:53 +00001202 swpFlags |= SWP_NOCOPYBITS;
1203 break;
1204
1205 case SW_MAXIMIZE:
Alexandre Julliardd37eb361997-07-20 16:23:21 +00001206 CONV_POINT16TO32( &lpPos->ptMaxPos, &pt );
1207 WINPOS_GetMinMaxInfo( wndPtr, &size, &pt, NULL, NULL );
1208 CONV_POINT32TO16( &pt, &lpPos->ptMaxPos );
Alexandre Julliard23946ad1997-06-16 17:43:53 +00001209
1210 if( wndPtr->dwStyle & WS_MINIMIZE )
1211 {
Alex Korobka44a1b591999-04-01 12:03:52 +00001212 if( wndPtr->flags & WIN_NATIVE )
1213 if( wndPtr->pDriver->pSetHostAttr( wndPtr, HAK_ICONICSTATE, FALSE ) )
1214 swpFlags |= MINMAX_NOSWP;
1215
Alexandre Julliard23946ad1997-06-16 17:43:53 +00001216 WINPOS_ShowIconTitle( wndPtr, FALSE );
1217 wndPtr->dwStyle &= ~WS_MINIMIZE;
1218 }
1219 wndPtr->dwStyle |= WS_MAXIMIZE;
1220
1221 SetRect16( lpRect, lpPos->ptMaxPos.x, lpPos->ptMaxPos.y,
1222 size.x, size.y );
1223 break;
1224
1225 case SW_RESTORE:
1226 if( wndPtr->dwStyle & WS_MINIMIZE )
1227 {
Alex Korobka44a1b591999-04-01 12:03:52 +00001228 if( wndPtr->flags & WIN_NATIVE )
1229 if( wndPtr->pDriver->pSetHostAttr( wndPtr, HAK_ICONICSTATE, FALSE ) )
1230 swpFlags |= MINMAX_NOSWP;
1231
Alexandre Julliard23946ad1997-06-16 17:43:53 +00001232 wndPtr->dwStyle &= ~WS_MINIMIZE;
1233 WINPOS_ShowIconTitle( wndPtr, FALSE );
Alex Korobka44a1b591999-04-01 12:03:52 +00001234
Alexandre Julliard23946ad1997-06-16 17:43:53 +00001235 if( wndPtr->flags & WIN_RESTORE_MAX)
1236 {
1237 /* Restore to maximized position */
Alexandre Julliardd37eb361997-07-20 16:23:21 +00001238 CONV_POINT16TO32( &lpPos->ptMaxPos, &pt );
1239 WINPOS_GetMinMaxInfo( wndPtr, &size, &pt, NULL, NULL);
1240 CONV_POINT32TO16( &pt, &lpPos->ptMaxPos );
Alexandre Julliard23946ad1997-06-16 17:43:53 +00001241 wndPtr->dwStyle |= WS_MAXIMIZE;
Alexandre Julliard60ce85c1998-02-01 18:33:27 +00001242 SetRect16( lpRect, lpPos->ptMaxPos.x, lpPos->ptMaxPos.y, size.x, size.y );
1243 break;
Alexandre Julliard23946ad1997-06-16 17:43:53 +00001244 }
1245 }
1246 else
1247 if( !(wndPtr->dwStyle & WS_MAXIMIZE) ) return (UINT16)(-1);
1248 else wndPtr->dwStyle &= ~WS_MAXIMIZE;
1249
1250 /* Restore to normal position */
1251
1252 *lpRect = lpPos->rectNormal;
1253 lpRect->right -= lpRect->left;
1254 lpRect->bottom -= lpRect->top;
1255
1256 break;
1257 }
1258 } else swpFlags |= SWP_NOSIZE | SWP_NOMOVE;
1259 return swpFlags;
1260}
1261
1262/***********************************************************************
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001263 * ShowWindowAsync (USER32.535)
Alexandre Julliarddadf78f1998-05-17 17:13:43 +00001264 *
1265 * doesn't wait; returns immediately.
1266 * used by threads to toggle windows in other (possibly hanging) threads
1267 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001268BOOL WINAPI ShowWindowAsync( HWND hwnd, INT cmd )
Alexandre Julliarddadf78f1998-05-17 17:13:43 +00001269{
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001270 /* FIXME: does ShowWindow() return immediately ? */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001271 return ShowWindow(hwnd, cmd);
Alexandre Julliarddadf78f1998-05-17 17:13:43 +00001272}
1273
1274
1275/***********************************************************************
Alexandre Julliard670cdc41997-08-24 16:00:30 +00001276 * ShowWindow16 (USER.42)
Alexandre Julliard5f721f81994-01-04 20:14:34 +00001277 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00001278BOOL16 WINAPI ShowWindow16( HWND16 hwnd, INT16 cmd )
Alexandre Julliard01d63461997-01-20 19:43:45 +00001279{
Alexandre Julliarda3960291999-02-26 11:11:13 +00001280 return ShowWindow(hwnd,cmd);
Alexandre Julliard01d63461997-01-20 19:43:45 +00001281}
Alexandre Julliard670cdc41997-08-24 16:00:30 +00001282
1283
Alexandre Julliard01d63461997-01-20 19:43:45 +00001284/***********************************************************************
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001285 * ShowWindow (USER32.534)
Alexandre Julliard01d63461997-01-20 19:43:45 +00001286 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001287BOOL WINAPI ShowWindow( HWND hwnd, INT cmd )
Alexandre Julliard5f721f81994-01-04 20:14:34 +00001288{
Alexandre Julliard23946ad1997-06-16 17:43:53 +00001289 WND* wndPtr = WIN_FindWndPtr( hwnd );
Alexandre Julliarda3960291999-02-26 11:11:13 +00001290 BOOL wasVisible, showFlag;
Alexandre Julliard23946ad1997-06-16 17:43:53 +00001291 RECT16 newPos = {0, 0, 0, 0};
Alex Korobka44a1b591999-04-01 12:03:52 +00001292 UINT swp = 0;
Alexandre Julliard5f721f81994-01-04 20:14:34 +00001293
Alexandre Julliard940d58c1994-09-16 09:24:37 +00001294 if (!wndPtr) return FALSE;
1295
Alexandre Julliard359f497e1999-07-04 16:02:24 +00001296 TRACE("hwnd=%04x, cmd=%d\n", hwnd, cmd);
Alexandre Julliard940d58c1994-09-16 09:24:37 +00001297
Alexandre Julliard5f721f81994-01-04 20:14:34 +00001298 wasVisible = (wndPtr->dwStyle & WS_VISIBLE) != 0;
Alexandre Julliard940d58c1994-09-16 09:24:37 +00001299
Alexandre Julliard5f721f81994-01-04 20:14:34 +00001300 switch(cmd)
1301 {
1302 case SW_HIDE:
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001303 if (!wasVisible) goto END;;
Alexandre Julliard23946ad1997-06-16 17:43:53 +00001304 swp |= SWP_HIDEWINDOW | SWP_NOSIZE | SWP_NOMOVE |
Alexandre Julliard5f721f81994-01-04 20:14:34 +00001305 SWP_NOACTIVATE | SWP_NOZORDER;
1306 break;
1307
1308 case SW_SHOWMINNOACTIVE:
Alexandre Julliard23946ad1997-06-16 17:43:53 +00001309 swp |= SWP_NOACTIVATE | SWP_NOZORDER;
Alexandre Julliard22945d51995-03-02 17:44:29 +00001310 /* fall through */
Alexandre Julliard5f721f81994-01-04 20:14:34 +00001311 case SW_SHOWMINIMIZED:
Alexandre Julliard23946ad1997-06-16 17:43:53 +00001312 swp |= SWP_SHOWWINDOW;
Alexandre Julliard22945d51995-03-02 17:44:29 +00001313 /* fall through */
1314 case SW_MINIMIZE:
Alexandre Julliard23946ad1997-06-16 17:43:53 +00001315 swp |= SWP_FRAMECHANGED;
1316 if( !(wndPtr->dwStyle & WS_MINIMIZE) )
1317 swp |= WINPOS_MinMaximize( wndPtr, SW_MINIMIZE, &newPos );
1318 else swp |= SWP_NOSIZE | SWP_NOMOVE;
Alexandre Julliard5f721f81994-01-04 20:14:34 +00001319 break;
1320
Alexandre Julliard23946ad1997-06-16 17:43:53 +00001321 case SW_SHOWMAXIMIZED: /* same as SW_MAXIMIZE */
1322 swp |= SWP_SHOWWINDOW | SWP_FRAMECHANGED;
1323 if( !(wndPtr->dwStyle & WS_MAXIMIZE) )
1324 swp |= WINPOS_MinMaximize( wndPtr, SW_MAXIMIZE, &newPos );
1325 else swp |= SWP_NOSIZE | SWP_NOMOVE;
Alexandre Julliard22945d51995-03-02 17:44:29 +00001326 break;
1327
1328 case SW_SHOWNA:
Alexandre Julliard23946ad1997-06-16 17:43:53 +00001329 swp |= SWP_NOACTIVATE | SWP_NOZORDER;
Alexandre Julliard22945d51995-03-02 17:44:29 +00001330 /* fall through */
Alexandre Julliard5f721f81994-01-04 20:14:34 +00001331 case SW_SHOW:
Alexandre Julliard23946ad1997-06-16 17:43:53 +00001332 swp |= SWP_SHOWWINDOW | SWP_NOSIZE | SWP_NOMOVE;
Francis Beaudet8623fdc1999-08-07 14:14:06 +00001333
1334 /*
1335 * ShowWindow has a little peculiar behavior that if the
1336 * window is already the topmost window, it will not
1337 * activate it.
1338 */
Abey George983f90a1999-10-13 15:43:45 +00001339 if (GetTopWindow((HWND)0)==hwnd && (wasVisible || GetActiveWindow() == hwnd))
Francis Beaudet8623fdc1999-08-07 14:14:06 +00001340 swp |= SWP_NOACTIVATE;
1341
Alexandre Julliarddba420a1994-02-02 06:48:31 +00001342 break;
1343
Alexandre Julliarddba420a1994-02-02 06:48:31 +00001344 case SW_SHOWNOACTIVATE:
Alexandre Julliard23946ad1997-06-16 17:43:53 +00001345 swp |= SWP_NOZORDER;
Alexandre Julliarda3960291999-02-26 11:11:13 +00001346 if (GetActiveWindow()) swp |= SWP_NOACTIVATE;
Alexandre Julliard22945d51995-03-02 17:44:29 +00001347 /* fall through */
1348 case SW_SHOWNORMAL: /* same as SW_NORMAL: */
Alexandre Julliard4f8c37b1996-01-14 18:12:01 +00001349 case SW_SHOWDEFAULT: /* FIXME: should have its own handler */
Alexandre Julliarddba420a1994-02-02 06:48:31 +00001350 case SW_RESTORE:
Alexandre Julliard23946ad1997-06-16 17:43:53 +00001351 swp |= SWP_SHOWWINDOW | SWP_FRAMECHANGED;
Alexandre Julliardd4719651995-12-12 18:49:11 +00001352
Alexandre Julliard23946ad1997-06-16 17:43:53 +00001353 if( wndPtr->dwStyle & (WS_MINIMIZE | WS_MAXIMIZE) )
1354 swp |= WINPOS_MinMaximize( wndPtr, SW_RESTORE, &newPos );
1355 else swp |= SWP_NOSIZE | SWP_NOMOVE;
Alexandre Julliard5f721f81994-01-04 20:14:34 +00001356 break;
1357 }
Alexandre Julliard940d58c1994-09-16 09:24:37 +00001358
Alexandre Julliard18f92e71996-07-17 20:02:21 +00001359 showFlag = (cmd != SW_HIDE);
1360 if (showFlag != wasVisible)
1361 {
Alexandre Julliarda3960291999-02-26 11:11:13 +00001362 SendMessageA( hwnd, WM_SHOWWINDOW, showFlag, 0 );
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001363 if (!IsWindow( hwnd )) goto END;
Alexandre Julliard18f92e71996-07-17 20:02:21 +00001364 }
1365
Alexandre Julliardac9c9b01996-07-28 18:50:11 +00001366 if ((wndPtr->dwStyle & WS_CHILD) &&
Alexandre Julliarda3960291999-02-26 11:11:13 +00001367 !IsWindowVisible( wndPtr->parent->hwndSelf ) &&
Alexandre Julliard23946ad1997-06-16 17:43:53 +00001368 (swp & (SWP_NOSIZE | SWP_NOMOVE)) == (SWP_NOSIZE | SWP_NOMOVE) )
Alexandre Julliardac9c9b01996-07-28 18:50:11 +00001369 {
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001370 /* Don't call SetWindowPos() on invisible child windows */
Alexandre Julliardac9c9b01996-07-28 18:50:11 +00001371 if (cmd == SW_HIDE) wndPtr->dwStyle &= ~WS_VISIBLE;
1372 else wndPtr->dwStyle |= WS_VISIBLE;
1373 }
1374 else
1375 {
1376 /* We can't activate a child window */
Thuy Nguyen22614a31999-10-13 13:53:10 +00001377 if ((wndPtr->dwStyle & WS_CHILD) &&
1378 !(wndPtr->dwExStyle & WS_EX_MDICHILD))
1379 swp |= SWP_NOACTIVATE | SWP_NOZORDER;
Alex Korobka44a1b591999-04-01 12:03:52 +00001380 if (!(swp & MINMAX_NOSWP))
Abey George983f90a1999-10-13 15:43:45 +00001381 {
Alex Korobka44a1b591999-04-01 12:03:52 +00001382 SetWindowPos( hwnd, HWND_TOP, newPos.left, newPos.top,
1383 newPos.right, newPos.bottom, LOWORD(swp) );
Abey George983f90a1999-10-13 15:43:45 +00001384 if (cmd == SW_HIDE)
1385 {
1386 /* FIXME: This will cause the window to be activated irrespective
1387 * of whether it is owned by the same thread. Has to be done
1388 * asynchronously.
1389 */
1390
1391 if (hwnd == GetActiveWindow())
1392 WINPOS_ActivateOtherWindow(wndPtr);
1393
1394 /* Revert focus to parent */
1395 if (hwnd == GetFocus() || IsChild(hwnd, GetFocus()))
1396 SetFocus( GetParent(hwnd) );
1397 }
1398 }
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001399 if (!IsWindow( hwnd )) goto END;
Alexandre Julliard23946ad1997-06-16 17:43:53 +00001400 else if( wndPtr->dwStyle & WS_MINIMIZE ) WINPOS_ShowIconTitle( wndPtr, TRUE );
Alexandre Julliardac9c9b01996-07-28 18:50:11 +00001401 }
Alexandre Julliard5f721f81994-01-04 20:14:34 +00001402
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001403 if (wndPtr->flags & WIN_NEED_SIZE)
Alexandre Julliard5f721f81994-01-04 20:14:34 +00001404 {
Alexandre Julliard18f92e71996-07-17 20:02:21 +00001405 /* should happen only in CreateWindowEx() */
Alexandre Julliard5f721f81994-01-04 20:14:34 +00001406 int wParam = SIZE_RESTORED;
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001407
1408 wndPtr->flags &= ~WIN_NEED_SIZE;
Alexandre Julliard5f721f81994-01-04 20:14:34 +00001409 if (wndPtr->dwStyle & WS_MAXIMIZE) wParam = SIZE_MAXIMIZED;
1410 else if (wndPtr->dwStyle & WS_MINIMIZE) wParam = SIZE_MINIMIZED;
Alexandre Julliarda3960291999-02-26 11:11:13 +00001411 SendMessageA( hwnd, WM_SIZE, wParam,
Alexandre Julliard5f721f81994-01-04 20:14:34 +00001412 MAKELONG(wndPtr->rectClient.right-wndPtr->rectClient.left,
1413 wndPtr->rectClient.bottom-wndPtr->rectClient.top));
Alexandre Julliarda3960291999-02-26 11:11:13 +00001414 SendMessageA( hwnd, WM_MOVE, 0,
Alexandre Julliard5f721f81994-01-04 20:14:34 +00001415 MAKELONG(wndPtr->rectClient.left, wndPtr->rectClient.top) );
1416 }
Alexandre Julliard940d58c1994-09-16 09:24:37 +00001417
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001418END:
1419 WIN_ReleaseWndPtr(wndPtr);
Alexandre Julliard5f721f81994-01-04 20:14:34 +00001420 return wasVisible;
1421}
1422
1423
1424/***********************************************************************
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001425 * GetInternalWindowPos16 (USER.460)
Alexandre Julliard86a8d0f1994-01-18 23:04:40 +00001426 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00001427UINT16 WINAPI GetInternalWindowPos16( HWND16 hwnd, LPRECT16 rectWnd,
1428 LPPOINT16 ptIcon )
Alexandre Julliard86a8d0f1994-01-18 23:04:40 +00001429{
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001430 WINDOWPLACEMENT16 wndpl;
Alexandre Julliard23946ad1997-06-16 17:43:53 +00001431 if (GetWindowPlacement16( hwnd, &wndpl ))
1432 {
1433 if (rectWnd) *rectWnd = wndpl.rcNormalPosition;
1434 if (ptIcon) *ptIcon = wndpl.ptMinPosition;
1435 return wndpl.showCmd;
1436 }
1437 return 0;
Alexandre Julliard86a8d0f1994-01-18 23:04:40 +00001438}
1439
1440
1441/***********************************************************************
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001442 * GetInternalWindowPos (USER32.245)
Alexandre Julliard86a8d0f1994-01-18 23:04:40 +00001443 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001444UINT WINAPI GetInternalWindowPos( HWND hwnd, LPRECT rectWnd,
1445 LPPOINT ptIcon )
Alexandre Julliard86a8d0f1994-01-18 23:04:40 +00001446{
Alexandre Julliarda3960291999-02-26 11:11:13 +00001447 WINDOWPLACEMENT wndpl;
1448 if (GetWindowPlacement( hwnd, &wndpl ))
Alexandre Julliard23946ad1997-06-16 17:43:53 +00001449 {
1450 if (rectWnd) *rectWnd = wndpl.rcNormalPosition;
1451 if (ptIcon) *ptIcon = wndpl.ptMinPosition;
1452 return wndpl.showCmd;
1453 }
1454 return 0;
1455}
1456
1457/***********************************************************************
1458 * GetWindowPlacement16 (USER.370)
1459 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00001460BOOL16 WINAPI GetWindowPlacement16( HWND16 hwnd, WINDOWPLACEMENT16 *wndpl )
Alexandre Julliard23946ad1997-06-16 17:43:53 +00001461{
1462 WND *pWnd = WIN_FindWndPtr( hwnd );
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001463 LPINTERNALPOS lpPos;
1464
1465 if(!pWnd ) return FALSE;
1466
1467 lpPos = (LPINTERNALPOS)WINPOS_InitInternalPos( pWnd,
Alexandre Julliarda3960291999-02-26 11:11:13 +00001468 *(LPPOINT)&pWnd->rectWindow.left, &pWnd->rectWindow );
Alexandre Julliard23946ad1997-06-16 17:43:53 +00001469 wndpl->length = sizeof(*wndpl);
1470 if( pWnd->dwStyle & WS_MINIMIZE )
Alexandre Julliardebfc0fe1998-06-28 18:40:26 +00001471 wndpl->showCmd = SW_SHOWMINIMIZED;
Alexandre Julliard23946ad1997-06-16 17:43:53 +00001472 else
1473 wndpl->showCmd = ( pWnd->dwStyle & WS_MAXIMIZE )
Alexandre Julliardebfc0fe1998-06-28 18:40:26 +00001474 ? SW_SHOWMAXIMIZED : SW_SHOWNORMAL ;
Alexandre Julliard23946ad1997-06-16 17:43:53 +00001475 if( pWnd->flags & WIN_RESTORE_MAX )
1476 wndpl->flags = WPF_RESTORETOMAXIMIZED;
1477 else
1478 wndpl->flags = 0;
1479 wndpl->ptMinPosition = lpPos->ptIconPos;
1480 wndpl->ptMaxPosition = lpPos->ptMaxPos;
1481 wndpl->rcNormalPosition = lpPos->rectNormal;
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001482
1483 WIN_ReleaseWndPtr(pWnd);
Alexandre Julliard23946ad1997-06-16 17:43:53 +00001484 return TRUE;
1485 }
Alexandre Julliard23946ad1997-06-16 17:43:53 +00001486
1487
1488/***********************************************************************
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001489 * GetWindowPlacement (USER32.307)
Alexandre Julliard638f1691999-01-17 16:32:32 +00001490 *
1491 * Win95:
1492 * Fails if wndpl->length of Win95 (!) apps is invalid.
Alexandre Julliard23946ad1997-06-16 17:43:53 +00001493 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001494BOOL WINAPI GetWindowPlacement( HWND hwnd, WINDOWPLACEMENT *pwpl32 )
Alexandre Julliard23946ad1997-06-16 17:43:53 +00001495{
1496 if( pwpl32 )
1497 {
1498 WINDOWPLACEMENT16 wpl;
1499 wpl.length = sizeof(wpl);
1500 if( GetWindowPlacement16( hwnd, &wpl ) )
1501 {
1502 pwpl32->length = sizeof(*pwpl32);
1503 pwpl32->flags = wpl.flags;
1504 pwpl32->showCmd = wpl.showCmd;
1505 CONV_POINT16TO32( &wpl.ptMinPosition, &pwpl32->ptMinPosition );
1506 CONV_POINT16TO32( &wpl.ptMaxPosition, &pwpl32->ptMaxPosition );
1507 CONV_RECT16TO32( &wpl.rcNormalPosition, &pwpl32->rcNormalPosition );
1508 return TRUE;
1509 }
1510 }
1511 return FALSE;
1512}
1513
1514
1515/***********************************************************************
1516 * WINPOS_SetPlacement
1517 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001518static BOOL WINPOS_SetPlacement( HWND hwnd, const WINDOWPLACEMENT16 *wndpl,
1519 UINT flags )
Alexandre Julliard23946ad1997-06-16 17:43:53 +00001520{
1521 WND *pWnd = WIN_FindWndPtr( hwnd );
1522 if( pWnd )
1523 {
1524 LPINTERNALPOS lpPos = (LPINTERNALPOS)WINPOS_InitInternalPos( pWnd,
Alexandre Julliarda3960291999-02-26 11:11:13 +00001525 *(LPPOINT)&pWnd->rectWindow.left, &pWnd->rectWindow );
Alexandre Julliard23946ad1997-06-16 17:43:53 +00001526
1527 if( flags & PLACE_MIN ) lpPos->ptIconPos = wndpl->ptMinPosition;
1528 if( flags & PLACE_MAX ) lpPos->ptMaxPos = wndpl->ptMaxPosition;
1529 if( flags & PLACE_RECT) lpPos->rectNormal = wndpl->rcNormalPosition;
1530
1531 if( pWnd->dwStyle & WS_MINIMIZE )
1532 {
1533 WINPOS_ShowIconTitle( pWnd, FALSE );
1534 if( wndpl->flags & WPF_SETMINPOSITION && !EMPTYPOINT(lpPos->ptIconPos))
Alexandre Julliarda3960291999-02-26 11:11:13 +00001535 SetWindowPos( hwnd, 0, lpPos->ptIconPos.x, lpPos->ptIconPos.y,
Alexandre Julliard23946ad1997-06-16 17:43:53 +00001536 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE );
1537 }
1538 else if( pWnd->dwStyle & WS_MAXIMIZE )
1539 {
1540 if( !EMPTYPOINT(lpPos->ptMaxPos) )
Alexandre Julliarda3960291999-02-26 11:11:13 +00001541 SetWindowPos( hwnd, 0, lpPos->ptMaxPos.x, lpPos->ptMaxPos.y,
Alexandre Julliard23946ad1997-06-16 17:43:53 +00001542 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE );
1543 }
1544 else if( flags & PLACE_RECT )
Alexandre Julliarda3960291999-02-26 11:11:13 +00001545 SetWindowPos( hwnd, 0, lpPos->rectNormal.left, lpPos->rectNormal.top,
Alexandre Julliard23946ad1997-06-16 17:43:53 +00001546 lpPos->rectNormal.right - lpPos->rectNormal.left,
1547 lpPos->rectNormal.bottom - lpPos->rectNormal.top,
1548 SWP_NOZORDER | SWP_NOACTIVATE );
1549
Alexandre Julliarda3960291999-02-26 11:11:13 +00001550 ShowWindow( hwnd, wndpl->showCmd );
1551 if( IsWindow(hwnd) && pWnd->dwStyle & WS_MINIMIZE )
Alexandre Julliard23946ad1997-06-16 17:43:53 +00001552 {
1553 if( pWnd->dwStyle & WS_VISIBLE ) WINPOS_ShowIconTitle( pWnd, TRUE );
1554
1555 /* SDK: ...valid only the next time... */
1556 if( wndpl->flags & WPF_RESTORETOMAXIMIZED ) pWnd->flags |= WIN_RESTORE_MAX;
1557 }
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001558 WIN_ReleaseWndPtr(pWnd);
Alexandre Julliard23946ad1997-06-16 17:43:53 +00001559 return TRUE;
1560 }
1561 return FALSE;
1562}
1563
1564
1565/***********************************************************************
1566 * SetWindowPlacement16 (USER.371)
1567 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00001568BOOL16 WINAPI SetWindowPlacement16(HWND16 hwnd, const WINDOWPLACEMENT16 *wndpl)
Alexandre Julliard23946ad1997-06-16 17:43:53 +00001569{
Alexandre Julliard670cdc41997-08-24 16:00:30 +00001570 return WINPOS_SetPlacement( hwnd, wndpl,
1571 PLACE_MIN | PLACE_MAX | PLACE_RECT );
Alexandre Julliard23946ad1997-06-16 17:43:53 +00001572}
1573
1574/***********************************************************************
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001575 * SetWindowPlacement (USER32.519)
Alexandre Julliard638f1691999-01-17 16:32:32 +00001576 *
1577 * Win95:
1578 * Fails if wndpl->length of Win95 (!) apps is invalid.
Alexandre Julliard23946ad1997-06-16 17:43:53 +00001579 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001580BOOL WINAPI SetWindowPlacement( HWND hwnd, const WINDOWPLACEMENT *pwpl32 )
Alexandre Julliard23946ad1997-06-16 17:43:53 +00001581{
1582 if( pwpl32 )
1583 {
Patrik Stridvalla9a671d1999-04-25 19:01:52 +00001584 WINDOWPLACEMENT16 wpl;
1585
1586 wpl.length = sizeof(WINDOWPLACEMENT16);
1587 wpl.flags = pwpl32->flags;
1588 wpl.showCmd = pwpl32->showCmd;
1589 wpl.ptMinPosition.x = pwpl32->ptMinPosition.x;
1590 wpl.ptMinPosition.y = pwpl32->ptMinPosition.y;
1591 wpl.ptMaxPosition.x = pwpl32->ptMaxPosition.x;
1592 wpl.ptMaxPosition.y = pwpl32->ptMaxPosition.y;
1593 wpl.rcNormalPosition.left = pwpl32->rcNormalPosition.left;
1594 wpl.rcNormalPosition.top = pwpl32->rcNormalPosition.top;
1595 wpl.rcNormalPosition.right = pwpl32->rcNormalPosition.right;
1596 wpl.rcNormalPosition.bottom = pwpl32->rcNormalPosition.bottom;
Alexandre Julliard23946ad1997-06-16 17:43:53 +00001597
1598 return WINPOS_SetPlacement( hwnd, &wpl, PLACE_MIN | PLACE_MAX | PLACE_RECT );
1599 }
1600 return FALSE;
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001601}
1602
1603
1604/***********************************************************************
1605 * SetInternalWindowPos16 (USER.461)
1606 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00001607void WINAPI SetInternalWindowPos16( HWND16 hwnd, UINT16 showCmd,
1608 LPRECT16 rect, LPPOINT16 pt )
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001609{
Alexandre Julliard23946ad1997-06-16 17:43:53 +00001610 if( IsWindow16(hwnd) )
1611 {
1612 WINDOWPLACEMENT16 wndpl;
Alexandre Julliarda3960291999-02-26 11:11:13 +00001613 UINT flags;
Alexandre Julliard86a8d0f1994-01-18 23:04:40 +00001614
Alexandre Julliard23946ad1997-06-16 17:43:53 +00001615 wndpl.length = sizeof(wndpl);
1616 wndpl.showCmd = showCmd;
1617 wndpl.flags = flags = 0;
1618
1619 if( pt )
1620 {
1621 flags |= PLACE_MIN;
1622 wndpl.flags |= WPF_SETMINPOSITION;
1623 wndpl.ptMinPosition = *pt;
1624 }
1625 if( rect )
1626 {
1627 flags |= PLACE_RECT;
1628 wndpl.rcNormalPosition = *rect;
1629 }
1630 WINPOS_SetPlacement( hwnd, &wndpl, flags );
1631 }
Alexandre Julliard86a8d0f1994-01-18 23:04:40 +00001632}
1633
1634
1635/***********************************************************************
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001636 * SetInternalWindowPos (USER32.483)
Alexandre Julliard86a8d0f1994-01-18 23:04:40 +00001637 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001638void WINAPI SetInternalWindowPos( HWND hwnd, UINT showCmd,
1639 LPRECT rect, LPPOINT pt )
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001640{
Alexandre Julliarda3960291999-02-26 11:11:13 +00001641 if( IsWindow(hwnd) )
Alexandre Julliard23946ad1997-06-16 17:43:53 +00001642 {
1643 WINDOWPLACEMENT16 wndpl;
Alexandre Julliarda3960291999-02-26 11:11:13 +00001644 UINT flags;
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001645
Alexandre Julliard23946ad1997-06-16 17:43:53 +00001646 wndpl.length = sizeof(wndpl);
1647 wndpl.showCmd = showCmd;
1648 wndpl.flags = flags = 0;
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001649
Alexandre Julliard23946ad1997-06-16 17:43:53 +00001650 if( pt )
1651 {
1652 flags |= PLACE_MIN;
1653 wndpl.flags |= WPF_SETMINPOSITION;
1654 CONV_POINT32TO16( pt, &wndpl.ptMinPosition );
1655 }
1656 if( rect )
1657 {
1658 flags |= PLACE_RECT;
1659 CONV_RECT32TO16( rect, &wndpl.rcNormalPosition );
1660 }
1661 WINPOS_SetPlacement( hwnd, &wndpl, flags );
1662 }
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001663}
1664
Alexandre Julliardd4719651995-12-12 18:49:11 +00001665/*******************************************************************
Alexandre Julliardd4719651995-12-12 18:49:11 +00001666 * WINPOS_SetActiveWindow
Alexandre Julliarddba420a1994-02-02 06:48:31 +00001667 *
Alexandre Julliard670cdc41997-08-24 16:00:30 +00001668 * SetActiveWindow() back-end. This is the only function that
1669 * can assign active status to a window. It must be called only
1670 * for the top level windows.
Alexandre Julliarddba420a1994-02-02 06:48:31 +00001671 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001672BOOL WINPOS_SetActiveWindow( HWND hWnd, BOOL fMouse, BOOL fChangeFocus)
Alexandre Julliarddba420a1994-02-02 06:48:31 +00001673{
Alexandre Julliard23946ad1997-06-16 17:43:53 +00001674 CBTACTIVATESTRUCT16* cbtStruct;
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001675 WND* wndPtr=0, *wndTemp;
Alexandre Julliard23946ad1997-06-16 17:43:53 +00001676 HQUEUE16 hOldActiveQueue, hNewActiveQueue;
Noel Borthwickb4278561999-02-05 10:37:53 +00001677 MESSAGEQUEUE *pOldActiveQueue = 0, *pNewActiveQueue = 0;
Alexandre Julliard23946ad1997-06-16 17:43:53 +00001678 WORD wIconized = 0;
Alex Korobka44a1b591999-04-01 12:03:52 +00001679 HWND hwndActive = 0;
1680 BOOL bRet = 0;
Noel Borthwickb4278561999-02-05 10:37:53 +00001681
Alexandre Julliard359f497e1999-07-04 16:02:24 +00001682 TRACE("(%04x, %d, %d)\n", hWnd, fMouse, fChangeFocus );
Ulrich Weigandb38e1de1999-06-12 06:42:20 +00001683
Noel Borthwickb4278561999-02-05 10:37:53 +00001684 /* Get current active window from the active queue */
1685 if ( hActiveQueue )
1686 {
1687 pOldActiveQueue = QUEUE_Lock( hActiveQueue );
1688 if ( pOldActiveQueue )
1689 hwndActive = PERQDATA_GetActiveWnd( pOldActiveQueue->pQData );
1690 }
Alexandre Julliardd4719651995-12-12 18:49:11 +00001691
1692 /* paranoid checks */
Alex Korobka44a1b591999-04-01 12:03:52 +00001693 if( hWnd == GetDesktopWindow() || (bRet = (hWnd == hwndActive)) )
1694 goto CLEANUP_END;
Alexandre Julliardd4719651995-12-12 18:49:11 +00001695
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001696/* if (wndPtr && (GetFastQueue16() != wndPtr->hmemTaskQ))
Alexandre Julliard670cdc41997-08-24 16:00:30 +00001697 * return 0;
1698 */
Alexandre Julliard23946ad1997-06-16 17:43:53 +00001699 wndPtr = WIN_FindWndPtr(hWnd);
Stephane Lussier1c4786f1999-01-28 10:54:11 +00001700 hOldActiveQueue = hActiveQueue;
Alexandre Julliard23946ad1997-06-16 17:43:53 +00001701
1702 if( (wndTemp = WIN_FindWndPtr(hwndActive)) )
Francois Boisvert3a3cd9f1999-03-28 12:42:52 +00001703 {
Alexandre Julliardd4719651995-12-12 18:49:11 +00001704 wIconized = HIWORD(wndTemp->dwStyle & WS_MINIMIZE);
Francois Boisvert3a3cd9f1999-03-28 12:42:52 +00001705 WIN_ReleaseWndPtr(wndTemp);
1706 }
Alexandre Julliardd4719651995-12-12 18:49:11 +00001707 else
Alexandre Julliard359f497e1999-07-04 16:02:24 +00001708 TRACE("no current active window.\n");
Francois Boisvert3a3cd9f1999-03-28 12:42:52 +00001709
Alexandre Julliardd4719651995-12-12 18:49:11 +00001710 /* call CBT hook chain */
Alexandre Julliardd90840e1996-06-11 16:02:08 +00001711 if ((cbtStruct = SEGPTR_NEW(CBTACTIVATESTRUCT16)))
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001712 {
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001713 cbtStruct->fMouse = fMouse;
1714 cbtStruct->hWndActive = hwndActive;
Alex Korobka44a1b591999-04-01 12:03:52 +00001715 bRet = (BOOL)HOOK_CallHooks16( WH_CBT, HCBT_ACTIVATE, (WPARAM16)hWnd,
1716 (LPARAM)SEGPTR_GET(cbtStruct) );
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001717 SEGPTR_FREE(cbtStruct);
Alex Korobka44a1b591999-04-01 12:03:52 +00001718 if (bRet) goto CLEANUP_END;
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001719 }
Alexandre Julliardd4719651995-12-12 18:49:11 +00001720
1721 /* set prev active wnd to current active wnd and send notification */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001722 if ((hwndPrevActive = hwndActive) && IsWindow(hwndPrevActive))
Alexandre Julliarddba420a1994-02-02 06:48:31 +00001723 {
Noel Borthwickb4278561999-02-05 10:37:53 +00001724 MESSAGEQUEUE *pTempActiveQueue = 0;
1725
Alexandre Julliarda3960291999-02-26 11:11:13 +00001726 if (!SendMessageA( hwndPrevActive, WM_NCACTIVATE, FALSE, 0 ))
Alexandre Julliardd4719651995-12-12 18:49:11 +00001727 {
Alex Korobka44a1b591999-04-01 12:03:52 +00001728 if (GetSysModalWindow16() != hWnd)
1729 goto CLEANUP_END;
Alexandre Julliardd4719651995-12-12 18:49:11 +00001730 /* disregard refusal if hWnd is sysmodal */
1731 }
1732
Alexandre Julliarda3960291999-02-26 11:11:13 +00001733 SendMessageA( hwndPrevActive, WM_ACTIVATE,
Alexandre Julliardef702d81996-05-28 18:54:58 +00001734 MAKEWPARAM( WA_INACTIVE, wIconized ),
1735 (LPARAM)hWnd );
Alexandre Julliardd4719651995-12-12 18:49:11 +00001736
Noel Borthwickb4278561999-02-05 10:37:53 +00001737 /* check if something happened during message processing
1738 * (global active queue may have changed)
1739 */
1740 pTempActiveQueue = QUEUE_Lock( hActiveQueue );
Alex Korobka98447491999-05-08 17:57:09 +00001741 if(!pTempActiveQueue)
1742 goto CLEANUP_END;
Francois Boisvert71bdc7c1999-04-11 11:59:25 +00001743
Noel Borthwickb4278561999-02-05 10:37:53 +00001744 hwndActive = PERQDATA_GetActiveWnd( pTempActiveQueue->pQData );
1745 QUEUE_Unlock( pTempActiveQueue );
1746 if( hwndPrevActive != hwndActive )
Alex Korobka44a1b591999-04-01 12:03:52 +00001747 goto CLEANUP_END;
Alexandre Julliarddba420a1994-02-02 06:48:31 +00001748 }
1749
Noel Borthwickb4278561999-02-05 10:37:53 +00001750 /* Set new active window in the message queue */
Alexandre Julliardd4719651995-12-12 18:49:11 +00001751 hwndActive = hWnd;
Noel Borthwickb4278561999-02-05 10:37:53 +00001752 if ( wndPtr )
1753 {
1754 pNewActiveQueue = QUEUE_Lock( wndPtr->hmemTaskQ );
1755 if ( pNewActiveQueue )
1756 PERQDATA_SetActiveWnd( pNewActiveQueue->pQData, hwndActive );
1757 }
Alex Korobka4f1ac051999-03-28 09:37:57 +00001758 else /* have to do this or MDI frame activation goes to hell */
1759 if( pOldActiveQueue )
1760 PERQDATA_SetActiveWnd( pOldActiveQueue->pQData, 0 );
Alexandre Julliardd4719651995-12-12 18:49:11 +00001761
1762 /* send palette messages */
Alexandre Julliard8cc3a5e1996-08-11 15:49:51 +00001763 if (hWnd && SendMessage16( hWnd, WM_QUERYNEWPALETTE, 0, 0L))
Alexandre Julliard530ee841996-10-23 16:59:13 +00001764 SendMessage16((HWND16)-1, WM_PALETTEISCHANGING, (WPARAM16)hWnd, 0L );
Alexandre Julliardd4719651995-12-12 18:49:11 +00001765
Alexandre Julliard23946ad1997-06-16 17:43:53 +00001766 /* if prev wnd is minimized redraw icon title */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001767 if( IsIconic( hwndPrevActive ) ) WINPOS_RedrawIconTitle(hwndPrevActive);
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001768
1769 /* managed windows will get ConfigureNotify event */
Alexandre Julliard8cc3a5e1996-08-11 15:49:51 +00001770 if (wndPtr && !(wndPtr->dwStyle & WS_CHILD) && !(wndPtr->flags & WIN_MANAGED))
Alexandre Julliardd4719651995-12-12 18:49:11 +00001771 {
1772 /* check Z-order and bring hWnd to the top */
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001773 for (wndTemp = WIN_LockWndPtr(WIN_GetDesktop()->child); wndTemp; WIN_UpdateWndPtr(&wndTemp,wndTemp->next))
1774 {
Alexandre Julliard59730ae1996-03-24 16:20:51 +00001775 if (wndTemp->dwStyle & WS_VISIBLE) break;
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001776 }
1777 WIN_ReleaseDesktop();
1778 WIN_ReleaseWndPtr(wndTemp);
Alexandre Julliardd4719651995-12-12 18:49:11 +00001779
1780 if( wndTemp != wndPtr )
Alexandre Julliarda3960291999-02-26 11:11:13 +00001781 SetWindowPos(hWnd, HWND_TOP, 0,0,0,0,
Alexandre Julliard01d63461997-01-20 19:43:45 +00001782 SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE );
Alex Korobka44a1b591999-04-01 12:03:52 +00001783 if (!IsWindow(hWnd))
1784 goto CLEANUP;
Alexandre Julliarddba420a1994-02-02 06:48:31 +00001785 }
Alexandre Julliardd4719651995-12-12 18:49:11 +00001786
Noel Borthwickb4278561999-02-05 10:37:53 +00001787 /* Get a handle to the new active queue */
Alexandre Julliard8cc3a5e1996-08-11 15:49:51 +00001788 hNewActiveQueue = wndPtr ? wndPtr->hmemTaskQ : 0;
Alexandre Julliard7e56f681996-01-31 19:02:28 +00001789
1790 /* send WM_ACTIVATEAPP if necessary */
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +00001791 if (hOldActiveQueue != hNewActiveQueue)
Alexandre Julliard7e56f681996-01-31 19:02:28 +00001792 {
Alexandre Julliard3051b641996-07-05 17:14:13 +00001793 WND **list, **ppWnd;
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001794 WND *pDesktop = WIN_GetDesktop();
Alexandre Julliardd4719651995-12-12 18:49:11 +00001795
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001796 if ((list = WIN_BuildWinArray( pDesktop, 0, NULL )))
Alexandre Julliard3051b641996-07-05 17:14:13 +00001797 {
1798 for (ppWnd = list; *ppWnd; ppWnd++)
1799 {
Alexandre Julliarda3960291999-02-26 11:11:13 +00001800 if (!IsWindow( (*ppWnd)->hwndSelf )) continue;
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +00001801
1802 if ((*ppWnd)->hmemTaskQ == hOldActiveQueue)
1803 SendMessage16( (*ppWnd)->hwndSelf, WM_ACTIVATEAPP,
1804 0, QUEUE_GetQueueTask(hNewActiveQueue) );
Alexandre Julliard3051b641996-07-05 17:14:13 +00001805 }
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001806 WIN_ReleaseWinArray(list);
Alexandre Julliard3051b641996-07-05 17:14:13 +00001807 }
Alexandre Julliardd4719651995-12-12 18:49:11 +00001808
Stephane Lussier1c4786f1999-01-28 10:54:11 +00001809 hActiveQueue = hNewActiveQueue;
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +00001810
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001811 if ((list = WIN_BuildWinArray(pDesktop, 0, NULL )))
Alexandre Julliard3051b641996-07-05 17:14:13 +00001812 {
1813 for (ppWnd = list; *ppWnd; ppWnd++)
1814 {
Alexandre Julliarda3960291999-02-26 11:11:13 +00001815 if (!IsWindow( (*ppWnd)->hwndSelf )) continue;
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +00001816
1817 if ((*ppWnd)->hmemTaskQ == hNewActiveQueue)
1818 SendMessage16( (*ppWnd)->hwndSelf, WM_ACTIVATEAPP,
1819 1, QUEUE_GetQueueTask( hOldActiveQueue ) );
Alexandre Julliard3051b641996-07-05 17:14:13 +00001820 }
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001821 WIN_ReleaseWinArray(list);
Alexandre Julliard3051b641996-07-05 17:14:13 +00001822 }
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001823 WIN_ReleaseDesktop();
Stephane Lussier1c4786f1999-01-28 10:54:11 +00001824
Ulrich Weigandb38e1de1999-06-12 06:42:20 +00001825 if (hWnd && !IsWindow(hWnd)) goto CLEANUP;
Alexandre Julliardd4719651995-12-12 18:49:11 +00001826 }
1827
Alexandre Julliard8cc3a5e1996-08-11 15:49:51 +00001828 if (hWnd)
1829 {
1830 /* walk up to the first unowned window */
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001831 wndTemp = WIN_LockWndPtr(wndPtr);
1832 while (wndTemp->owner)
1833 {
1834 WIN_UpdateWndPtr(&wndTemp,wndTemp->owner);
1835 }
Alexandre Julliard8cc3a5e1996-08-11 15:49:51 +00001836 /* and set last active owned popup */
1837 wndTemp->hwndLastActive = hWnd;
Alexandre Julliardd4719651995-12-12 18:49:11 +00001838
Alexandre Julliard8cc3a5e1996-08-11 15:49:51 +00001839 wIconized = HIWORD(wndTemp->dwStyle & WS_MINIMIZE);
Francois Boisvert3a3cd9f1999-03-28 12:42:52 +00001840 WIN_ReleaseWndPtr(wndTemp);
Alexandre Julliarda3960291999-02-26 11:11:13 +00001841 SendMessageA( hWnd, WM_NCACTIVATE, TRUE, 0 );
Alexandre Julliarda3960291999-02-26 11:11:13 +00001842 SendMessageA( hWnd, WM_ACTIVATE,
Alexandre Julliardca22b331996-07-12 19:02:39 +00001843 MAKEWPARAM( (fMouse) ? WA_CLICKACTIVE : WA_ACTIVE, wIconized),
Alexandre Julliardd4719651995-12-12 18:49:11 +00001844 (LPARAM)hwndPrevActive );
Alexandre Julliarda3960291999-02-26 11:11:13 +00001845 if( !IsWindow(hWnd) ) goto CLEANUP;
Alexandre Julliard8cc3a5e1996-08-11 15:49:51 +00001846 }
Alexandre Julliardd4719651995-12-12 18:49:11 +00001847
1848 /* change focus if possible */
Ulrich Weigandb38e1de1999-06-12 06:42:20 +00001849 if ( fChangeFocus )
1850 {
1851 if ( pNewActiveQueue )
1852 {
1853 HWND hOldFocus = PERQDATA_GetFocusWnd( pNewActiveQueue->pQData );
1854
1855 if ( WIN_GetTopParent( hOldFocus ) != hwndActive )
1856 FOCUS_SwitchFocus( pNewActiveQueue, hOldFocus,
1857 (wndPtr && (wndPtr->dwStyle & WS_MINIMIZE))?
1858 0 : hwndActive );
1859 }
1860
1861 if ( pOldActiveQueue &&
1862 ( !pNewActiveQueue ||
1863 pNewActiveQueue->pQData != pOldActiveQueue->pQData ) )
1864 {
1865 HWND hOldFocus = PERQDATA_GetFocusWnd( pOldActiveQueue->pQData );
1866 if ( hOldFocus )
1867 FOCUS_SwitchFocus( pOldActiveQueue, hOldFocus, 0 );
1868 }
1869 }
Alexandre Julliardd4719651995-12-12 18:49:11 +00001870
Patrik Stridvalle35d6361998-12-07 09:13:40 +00001871 if( !hwndPrevActive && wndPtr )
1872 (*wndPtr->pDriver->pForceWindowRaise)(wndPtr);
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +00001873
Alexandre Julliard23946ad1997-06-16 17:43:53 +00001874 /* if active wnd is minimized redraw icon title */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001875 if( IsIconic(hwndActive) ) WINPOS_RedrawIconTitle(hwndActive);
Alexandre Julliard23946ad1997-06-16 17:43:53 +00001876
Alex Korobka44a1b591999-04-01 12:03:52 +00001877 bRet = (hWnd == hwndActive); /* Success? */
Noel Borthwickb4278561999-02-05 10:37:53 +00001878
Alex Korobka44a1b591999-04-01 12:03:52 +00001879CLEANUP: /* Unlock the message queues before returning */
Noel Borthwickb4278561999-02-05 10:37:53 +00001880
Noel Borthwickb4278561999-02-05 10:37:53 +00001881 if ( pNewActiveQueue )
1882 QUEUE_Unlock( pNewActiveQueue );
Alex Korobka44a1b591999-04-01 12:03:52 +00001883
1884CLEANUP_END:
1885
1886 if ( pOldActiveQueue )
1887 QUEUE_Unlock( pOldActiveQueue );
1888
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001889 WIN_ReleaseWndPtr(wndPtr);
Alex Korobka44a1b591999-04-01 12:03:52 +00001890 return bRet;
Alexandre Julliardd4719651995-12-12 18:49:11 +00001891}
1892
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +00001893/*******************************************************************
1894 * WINPOS_ActivateOtherWindow
1895 *
Alexandre Julliard670cdc41997-08-24 16:00:30 +00001896 * Activates window other than pWnd.
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +00001897 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001898BOOL WINPOS_ActivateOtherWindow(WND* pWnd)
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +00001899{
Alexandre Julliarda3960291999-02-26 11:11:13 +00001900 BOOL bRet = 0;
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +00001901 WND* pWndTo = NULL;
Alexandre Julliarda3960291999-02-26 11:11:13 +00001902 HWND hwndActive = 0;
Noel Borthwickb4278561999-02-05 10:37:53 +00001903
1904 /* Get current active window from the active queue */
1905 if ( hActiveQueue )
1906 {
1907 MESSAGEQUEUE *pActiveQueue = QUEUE_Lock( hActiveQueue );
1908 if ( pActiveQueue )
1909 {
1910 hwndActive = PERQDATA_GetActiveWnd( pActiveQueue->pQData );
1911 QUEUE_Unlock( pActiveQueue );
1912 }
1913 }
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +00001914
1915 if( pWnd->hwndSelf == hwndPrevActive )
1916 hwndPrevActive = 0;
1917
1918 if( hwndActive != pWnd->hwndSelf &&
Alexandre Julliard7ff1c411997-05-25 13:58:18 +00001919 ( hwndActive || QUEUE_IsExitingQueue(pWnd->hmemTaskQ)) )
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +00001920 return 0;
1921
Alexandre Julliard670cdc41997-08-24 16:00:30 +00001922 if( !(pWnd->dwStyle & WS_POPUP) || !(pWnd->owner) ||
1923 !WINPOS_CanActivate((pWndTo = WIN_GetTopParentPtr(pWnd->owner))) )
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +00001924 {
Alexandre Julliard670cdc41997-08-24 16:00:30 +00001925 WND* pWndPtr = WIN_GetTopParentPtr(pWnd);
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +00001926
Noel Borthwick10619e91999-05-02 11:20:00 +00001927 WIN_ReleaseWndPtr(pWndTo);
Alexandre Julliard670cdc41997-08-24 16:00:30 +00001928 pWndTo = WIN_FindWndPtr(hwndPrevActive);
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +00001929
Alexandre Julliard670cdc41997-08-24 16:00:30 +00001930 while( !WINPOS_CanActivate(pWndTo) )
1931 {
1932 /* by now owned windows should've been taken care of */
Francois Boisvert3a3cd9f1999-03-28 12:42:52 +00001933 WIN_UpdateWndPtr(&pWndTo,pWndPtr->next);
1934 WIN_UpdateWndPtr(&pWndPtr,pWndTo);
Alexandre Julliard670cdc41997-08-24 16:00:30 +00001935 if( !pWndTo ) break;
1936 }
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001937 WIN_ReleaseWndPtr(pWndPtr);
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +00001938 }
1939
Alexandre Julliard670cdc41997-08-24 16:00:30 +00001940 bRet = WINPOS_SetActiveWindow( pWndTo ? pWndTo->hwndSelf : 0, FALSE, TRUE );
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +00001941
1942 /* switch desktop queue to current active */
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001943 if( pWndTo )
1944 {
1945 WIN_GetDesktop()->hmemTaskQ = pWndTo->hmemTaskQ;
1946 WIN_ReleaseWndPtr(pWndTo);
1947 WIN_ReleaseDesktop();
1948 }
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +00001949
1950 hwndPrevActive = 0;
1951 return bRet;
1952}
Alexandre Julliardd4719651995-12-12 18:49:11 +00001953
1954/*******************************************************************
1955 * WINPOS_ChangeActiveWindow
1956 *
1957 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001958BOOL WINPOS_ChangeActiveWindow( HWND hWnd, BOOL mouseMsg )
Alexandre Julliardd4719651995-12-12 18:49:11 +00001959{
Alex Korobka4f1ac051999-03-28 09:37:57 +00001960 WND *wndPtr, *wndTemp;
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001961 BOOL retvalue;
Alexandre Julliarda3960291999-02-26 11:11:13 +00001962 HWND hwndActive = 0;
Noel Borthwickb4278561999-02-05 10:37:53 +00001963
1964 /* Get current active window from the active queue */
1965 if ( hActiveQueue )
1966 {
1967 MESSAGEQUEUE *pActiveQueue = QUEUE_Lock( hActiveQueue );
1968 if ( pActiveQueue )
1969 {
1970 hwndActive = PERQDATA_GetActiveWnd( pActiveQueue->pQData );
1971 QUEUE_Unlock( pActiveQueue );
1972 }
1973 }
Alexandre Julliardd4719651995-12-12 18:49:11 +00001974
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001975 if (!hWnd)
Alex Korobka4f1ac051999-03-28 09:37:57 +00001976 return WINPOS_SetActiveWindow( 0, mouseMsg, TRUE );
Alexandre Julliard8cc3a5e1996-08-11 15:49:51 +00001977
Alex Korobka4f1ac051999-03-28 09:37:57 +00001978 wndPtr = WIN_FindWndPtr(hWnd);
1979 if( !wndPtr ) return FALSE;
Alexandre Julliardd4719651995-12-12 18:49:11 +00001980
Alexandre Julliardc981d0b1996-03-31 16:40:13 +00001981 /* child windows get WM_CHILDACTIVATE message */
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001982 if( (wndPtr->dwStyle & (WS_CHILD | WS_POPUP)) == WS_CHILD )
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001983 {
1984 retvalue = SendMessageA(hWnd, WM_CHILDACTIVATE, 0, 0L);
1985 goto end;
1986 }
Alexandre Julliardd4719651995-12-12 18:49:11 +00001987
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001988 if( hWnd == hwndActive )
1989 {
1990 retvalue = FALSE;
1991 goto end;
1992 }
Alexandre Julliardd4719651995-12-12 18:49:11 +00001993
1994 if( !WINPOS_SetActiveWindow(hWnd ,mouseMsg ,TRUE) )
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001995 {
1996 retvalue = FALSE;
1997 goto end;
1998 }
Alexandre Julliardd4719651995-12-12 18:49:11 +00001999
Alexandre Julliardc981d0b1996-03-31 16:40:13 +00002000 /* switch desktop queue to current active */
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002001 wndTemp = WIN_GetDesktop();
2002 if( wndPtr->parent == wndTemp)
2003 wndTemp->hmemTaskQ = wndPtr->hmemTaskQ;
2004 WIN_ReleaseDesktop();
Alexandre Julliardd4719651995-12-12 18:49:11 +00002005
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002006 retvalue = TRUE;
2007end:
2008 WIN_ReleaseWndPtr(wndPtr);
2009 return retvalue;
Alexandre Julliarddba420a1994-02-02 06:48:31 +00002010}
2011
2012
Alexandre Julliard86a8d0f1994-01-18 23:04:40 +00002013/***********************************************************************
Alexandre Julliard2d159fb1994-07-15 16:04:31 +00002014 * WINPOS_SendNCCalcSize
2015 *
2016 * Send a WM_NCCALCSIZE message to a window.
2017 * All parameters are read-only except newClientRect.
2018 * oldWindowRect, oldClientRect and winpos must be non-NULL only
2019 * when calcValidRect is TRUE.
2020 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002021LONG WINPOS_SendNCCalcSize( HWND hwnd, BOOL calcValidRect,
2022 RECT *newWindowRect, RECT *oldWindowRect,
2023 RECT *oldClientRect, WINDOWPOS *winpos,
2024 RECT *newClientRect )
Alexandre Julliard2d159fb1994-07-15 16:04:31 +00002025{
Alexandre Julliarda3960291999-02-26 11:11:13 +00002026 NCCALCSIZE_PARAMS params;
2027 WINDOWPOS winposCopy;
Alexandre Julliard2d159fb1994-07-15 16:04:31 +00002028 LONG result;
2029
Alexandre Julliardd37eb361997-07-20 16:23:21 +00002030 params.rgrc[0] = *newWindowRect;
Alexandre Julliard2d159fb1994-07-15 16:04:31 +00002031 if (calcValidRect)
2032 {
Alexandre Julliardebfc0fe1998-06-28 18:40:26 +00002033 winposCopy = *winpos;
Alexandre Julliardd37eb361997-07-20 16:23:21 +00002034 params.rgrc[1] = *oldWindowRect;
2035 params.rgrc[2] = *oldClientRect;
Alexandre Julliardebfc0fe1998-06-28 18:40:26 +00002036 params.lppos = &winposCopy;
Alexandre Julliard2d159fb1994-07-15 16:04:31 +00002037 }
Alexandre Julliarda3960291999-02-26 11:11:13 +00002038 result = SendMessageA( hwnd, WM_NCCALCSIZE, calcValidRect,
Alexandre Julliardd37eb361997-07-20 16:23:21 +00002039 (LPARAM)&params );
Alexandre Julliard359f497e1999-07-04 16:02:24 +00002040 TRACE("%d,%d-%d,%d\n",
Alexandre Julliardd37eb361997-07-20 16:23:21 +00002041 params.rgrc[0].left, params.rgrc[0].top,
2042 params.rgrc[0].right, params.rgrc[0].bottom );
Abey Georgec684d8e1999-09-03 15:09:57 +00002043
2044 /* If the application send back garbage, ignore it */
2045 if (params.rgrc[0].left <= params.rgrc[0].right && params.rgrc[0].top <= params.rgrc[0].bottom)
2046 *newClientRect = params.rgrc[0];
2047
Alexandre Julliard2d159fb1994-07-15 16:04:31 +00002048 return result;
2049}
2050
2051
2052/***********************************************************************
Alexandre Julliard2d93d001996-05-21 15:01:41 +00002053 * WINPOS_HandleWindowPosChanging16
Alexandre Julliard2d159fb1994-07-15 16:04:31 +00002054 *
2055 * Default handling for a WM_WINDOWPOSCHANGING. Called from DefWindowProc().
2056 */
Alexandre Julliard2d93d001996-05-21 15:01:41 +00002057LONG WINPOS_HandleWindowPosChanging16( WND *wndPtr, WINDOWPOS16 *winpos )
Alexandre Julliard2d159fb1994-07-15 16:04:31 +00002058{
Alexandre Julliarda3960291999-02-26 11:11:13 +00002059 POINT maxSize, minTrack;
Alexandre Julliard2d93d001996-05-21 15:01:41 +00002060 if (winpos->flags & SWP_NOSIZE) return 0;
2061 if ((wndPtr->dwStyle & WS_THICKFRAME) ||
2062 ((wndPtr->dwStyle & (WS_POPUP | WS_CHILD)) == 0))
2063 {
Alexandre Julliard77b99181997-09-14 17:17:23 +00002064 WINPOS_GetMinMaxInfo( wndPtr, &maxSize, NULL, &minTrack, NULL );
2065 if (maxSize.x < winpos->cx) winpos->cx = maxSize.x;
2066 if (maxSize.y < winpos->cy) winpos->cy = maxSize.y;
2067 if (!(wndPtr->dwStyle & WS_MINIMIZE))
2068 {
2069 if (winpos->cx < minTrack.x ) winpos->cx = minTrack.x;
2070 if (winpos->cy < minTrack.y ) winpos->cy = minTrack.y;
2071 }
Alexandre Julliard2d93d001996-05-21 15:01:41 +00002072 }
2073 return 0;
2074}
2075
2076
2077/***********************************************************************
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002078 * WINPOS_HandleWindowPosChanging
Alexandre Julliard2d93d001996-05-21 15:01:41 +00002079 *
2080 * Default handling for a WM_WINDOWPOSCHANGING. Called from DefWindowProc().
2081 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002082LONG WINPOS_HandleWindowPosChanging( WND *wndPtr, WINDOWPOS *winpos )
Alexandre Julliard2d93d001996-05-21 15:01:41 +00002083{
Alexandre Julliarda3960291999-02-26 11:11:13 +00002084 POINT maxSize;
Alexandre Julliard2d93d001996-05-21 15:01:41 +00002085 if (winpos->flags & SWP_NOSIZE) return 0;
Alexandre Julliard2d159fb1994-07-15 16:04:31 +00002086 if ((wndPtr->dwStyle & WS_THICKFRAME) ||
Alexandre Julliardade697e1995-11-26 13:59:11 +00002087 ((wndPtr->dwStyle & (WS_POPUP | WS_CHILD)) == 0))
Alexandre Julliard2d159fb1994-07-15 16:04:31 +00002088 {
Alexandre Julliard23946ad1997-06-16 17:43:53 +00002089 WINPOS_GetMinMaxInfo( wndPtr, &maxSize, NULL, NULL, NULL );
Alexandre Julliard902da691995-11-05 14:39:02 +00002090 winpos->cx = MIN( winpos->cx, maxSize.x );
2091 winpos->cy = MIN( winpos->cy, maxSize.y );
Alexandre Julliard2d159fb1994-07-15 16:04:31 +00002092 }
2093 return 0;
2094}
2095
Alexandre Julliard2d159fb1994-07-15 16:04:31 +00002096/***********************************************************************
Alex Korobka4f1ac051999-03-28 09:37:57 +00002097 * SWP_DoOwnedPopups
Alexandre Julliardc981d0b1996-03-31 16:40:13 +00002098 *
2099 * fix Z order taking into account owned popups -
Alexandre Julliarda0d77311998-09-13 16:32:00 +00002100 * basically we need to maintain them above the window that owns them
Alex Korobka4f1ac051999-03-28 09:37:57 +00002101 *
2102 * FIXME: hide/show owned popups when owner visibility changes.
Alexandre Julliardc981d0b1996-03-31 16:40:13 +00002103 */
Alex Korobka4f1ac051999-03-28 09:37:57 +00002104static HWND SWP_DoOwnedPopups(WND* pDesktop, WND* wndPtr, HWND hwndInsertAfter, WORD flags)
Alexandre Julliardc981d0b1996-03-31 16:40:13 +00002105{
Alex Korobka4f1ac051999-03-28 09:37:57 +00002106 WND* w = WIN_LockWndPtr(pDesktop->child);
Alexandre Julliardc981d0b1996-03-31 16:40:13 +00002107
Alexandre Julliard359f497e1999-07-04 16:02:24 +00002108 WARN("(%04x) hInsertAfter = %04x\n", wndPtr->hwndSelf, hwndInsertAfter );
Alexandre Julliardc981d0b1996-03-31 16:40:13 +00002109
Alex Korobka4f1ac051999-03-28 09:37:57 +00002110 if( (wndPtr->dwStyle & WS_POPUP) && wndPtr->owner )
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +00002111 {
Alex Korobka4f1ac051999-03-28 09:37:57 +00002112 /* make sure this popup stays above the owner */
2113
2114 HWND hwndLocalPrev = HWND_TOP;
2115
2116 if( hwndInsertAfter != HWND_TOP )
2117 {
2118 while( w != wndPtr->owner )
2119 {
2120 if (w != wndPtr) hwndLocalPrev = w->hwndSelf;
2121 if( hwndLocalPrev == hwndInsertAfter ) break;
2122 WIN_UpdateWndPtr(&w,w->next);
2123 }
2124 hwndInsertAfter = hwndLocalPrev;
2125 }
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +00002126 }
Alex Korobka4f1ac051999-03-28 09:37:57 +00002127 else if( wndPtr->dwStyle & WS_CHILD )
2128 goto END;
2129
2130 WIN_UpdateWndPtr(&w, pDesktop->child);
2131
2132 while( w )
2133 {
2134 if( w == wndPtr ) break;
2135
2136 if( (w->dwStyle & WS_POPUP) && w->owner == wndPtr )
2137 {
2138 SetWindowPos(w->hwndSelf, hwndInsertAfter, 0, 0, 0, 0,
2139 SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE | SWP_NOSENDCHANGING | SWP_DEFERERASE);
2140 hwndInsertAfter = w->hwndSelf;
2141 }
2142 WIN_UpdateWndPtr(&w, w->next);
2143 }
Alexandre Julliardc981d0b1996-03-31 16:40:13 +00002144
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002145END:
Alex Korobka4f1ac051999-03-28 09:37:57 +00002146 WIN_ReleaseWndPtr(w);
2147 return hwndInsertAfter;
Alexandre Julliardc981d0b1996-03-31 16:40:13 +00002148}
2149
Alexandre Julliardcdcdede1996-04-21 14:57:41 +00002150/***********************************************************************
Alex Korobka4f1ac051999-03-28 09:37:57 +00002151 * SWP_CopyValidBits
Alexandre Julliardcdcdede1996-04-21 14:57:41 +00002152 *
2153 * Make window look nice without excessive repainting
2154 *
Alex Korobka4f1ac051999-03-28 09:37:57 +00002155 * visible and update regions are in window coordinates
Alexandre Julliardcdcdede1996-04-21 14:57:41 +00002156 * client and window rectangles are in parent client coordinates
Alexandre Julliard23946ad1997-06-16 17:43:53 +00002157 *
Alex Korobka4f1ac051999-03-28 09:37:57 +00002158 * FIXME: SWP_EX_PAINTSELF in uFlags works only if both old and new
2159 * window rects have the same origin.
2160 *
2161 * Returns: uFlags and a dirty region in *pVisRgn.
Alexandre Julliardcdcdede1996-04-21 14:57:41 +00002162 */
Alex Korobka4f1ac051999-03-28 09:37:57 +00002163static UINT SWP_CopyValidBits( WND* Wnd, HRGN* pVisRgn,
2164 LPRECT lpOldWndRect,
2165 LPRECT lpOldClientRect, UINT uFlags )
Alexandre Julliardcdcdede1996-04-21 14:57:41 +00002166{
Alex Korobka4f1ac051999-03-28 09:37:57 +00002167 RECT r;
2168 HRGN newVisRgn, dirtyRgn;
2169 INT my = COMPLEXREGION;
Alexandre Julliardcdcdede1996-04-21 14:57:41 +00002170
Alexandre Julliard359f497e1999-07-04 16:02:24 +00002171 TRACE("\tnew wnd=(%i %i-%i %i) old wnd=(%i %i-%i %i), %04x\n",
Alexandre Julliarda69b88b1998-03-15 20:29:56 +00002172 Wnd->rectWindow.left, Wnd->rectWindow.top,
2173 Wnd->rectWindow.right, Wnd->rectWindow.bottom,
2174 lpOldWndRect->left, lpOldWndRect->top,
Alex Korobka4f1ac051999-03-28 09:37:57 +00002175 lpOldWndRect->right, lpOldWndRect->bottom, *pVisRgn);
Alexandre Julliard359f497e1999-07-04 16:02:24 +00002176 TRACE("\tnew client=(%i %i-%i %i) old client=(%i %i-%i %i)\n",
Alexandre Julliarda69b88b1998-03-15 20:29:56 +00002177 Wnd->rectClient.left, Wnd->rectClient.top,
2178 Wnd->rectClient.right, Wnd->rectClient.bottom,
2179 lpOldClientRect->left, lpOldClientRect->top,
2180 lpOldClientRect->right,lpOldClientRect->bottom );
Alexandre Julliardcdcdede1996-04-21 14:57:41 +00002181
Alex Korobka4f1ac051999-03-28 09:37:57 +00002182 if( Wnd->hrgnUpdate == 1 )
2183 uFlags |= SWP_EX_NOCOPY; /* whole window is invalid, nothing to copy */
Alexandre Julliard1e37a181996-08-18 16:21:52 +00002184
Alex Korobka4f1ac051999-03-28 09:37:57 +00002185 newVisRgn = DCE_GetVisRgn( Wnd->hwndSelf, DCX_WINDOW | DCX_CLIPSIBLINGS, 0, 0);
2186 dirtyRgn = CreateRectRgn( 0, 0, 0, 0 );
Alexandre Julliardcdcdede1996-04-21 14:57:41 +00002187
Alex Korobka4f1ac051999-03-28 09:37:57 +00002188 if( !(uFlags & SWP_EX_NOCOPY) ) /* make sure dst region covers only valid bits */
2189 my = CombineRgn( dirtyRgn, newVisRgn, *pVisRgn, RGN_AND );
Alexandre Julliardcdcdede1996-04-21 14:57:41 +00002190
Alex Korobka4f1ac051999-03-28 09:37:57 +00002191 if( (my == NULLREGION) || (uFlags & SWP_EX_NOCOPY) )
2192 {
2193nocopy:
Alexandre Julliardcdcdede1996-04-21 14:57:41 +00002194
Alexandre Julliard359f497e1999-07-04 16:02:24 +00002195 TRACE("\twon't copy anything!\n");
Alexandre Julliardcdcdede1996-04-21 14:57:41 +00002196
Alex Korobka4f1ac051999-03-28 09:37:57 +00002197 /* set dirtyRgn to the sum of old and new visible regions
2198 * in parent client coordinates */
Alexandre Julliardcdcdede1996-04-21 14:57:41 +00002199
Alex Korobka4f1ac051999-03-28 09:37:57 +00002200 OffsetRgn( newVisRgn, Wnd->rectWindow.left, Wnd->rectWindow.top );
2201 OffsetRgn( *pVisRgn, lpOldWndRect->left, lpOldWndRect->top );
Alexandre Julliardcdcdede1996-04-21 14:57:41 +00002202
Alex Korobka4f1ac051999-03-28 09:37:57 +00002203 CombineRgn(*pVisRgn, *pVisRgn, newVisRgn, RGN_OR );
2204 }
2205 else /* copy valid bits to a new location */
2206 {
2207 INT dx, dy, ow, oh, nw, nh, ocw, ncw, och, nch;
2208 HRGN hrgnValid = dirtyRgn; /* non-empty intersection of old and new visible rgns */
Alexandre Julliardcdcdede1996-04-21 14:57:41 +00002209
Alex Korobka4f1ac051999-03-28 09:37:57 +00002210 /* subtract already invalid region inside Wnd from the dst region */
Alexandre Julliardcdcdede1996-04-21 14:57:41 +00002211
Alex Korobka4f1ac051999-03-28 09:37:57 +00002212 if( Wnd->hrgnUpdate )
2213 if( CombineRgn( hrgnValid, hrgnValid, Wnd->hrgnUpdate, RGN_DIFF) == NULLREGION )
2214 goto nocopy;
Alexandre Julliardcdcdede1996-04-21 14:57:41 +00002215
Alex Korobka4f1ac051999-03-28 09:37:57 +00002216 /* check if entire window can be copied */
Alexandre Julliardcdcdede1996-04-21 14:57:41 +00002217
Alex Korobka4f1ac051999-03-28 09:37:57 +00002218 ow = lpOldWndRect->right - lpOldWndRect->left;
2219 oh = lpOldWndRect->bottom - lpOldWndRect->top;
2220 nw = Wnd->rectWindow.right - Wnd->rectWindow.left;
2221 nh = Wnd->rectWindow.bottom - Wnd->rectWindow.top;
Alexandre Julliardcdcdede1996-04-21 14:57:41 +00002222
Alex Korobka4f1ac051999-03-28 09:37:57 +00002223 ocw = lpOldClientRect->right - lpOldClientRect->left;
2224 och = lpOldClientRect->bottom - lpOldClientRect->top;
2225 ncw = Wnd->rectClient.right - Wnd->rectClient.left;
2226 nch = Wnd->rectClient.bottom - Wnd->rectClient.top;
2227
2228 if( (ocw != ncw) || (och != nch) ||
Alex Korobka98447491999-05-08 17:57:09 +00002229 ( ow != nw) || ( oh != nh) ||
Alex Korobka4f1ac051999-03-28 09:37:57 +00002230 ((lpOldClientRect->top - lpOldWndRect->top) !=
2231 (Wnd->rectClient.top - Wnd->rectWindow.top)) ||
2232 ((lpOldClientRect->left - lpOldWndRect->left) !=
2233 (Wnd->rectClient.left - Wnd->rectWindow.left)) )
2234 {
2235 dx = Wnd->rectClient.left - lpOldClientRect->left;
2236 dy = Wnd->rectClient.top - lpOldClientRect->top;
2237
2238 /* restrict valid bits to the common client rect */
2239
2240 r.left = Wnd->rectClient.left - Wnd->rectWindow.left;
2241 r.top = Wnd->rectClient.top - Wnd->rectWindow.top;
2242 r.right = r.left + MIN( ocw, ncw );
2243 r.bottom = r.top + MIN( och, nch );
2244
2245 REGION_CropRgn( hrgnValid, hrgnValid, &r,
2246 (uFlags & SWP_EX_PAINTSELF) ? NULL : (POINT*)&(Wnd->rectWindow));
2247 GetRgnBox( hrgnValid, &r );
2248 if( IsRectEmpty( &r ) )
2249 goto nocopy;
2250 r = *lpOldClientRect;
2251 }
Alexandre Julliard1e37a181996-08-18 16:21:52 +00002252 else
Alex Korobka4f1ac051999-03-28 09:37:57 +00002253 {
2254 dx = Wnd->rectWindow.left - lpOldWndRect->left;
2255 dy = Wnd->rectWindow.top - lpOldWndRect->top;
2256 if( !(uFlags & SWP_EX_PAINTSELF) )
2257 OffsetRgn( hrgnValid, Wnd->rectWindow.left, Wnd->rectWindow.top );
2258 r = *lpOldWndRect;
2259 }
Alexandre Julliardcdcdede1996-04-21 14:57:41 +00002260
Alex Korobka4f1ac051999-03-28 09:37:57 +00002261 if( !(uFlags & SWP_EX_PAINTSELF) )
2262 {
2263 /* Move remaining regions to parent coordinates */
2264 OffsetRgn( newVisRgn, Wnd->rectWindow.left, Wnd->rectWindow.top );
2265 OffsetRgn( *pVisRgn, lpOldWndRect->left, lpOldWndRect->top );
2266 }
2267 else
2268 OffsetRect( &r, -lpOldWndRect->left, -lpOldWndRect->top );
Alexandre Julliardcdcdede1996-04-21 14:57:41 +00002269
Alexandre Julliard359f497e1999-07-04 16:02:24 +00002270 TRACE("\tcomputing dirty region!\n");
Alexandre Julliardcdcdede1996-04-21 14:57:41 +00002271
Alex Korobka4f1ac051999-03-28 09:37:57 +00002272 /* Compute combined dirty region (old + new - valid) */
2273 CombineRgn( *pVisRgn, *pVisRgn, newVisRgn, RGN_OR);
2274 CombineRgn( *pVisRgn, *pVisRgn, hrgnValid, RGN_DIFF);
Alexandre Julliardcdcdede1996-04-21 14:57:41 +00002275
Alex Korobka4f1ac051999-03-28 09:37:57 +00002276 /* Blt valid bits, r is the rect to copy */
Alexandre Julliardcdcdede1996-04-21 14:57:41 +00002277
Alex Korobka4f1ac051999-03-28 09:37:57 +00002278 if( dx || dy )
2279 {
Alex Korobka98447491999-05-08 17:57:09 +00002280 RECT rClip;
2281 HDC hDC;
Alex Korobka4f1ac051999-03-28 09:37:57 +00002282 DC* dc;
Alex Korobka98447491999-05-08 17:57:09 +00002283
2284 /* get DC and clip rect with drawable rect to avoid superfluous expose events
2285 from copying clipped areas */
2286
2287 if( uFlags & SWP_EX_PAINTSELF )
2288 {
2289 hDC = GetDCEx( Wnd->hwndSelf, hrgnValid, DCX_WINDOW | DCX_CACHE |
2290 DCX_KEEPCLIPRGN | DCX_INTERSECTRGN | DCX_CLIPSIBLINGS );
2291 rClip.right = nw; rClip.bottom = nh;
2292 }
2293 else
2294 {
2295 hDC = GetDCEx( Wnd->parent->hwndSelf, hrgnValid, DCX_CACHE |
2296 DCX_KEEPCLIPRGN | DCX_INTERSECTRGN | DCX_CLIPSIBLINGS );
2297 rClip.right = Wnd->parent->rectClient.right - Wnd->parent->rectClient.left;
2298 rClip.bottom = Wnd->parent->rectClient.bottom - Wnd->parent->rectClient.top;
2299 }
2300 rClip.left = rClip.top = 0;
2301
Alex Korobka4f1ac051999-03-28 09:37:57 +00002302 if( (dc = (DC *)GDI_GetObjPtr(hDC, DC_MAGIC)) )
2303 {
2304 if( oh > nh ) r.bottom = r.top + nh;
2305 if( ow < nw ) r.right = r.left + nw;
Alexandre Julliardcdcdede1996-04-21 14:57:41 +00002306
Alex Korobka98447491999-05-08 17:57:09 +00002307 if( IntersectRect( &r, &r, &rClip ) )
Abey George8beefb51999-07-18 15:40:03 +00002308 {
Alex Korobka98447491999-05-08 17:57:09 +00002309 Wnd->pDriver->pSurfaceCopy( Wnd->parent, dc, dx, dy, &r, TRUE );
Alexandre Julliardcdcdede1996-04-21 14:57:41 +00002310
Abey George8beefb51999-07-18 15:40:03 +00002311 /* When you copy the bits without repainting, parent doesn't
2312 get validated appropriately. Therefore, we have to validate
2313 the parent with the windows' updated region when the
2314 parent's update region is not empty. */
2315
2316 if (Wnd->parent->hrgnUpdate != 0 && !(Wnd->parent->dwStyle & WS_CLIPCHILDREN))
2317 {
2318 OffsetRect(&r, dx, dy);
2319 ValidateRect(Wnd->parent->hwndSelf, &r);
2320 }
2321 }
2322
Alex Korobka4f1ac051999-03-28 09:37:57 +00002323 GDI_HEAP_UNLOCK( hDC );
2324 }
2325 ReleaseDC( (uFlags & SWP_EX_PAINTSELF) ?
2326 Wnd->hwndSelf : Wnd->parent->hwndSelf, hDC);
2327 }
2328 }
Alexandre Julliardcdcdede1996-04-21 14:57:41 +00002329
Alex Korobka4f1ac051999-03-28 09:37:57 +00002330 /* *pVisRgn now points to the invalidated region */
Alexandre Julliardcdcdede1996-04-21 14:57:41 +00002331
Alexandre Julliarda3960291999-02-26 11:11:13 +00002332 DeleteObject(newVisRgn);
Alex Korobka4f1ac051999-03-28 09:37:57 +00002333 DeleteObject(dirtyRgn);
Alexandre Julliard1e37a181996-08-18 16:21:52 +00002334 return uFlags;
Alexandre Julliardcdcdede1996-04-21 14:57:41 +00002335}
Alexandre Julliardaca05781994-10-17 18:12:41 +00002336
Alexandre Julliard22945d51995-03-02 17:44:29 +00002337/***********************************************************************
Alex Korobka4f1ac051999-03-28 09:37:57 +00002338 * SWP_DoSimpleFrameChanged
Alex Korobka44a1b591999-04-01 12:03:52 +00002339 *
2340 * NOTE: old and new client rect origins are identical, only
2341 * extents may have changed. Window extents are the same.
Alex Korobka4f1ac051999-03-28 09:37:57 +00002342 */
Alex Korobka44a1b591999-04-01 12:03:52 +00002343static void SWP_DoSimpleFrameChanged( WND* wndPtr, RECT* pOldClientRect, WORD swpFlags, UINT uFlags )
Alex Korobka4f1ac051999-03-28 09:37:57 +00002344{
Alex Korobka44a1b591999-04-01 12:03:52 +00002345 INT i = 0;
Alex Korobka4f1ac051999-03-28 09:37:57 +00002346 RECT rect;
Alex Korobka44a1b591999-04-01 12:03:52 +00002347 HRGN hrgn = 0;
Alex Korobka4f1ac051999-03-28 09:37:57 +00002348
Alex Korobka44a1b591999-04-01 12:03:52 +00002349 if( !(swpFlags & SWP_NOCLIENTSIZE) )
Alex Korobka4f1ac051999-03-28 09:37:57 +00002350 {
Alex Korobka98447491999-05-08 17:57:09 +00002351 /* Client rect changed its position/size, most likely a scrollar
2352 * was added/removed.
2353 *
2354 * FIXME: WVR alignment flags
2355 */
Alex Korobka44a1b591999-04-01 12:03:52 +00002356
2357 if( wndPtr->rectClient.right > pOldClientRect->right ) /* right edge */
2358 {
2359 i++;
2360 rect.top = 0;
2361 rect.bottom = wndPtr->rectClient.bottom - wndPtr->rectClient.top;
2362 rect.right = wndPtr->rectClient.right - wndPtr->rectClient.left;
2363 if(!(uFlags & SWP_EX_NOCOPY))
2364 rect.left = pOldClientRect->right - wndPtr->rectClient.left;
2365 else
2366 {
2367 rect.left = 0;
2368 goto redraw;
2369 }
2370 }
2371
2372 if( wndPtr->rectClient.bottom > pOldClientRect->bottom ) /* bottom edge */
2373 {
2374 if( i )
2375 hrgn = CreateRectRgnIndirect( &rect );
2376 rect.left = 0;
2377 rect.right = wndPtr->rectClient.right - wndPtr->rectClient.left;
2378 rect.bottom = wndPtr->rectClient.bottom - wndPtr->rectClient.top;
2379 if(!(uFlags & SWP_EX_NOCOPY))
2380 rect.top = pOldClientRect->bottom - wndPtr->rectClient.top;
2381 else
2382 rect.top = 0;
2383 if( i++ )
2384 REGION_UnionRectWithRgn( hrgn, &rect );
2385 }
2386
2387 if( i == 0 && (uFlags & SWP_EX_NOCOPY) ) /* force redraw anyway */
2388 {
2389 rect = wndPtr->rectWindow;
2390 OffsetRect( &rect, wndPtr->rectWindow.left - wndPtr->rectClient.left,
2391 wndPtr->rectWindow.top - wndPtr->rectClient.top );
2392 i++;
2393 }
2394 }
2395
2396 if( i )
2397 {
2398redraw:
2399 PAINT_RedrawWindow( wndPtr->hwndSelf, &rect, hrgn, RDW_INVALIDATE | RDW_FRAME | RDW_ERASE |
2400 RDW_ERASENOW | RDW_ALLCHILDREN, RDW_EX_TOPFRAME | RDW_EX_USEHRGN );
2401 }
2402 else
Alex Korobka98447491999-05-08 17:57:09 +00002403 {
2404 WIN_UpdateNCRgn(wndPtr, 0, UNC_UPDATE | UNC_ENTIRE);
2405 }
Alex Korobka44a1b591999-04-01 12:03:52 +00002406
2407 if( hrgn > 1 )
2408 DeleteObject( hrgn );
Alex Korobka4f1ac051999-03-28 09:37:57 +00002409}
2410
2411/***********************************************************************
2412 * SWP_DoWinPosChanging
2413 */
2414static BOOL SWP_DoWinPosChanging( WND* wndPtr, WINDOWPOS* pWinpos,
2415 RECT* pNewWindowRect, RECT* pNewClientRect )
2416{
2417 /* Send WM_WINDOWPOSCHANGING message */
2418
2419 if (!(pWinpos->flags & SWP_NOSENDCHANGING))
2420 SendMessageA( wndPtr->hwndSelf, WM_WINDOWPOSCHANGING, 0, (LPARAM)pWinpos );
2421
2422 /* Calculate new position and size */
2423
2424 *pNewWindowRect = wndPtr->rectWindow;
2425 *pNewClientRect = (wndPtr->dwStyle & WS_MINIMIZE) ? wndPtr->rectWindow
2426 : wndPtr->rectClient;
2427
2428 if (!(pWinpos->flags & SWP_NOSIZE))
2429 {
2430 pNewWindowRect->right = pNewWindowRect->left + pWinpos->cx;
2431 pNewWindowRect->bottom = pNewWindowRect->top + pWinpos->cy;
2432 }
2433 if (!(pWinpos->flags & SWP_NOMOVE))
2434 {
2435 pNewWindowRect->left = pWinpos->x;
2436 pNewWindowRect->top = pWinpos->y;
2437 pNewWindowRect->right += pWinpos->x - wndPtr->rectWindow.left;
2438 pNewWindowRect->bottom += pWinpos->y - wndPtr->rectWindow.top;
2439
2440 OffsetRect( pNewClientRect, pWinpos->x - wndPtr->rectWindow.left,
2441 pWinpos->y - wndPtr->rectWindow.top );
2442 }
2443
2444 pWinpos->flags |= SWP_NOCLIENTMOVE | SWP_NOCLIENTSIZE;
2445 return TRUE;
2446}
2447
2448/***********************************************************************
2449 * SWP_DoNCCalcSize
2450 */
2451static UINT SWP_DoNCCalcSize( WND* wndPtr, WINDOWPOS* pWinpos,
2452 RECT* pNewWindowRect, RECT* pNewClientRect, WORD f)
2453{
2454 UINT wvrFlags = 0;
2455
2456 /* Send WM_NCCALCSIZE message to get new client area */
2457 if( (pWinpos->flags & (SWP_FRAMECHANGED | SWP_NOSIZE)) != SWP_NOSIZE )
2458 {
2459 wvrFlags = WINPOS_SendNCCalcSize( pWinpos->hwnd, TRUE, pNewWindowRect,
2460 &wndPtr->rectWindow, &wndPtr->rectClient,
2461 pWinpos, pNewClientRect );
2462
2463 /* FIXME: WVR_ALIGNxxx */
2464
2465 if( pNewClientRect->left != wndPtr->rectClient.left ||
2466 pNewClientRect->top != wndPtr->rectClient.top )
2467 pWinpos->flags &= ~SWP_NOCLIENTMOVE;
2468
2469 if( (pNewClientRect->right - pNewClientRect->left !=
2470 wndPtr->rectClient.right - wndPtr->rectClient.left) ||
2471 (pNewClientRect->bottom - pNewClientRect->top !=
2472 wndPtr->rectClient.bottom - wndPtr->rectClient.top) )
2473 pWinpos->flags &= ~SWP_NOCLIENTSIZE;
2474 }
2475 else
2476 if( !(f & SWP_NOMOVE) && (pNewClientRect->left != wndPtr->rectClient.left ||
2477 pNewClientRect->top != wndPtr->rectClient.top) )
2478 pWinpos->flags &= ~SWP_NOCLIENTMOVE;
2479 return wvrFlags;
2480}
2481
2482/***********************************************************************
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002483 * SetWindowPos (USER.2)
Alexandre Julliard2d159fb1994-07-15 16:04:31 +00002484 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00002485BOOL16 WINAPI SetWindowPos16( HWND16 hwnd, HWND16 hwndInsertAfter,
2486 INT16 x, INT16 y, INT16 cx, INT16 cy, WORD flags)
Alexandre Julliard01d63461997-01-20 19:43:45 +00002487{
Alexandre Julliarda3960291999-02-26 11:11:13 +00002488 return SetWindowPos(hwnd,(INT)(INT16)hwndInsertAfter,x,y,cx,cy,flags);
Alexandre Julliard01d63461997-01-20 19:43:45 +00002489}
2490
2491/***********************************************************************
Alexandre Julliardc7c217b1998-04-13 12:21:30 +00002492 * SetWindowPos (USER32.520)
Alexandre Julliard01d63461997-01-20 19:43:45 +00002493 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002494BOOL WINAPI SetWindowPos( HWND hwnd, HWND hwndInsertAfter,
Ulrich Weigand7f53c571999-06-18 17:03:13 +00002495 INT x, INT y, INT cx, INT cy, UINT flags )
Alexandre Julliard2d159fb1994-07-15 16:04:31 +00002496{
Alex Korobka4f1ac051999-03-28 09:37:57 +00002497 WINDOWPOS winpos;
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002498 WND * wndPtr,*wndTemp;
Alex Korobka4f1ac051999-03-28 09:37:57 +00002499 RECT newWindowRect, newClientRect;
2500 RECT oldWindowRect, oldClientRect;
Alexandre Julliarda3960291999-02-26 11:11:13 +00002501 HRGN visRgn = 0;
Alex Korobka4f1ac051999-03-28 09:37:57 +00002502 UINT wvrFlags = 0, uFlags = 0;
Ulrich Weigand7f53c571999-06-18 17:03:13 +00002503 BOOL retvalue, resync = FALSE, bChangePos;
Alex Korobka4f1ac051999-03-28 09:37:57 +00002504 HWND hwndActive = 0;
Noel Borthwickb4278561999-02-05 10:37:53 +00002505
2506 /* Get current active window from the active queue */
2507 if ( hActiveQueue )
2508 {
2509 MESSAGEQUEUE *pActiveQueue = QUEUE_Lock( hActiveQueue );
2510 if ( pActiveQueue )
2511 {
2512 hwndActive = PERQDATA_GetActiveWnd( pActiveQueue->pQData );
2513 QUEUE_Unlock( pActiveQueue );
2514 }
2515 }
Alexandre Julliardcdcdede1996-04-21 14:57:41 +00002516
Alexandre Julliard359f497e1999-07-04 16:02:24 +00002517 TRACE("hwnd %04x, swp (%i,%i)-(%i,%i) flags %08x\n",
Alexandre Julliard18f92e71996-07-17 20:02:21 +00002518 hwnd, x, y, x+cx, y+cy, flags);
Alex Korobka4f1ac051999-03-28 09:37:57 +00002519
Ulrich Weigand7f53c571999-06-18 17:03:13 +00002520 bChangePos = !(flags & SWP_WINE_NOHOSTMOVE);
2521 flags &= ~SWP_WINE_NOHOSTMOVE;
2522
2523
Alex Korobka4f1ac051999-03-28 09:37:57 +00002524 /* ------------------------------------------------------------------------ CHECKS */
2525
Alexandre Julliard2d159fb1994-07-15 16:04:31 +00002526 /* Check window handle */
2527
Alexandre Julliarda3960291999-02-26 11:11:13 +00002528 if (hwnd == GetDesktopWindow()) return FALSE;
Alexandre Julliarde2abbb11995-03-19 17:39:39 +00002529 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return FALSE;
Alexandre Julliard2d159fb1994-07-15 16:04:31 +00002530
Alexandre Julliard359f497e1999-07-04 16:02:24 +00002531 TRACE("\tcurrent (%i,%i)-(%i,%i), style %08x\n", wndPtr->rectWindow.left, wndPtr->rectWindow.top,
Alex Korobka4f1ac051999-03-28 09:37:57 +00002532 wndPtr->rectWindow.right, wndPtr->rectWindow.bottom, (unsigned)wndPtr->dwStyle );
2533
2534 /* Fix redundant flags */
2535
Alexandre Julliard491502b1997-11-01 19:08:16 +00002536 if(wndPtr->dwStyle & WS_VISIBLE)
Alexandre Julliarde658d821997-11-30 17:45:40 +00002537 flags &= ~SWP_SHOWWINDOW;
Alexandre Julliard18f92e71996-07-17 20:02:21 +00002538 else
2539 {
Alex Korobka4f1ac051999-03-28 09:37:57 +00002540 if (!(flags & SWP_SHOWWINDOW))
2541 flags |= SWP_NOREDRAW;
Alexandre Julliard18f92e71996-07-17 20:02:21 +00002542 flags &= ~SWP_HIDEWINDOW;
Alexandre Julliard18f92e71996-07-17 20:02:21 +00002543 }
2544
Alex Korobka4f1ac051999-03-28 09:37:57 +00002545 if ( cx < 0 ) cx = 0; if( cy < 0 ) cy = 0;
Alexandre Julliard2d159fb1994-07-15 16:04:31 +00002546
Alexandre Julliarde2abbb11995-03-19 17:39:39 +00002547 if ((wndPtr->rectWindow.right - wndPtr->rectWindow.left == cx) &&
2548 (wndPtr->rectWindow.bottom - wndPtr->rectWindow.top == cy))
2549 flags |= SWP_NOSIZE; /* Already the right size */
Alex Korobka4f1ac051999-03-28 09:37:57 +00002550
Alexandre Julliarde2abbb11995-03-19 17:39:39 +00002551 if ((wndPtr->rectWindow.left == x) && (wndPtr->rectWindow.top == y))
2552 flags |= SWP_NOMOVE; /* Already the right position */
Alexandre Julliard2d159fb1994-07-15 16:04:31 +00002553
Alex Korobka4f1ac051999-03-28 09:37:57 +00002554 if (hwnd == hwndActive)
2555 flags |= SWP_NOACTIVATE; /* Already active */
Ulrich Weigandc7582011999-05-22 18:54:41 +00002556 else if ( (wndPtr->dwStyle & (WS_POPUP | WS_CHILD)) != WS_CHILD )
Alex Korobka4f1ac051999-03-28 09:37:57 +00002557 {
2558 if(!(flags & SWP_NOACTIVATE)) /* Bring to the top when activating */
2559 {
2560 flags &= ~SWP_NOZORDER;
2561 hwndInsertAfter = HWND_TOP;
2562 goto Pos;
2563 }
2564 }
2565
Alexandre Julliarde2abbb11995-03-19 17:39:39 +00002566 /* Check hwndInsertAfter */
Alexandre Julliard2d159fb1994-07-15 16:04:31 +00002567
Alex Korobka4f1ac051999-03-28 09:37:57 +00002568 /* FIXME: TOPMOST not supported yet */
Alexandre Julliarde2abbb11995-03-19 17:39:39 +00002569 if ((hwndInsertAfter == HWND_TOPMOST) ||
2570 (hwndInsertAfter == HWND_NOTOPMOST)) hwndInsertAfter = HWND_TOP;
Alexandre Julliardcdcdede1996-04-21 14:57:41 +00002571
Alexandre Julliarde2abbb11995-03-19 17:39:39 +00002572 /* hwndInsertAfter must be a sibling of the window */
Alexandre Julliardcdcdede1996-04-21 14:57:41 +00002573 if ((hwndInsertAfter != HWND_TOP) && (hwndInsertAfter != HWND_BOTTOM))
Alex Korobka4f1ac051999-03-28 09:37:57 +00002574 {
Alexandre Julliardcdcdede1996-04-21 14:57:41 +00002575 WND* wnd = WIN_FindWndPtr(hwndInsertAfter);
Alexandre Julliard642d3131998-07-12 19:29:36 +00002576
Huw D M Davies1b450201999-01-31 09:17:38 +00002577 if( wnd ) {
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002578 if( wnd->parent != wndPtr->parent )
2579 {
2580 retvalue = FALSE;
2581 WIN_ReleaseWndPtr(wnd);
2582 goto END;
2583 }
Alexandre Julliard642d3131998-07-12 19:29:36 +00002584 if( wnd->next == wndPtr ) flags |= SWP_NOZORDER;
2585 }
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002586 WIN_ReleaseWndPtr(wnd);
Jesper Skov5c3e4571998-11-01 19:27:22 +00002587 }
Alexandre Julliarde2abbb11995-03-19 17:39:39 +00002588
Alex Korobka4f1ac051999-03-28 09:37:57 +00002589Pos: /* ------------------------------------------------------------------------ MAIN part */
2590
Alexandre Julliard2787be81995-05-22 18:23:01 +00002591 /* Fill the WINDOWPOS structure */
Alexandre Julliarde2abbb11995-03-19 17:39:39 +00002592
Alexandre Julliardd37eb361997-07-20 16:23:21 +00002593 winpos.hwnd = hwnd;
2594 winpos.hwndInsertAfter = hwndInsertAfter;
2595 winpos.x = x;
2596 winpos.y = y;
2597 winpos.cx = cx;
2598 winpos.cy = cy;
2599 winpos.flags = flags;
Alexandre Julliarde2abbb11995-03-19 17:39:39 +00002600
Alex Korobka4f1ac051999-03-28 09:37:57 +00002601 SWP_DoWinPosChanging( wndPtr, &winpos, &newWindowRect, &newClientRect );
Alexandre Julliarde2abbb11995-03-19 17:39:39 +00002602
Alex Korobka4f1ac051999-03-28 09:37:57 +00002603 if((winpos.flags & (SWP_NOZORDER | SWP_HIDEWINDOW | SWP_SHOWWINDOW)) != SWP_NOZORDER)
Alexandre Julliard2d159fb1994-07-15 16:04:31 +00002604 {
Alexandre Julliardc981d0b1996-03-31 16:40:13 +00002605 if( wndPtr->parent == WIN_GetDesktop() )
Alex Korobka4f1ac051999-03-28 09:37:57 +00002606 hwndInsertAfter = SWP_DoOwnedPopups( wndPtr->parent, wndPtr,
2607 hwndInsertAfter, winpos.flags );
2608 WIN_ReleaseDesktop();
Alexandre Julliard2d159fb1994-07-15 16:04:31 +00002609 }
2610
Alex Korobka4f1ac051999-03-28 09:37:57 +00002611 if(!(wndPtr->flags & WIN_NATIVE) )
Alexandre Julliard491502b1997-11-01 19:08:16 +00002612 {
Alex Korobka4f1ac051999-03-28 09:37:57 +00002613 if( hwndInsertAfter == HWND_TOP )
2614 winpos.flags |= ( wndPtr->parent->child == wndPtr)? SWP_NOZORDER: 0;
2615 else
2616 if( hwndInsertAfter == HWND_BOTTOM )
2617 winpos.flags |= ( wndPtr->next )? 0: SWP_NOZORDER;
2618 else
2619 if( !(winpos.flags & SWP_NOZORDER) )
2620 if( GetWindow(hwndInsertAfter, GW_HWNDNEXT) == wndPtr->hwndSelf )
2621 winpos.flags |= SWP_NOZORDER;
Alexandre Julliardcdcdede1996-04-21 14:57:41 +00002622
Alex Korobka98447491999-05-08 17:57:09 +00002623 if( !(winpos.flags & (SWP_NOREDRAW | SWP_SHOWWINDOW)) &&
Alex Korobka4f1ac051999-03-28 09:37:57 +00002624 ((winpos.flags & (SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_HIDEWINDOW | SWP_FRAMECHANGED))
2625 != (SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER)) )
2626 {
2627 /* get a previous visible region for SWP_CopyValidBits() */
Thuy Nguyenf18e7c31999-07-27 17:03:16 +00002628 DWORD flags = DCX_WINDOW;
2629
2630 if (wndPtr->dwStyle & WS_CLIPSIBLINGS)
2631 flags |= DCX_CLIPSIBLINGS;
Alexandre Julliardcdcdede1996-04-21 14:57:41 +00002632
Thuy Nguyenf18e7c31999-07-27 17:03:16 +00002633 visRgn = DCE_GetVisRgn(hwnd, flags, 0, 0);
Alex Korobka4f1ac051999-03-28 09:37:57 +00002634 }
Alexandre Julliard491502b1997-11-01 19:08:16 +00002635 }
Alexandre Julliard2d159fb1994-07-15 16:04:31 +00002636
Alex Korobka4f1ac051999-03-28 09:37:57 +00002637 /* Common operations */
2638
Alex Korobka44a1b591999-04-01 12:03:52 +00002639 wvrFlags = SWP_DoNCCalcSize( wndPtr, &winpos, &newWindowRect, &newClientRect, flags );
Alex Korobka4f1ac051999-03-28 09:37:57 +00002640
Rein Klazesd38f6002000-01-08 22:22:28 +00002641 if(!(winpos.flags & SWP_NOZORDER) && winpos.hwnd != hwndInsertAfter)
Alex Korobka4f1ac051999-03-28 09:37:57 +00002642 {
Eric Pouech6cf348d1999-05-22 19:20:02 +00002643 if ( WIN_UnlinkWindow( winpos.hwnd ) )
2644 WIN_LinkWindow( winpos.hwnd, hwndInsertAfter );
Alex Korobka4f1ac051999-03-28 09:37:57 +00002645 }
2646
2647 /* Reset active DCEs */
Alexandre Julliard1e9ac791996-06-06 18:38:27 +00002648
Alexandre Julliard491502b1997-11-01 19:08:16 +00002649 if( (((winpos.flags & SWP_AGG_NOPOSCHANGE) != SWP_AGG_NOPOSCHANGE) &&
2650 wndPtr->dwStyle & WS_VISIBLE) ||
2651 (flags & (SWP_HIDEWINDOW | SWP_SHOWWINDOW)) )
2652 {
Alexandre Julliarda3960291999-02-26 11:11:13 +00002653 RECT rect;
Alexandre Julliard1e9ac791996-06-06 18:38:27 +00002654
Alexandre Julliarda3960291999-02-26 11:11:13 +00002655 UnionRect(&rect, &newWindowRect, &wndPtr->rectWindow);
Alexandre Julliard60ce85c1998-02-01 18:33:27 +00002656 DCE_InvalidateDCE(wndPtr, &rect);
Alexandre Julliard491502b1997-11-01 19:08:16 +00002657 }
Alexandre Julliard1e9ac791996-06-06 18:38:27 +00002658
Alexandre Julliard1e37a181996-08-18 16:21:52 +00002659 oldWindowRect = wndPtr->rectWindow;
Alex Korobka4f1ac051999-03-28 09:37:57 +00002660 oldClientRect = wndPtr->rectClient;
Alexandre Julliard2d159fb1994-07-15 16:04:31 +00002661
Alex Korobka44a1b591999-04-01 12:03:52 +00002662 /* Find out if we have to redraw the whole client rect */
2663
2664 if( oldClientRect.bottom - oldClientRect.top ==
2665 newClientRect.bottom - newClientRect.top ) wvrFlags &= ~WVR_VREDRAW;
2666
2667 if( oldClientRect.right - oldClientRect.left ==
2668 newClientRect.right - newClientRect.left ) wvrFlags &= ~WVR_HREDRAW;
2669
Alex Korobka98447491999-05-08 17:57:09 +00002670 if( (winpos.flags & SWP_NOCOPYBITS) || (!(winpos.flags & SWP_NOCLIENTSIZE) &&
2671 (wvrFlags >= WVR_HREDRAW) && (wvrFlags < WVR_VALIDRECTS)) )
2672 {
2673 uFlags |= SWP_EX_NOCOPY;
2674 }
2675/*
2676 * Use this later in CopyValidBits()
2677 *
2678 else if( 0 )
2679 uFlags |= SWP_EX_NONCLIENT;
2680 */
Alex Korobka44a1b591999-04-01 12:03:52 +00002681
2682 /* FIXME: actually do something with WVR_VALIDRECTS */
2683
2684 wndPtr->rectWindow = newWindowRect;
2685 wndPtr->rectClient = newClientRect;
2686
Alex Korobka4f1ac051999-03-28 09:37:57 +00002687 if (wndPtr->flags & WIN_NATIVE) /* -------------------------------------------- hosted window */
Alexandre Julliardaca05781994-10-17 18:12:41 +00002688 {
Alex Korobka4f1ac051999-03-28 09:37:57 +00002689 BOOL bCallDriver = TRUE;
2690 HWND tempInsertAfter = winpos.hwndInsertAfter;
Alexandre Julliardc981d0b1996-03-31 16:40:13 +00002691
Alexandre Julliardd37eb361997-07-20 16:23:21 +00002692 winpos.hwndInsertAfter = hwndInsertAfter;
Alexandre Julliard1e37a181996-08-18 16:21:52 +00002693
Alex Korobka4f1ac051999-03-28 09:37:57 +00002694 if( !(winpos.flags & (SWP_SHOWWINDOW | SWP_HIDEWINDOW | SWP_NOREDRAW)) )
Jesper Skov5c3e4571998-11-01 19:27:22 +00002695 {
Alex Korobka4f1ac051999-03-28 09:37:57 +00002696 /* This is the only place where we need to force repainting of the contents
2697 of windows created by the host window system, all other cases go through the
2698 expose event handling */
2699
Alex Korobka98447491999-05-08 17:57:09 +00002700 if( (winpos.flags & (SWP_NOSIZE | SWP_FRAMECHANGED)) == (SWP_NOSIZE | SWP_FRAMECHANGED) )
Alex Korobka4f1ac051999-03-28 09:37:57 +00002701 {
Alex Korobka98447491999-05-08 17:57:09 +00002702 cx = newWindowRect.right - newWindowRect.left;
2703 cy = newWindowRect.bottom - newWindowRect.top;
Alex Korobka4f1ac051999-03-28 09:37:57 +00002704
Ulrich Weigand7f53c571999-06-18 17:03:13 +00002705 wndPtr->pDriver->pSetWindowPos(wndPtr, &winpos, bChangePos);
Alex Korobka98447491999-05-08 17:57:09 +00002706 winpos.hwndInsertAfter = tempInsertAfter;
2707 bCallDriver = FALSE;
2708
2709 if( winpos.flags & SWP_NOCLIENTMOVE )
2710 SWP_DoSimpleFrameChanged(wndPtr, &oldClientRect, winpos.flags, uFlags );
2711 else
Alex Korobka4f1ac051999-03-28 09:37:57 +00002712 {
Alex Korobka98447491999-05-08 17:57:09 +00002713 /* client area moved but window extents remained the same, copy valid bits */
Alex Korobka4f1ac051999-03-28 09:37:57 +00002714
Alex Korobka98447491999-05-08 17:57:09 +00002715 visRgn = CreateRectRgn( 0, 0, cx, cy );
2716 uFlags = SWP_CopyValidBits( wndPtr, &visRgn, &oldWindowRect, &oldClientRect,
2717 uFlags | SWP_EX_PAINTSELF );
Alex Korobka4f1ac051999-03-28 09:37:57 +00002718 }
2719 }
2720 }
2721
2722 if( bCallDriver )
2723 {
Alex Korobka98447491999-05-08 17:57:09 +00002724 if( !(winpos.flags & (SWP_SHOWWINDOW | SWP_HIDEWINDOW | SWP_NOREDRAW)) )
Alex Korobka4f1ac051999-03-28 09:37:57 +00002725 {
Alex Korobka98447491999-05-08 17:57:09 +00002726 if( (oldClientRect.left - oldWindowRect.left == newClientRect.left - newWindowRect.left) &&
2727 (oldClientRect.top - oldWindowRect.top == newClientRect.top - newWindowRect.top) &&
2728 !(uFlags & SWP_EX_NOCOPY) )
Alex Korobka4f1ac051999-03-28 09:37:57 +00002729 {
Alex Korobka98447491999-05-08 17:57:09 +00002730 /* The origin of the client rect didn't move so we can try to repaint
2731 * only the nonclient area by setting bit gravity hint for the host window system.
2732 */
Alexandre Julliardcdcdede1996-04-21 14:57:41 +00002733
Alex Korobka98447491999-05-08 17:57:09 +00002734 if( !(wndPtr->flags & WIN_MANAGED) )
2735 {
2736 HRGN hrgn = CreateRectRgn( 0, 0, newWindowRect.right - newWindowRect.left,
2737 newWindowRect.bottom - newWindowRect.top);
2738 RECT rcn = newClientRect;
2739 RECT rco = oldClientRect;
2740
2741 OffsetRect( &rcn, -newWindowRect.left, -newWindowRect.top );
2742 OffsetRect( &rco, -oldWindowRect.left, -oldWindowRect.top );
2743 IntersectRect( &rcn, &rcn, &rco );
2744 visRgn = CreateRectRgnIndirect( &rcn );
2745 CombineRgn( visRgn, hrgn, visRgn, RGN_DIFF );
2746 DeleteObject( hrgn );
2747 uFlags = SWP_EX_PAINTSELF;
2748 }
2749 wndPtr->pDriver->pSetHostAttr(wndPtr, HAK_BITGRAVITY, BGNorthWest );
2750 }
2751 else
2752 wndPtr->pDriver->pSetHostAttr(wndPtr, HAK_BITGRAVITY, BGForget );
Alex Korobka4f1ac051999-03-28 09:37:57 +00002753 }
Alex Korobka98447491999-05-08 17:57:09 +00002754
Ulrich Weigand7f53c571999-06-18 17:03:13 +00002755 wndPtr->pDriver->pSetWindowPos(wndPtr, &winpos, bChangePos);
Alex Korobka98447491999-05-08 17:57:09 +00002756 winpos.hwndInsertAfter = tempInsertAfter;
Alex Korobka4f1ac051999-03-28 09:37:57 +00002757 }
Alexandre Julliardcdcdede1996-04-21 14:57:41 +00002758
Alex Korobka4f1ac051999-03-28 09:37:57 +00002759 if( winpos.flags & SWP_SHOWWINDOW )
2760 {
2761 HWND focus, curr;
2762
2763 wndPtr->dwStyle |= WS_VISIBLE;
2764
2765 if (wndPtr->flags & WIN_MANAGED) resync = TRUE;
2766
2767 /* focus was set to unmapped window, reset host focus
2768 * since the window is now visible */
2769
2770 focus = curr = GetFocus();
2771 while (curr)
2772 {
2773 if (curr == hwnd)
2774 {
2775 WND *pFocus = WIN_FindWndPtr( focus );
2776 if (pFocus)
2777 pFocus->pDriver->pSetFocus(pFocus);
2778 WIN_ReleaseWndPtr(pFocus);
2779 break;
2780 }
2781 curr = GetParent(curr);
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00002782 }
Jesper Skov5c3e4571998-11-01 19:27:22 +00002783 }
Alexandre Julliardaca05781994-10-17 18:12:41 +00002784 }
Alex Korobka4f1ac051999-03-28 09:37:57 +00002785 else /* -------------------------------------------- emulated window */
Alexandre Julliardaca05781994-10-17 18:12:41 +00002786 {
Alex Korobka4f1ac051999-03-28 09:37:57 +00002787 if( winpos.flags & SWP_SHOWWINDOW )
Alexandre Julliard1e37a181996-08-18 16:21:52 +00002788 {
Alex Korobka4f1ac051999-03-28 09:37:57 +00002789 wndPtr->dwStyle |= WS_VISIBLE;
2790 uFlags |= SWP_EX_PAINTSELF;
Alex Korobka44a1b591999-04-01 12:03:52 +00002791 visRgn = 1; /* redraw the whole window */
Alexandre Julliard1e37a181996-08-18 16:21:52 +00002792 }
Alex Korobka4f1ac051999-03-28 09:37:57 +00002793 else if( !(winpos.flags & SWP_NOREDRAW) )
2794 {
2795 if( winpos.flags & SWP_HIDEWINDOW )
2796 {
2797 if( visRgn > 1 ) /* map to parent */
2798 OffsetRgn( visRgn, oldWindowRect.left, oldWindowRect.top );
2799 else
2800 visRgn = 0;
Alexandre Julliarde658d821997-11-30 17:45:40 +00002801 }
Alex Korobka4f1ac051999-03-28 09:37:57 +00002802 else
2803 {
Alex Korobka4f1ac051999-03-28 09:37:57 +00002804 if( (winpos.flags & SWP_AGG_NOPOSCHANGE) != SWP_AGG_NOPOSCHANGE )
2805 uFlags = SWP_CopyValidBits(wndPtr, &visRgn, &oldWindowRect,
2806 &oldClientRect, uFlags);
2807 else
2808 {
Alex Korobka44a1b591999-04-01 12:03:52 +00002809 /* nothing moved, redraw frame if needed */
2810
Alex Korobka4f1ac051999-03-28 09:37:57 +00002811 if( winpos.flags & SWP_FRAMECHANGED )
Alex Korobka44a1b591999-04-01 12:03:52 +00002812 SWP_DoSimpleFrameChanged( wndPtr, &oldClientRect, winpos.flags, uFlags );
Alex Korobka4f1ac051999-03-28 09:37:57 +00002813 if( visRgn )
2814 {
2815 DeleteObject( visRgn );
2816 visRgn = 0;
2817 }
2818 }
2819 }
Alexandre Julliarde658d821997-11-30 17:45:40 +00002820 }
Alexandre Julliard2d159fb1994-07-15 16:04:31 +00002821 }
Alex Korobka4f1ac051999-03-28 09:37:57 +00002822
2823 if( winpos.flags & SWP_HIDEWINDOW )
Alexandre Julliard2d159fb1994-07-15 16:04:31 +00002824 {
Alex Korobka4f1ac051999-03-28 09:37:57 +00002825 wndPtr->dwStyle &= ~WS_VISIBLE;
Alexandre Julliardd4719651995-12-12 18:49:11 +00002826
Alexandre Julliarda3960291999-02-26 11:11:13 +00002827 if (hwnd == CARET_GetHwnd()) DestroyCaret();
Alexandre Julliard2d159fb1994-07-15 16:04:31 +00002828 }
2829
Alex Korobka4f1ac051999-03-28 09:37:57 +00002830 /* ------------------------------------------------------------------------ FINAL */
2831
Alex Korobka4f1ac051999-03-28 09:37:57 +00002832 if (wndPtr->flags & WIN_NATIVE)
Ulrich Weigand203780e1999-07-10 10:24:31 +00002833 EVENT_Synchronize(); /* Synchronize with the host window system */
Alexandre Julliardd4719651995-12-12 18:49:11 +00002834
Alexandre Julliarda3960291999-02-26 11:11:13 +00002835 if (!GetCapture() && ((wndPtr->dwStyle & WS_VISIBLE) || (flags & SWP_HIDEWINDOW)))
Ulrich Weigand153334e1999-06-05 09:02:11 +00002836 {
2837 /* Simulate a mouse event to set the cursor */
Lionel Ulmeracc74671999-11-07 21:25:57 +00002838 int iWndsLocks = WIN_SuspendWndsLock();
2839
2840 hardware_event( WM_MOUSEMOVE, GET_KEYSTATE(), 0,
2841 PosX, PosY, GetTickCount(), 0 );
2842
2843 WIN_RestoreWndsLock(iWndsLocks);
Ulrich Weigand153334e1999-06-05 09:02:11 +00002844 }
Alexandre Julliardd4719651995-12-12 18:49:11 +00002845
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002846 wndTemp = WIN_GetDesktop();
Alex Korobka4f1ac051999-03-28 09:37:57 +00002847
Alex Korobka44a1b591999-04-01 12:03:52 +00002848 /* repaint invalidated region (if any)
2849 *
2850 * FIXME: if SWP_NOACTIVATE is not set then set invalid regions here without any painting
2851 * and force update after ChangeActiveWindow() to avoid painting frames twice.
2852 */
Alex Korobka4f1ac051999-03-28 09:37:57 +00002853
2854 if( visRgn )
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002855 {
Alex Korobka4f1ac051999-03-28 09:37:57 +00002856 if( !(winpos.flags & SWP_NOREDRAW) )
2857 {
Yuxi Zhang8e35d651999-07-04 10:53:43 +00002858
Yuxi Zhanga961c441999-07-31 11:09:33 +00002859 /* Use PAINT_RedrawWindow to explicitly force an invalidation of the window,
2860 its parent and sibling and so on, and then erase the parent window
2861 back ground if the parent is either a top-level window or its parent's parent
2862 is top-level window. Rely on the system to repaint other affected
2863 windows later on. */
Alex Korobka4f1ac051999-03-28 09:37:57 +00002864 if( uFlags & SWP_EX_PAINTSELF )
2865 {
Yuxi Zhanga961c441999-07-31 11:09:33 +00002866 PAINT_RedrawWindow( wndPtr->hwndSelf, NULL, (visRgn == 1) ? 0 : visRgn,
2867 RDW_ERASE | RDW_FRAME | RDW_INVALIDATE | RDW_ALLCHILDREN,
2868 RDW_EX_XYWINDOW | RDW_EX_USEHRGN );
Alex Korobka4f1ac051999-03-28 09:37:57 +00002869 }
2870 else
2871 {
Yuxi Zhang8e35d651999-07-04 10:53:43 +00002872 PAINT_RedrawWindow( wndPtr->parent->hwndSelf, NULL, (visRgn == 1) ? 0 : visRgn,
Yuxi Zhanga961c441999-07-31 11:09:33 +00002873 RDW_ERASE | RDW_INVALIDATE | RDW_ALLCHILDREN,
2874 RDW_EX_USEHRGN );
Yuxi Zhang8e35d651999-07-04 10:53:43 +00002875 }
Yuxi Zhang8e35d651999-07-04 10:53:43 +00002876
Yuxi Zhanga961c441999-07-31 11:09:33 +00002877 if(wndPtr -> parent == wndTemp || wndPtr->parent->parent == wndTemp )
Yuxi Zhang8e35d651999-07-04 10:53:43 +00002878 {
Yuxi Zhanga961c441999-07-31 11:09:33 +00002879 PAINT_RedrawWindow( wndPtr->parent->hwndSelf, NULL, 0,
2880 RDW_ERASENOW | RDW_NOCHILDREN, 0 );
Alex Korobka4f1ac051999-03-28 09:37:57 +00002881 }
2882 }
2883 if( visRgn != 1 )
2884 DeleteObject( visRgn );
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002885 }
Alex Korobka4f1ac051999-03-28 09:37:57 +00002886
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002887 WIN_ReleaseDesktop();
Alexandre Julliard2d159fb1994-07-15 16:04:31 +00002888
Alex Korobka44a1b591999-04-01 12:03:52 +00002889 if (!(flags & SWP_NOACTIVATE))
2890 WINPOS_ChangeActiveWindow( winpos.hwnd, FALSE );
2891
Alexandre Julliard2d159fb1994-07-15 16:04:31 +00002892 /* And last, send the WM_WINDOWPOSCHANGED message */
2893
Alexandre Julliard359f497e1999-07-04 16:02:24 +00002894 TRACE("\tstatus flags = %04x\n", winpos.flags & SWP_AGG_STATUSFLAGS);
Alexandre Julliard18f92e71996-07-17 20:02:21 +00002895
Alexandre Julliardc7c217b1998-04-13 12:21:30 +00002896 if ( resync ||
2897 (((winpos.flags & SWP_AGG_STATUSFLAGS) != SWP_AGG_NOPOSCHANGE) &&
2898 !(winpos.flags & SWP_NOSENDCHANGING)) )
2899 {
Alexandre Julliarda3960291999-02-26 11:11:13 +00002900 SendMessageA( winpos.hwnd, WM_WINDOWPOSCHANGED, 0, (LPARAM)&winpos );
Ulrich Weigand203780e1999-07-10 10:24:31 +00002901 if (resync) EVENT_Synchronize();
Alexandre Julliardc7c217b1998-04-13 12:21:30 +00002902 }
Alexandre Julliarde2abbb11995-03-19 17:39:39 +00002903
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002904 retvalue = TRUE;
2905END:
2906 WIN_ReleaseWndPtr(wndPtr);
2907 return retvalue;
Alexandre Julliard2d159fb1994-07-15 16:04:31 +00002908}
2909
2910
2911/***********************************************************************
Alexandre Julliard01d63461997-01-20 19:43:45 +00002912 * BeginDeferWindowPos16 (USER.259)
Alexandre Julliardaca05781994-10-17 18:12:41 +00002913 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00002914HDWP16 WINAPI BeginDeferWindowPos16( INT16 count )
Alexandre Julliardaca05781994-10-17 18:12:41 +00002915{
Alexandre Julliarda3960291999-02-26 11:11:13 +00002916 return BeginDeferWindowPos( count );
Alexandre Julliard01d63461997-01-20 19:43:45 +00002917}
2918
2919
2920/***********************************************************************
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002921 * BeginDeferWindowPos (USER32.9)
Alexandre Julliard01d63461997-01-20 19:43:45 +00002922 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002923HDWP WINAPI BeginDeferWindowPos( INT count )
Alexandre Julliard01d63461997-01-20 19:43:45 +00002924{
Alexandre Julliarda3960291999-02-26 11:11:13 +00002925 HDWP handle;
Alexandre Julliardaca05781994-10-17 18:12:41 +00002926 DWP *pDWP;
2927
2928 if (count <= 0) return 0;
Alexandre Julliarda3960291999-02-26 11:11:13 +00002929 handle = USER_HEAP_ALLOC( sizeof(DWP) + (count-1)*sizeof(WINDOWPOS) );
Alexandre Julliardaca05781994-10-17 18:12:41 +00002930 if (!handle) return 0;
Alexandre Julliarde2abbb11995-03-19 17:39:39 +00002931 pDWP = (DWP *) USER_HEAP_LIN_ADDR( handle );
Alexandre Julliardaca05781994-10-17 18:12:41 +00002932 pDWP->actualCount = 0;
2933 pDWP->suggestedCount = count;
2934 pDWP->valid = TRUE;
2935 pDWP->wMagic = DWP_MAGIC;
Alexandre Julliard3a405ba1994-10-30 16:25:19 +00002936 pDWP->hwndParent = 0;
Alexandre Julliardaca05781994-10-17 18:12:41 +00002937 return handle;
2938}
2939
2940
2941/***********************************************************************
Alexandre Julliard01d63461997-01-20 19:43:45 +00002942 * DeferWindowPos16 (USER.260)
Alexandre Julliardaca05781994-10-17 18:12:41 +00002943 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00002944HDWP16 WINAPI DeferWindowPos16( HDWP16 hdwp, HWND16 hwnd, HWND16 hwndAfter,
2945 INT16 x, INT16 y, INT16 cx, INT16 cy,
2946 UINT16 flags )
Alexandre Julliard01d63461997-01-20 19:43:45 +00002947{
Alexandre Julliarda3960291999-02-26 11:11:13 +00002948 return DeferWindowPos( hdwp, hwnd, (INT)(INT16)hwndAfter,
Alexandre Julliard01d63461997-01-20 19:43:45 +00002949 x, y, cx, cy, flags );
2950}
2951
2952
2953/***********************************************************************
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002954 * DeferWindowPos (USER32.128)
Alexandre Julliard01d63461997-01-20 19:43:45 +00002955 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002956HDWP WINAPI DeferWindowPos( HDWP hdwp, HWND hwnd, HWND hwndAfter,
2957 INT x, INT y, INT cx, INT cy,
2958 UINT flags )
Alexandre Julliardaca05781994-10-17 18:12:41 +00002959{
2960 DWP *pDWP;
2961 int i;
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002962 HDWP newhdwp = hdwp,retvalue;
2963 /* HWND parent; */
Alexandre Julliard77b99181997-09-14 17:17:23 +00002964 WND *pWnd;
Alexandre Julliardaca05781994-10-17 18:12:41 +00002965
Alexandre Julliarde2abbb11995-03-19 17:39:39 +00002966 pDWP = (DWP *) USER_HEAP_LIN_ADDR( hdwp );
Alexandre Julliardaca05781994-10-17 18:12:41 +00002967 if (!pDWP) return 0;
Alexandre Julliarda3960291999-02-26 11:11:13 +00002968 if (hwnd == GetDesktopWindow()) return 0;
Alexandre Julliard3a405ba1994-10-30 16:25:19 +00002969
Alexandre Julliard77b99181997-09-14 17:17:23 +00002970 if (!(pWnd=WIN_FindWndPtr( hwnd ))) {
2971 USER_HEAP_FREE( hdwp );
2972 return 0;
2973 }
2974
Alexandre Julliarddadf78f1998-05-17 17:13:43 +00002975/* Numega Bounds Checker Demo dislikes the following code.
2976 In fact, I've not been able to find any "same parent" requirement in any docu
2977 [AM 980509]
2978 */
2979#if 0
2980 /* All the windows of a DeferWindowPos() must have the same parent */
Alexandre Julliard77b99181997-09-14 17:17:23 +00002981 parent = pWnd->parent->hwndSelf;
Alexandre Julliarde2991ea1995-07-29 13:09:43 +00002982 if (pDWP->actualCount == 0) pDWP->hwndParent = parent;
2983 else if (parent != pDWP->hwndParent)
Alexandre Julliard3a405ba1994-10-30 16:25:19 +00002984 {
2985 USER_HEAP_FREE( hdwp );
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002986 retvalue = 0;
2987 goto END;
Alexandre Julliard3a405ba1994-10-30 16:25:19 +00002988 }
Alexandre Julliarddadf78f1998-05-17 17:13:43 +00002989#endif
Alexandre Julliard3a405ba1994-10-30 16:25:19 +00002990
Alexandre Julliardaca05781994-10-17 18:12:41 +00002991 for (i = 0; i < pDWP->actualCount; i++)
2992 {
2993 if (pDWP->winPos[i].hwnd == hwnd)
2994 {
2995 /* Merge with the other changes */
2996 if (!(flags & SWP_NOZORDER))
2997 {
2998 pDWP->winPos[i].hwndInsertAfter = hwndAfter;
2999 }
3000 if (!(flags & SWP_NOMOVE))
3001 {
3002 pDWP->winPos[i].x = x;
3003 pDWP->winPos[i].y = y;
3004 }
3005 if (!(flags & SWP_NOSIZE))
3006 {
3007 pDWP->winPos[i].cx = cx;
3008 pDWP->winPos[i].cy = cy;
3009 }
Alexandre Julliard17216f51997-10-12 16:30:17 +00003010 pDWP->winPos[i].flags &= flags | ~(SWP_NOSIZE | SWP_NOMOVE |
3011 SWP_NOZORDER | SWP_NOREDRAW |
3012 SWP_NOACTIVATE | SWP_NOCOPYBITS|
3013 SWP_NOOWNERZORDER);
Alexandre Julliardaca05781994-10-17 18:12:41 +00003014 pDWP->winPos[i].flags |= flags & (SWP_SHOWWINDOW | SWP_HIDEWINDOW |
3015 SWP_FRAMECHANGED);
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00003016 retvalue = hdwp;
3017 goto END;
Alexandre Julliardaca05781994-10-17 18:12:41 +00003018 }
3019 }
3020 if (pDWP->actualCount >= pDWP->suggestedCount)
3021 {
3022 newhdwp = USER_HEAP_REALLOC( hdwp,
Alexandre Julliarda3960291999-02-26 11:11:13 +00003023 sizeof(DWP) + pDWP->suggestedCount*sizeof(WINDOWPOS) );
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00003024 if (!newhdwp)
3025 {
3026 retvalue = 0;
3027 goto END;
3028 }
Alexandre Julliarde2abbb11995-03-19 17:39:39 +00003029 pDWP = (DWP *) USER_HEAP_LIN_ADDR( newhdwp );
Alexandre Julliardaca05781994-10-17 18:12:41 +00003030 pDWP->suggestedCount++;
3031 }
3032 pDWP->winPos[pDWP->actualCount].hwnd = hwnd;
3033 pDWP->winPos[pDWP->actualCount].hwndInsertAfter = hwndAfter;
3034 pDWP->winPos[pDWP->actualCount].x = x;
3035 pDWP->winPos[pDWP->actualCount].y = y;
3036 pDWP->winPos[pDWP->actualCount].cx = cx;
3037 pDWP->winPos[pDWP->actualCount].cy = cy;
3038 pDWP->winPos[pDWP->actualCount].flags = flags;
3039 pDWP->actualCount++;
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00003040 retvalue = newhdwp;
3041END:
3042 WIN_ReleaseWndPtr(pWnd);
3043 return retvalue;
Alexandre Julliardaca05781994-10-17 18:12:41 +00003044}
3045
3046
3047/***********************************************************************
Alexandre Julliard01d63461997-01-20 19:43:45 +00003048 * EndDeferWindowPos16 (USER.261)
Alexandre Julliardaca05781994-10-17 18:12:41 +00003049 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00003050BOOL16 WINAPI EndDeferWindowPos16( HDWP16 hdwp )
Alexandre Julliard01d63461997-01-20 19:43:45 +00003051{
Alexandre Julliarda3960291999-02-26 11:11:13 +00003052 return EndDeferWindowPos( hdwp );
Alexandre Julliard01d63461997-01-20 19:43:45 +00003053}
3054
3055
3056/***********************************************************************
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00003057 * EndDeferWindowPos (USER32.173)
Alexandre Julliard01d63461997-01-20 19:43:45 +00003058 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00003059BOOL WINAPI EndDeferWindowPos( HDWP hdwp )
Alexandre Julliardaca05781994-10-17 18:12:41 +00003060{
3061 DWP *pDWP;
Alexandre Julliarda3960291999-02-26 11:11:13 +00003062 WINDOWPOS *winpos;
3063 BOOL res = TRUE;
Alexandre Julliardaca05781994-10-17 18:12:41 +00003064 int i;
3065
Alexandre Julliarde2abbb11995-03-19 17:39:39 +00003066 pDWP = (DWP *) USER_HEAP_LIN_ADDR( hdwp );
Alexandre Julliardaca05781994-10-17 18:12:41 +00003067 if (!pDWP) return FALSE;
Alexandre Julliarde2abbb11995-03-19 17:39:39 +00003068 for (i = 0, winpos = pDWP->winPos; i < pDWP->actualCount; i++, winpos++)
Alexandre Julliardaca05781994-10-17 18:12:41 +00003069 {
Alexandre Julliarda3960291999-02-26 11:11:13 +00003070 if (!(res = SetWindowPos( winpos->hwnd, winpos->hwndInsertAfter,
Alexandre Julliard01d63461997-01-20 19:43:45 +00003071 winpos->x, winpos->y, winpos->cx,
3072 winpos->cy, winpos->flags ))) break;
Alexandre Julliardaca05781994-10-17 18:12:41 +00003073 }
3074 USER_HEAP_FREE( hdwp );
3075 return res;
3076}
3077
3078
3079/***********************************************************************
Alexandre Julliard3a405ba1994-10-30 16:25:19 +00003080 * TileChildWindows (USER.199)
3081 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00003082void WINAPI TileChildWindows16( HWND16 parent, WORD action )
Alexandre Julliard3a405ba1994-10-30 16:25:19 +00003083{
Alexandre Julliard359f497e1999-07-04 16:02:24 +00003084 FIXME("(%04x, %d): stub\n", parent, action);
Alexandre Julliard3a405ba1994-10-30 16:25:19 +00003085}
3086
3087/***********************************************************************
3088 * CascageChildWindows (USER.198)
3089 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00003090void WINAPI CascadeChildWindows16( HWND16 parent, WORD action )
Alexandre Julliard3a405ba1994-10-30 16:25:19 +00003091{
Alexandre Julliard359f497e1999-07-04 16:02:24 +00003092 FIXME("(%04x, %d): stub\n", parent, action);
Alexandre Julliard3a405ba1994-10-30 16:25:19 +00003093}
Juergen Schmiedddb2e291999-05-02 09:19:19 +00003094
3095/***********************************************************************
3096 * SetProgmanWindow [USER32.522]
3097 */
3098HRESULT WINAPI SetProgmanWindow ( HWND hwnd )
3099{
3100 hGlobalProgmanWindow = hwnd;
3101 return hGlobalProgmanWindow;
3102}
3103
Juergen Schmied2c205911998-10-15 12:35:41 +00003104/***********************************************************************
3105 * GetProgmanWindow [USER32.289]
3106 */
3107HRESULT WINAPI GetProgmanWindow ( )
Juergen Schmiedddb2e291999-05-02 09:19:19 +00003108{
3109 return hGlobalProgmanWindow;
Juergen Schmied2c205911998-10-15 12:35:41 +00003110}
Juergen Schmiedddb2e291999-05-02 09:19:19 +00003111
3112/***********************************************************************
3113 * SetShellWindowEx [USER32.531]
3114 * hwndProgman = Progman[Program Manager]
3115 * |-> SHELLDLL_DefView
3116 * hwndListView = | |-> SysListView32
3117 * | | |-> tooltips_class32
3118 * | |
3119 * | |-> SysHeader32
3120 * |
3121 * |-> ProxyTarget
3122 */
3123HRESULT WINAPI SetShellWindowEx ( HWND hwndProgman, HWND hwndListView )
3124{
Alexandre Julliard359f497e1999-07-04 16:02:24 +00003125 FIXME("0x%08x 0x%08x stub\n",hwndProgman ,hwndListView );
Juergen Schmiedddb2e291999-05-02 09:19:19 +00003126 hGlobalShellWindow = hwndProgman;
3127 return hGlobalShellWindow;
3128
3129}
3130
3131/***********************************************************************
3132 * SetTaskmanWindow [USER32.537]
3133 * NOTES
3134 * hwnd = MSTaskSwWClass
3135 * |-> SysTabControl32
3136 */
3137HRESULT WINAPI SetTaskmanWindow ( HWND hwnd )
3138{
3139 hGlobalTaskmanWindow = hwnd;
3140 return hGlobalTaskmanWindow;
3141}
3142
Juergen Schmied2c205911998-10-15 12:35:41 +00003143/***********************************************************************
3144 * GetTaskmanWindow [USER32.304]
3145 */
3146HRESULT WINAPI GetTaskmanWindow ( )
Juergen Schmiedddb2e291999-05-02 09:19:19 +00003147{
3148 return hGlobalTaskmanWindow;
Juergen Schmied2c205911998-10-15 12:35:41 +00003149}