diff --git a/dlls/user32/win.c b/dlls/user32/win.c index 76351f46232..6d065bef41c 100644 --- a/dlls/user32/win.c +++ b/dlls/user32/win.c @@ -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 ); diff --git a/dlls/user32/win.h b/dlls/user32/win.h index 209854fcf3a..5a5708e1bbd 100644 --- a/dlls/user32/win.h +++ b/dlls/user32/win.h @@ -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; diff --git a/dlls/user32/winpos.c b/dlls/user32/winpos.c index d61fe014841..a2449d6cbce 100644 --- a/dlls/user32/winpos.c +++ b/dlls/user32/winpos.c @@ -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 );