Commit c7e5ab19 authored by Jacek Caban's avatar Jacek Caban Committed by Alexandre Julliard

win32u: Move GetWindowPlacement and MonitorFromWindow implementation from user32.

parent c45af8f3
......@@ -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,
};
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment