win32u: Move GetWindowPlacement and MonitorFromWindow implementation from user32.
Signed-off-by: Jacek Caban <jacek@codeweavers.com> Signed-off-by: Huw Davies <huw@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
c45af8f353
commit
c7e5ab198e
|
@ -1011,24 +1011,9 @@ HMONITOR WINAPI MonitorFromPoint( POINT pt, DWORD flags )
|
|||
/***********************************************************************
|
||||
* MonitorFromWindow (USER32.@)
|
||||
*/
|
||||
HMONITOR WINAPI MonitorFromWindow(HWND hWnd, DWORD dwFlags)
|
||||
HMONITOR WINAPI MonitorFromWindow( HWND hwnd, DWORD flags )
|
||||
{
|
||||
RECT rect;
|
||||
WINDOWPLACEMENT wp;
|
||||
|
||||
TRACE("(%p, 0x%08x)\n", hWnd, dwFlags);
|
||||
|
||||
wp.length = sizeof(wp);
|
||||
if (IsIconic(hWnd) && GetWindowPlacement(hWnd, &wp))
|
||||
return MonitorFromRect( &wp.rcNormalPosition, dwFlags );
|
||||
|
||||
if (GetWindowRect( hWnd, &rect ))
|
||||
return MonitorFromRect( &rect, dwFlags );
|
||||
|
||||
if (!(dwFlags & (MONITOR_DEFAULTTOPRIMARY|MONITOR_DEFAULTTONEAREST))) return 0;
|
||||
/* retrieve the primary */
|
||||
SetRect( &rect, 0, 0, 1, 1 );
|
||||
return MonitorFromRect( &rect, dwFlags );
|
||||
return UlongToHandle( NtUserCallHwndParam( hwnd, flags, NtUserMonitorFromWindow ));
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
|
|
|
@ -1219,85 +1219,7 @@ static void update_maximized_pos( WND *wnd, RECT *work_rect )
|
|||
*/
|
||||
BOOL WINAPI GetWindowPlacement( HWND hwnd, WINDOWPLACEMENT *wndpl )
|
||||
{
|
||||
RECT work_rect = get_maximized_work_rect( hwnd );
|
||||
WND *pWnd = WIN_GetPtr( hwnd );
|
||||
|
||||
if (!pWnd) return FALSE;
|
||||
|
||||
if (pWnd == WND_DESKTOP)
|
||||
{
|
||||
wndpl->length = sizeof(*wndpl);
|
||||
wndpl->showCmd = SW_SHOWNORMAL;
|
||||
wndpl->flags = 0;
|
||||
wndpl->ptMinPosition.x = -1;
|
||||
wndpl->ptMinPosition.y = -1;
|
||||
wndpl->ptMaxPosition.x = -1;
|
||||
wndpl->ptMaxPosition.y = -1;
|
||||
GetWindowRect( hwnd, &wndpl->rcNormalPosition );
|
||||
return TRUE;
|
||||
}
|
||||
if (pWnd == WND_OTHER_PROCESS)
|
||||
{
|
||||
RECT normal_position;
|
||||
DWORD style;
|
||||
|
||||
if (!GetWindowRect(hwnd, &normal_position))
|
||||
return FALSE;
|
||||
|
||||
FIXME("not fully supported on other process window %p.\n", hwnd);
|
||||
|
||||
wndpl->length = sizeof(*wndpl);
|
||||
style = GetWindowLongW(hwnd, GWL_STYLE);
|
||||
if (style & WS_MINIMIZE)
|
||||
wndpl->showCmd = SW_SHOWMINIMIZED;
|
||||
else
|
||||
wndpl->showCmd = (style & WS_MAXIMIZE) ? SW_SHOWMAXIMIZED : SW_SHOWNORMAL;
|
||||
/* provide some dummy information */
|
||||
wndpl->flags = 0;
|
||||
wndpl->ptMinPosition.x = -1;
|
||||
wndpl->ptMinPosition.y = -1;
|
||||
wndpl->ptMaxPosition.x = -1;
|
||||
wndpl->ptMaxPosition.y = -1;
|
||||
wndpl->rcNormalPosition = normal_position;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* update the placement according to the current style */
|
||||
if (pWnd->dwStyle & WS_MINIMIZE)
|
||||
{
|
||||
pWnd->min_pos.x = pWnd->window_rect.left;
|
||||
pWnd->min_pos.y = pWnd->window_rect.top;
|
||||
}
|
||||
else if (pWnd->dwStyle & WS_MAXIMIZE)
|
||||
{
|
||||
pWnd->max_pos.x = pWnd->window_rect.left;
|
||||
pWnd->max_pos.y = pWnd->window_rect.top;
|
||||
}
|
||||
else
|
||||
{
|
||||
pWnd->normal_rect = pWnd->window_rect;
|
||||
}
|
||||
update_maximized_pos( pWnd, &work_rect );
|
||||
|
||||
wndpl->length = sizeof(*wndpl);
|
||||
if( pWnd->dwStyle & WS_MINIMIZE )
|
||||
wndpl->showCmd = SW_SHOWMINIMIZED;
|
||||
else
|
||||
wndpl->showCmd = ( pWnd->dwStyle & WS_MAXIMIZE ) ? SW_SHOWMAXIMIZED : SW_SHOWNORMAL ;
|
||||
if( pWnd->flags & WIN_RESTORE_MAX )
|
||||
wndpl->flags = WPF_RESTORETOMAXIMIZED;
|
||||
else
|
||||
wndpl->flags = 0;
|
||||
wndpl->ptMinPosition = EMPTYPOINT(pWnd->min_pos) ? pWnd->min_pos : point_win_to_thread_dpi( hwnd, pWnd->min_pos );
|
||||
wndpl->ptMaxPosition = EMPTYPOINT(pWnd->max_pos) ? pWnd->max_pos : point_win_to_thread_dpi( hwnd, pWnd->max_pos );
|
||||
wndpl->rcNormalPosition = rect_win_to_thread_dpi( hwnd, 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;
|
||||
return NtUserCallHwndParam( hwnd, (UINT_PTR)wndpl, NtUserGetWindowPlacement );
|
||||
}
|
||||
|
||||
/* make sure the specified rect is visible on screen */
|
||||
|
|
|
@ -1376,7 +1376,7 @@ BOOL mirror_window_region( HWND hwnd, HRGN hrgn )
|
|||
{
|
||||
RECT rect;
|
||||
|
||||
if (!get_window_rect( hwnd, &rect )) return FALSE;
|
||||
if (!get_window_rect( hwnd, &rect, get_thread_dpi() )) return FALSE;
|
||||
return mirror_region( hrgn, hrgn, rect.right - rect.left ) != ERROR;
|
||||
}
|
||||
|
||||
|
|
|
@ -1945,7 +1945,7 @@ BOOL WINAPI NtUserEnumDisplayMonitors( HDC hdc, RECT *rect, MONITORENUMPROC proc
|
|||
return ret;
|
||||
}
|
||||
|
||||
static BOOL get_monitor_info( HMONITOR handle, MONITORINFO *info )
|
||||
BOOL get_monitor_info( HMONITOR handle, MONITORINFO *info )
|
||||
{
|
||||
struct monitor *monitor;
|
||||
UINT dpi_from, dpi_to;
|
||||
|
@ -2062,6 +2062,27 @@ HMONITOR monitor_from_point( POINT pt, DWORD flags, UINT dpi )
|
|||
return monitor_from_rect( &rect, flags, dpi );
|
||||
}
|
||||
|
||||
/* see MonitorFromWindow */
|
||||
HMONITOR monitor_from_window( HWND hwnd, DWORD flags, UINT dpi )
|
||||
{
|
||||
RECT rect;
|
||||
WINDOWPLACEMENT wp;
|
||||
|
||||
TRACE( "(%p, 0x%08x)\n", hwnd, flags );
|
||||
|
||||
wp.length = sizeof(wp);
|
||||
if (is_iconic( hwnd ) && get_window_placement( hwnd, &wp ))
|
||||
return monitor_from_rect( &wp.rcNormalPosition, flags, dpi );
|
||||
|
||||
if (get_window_rect( hwnd, &rect, dpi ))
|
||||
return monitor_from_rect( &rect, flags, dpi );
|
||||
|
||||
if (!(flags & (MONITOR_DEFAULTTOPRIMARY|MONITOR_DEFAULTTONEAREST))) return 0;
|
||||
/* retrieve the primary */
|
||||
SetRect( &rect, 0, 0, 1, 1 );
|
||||
return monitor_from_rect( &rect, flags, dpi );
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* NtUserGetSystemDpiForProcess (win32u.@)
|
||||
*/
|
||||
|
|
|
@ -289,6 +289,7 @@ extern LRESULT send_message( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam )
|
|||
/* sysparams.c */
|
||||
extern RECT get_display_rect( const WCHAR *display ) DECLSPEC_HIDDEN;
|
||||
extern UINT get_monitor_dpi( HMONITOR monitor ) DECLSPEC_HIDDEN;
|
||||
extern BOOL get_monitor_info( HMONITOR handle, MONITORINFO *info ) DECLSPEC_HIDDEN;
|
||||
extern UINT get_win_monitor_dpi( HWND hwnd ) DECLSPEC_HIDDEN;
|
||||
extern RECT get_primary_monitor_rect( UINT dpi ) DECLSPEC_HIDDEN;
|
||||
extern UINT get_system_dpi(void) DECLSPEC_HIDDEN;
|
||||
|
@ -299,6 +300,7 @@ extern POINT map_dpi_point( POINT pt, UINT dpi_from, UINT dpi_to ) DECLSPEC_HIDD
|
|||
extern RECT map_dpi_rect( RECT rect, UINT dpi_from, UINT dpi_to ) DECLSPEC_HIDDEN;
|
||||
extern HMONITOR monitor_from_point( POINT pt, DWORD flags, UINT dpi ) DECLSPEC_HIDDEN;
|
||||
extern HMONITOR monitor_from_rect( const RECT *rect, DWORD flags, UINT dpi ) DECLSPEC_HIDDEN;
|
||||
extern HMONITOR monitor_from_window( HWND hwnd, DWORD flags, UINT dpi ) DECLSPEC_HIDDEN;
|
||||
extern void user_lock(void) DECLSPEC_HIDDEN;
|
||||
extern void user_unlock(void) DECLSPEC_HIDDEN;
|
||||
extern void user_check_not_lock(void) DECLSPEC_HIDDEN;
|
||||
|
@ -306,10 +308,12 @@ extern void user_check_not_lock(void) DECLSPEC_HIDDEN;
|
|||
/* window.c */
|
||||
struct tagWND;
|
||||
extern HWND get_desktop_window(void) DECLSPEC_HIDDEN;
|
||||
extern BOOL get_window_placement( HWND hwnd, WINDOWPLACEMENT *placement ) DECLSPEC_HIDDEN;
|
||||
extern HWND is_current_thread_window( HWND hwnd ) DECLSPEC_HIDDEN;
|
||||
extern BOOL is_iconic( HWND hwnd ) DECLSPEC_HIDDEN;
|
||||
extern void flush_window_surfaces( BOOL idle ) DECLSPEC_HIDDEN;
|
||||
extern DWORD get_window_long( HWND hwnd, INT offset ) DECLSPEC_HIDDEN;
|
||||
extern BOOL get_window_rect( HWND hwnd, RECT *rect ) DECLSPEC_HIDDEN;
|
||||
extern BOOL get_window_rect( HWND hwnd, RECT *rect, UINT dpi ) DECLSPEC_HIDDEN;
|
||||
extern void register_window_surface( struct window_surface *old,
|
||||
struct window_surface *new ) DECLSPEC_HIDDEN;
|
||||
|
||||
|
|
|
@ -764,7 +764,7 @@ static LONG_PTR get_win_data( const void *ptr, UINT size )
|
|||
}
|
||||
}
|
||||
|
||||
static BOOL is_iconic( HWND hwnd )
|
||||
BOOL is_iconic( HWND hwnd )
|
||||
{
|
||||
return (get_window_long( hwnd, GWL_STYLE ) & WS_MINIMIZE) != 0;
|
||||
}
|
||||
|
@ -1001,8 +1001,8 @@ static void mirror_rect( const RECT *window_rect, RECT *rect )
|
|||
*
|
||||
* Get the window and client rectangles.
|
||||
*/
|
||||
static BOOL get_window_rects( HWND hwnd, enum coords_relative relative, RECT *window_rect,
|
||||
RECT *client_rect, UINT dpi )
|
||||
BOOL get_window_rects( HWND hwnd, enum coords_relative relative, RECT *window_rect,
|
||||
RECT *client_rect, UINT dpi )
|
||||
{
|
||||
WND *win = get_win_ptr( hwnd );
|
||||
BOOL ret = TRUE;
|
||||
|
@ -1134,9 +1134,9 @@ other_process:
|
|||
}
|
||||
|
||||
/* see GetWindowRect */
|
||||
BOOL get_window_rect( HWND hwnd, RECT *rect )
|
||||
BOOL get_window_rect( HWND hwnd, RECT *rect, UINT dpi )
|
||||
{
|
||||
return get_window_rects( hwnd, COORDS_SCREEN, rect, NULL, get_thread_dpi() );
|
||||
return get_window_rects( hwnd, COORDS_SCREEN, rect, NULL, dpi );
|
||||
}
|
||||
|
||||
/* see GetClientRect */
|
||||
|
@ -1412,6 +1412,164 @@ HWND WINAPI NtUserWindowFromPoint( LONG x, LONG y )
|
|||
return window_from_point( 0, pt, &hittest );
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
* get_work_rect
|
||||
*
|
||||
* Get the work area that a maximized window can cover, depending on style.
|
||||
*/
|
||||
static BOOL get_work_rect( HWND hwnd, RECT *rect )
|
||||
{
|
||||
HMONITOR monitor = monitor_from_window( hwnd, MONITOR_DEFAULTTOPRIMARY, get_thread_dpi() );
|
||||
MONITORINFO mon_info;
|
||||
DWORD style;
|
||||
|
||||
if (!monitor) return FALSE;
|
||||
|
||||
mon_info.cbSize = sizeof(mon_info);
|
||||
get_monitor_info( monitor, &mon_info );
|
||||
*rect = mon_info.rcMonitor;
|
||||
|
||||
style = get_window_long( hwnd, GWL_STYLE );
|
||||
if (style & WS_MAXIMIZEBOX)
|
||||
{
|
||||
if ((style & WS_CAPTION) == WS_CAPTION || !(style & (WS_CHILD | WS_POPUP)))
|
||||
*rect = mon_info.rcWork;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static RECT get_maximized_work_rect( HWND hwnd )
|
||||
{
|
||||
RECT work_rect = { 0 };
|
||||
|
||||
if ((get_window_long( hwnd, GWL_STYLE ) & (WS_MINIMIZE | WS_MAXIMIZE)) == WS_MAXIMIZE)
|
||||
{
|
||||
if (!get_work_rect( hwnd, &work_rect ))
|
||||
work_rect = get_primary_monitor_rect( get_thread_dpi() );
|
||||
}
|
||||
return work_rect;
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
* update_maximized_pos
|
||||
*
|
||||
* For top level windows covering the work area, we might have to
|
||||
* "forget" the maximized position. Windows presumably does this
|
||||
* to avoid situations where the border style changes, which would
|
||||
* lead the window to be outside the screen, or the window gets
|
||||
* reloaded on a different screen, and the "saved" position no
|
||||
* longer applies to it (despite being maximized).
|
||||
*
|
||||
* Some applications (e.g. Imperiums: Greek Wars) depend on this.
|
||||
*/
|
||||
static void update_maximized_pos( WND *wnd, RECT *work_rect )
|
||||
{
|
||||
if (wnd->parent && wnd->parent != get_desktop_window())
|
||||
return;
|
||||
|
||||
if (wnd->dwStyle & WS_MAXIMIZE)
|
||||
{
|
||||
if (wnd->window_rect.left <= work_rect->left && wnd->window_rect.top <= work_rect->top &&
|
||||
wnd->window_rect.right >= work_rect->right && wnd->window_rect.bottom >= work_rect->bottom)
|
||||
wnd->max_pos.x = wnd->max_pos.y = -1;
|
||||
}
|
||||
else
|
||||
wnd->max_pos.x = wnd->max_pos.y = -1;
|
||||
}
|
||||
|
||||
static BOOL empty_point( POINT pt )
|
||||
{
|
||||
return pt.x == -1 && pt.y == -1;
|
||||
}
|
||||
|
||||
/* see GetWindowPlacement */
|
||||
BOOL get_window_placement( HWND hwnd, WINDOWPLACEMENT *placement )
|
||||
{
|
||||
RECT work_rect = get_maximized_work_rect( hwnd );
|
||||
WND *win = get_win_ptr( hwnd );
|
||||
UINT win_dpi;
|
||||
|
||||
if (!win) return FALSE;
|
||||
|
||||
if (win == WND_DESKTOP)
|
||||
{
|
||||
placement->length = sizeof(*placement);
|
||||
placement->showCmd = SW_SHOWNORMAL;
|
||||
placement->flags = 0;
|
||||
placement->ptMinPosition.x = -1;
|
||||
placement->ptMinPosition.y = -1;
|
||||
placement->ptMaxPosition.x = -1;
|
||||
placement->ptMaxPosition.y = -1;
|
||||
get_window_rect( hwnd, &placement->rcNormalPosition, get_thread_dpi() );
|
||||
return TRUE;
|
||||
}
|
||||
if (win == WND_OTHER_PROCESS)
|
||||
{
|
||||
RECT normal_position;
|
||||
DWORD style;
|
||||
|
||||
if (!get_window_rect( hwnd, &normal_position, get_thread_dpi() ))
|
||||
return FALSE;
|
||||
|
||||
FIXME("not fully supported on other process window %p.\n", hwnd);
|
||||
|
||||
placement->length = sizeof(*placement);
|
||||
style = get_window_long( hwnd, GWL_STYLE );
|
||||
if (style & WS_MINIMIZE)
|
||||
placement->showCmd = SW_SHOWMINIMIZED;
|
||||
else
|
||||
placement->showCmd = (style & WS_MAXIMIZE) ? SW_SHOWMAXIMIZED : SW_SHOWNORMAL;
|
||||
/* provide some dummy information */
|
||||
placement->flags = 0;
|
||||
placement->ptMinPosition.x = -1;
|
||||
placement->ptMinPosition.y = -1;
|
||||
placement->ptMaxPosition.x = -1;
|
||||
placement->ptMaxPosition.y = -1;
|
||||
placement->rcNormalPosition = normal_position;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* update the placement according to the current style */
|
||||
if (win->dwStyle & WS_MINIMIZE)
|
||||
{
|
||||
win->min_pos.x = win->window_rect.left;
|
||||
win->min_pos.y = win->window_rect.top;
|
||||
}
|
||||
else if (win->dwStyle & WS_MAXIMIZE)
|
||||
{
|
||||
win->max_pos.x = win->window_rect.left;
|
||||
win->max_pos.y = win->window_rect.top;
|
||||
}
|
||||
else
|
||||
{
|
||||
win->normal_rect = win->window_rect;
|
||||
}
|
||||
update_maximized_pos( win, &work_rect );
|
||||
|
||||
placement->length = sizeof(*placement);
|
||||
if (win->dwStyle & WS_MINIMIZE)
|
||||
placement->showCmd = SW_SHOWMINIMIZED;
|
||||
else
|
||||
placement->showCmd = ( win->dwStyle & WS_MAXIMIZE ) ? SW_SHOWMAXIMIZED : SW_SHOWNORMAL ;
|
||||
if (win->flags & WIN_RESTORE_MAX)
|
||||
placement->flags = WPF_RESTORETOMAXIMIZED;
|
||||
else
|
||||
placement->flags = 0;
|
||||
win_dpi = get_dpi_for_window( hwnd );
|
||||
placement->ptMinPosition = empty_point(win->min_pos) ? win->min_pos
|
||||
: map_dpi_point( win->min_pos, win_dpi, get_thread_dpi() );
|
||||
placement->ptMaxPosition = empty_point(win->max_pos) ? win->max_pos
|
||||
: map_dpi_point( win->max_pos, win_dpi, get_thread_dpi() );
|
||||
placement->rcNormalPosition = map_dpi_rect( win->normal_rect, win_dpi, get_thread_dpi() );
|
||||
release_win_ptr( win );
|
||||
|
||||
TRACE( "%p: returning min %d,%d max %d,%d normal %s\n",
|
||||
hwnd, placement->ptMinPosition.x, placement->ptMinPosition.y,
|
||||
placement->ptMaxPosition.x, placement->ptMaxPosition.y,
|
||||
wine_dbgstr_rect(&placement->rcNormalPosition) );
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* NtUserBuildHwndList (win32u.@)
|
||||
*/
|
||||
|
@ -1602,8 +1760,10 @@ ULONG_PTR WINAPI NtUserCallHwndParam( HWND hwnd, DWORD_PTR param, DWORD code )
|
|||
return get_window_long_ptr( hwnd, param, TRUE );
|
||||
case NtUserGetWindowLongPtrW:
|
||||
return get_window_long_ptr( hwnd, param, FALSE );
|
||||
case NtUserGetWindowPlacement:
|
||||
return get_window_placement( hwnd, (WINDOWPLACEMENT *)param );
|
||||
case NtUserGetWindowRect:
|
||||
return get_window_rect( hwnd, (RECT *)param );
|
||||
return get_window_rect( hwnd, (RECT *)param, get_thread_dpi() );
|
||||
case NtUserGetWindowRelative:
|
||||
return HandleToUlong( get_window_relative( hwnd, param ));
|
||||
case NtUserGetWindowThread:
|
||||
|
@ -1612,6 +1772,8 @@ ULONG_PTR WINAPI NtUserCallHwndParam( HWND hwnd, DWORD_PTR param, DWORD code )
|
|||
return get_window_word( hwnd, param );
|
||||
case NtUserIsChild:
|
||||
return is_child( hwnd, UlongToHandle(param) );
|
||||
case NtUserMonitorFromWindow:
|
||||
return HandleToUlong( monitor_from_window( hwnd, param, NtUserMonitorFromWindow ));
|
||||
/* temporary exports */
|
||||
case NtUserIsWindowDrawable:
|
||||
return is_window_drawable( hwnd, param );
|
||||
|
|
|
@ -166,11 +166,13 @@ enum
|
|||
NtUserGetWindowLongW,
|
||||
NtUserGetWindowLongPtrA,
|
||||
NtUserGetWindowLongPtrW,
|
||||
NtUserGetWindowPlacement,
|
||||
NtUserGetWindowRect,
|
||||
NtUserGetWindowRelative,
|
||||
NtUserGetWindowThread,
|
||||
NtUserGetWindowWord,
|
||||
NtUserIsChild,
|
||||
NtUserMonitorFromWindow,
|
||||
/* temporary exports */
|
||||
NtUserIsWindowDrawable,
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue