user32: Store the window placement information directly in the main window structure.

oldstable
Alexandre Julliard 2008-03-04 20:45:40 +01:00
parent accfce21d3
commit e6a3d80828
3 changed files with 91 additions and 128 deletions

View File

@ -596,6 +596,7 @@ LRESULT WIN_DestroyWindow( HWND hwnd )
WND *wndPtr;
HWND *list;
HMENU menu = 0, sys_menu;
HWND icon_title;
TRACE("%p\n", hwnd );
@ -627,8 +628,6 @@ LRESULT WIN_DestroyWindow( HWND hwnd )
/* FIXME: do we need to fake QS_MOUSEMOVE wakebit? */
WINPOS_CheckInternalPos( hwnd );
/* free resources associated with the window */
if (!(wndPtr = WIN_GetPtr( hwnd )) || wndPtr == WND_OTHER_PROCESS) return 0;
@ -637,8 +636,10 @@ LRESULT WIN_DestroyWindow( HWND hwnd )
sys_menu = wndPtr->hSysMenu;
free_dce( wndPtr->dce, hwnd );
wndPtr->dce = NULL;
icon_title = wndPtr->icon_title;
WIN_ReleasePtr( wndPtr );
if (icon_title) DestroyWindow( icon_title );
if (menu) DestroyMenu( menu );
if (sys_menu) DestroyMenu( sys_menu );

View File

@ -45,6 +45,10 @@ typedef struct tagWND
HINSTANCE hInstance; /* Window hInstance (from CreateWindow) */
RECT rectClient; /* Client area rel. to parent client area */
RECT rectWindow; /* Whole window rel. to parent client area */
RECT normal_rect; /* Normal window rect saved when maximized/minimized */
POINT min_pos; /* Position for minimized window */
POINT max_pos; /* Position for maximized window */
HWND icon_title; /* Icon title window */
LPWSTR text; /* Window text */
void *pVScroll; /* Vertical scroll-bar info */
void *pHScroll; /* Horizontal scroll-bar info */
@ -113,7 +117,6 @@ extern void WINPOS_GetMinMaxInfo( HWND hwnd, POINT *maxSize, POINT *maxPos, POIN
POINT *maxTrack ) DECLSPEC_HIDDEN;
extern LONG WINPOS_HandleWindowPosChanging(HWND hwnd, WINDOWPOS *winpos) DECLSPEC_HIDDEN;
extern HWND WINPOS_WindowFromPoint( HWND hwndScope, POINT pt, INT *hittest ) DECLSPEC_HIDDEN;
extern void WINPOS_CheckInternalPos( HWND hwnd ) DECLSPEC_HIDDEN;
extern void WINPOS_ActivateOtherWindow( HWND hwnd ) DECLSPEC_HIDDEN;
extern UINT WINPOS_MinMaximize( HWND hwnd, UINT cmd, LPRECT rect ) DECLSPEC_HIDDEN;

View File

@ -53,7 +53,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(win);
(((style) & WS_THICKFRAME) && \
!(((style) & (WS_DLGFRAME|WS_BORDER)) == WS_DLGFRAME))
#define EMPTYPOINT(pt) ((*(LONG*)&(pt)) == -1)
#define EMPTYPOINT(pt) ((pt).x == -1 && (pt).y == -1)
#define PLACE_MIN 0x0001
#define PLACE_MAX 0x0002
@ -72,44 +72,6 @@ typedef struct
WINDOWPOS winPos[1];
} DWP;
typedef struct
{
RECT16 rectNormal;
POINT16 ptIconPos;
POINT16 ptMaxPos;
HWND hwndIconTitle;
} INTERNALPOS, *LPINTERNALPOS;
/* ----- internal functions ----- */
static const WCHAR SysIP_W[] = { 'S','y','s','I','P',0 };
static inline INTERNALPOS *get_internal_pos( HWND hwnd )
{
return GetPropW( hwnd, SysIP_W );
}
static inline void set_internal_pos( HWND hwnd, INTERNALPOS *pos )
{
SetPropW( hwnd, SysIP_W, pos );
}
/***********************************************************************
* WINPOS_CheckInternalPos
*
* Called when a window is destroyed.
*/
void WINPOS_CheckInternalPos( HWND hwnd )
{
LPINTERNALPOS lpPos = get_internal_pos( hwnd );
if ( lpPos )
{
if( IsWindow(lpPos->hwndIconTitle) )
DestroyWindow( lpPos->hwndIconTitle );
HeapFree( GetProcessHeap(), 0, lpPos );
}
}
/***********************************************************************
* ArrangeIconicWindows (USER32.@)
@ -647,47 +609,34 @@ BOOL WINAPI MoveWindow( HWND hwnd, INT x, INT y, INT cx, INT cy,
}
/***********************************************************************
* WINPOS_InitInternalPos
* WINPOS_InitPlacement
*/
static LPINTERNALPOS WINPOS_InitInternalPos( WND* wnd )
static void WINPOS_InitPlacement( WND* wnd )
{
LPINTERNALPOS lpPos = get_internal_pos( wnd->hwndSelf );
if( !lpPos )
if (IsRectEmpty( &wnd->normal_rect ))
{
/* this happens when the window is minimized/maximized
* for the first time (rectWindow is not adjusted yet) */
lpPos = HeapAlloc( GetProcessHeap(), 0, sizeof(INTERNALPOS) );
if( !lpPos ) return NULL;
set_internal_pos( wnd->hwndSelf, lpPos );
lpPos->hwndIconTitle = 0; /* defer until needs to be shown */
lpPos->rectNormal.left = wnd->rectWindow.left;
lpPos->rectNormal.top = wnd->rectWindow.top;
lpPos->rectNormal.right = wnd->rectWindow.right;
lpPos->rectNormal.bottom = wnd->rectWindow.bottom;
lpPos->ptIconPos.x = lpPos->ptIconPos.y = -1;
lpPos->ptMaxPos.x = lpPos->ptMaxPos.y = -1;
wnd->normal_rect = wnd->rectWindow;
wnd->min_pos.x = wnd->min_pos.y = -1;
wnd->max_pos.x = wnd->max_pos.y = -1;
}
if( wnd->dwStyle & WS_MINIMIZE )
{
lpPos->ptIconPos.x = wnd->rectWindow.left;
lpPos->ptIconPos.y = wnd->rectWindow.top;
wnd->min_pos.x = wnd->rectWindow.left;
wnd->min_pos.y = wnd->rectWindow.top;
}
else if( wnd->dwStyle & WS_MAXIMIZE )
{
lpPos->ptMaxPos.x = wnd->rectWindow.left;
lpPos->ptMaxPos.y = wnd->rectWindow.top;
wnd->max_pos.x = wnd->rectWindow.left;
wnd->max_pos.y = wnd->rectWindow.top;
}
else
{
lpPos->rectNormal.left = wnd->rectWindow.left;
lpPos->rectNormal.top = wnd->rectWindow.top;
lpPos->rectNormal.right = wnd->rectWindow.right;
lpPos->rectNormal.bottom = wnd->rectWindow.bottom;
wnd->normal_rect = wnd->rectWindow;
}
return lpPos;
}
/***********************************************************************
@ -695,17 +644,18 @@ static LPINTERNALPOS WINPOS_InitInternalPos( WND* wnd )
*/
BOOL WINPOS_RedrawIconTitle( HWND hWnd )
{
LPINTERNALPOS lpPos = get_internal_pos( hWnd );
if( lpPos )
HWND icon_title = 0;
WND *win = WIN_GetPtr( hWnd );
if (win && win != WND_OTHER_PROCESS && win != WND_DESKTOP)
{
if( lpPos->hwndIconTitle )
{
SendMessageW( lpPos->hwndIconTitle, WM_SHOWWINDOW, TRUE, 0);
InvalidateRect( lpPos->hwndIconTitle, NULL, TRUE );
return TRUE;
}
icon_title = win->icon_title;
WIN_ReleasePtr( win );
}
return FALSE;
if (!icon_title) return FALSE;
SendMessageW( icon_title, WM_SHOWWINDOW, TRUE, 0 );
InvalidateRect( icon_title, NULL, TRUE );
return TRUE;
}
/***********************************************************************
@ -713,17 +663,30 @@ BOOL WINPOS_RedrawIconTitle( HWND hWnd )
*/
BOOL WINPOS_ShowIconTitle( HWND hwnd, BOOL bShow )
{
LPINTERNALPOS lpPos = get_internal_pos( hwnd );
if (lpPos && !GetPropA( hwnd, "__wine_x11_managed" ))
if (!GetPropA( hwnd, "__wine_x11_managed" ))
{
HWND title = lpPos->hwndIconTitle;
WND *win = WIN_GetPtr( hwnd );
HWND title = 0;
TRACE("%p %i\n", hwnd, (bShow != 0) );
if (!win || win == WND_OTHER_PROCESS || win == WND_DESKTOP) return FALSE;
title = win->icon_title;
WIN_ReleasePtr( win );
if( bShow )
{
if (!title) lpPos->hwndIconTitle = title = ICONTITLE_Create( hwnd );
if (!title)
{
title = ICONTITLE_Create( hwnd );
if (!(win = WIN_GetPtr( hwnd )) || win == WND_OTHER_PROCESS)
{
DestroyWindow( title );
return FALSE;
}
win->icon_title = title;
WIN_ReleasePtr( win );
}
if (!IsWindowVisible(title))
{
SendMessageW( title, WM_SHOWWINDOW, TRUE, 0 );
@ -744,13 +707,13 @@ BOOL WINPOS_ShowIconTitle( HWND hwnd, BOOL bShow )
void WINPOS_GetMinMaxInfo( HWND hwnd, POINT *maxSize, POINT *maxPos,
POINT *minTrack, POINT *maxTrack )
{
LPINTERNALPOS lpPos;
MINMAXINFO MinMax;
HMONITOR monitor;
INT xinc, yinc;
LONG style = GetWindowLongA( hwnd, GWL_STYLE );
LONG exstyle = GetWindowLongA( hwnd, GWL_EXSTYLE );
RECT rc;
WND *win;
/* Compute default values */
@ -804,16 +767,12 @@ void WINPOS_GetMinMaxInfo( HWND hwnd, POINT *maxSize, POINT *maxPos,
MinMax.ptMaxSize.x += 2 * xinc;
MinMax.ptMaxSize.y += 2 * yinc;
lpPos = get_internal_pos( hwnd );
if( lpPos && !EMPTYPOINT(lpPos->ptMaxPos) )
MinMax.ptMaxPosition.x = -xinc;
MinMax.ptMaxPosition.y = -yinc;
if ((win = WIN_GetPtr( hwnd )) && win != WND_DESKTOP && win != WND_OTHER_PROCESS)
{
MinMax.ptMaxPosition.x = lpPos->ptMaxPos.x;
MinMax.ptMaxPosition.y = lpPos->ptMaxPos.y;
}
else
{
MinMax.ptMaxPosition.x = -xinc;
MinMax.ptMaxPosition.y = -yinc;
if (!EMPTYPOINT(win->max_pos)) MinMax.ptMaxPosition = win->max_pos;
WIN_ReleasePtr( win );
}
SendMessageW( hwnd, WM_GETMINMAXINFO, 0, (LPARAM)&MinMax );
@ -1246,7 +1205,6 @@ UINT WINAPI GetInternalWindowPos( HWND hwnd, LPRECT rectWnd,
BOOL WINAPI GetWindowPlacement( HWND hwnd, WINDOWPLACEMENT *wndpl )
{
WND *pWnd = WIN_GetPtr( hwnd );
LPINTERNALPOS lpPos;
if (!pWnd || pWnd == WND_DESKTOP) return FALSE;
if (pWnd == WND_OTHER_PROCESS)
@ -1255,7 +1213,7 @@ BOOL WINAPI GetWindowPlacement( HWND hwnd, WINDOWPLACEMENT *wndpl )
return FALSE;
}
lpPos = WINPOS_InitInternalPos( pWnd );
WINPOS_InitPlacement( pWnd );
wndpl->length = sizeof(*wndpl);
if( pWnd->dwStyle & WS_MINIMIZE )
wndpl->showCmd = SW_SHOWMINIMIZED;
@ -1265,15 +1223,15 @@ BOOL WINAPI GetWindowPlacement( HWND hwnd, WINDOWPLACEMENT *wndpl )
wndpl->flags = WPF_RESTORETOMAXIMIZED;
else
wndpl->flags = 0;
wndpl->ptMinPosition.x = lpPos->ptIconPos.x;
wndpl->ptMinPosition.y = lpPos->ptIconPos.y;
wndpl->ptMaxPosition.x = lpPos->ptMaxPos.x;
wndpl->ptMaxPosition.y = lpPos->ptMaxPos.y;
wndpl->rcNormalPosition.left = lpPos->rectNormal.left;
wndpl->rcNormalPosition.top = lpPos->rectNormal.top;
wndpl->rcNormalPosition.right = lpPos->rectNormal.right;
wndpl->rcNormalPosition.bottom = lpPos->rectNormal.bottom;
wndpl->ptMinPosition = pWnd->min_pos;
wndpl->ptMaxPosition = pWnd->max_pos;
wndpl->rcNormalPosition = pWnd->normal_rect;
WIN_ReleasePtr( pWnd );
TRACE( "%p: returning min %d,%d max %d,%d normal %s\n",
hwnd, wndpl->ptMinPosition.x, wndpl->ptMinPosition.y,
wndpl->ptMaxPosition.x, wndpl->ptMaxPosition.y,
wine_dbgstr_rect(&wndpl->rcNormalPosition) );
return TRUE;
}
@ -1283,51 +1241,52 @@ BOOL WINAPI GetWindowPlacement( HWND hwnd, WINDOWPLACEMENT *wndpl )
*/
static BOOL WINPOS_SetPlacement( HWND hwnd, const WINDOWPLACEMENT *wndpl, UINT flags )
{
LPINTERNALPOS lpPos;
DWORD style;
WND *pWnd = WIN_GetPtr( hwnd );
POINT pt;
RECT rect;
if (!pWnd || pWnd == WND_OTHER_PROCESS || pWnd == WND_DESKTOP) return FALSE;
lpPos = WINPOS_InitInternalPos( pWnd );
if( flags & PLACE_MIN )
{
lpPos->ptIconPos.x = wndpl->ptMinPosition.x;
lpPos->ptIconPos.y = wndpl->ptMinPosition.y;
}
if( flags & PLACE_MAX )
{
lpPos->ptMaxPos.x = wndpl->ptMaxPosition.x;
lpPos->ptMaxPos.y = wndpl->ptMaxPosition.y;
}
if( flags & PLACE_RECT)
{
lpPos->rectNormal.left = wndpl->rcNormalPosition.left;
lpPos->rectNormal.top = wndpl->rcNormalPosition.top;
lpPos->rectNormal.right = wndpl->rcNormalPosition.right;
lpPos->rectNormal.bottom = wndpl->rcNormalPosition.bottom;
}
TRACE( "%p: setting min %d,%d max %d,%d normal %s flags %x\n",
hwnd, wndpl->ptMinPosition.x, wndpl->ptMinPosition.y,
wndpl->ptMaxPosition.x, wndpl->ptMaxPosition.y,
wine_dbgstr_rect(&wndpl->rcNormalPosition), flags );
if( flags & PLACE_MIN ) pWnd->min_pos = wndpl->ptMinPosition;
if( flags & PLACE_MAX ) pWnd->max_pos = wndpl->ptMaxPosition;
if( flags & PLACE_RECT) pWnd->normal_rect = wndpl->rcNormalPosition;
style = pWnd->dwStyle;
pt.x = pt.y = -1;
SetRectEmpty( &rect );
if( style & WS_MINIMIZE )
{
if (wndpl->flags & WPF_SETMINPOSITION) pt = pWnd->min_pos;
}
else if( style & WS_MAXIMIZE )
{
pt = pWnd->max_pos;
}
else if( flags & PLACE_RECT )
rect = pWnd->normal_rect;
WIN_ReleasePtr( pWnd );
if( style & WS_MINIMIZE )
{
WINPOS_ShowIconTitle( hwnd, FALSE );
if( wndpl->flags & WPF_SETMINPOSITION && !EMPTYPOINT(lpPos->ptIconPos))
SetWindowPos( hwnd, 0, lpPos->ptIconPos.x, lpPos->ptIconPos.y,
0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE );
if (!EMPTYPOINT(pt)) SetWindowPos( hwnd, 0, pt.x, pt.y, 0, 0,
SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE );
}
else if( style & WS_MAXIMIZE )
{
if( !EMPTYPOINT(lpPos->ptMaxPos) )
SetWindowPos( hwnd, 0, lpPos->ptMaxPos.x, lpPos->ptMaxPos.y,
0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE );
if (!EMPTYPOINT(pt)) SetWindowPos( hwnd, 0, pt.x, pt.y, 0, 0,
SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE );
}
else if( flags & PLACE_RECT )
SetWindowPos( hwnd, 0, lpPos->rectNormal.left, lpPos->rectNormal.top,
lpPos->rectNormal.right - lpPos->rectNormal.left,
lpPos->rectNormal.bottom - lpPos->rectNormal.top,
SetWindowPos( hwnd, 0, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top,
SWP_NOZORDER | SWP_NOACTIVATE );
ShowWindow( hwnd, wndpl->showCmd );