Alexandre Julliard : user32: Force the window position to be on-screen in SetWindowPlacement.
Alexandre Julliard
julliard at winehq.org
Fri Mar 7 05:30:12 CST 2008
Module: wine
Branch: master
Commit: b7d103b634d676e46ef30434ae5f32ba840be155
URL: http://source.winehq.org/git/wine.git/?a=commit;h=b7d103b634d676e46ef30434ae5f32ba840be155
Author: Alexandre Julliard <julliard at winehq.org>
Date: Fri Mar 7 11:00:36 2008 +0100
user32: Force the window position to be on-screen in SetWindowPlacement.
---
dlls/user32/winpos.c | 133 ++++++++++++++++++++++++++++++++------------------
1 files changed, 86 insertions(+), 47 deletions(-)
diff --git a/dlls/user32/winpos.c b/dlls/user32/winpos.c
index e9422be..e216065 100644
--- a/dlls/user32/winpos.c
+++ b/dlls/user32/winpos.c
@@ -1235,6 +1235,48 @@ BOOL WINAPI GetWindowPlacement( HWND hwnd, WINDOWPLACEMENT *wndpl )
return TRUE;
}
+/* make sure the specified rect is visible on screen */
+static void make_rect_onscreen( RECT *rect )
+{
+ MONITORINFO info;
+ HMONITOR monitor = MonitorFromRect( rect, MONITOR_DEFAULTTONEAREST );
+
+ info.cbSize = sizeof(info);
+ if (!monitor || !GetMonitorInfoW( monitor, &info )) return;
+ /* FIXME: map coordinates from rcWork to rcMonitor */
+ if (rect->right <= info.rcWork.left)
+ {
+ rect->right += info.rcWork.left - rect->left;
+ rect->left = info.rcWork.left;
+ }
+ else if (rect->left >= info.rcWork.right)
+ {
+ rect->left += info.rcWork.right - rect->right;
+ rect->right = info.rcWork.right;
+ }
+ if (rect->bottom <= info.rcWork.top)
+ {
+ rect->bottom += info.rcWork.top - rect->top;
+ rect->top = info.rcWork.top;
+ }
+ else if (rect->top >= info.rcWork.bottom)
+ {
+ rect->top += info.rcWork.bottom - rect->bottom;
+ rect->bottom = info.rcWork.bottom;
+ }
+}
+
+/* make sure the specified point is visible on screen */
+static void make_point_onscreen( POINT *pt )
+{
+ RECT rect;
+
+ SetRect( &rect, pt->x, pt->y, pt->x + 1, pt->y + 1 );
+ make_rect_onscreen( &rect );
+ pt->x = rect.left;
+ pt->y = rect.top;
+}
+
/***********************************************************************
* WINPOS_SetPlacement
@@ -1243,50 +1285,48 @@ static BOOL WINPOS_SetPlacement( HWND hwnd, const WINDOWPLACEMENT *wndpl, UINT f
{
DWORD style;
WND *pWnd = WIN_GetPtr( hwnd );
- POINT pt;
- RECT rect;
+ WINDOWPLACEMENT wp = *wndpl;
- if (!pWnd || pWnd == WND_OTHER_PROCESS || pWnd == WND_DESKTOP) return FALSE;
+ if (flags & PLACE_MIN) make_point_onscreen( &wp.ptMinPosition );
+ if (flags & PLACE_MAX) make_point_onscreen( &wp.ptMaxPosition );
+ if (flags & PLACE_RECT) make_rect_onscreen( &wp.rcNormalPosition );
- TRACE( "%p: setting min %d,%d max %d,%d normal %s flags %x\n",
+ TRACE( "%p: setting min %d,%d max %d,%d normal %s flags %x ajusted to 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), flags );
+ wine_dbgstr_rect(&wndpl->rcNormalPosition), flags,
+ wp.ptMinPosition.x, wp.ptMinPosition.y, wp.ptMaxPosition.x, wp.ptMaxPosition.y,
+ wine_dbgstr_rect(&wp.rcNormalPosition) );
- 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;
+ if (!pWnd || pWnd == WND_OTHER_PROCESS || pWnd == WND_DESKTOP) return FALSE;
- style = pWnd->dwStyle;
- pt.x = pt.y = -1;
- SetRectEmpty( &rect );
+ if( flags & PLACE_MIN ) pWnd->min_pos = wp.ptMinPosition;
+ if( flags & PLACE_MAX ) pWnd->max_pos = wp.ptMaxPosition;
+ if( flags & PLACE_RECT) pWnd->normal_rect = wp.rcNormalPosition;
- 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;
+ style = pWnd->dwStyle;
WIN_ReleasePtr( pWnd );
if( style & WS_MINIMIZE )
{
- WINPOS_ShowIconTitle( hwnd, FALSE );
- if (!EMPTYPOINT(pt)) SetWindowPos( hwnd, 0, pt.x, pt.y, 0, 0,
- SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE );
+ if (flags & PLACE_MIN)
+ {
+ WINPOS_ShowIconTitle( hwnd, FALSE );
+ SetWindowPos( hwnd, 0, wp.ptMinPosition.x, wp.ptMinPosition.y, 0, 0,
+ SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE );
+ }
}
else if( style & WS_MAXIMIZE )
{
- if (!EMPTYPOINT(pt)) SetWindowPos( hwnd, 0, pt.x, pt.y, 0, 0,
- SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE );
+ if (flags & PLACE_MAX)
+ SetWindowPos( hwnd, 0, wp.ptMaxPosition.x, wp.ptMaxPosition.y, 0, 0,
+ SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE );
}
else if( flags & PLACE_RECT )
- SetWindowPos( hwnd, 0, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top,
+ SetWindowPos( hwnd, 0, wp.rcNormalPosition.left, wp.rcNormalPosition.top,
+ wp.rcNormalPosition.right - wp.rcNormalPosition.left,
+ wp.rcNormalPosition.bottom - wp.rcNormalPosition.top,
SWP_NOZORDER | SWP_NOACTIVATE );
ShowWindow( hwnd, wndpl->showCmd );
@@ -1318,8 +1358,10 @@ static BOOL WINPOS_SetPlacement( HWND hwnd, const WINDOWPLACEMENT *wndpl, UINT f
*/
BOOL WINAPI SetWindowPlacement( HWND hwnd, const WINDOWPLACEMENT *wpl )
{
+ UINT flags = PLACE_MAX | PLACE_RECT;
if (!wpl) return FALSE;
- return WINPOS_SetPlacement( hwnd, wpl, PLACE_MIN | PLACE_MAX | PLACE_RECT );
+ if (wpl->flags & WPF_SETMINPOSITION) flags |= PLACE_MIN;
+ return WINPOS_SetPlacement( hwnd, wpl, flags );
}
@@ -1354,28 +1396,25 @@ BOOL WINAPI AnimateWindow(HWND hwnd, DWORD dwTime, DWORD dwFlags)
void WINAPI SetInternalWindowPos( HWND hwnd, UINT showCmd,
LPRECT rect, LPPOINT pt )
{
- if( IsWindow(hwnd) )
- {
- WINDOWPLACEMENT wndpl;
- UINT flags;
+ WINDOWPLACEMENT wndpl;
+ UINT flags;
- wndpl.length = sizeof(wndpl);
- wndpl.showCmd = showCmd;
- wndpl.flags = flags = 0;
+ wndpl.length = sizeof(wndpl);
+ wndpl.showCmd = showCmd;
+ wndpl.flags = flags = 0;
- if( pt )
- {
- flags |= PLACE_MIN;
- wndpl.flags |= WPF_SETMINPOSITION;
- wndpl.ptMinPosition = *pt;
- }
- if( rect )
- {
- flags |= PLACE_RECT;
- wndpl.rcNormalPosition = *rect;
- }
- WINPOS_SetPlacement( hwnd, &wndpl, flags );
+ if( pt )
+ {
+ flags |= PLACE_MIN;
+ wndpl.flags |= WPF_SETMINPOSITION;
+ wndpl.ptMinPosition = *pt;
+ }
+ if( rect )
+ {
+ flags |= PLACE_RECT;
+ wndpl.rcNormalPosition = *rect;
}
+ WINPOS_SetPlacement( hwnd, &wndpl, flags );
}
More information about the wine-cvs
mailing list