From: Jacek Caban jacek@codeweavers.com
Signed-off-by: Jacek Caban jacek@codeweavers.com Signed-off-by: Huw Davies huw@codeweavers.com --- dlls/user32/user_main.c | 1 + dlls/user32/winpos.c | 92 ++-------------------------------- dlls/win32u/menu.c | 6 +++ dlls/win32u/ntuser_private.h | 1 + dlls/win32u/win32u_private.h | 3 ++ dlls/win32u/window.c | 97 ++++++++++++++++++++++++++++++++++++ include/ntuser.h | 1 + 7 files changed, 113 insertions(+), 88 deletions(-)
diff --git a/dlls/user32/user_main.c b/dlls/user32/user_main.c index bc0dec6b579..15293d76c41 100644 --- a/dlls/user32/user_main.c +++ b/dlls/user32/user_main.c @@ -154,6 +154,7 @@ static void CDECL free_win_ptr( WND *win )
static const struct user_callbacks user_funcs = { + AdjustWindowRectEx, CopyImage, DestroyCaret, DestroyMenu, diff --git a/dlls/user32/winpos.c b/dlls/user32/winpos.c index b3e8aff3cfa..1951f887351 100644 --- a/dlls/user32/winpos.c +++ b/dlls/user32/winpos.c @@ -48,8 +48,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(win); (((style) & WS_THICKFRAME) && \ !(((style) & (WS_DLGFRAME|WS_BORDER)) == WS_DLGFRAME))
-#define EMPTYPOINT(pt) ((pt).x == -1 && (pt).y == -1) - #define ON_LEFT_BORDER(hit) \ (((hit) == HTLEFT) || ((hit) == HTTOPLEFT) || ((hit) == HTBOTTOMLEFT)) #define ON_RIGHT_BORDER(hit) \ @@ -548,94 +546,12 @@ static BOOL get_work_rect( HWND hwnd, RECT *rect ) */ MINMAXINFO WINPOS_GetMinMaxInfo( HWND hwnd ) { - DPI_AWARENESS_CONTEXT context; - RECT rc_work, rc_primary; - MINMAXINFO MinMax; - INT xinc, yinc; - LONG style = GetWindowLongW( hwnd, GWL_STYLE ); - LONG adjustedStyle; - LONG exstyle = GetWindowLongW( hwnd, GWL_EXSTYLE ); - RECT rc; - WND *win; - - context = SetThreadDpiAwarenessContext( GetWindowDpiAwarenessContext( hwnd )); - - /* Compute default values */ - - GetWindowRect(hwnd, &rc); - MinMax.ptReserved.x = rc.left; - MinMax.ptReserved.y = rc.top; - - if ((style & WS_CAPTION) == WS_CAPTION) - adjustedStyle = style & ~WS_BORDER; /* WS_CAPTION = WS_DLGFRAME | WS_BORDER */ - else - adjustedStyle = style; - - GetClientRect(NtUserGetAncestor(hwnd,GA_PARENT), &rc); - AdjustWindowRectEx(&rc, adjustedStyle, ((style & WS_POPUP) && GetMenu(hwnd)), exstyle); - - xinc = -rc.left; - yinc = -rc.top; - - MinMax.ptMaxSize.x = rc.right - rc.left; - MinMax.ptMaxSize.y = rc.bottom - rc.top; - if (style & (WS_DLGFRAME | WS_BORDER)) - { - MinMax.ptMinTrackSize.x = GetSystemMetrics(SM_CXMINTRACK); - MinMax.ptMinTrackSize.y = GetSystemMetrics(SM_CYMINTRACK); - } - else - { - MinMax.ptMinTrackSize.x = 2 * xinc; - MinMax.ptMinTrackSize.y = 2 * yinc; - } - MinMax.ptMaxTrackSize.x = GetSystemMetrics(SM_CXMAXTRACK); - MinMax.ptMaxTrackSize.y = GetSystemMetrics(SM_CYMAXTRACK); - MinMax.ptMaxPosition.x = -xinc; - MinMax.ptMaxPosition.y = -yinc; - - if ((win = WIN_GetPtr( hwnd )) && win != WND_DESKTOP && win != WND_OTHER_PROCESS) - { - if (!EMPTYPOINT(win->max_pos)) MinMax.ptMaxPosition = win->max_pos; - WIN_ReleasePtr( win ); - } - - SendMessageW( hwnd, WM_GETMINMAXINFO, 0, (LPARAM)&MinMax ); - - /* if the app didn't change the values, adapt them for the current monitor */ - - if (get_work_rect( hwnd, &rc_work )) - { - rc_primary = get_primary_monitor_rect(); - if (MinMax.ptMaxSize.x == (rc_primary.right - rc_primary.left) + 2 * xinc && - MinMax.ptMaxSize.y == (rc_primary.bottom - rc_primary.top) + 2 * yinc) - { - MinMax.ptMaxSize.x = (rc_work.right - rc_work.left) + 2 * xinc; - MinMax.ptMaxSize.y = (rc_work.bottom - rc_work.top) + 2 * yinc; - } - if (MinMax.ptMaxPosition.x == -xinc && MinMax.ptMaxPosition.y == -yinc) - { - MinMax.ptMaxPosition.x = rc_work.left - xinc; - MinMax.ptMaxPosition.y = rc_work.top - yinc; - } - } - - /* Some sanity checks */ - - TRACE("%d %d / %d %d / %d %d / %d %d\n", - MinMax.ptMaxSize.x, MinMax.ptMaxSize.y, - MinMax.ptMaxPosition.x, MinMax.ptMaxPosition.y, - MinMax.ptMaxTrackSize.x, MinMax.ptMaxTrackSize.y, - MinMax.ptMinTrackSize.x, MinMax.ptMinTrackSize.y); - MinMax.ptMaxTrackSize.x = max( MinMax.ptMaxTrackSize.x, - MinMax.ptMinTrackSize.x ); - MinMax.ptMaxTrackSize.y = max( MinMax.ptMaxTrackSize.y, - MinMax.ptMinTrackSize.y ); - - SetThreadDpiAwarenessContext( context ); - return MinMax; + MINMAXINFO info; + NtUserCallHwndParam( hwnd, (UINT_PTR)&info, NtUserGetMinMaxInfo ); + return info; }
+ static POINT get_first_minimized_child_pos( const RECT *parent, const MINIMIZEDMETRICS *mm, int width, int height ) { diff --git a/dlls/win32u/menu.c b/dlls/win32u/menu.c index 1e8410d347e..921c5752536 100644 --- a/dlls/win32u/menu.c +++ b/dlls/win32u/menu.c @@ -106,6 +106,12 @@ BOOL WINAPI NtUserDestroyAcceleratorTable( HACCEL handle ) return TRUE; }
+/* see GetMenu */ +HMENU get_menu( HWND hwnd ) +{ + return UlongToHandle( get_window_long( hwnd, GWLP_ID )); +} + /********************************************************************** * NtUserDestroyMenu (win32u.@) */ diff --git a/dlls/win32u/ntuser_private.h b/dlls/win32u/ntuser_private.h index b3cafe791df..51f17f63de5 100644 --- a/dlls/win32u/ntuser_private.h +++ b/dlls/win32u/ntuser_private.h @@ -30,6 +30,7 @@ struct tagWND;
struct user_callbacks { + BOOL (WINAPI *pAdjustWindowRectEx)( RECT *, DWORD, BOOL, DWORD ); HANDLE (WINAPI *pCopyImage)( HANDLE, UINT, INT, INT, UINT ); BOOL (WINAPI *pDestroyCaret)(void); BOOL (WINAPI *pDestroyMenu)( HMENU ); diff --git a/dlls/win32u/win32u_private.h b/dlls/win32u/win32u_private.h index 83b0e093a20..2e8a8e3da8e 100644 --- a/dlls/win32u/win32u_private.h +++ b/dlls/win32u/win32u_private.h @@ -316,6 +316,9 @@ extern BOOL WINAPI release_capture(void) DECLSPEC_HIDDEN; extern BOOL set_capture_window( HWND hwnd, UINT gui_flags, HWND *prev_ret ) DECLSPEC_HIDDEN; extern BOOL set_foreground_window( HWND hwnd, BOOL mouse ) DECLSPEC_HIDDEN;
+/* menu.c */ +extern HMENU get_menu( HWND hwnd ) DECLSPEC_HIDDEN; + /* message.c */ extern BOOL kill_system_timer( HWND hwnd, UINT_PTR id ) DECLSPEC_HIDDEN; extern LRESULT post_message( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam ) DECLSPEC_HIDDEN; diff --git a/dlls/win32u/window.c b/dlls/win32u/window.c index f8d147b785c..1069ace0794 100644 --- a/dlls/win32u/window.c +++ b/dlls/win32u/window.c @@ -3267,6 +3267,100 @@ static void send_parent_notify( HWND hwnd, UINT msg ) } }
+/******************************************************************* + * get_min_max_info + * + * Get the minimized and maximized information for a window. + */ +static MINMAXINFO get_min_max_info( HWND hwnd ) +{ + LONG style = get_window_long( hwnd, GWL_STYLE ); + LONG exstyle = get_window_long( hwnd, GWL_EXSTYLE ); + DPI_AWARENESS_CONTEXT context; + RECT rc_work, rc_primary; + LONG adjusted_style; + MINMAXINFO minmax; + INT xinc, yinc; + RECT rc; + WND *win; + + context = set_thread_dpi_awareness_context( get_window_dpi_awareness_context( hwnd )); + + /* Compute default values */ + + get_window_rect( hwnd, &rc, get_thread_dpi() ); + minmax.ptReserved.x = rc.left; + minmax.ptReserved.y = rc.top; + + if ((style & WS_CAPTION) == WS_CAPTION) + adjusted_style = style & ~WS_BORDER; /* WS_CAPTION = WS_DLGFRAME | WS_BORDER */ + else + adjusted_style = style; + + get_client_rect( NtUserGetAncestor( hwnd, GA_PARENT ), &rc ); + if (user_callbacks) + user_callbacks->pAdjustWindowRectEx( &rc, adjusted_style, + (style & WS_POPUP) && get_menu( hwnd ), exstyle); + + xinc = -rc.left; + yinc = -rc.top; + + minmax.ptMaxSize.x = rc.right - rc.left; + minmax.ptMaxSize.y = rc.bottom - rc.top; + if (style & (WS_DLGFRAME | WS_BORDER)) + { + minmax.ptMinTrackSize.x = get_system_metrics( SM_CXMINTRACK ); + minmax.ptMinTrackSize.y = get_system_metrics( SM_CYMINTRACK ); + } + else + { + minmax.ptMinTrackSize.x = 2 * xinc; + minmax.ptMinTrackSize.y = 2 * yinc; + } + minmax.ptMaxTrackSize.x = get_system_metrics( SM_CXMAXTRACK ); + minmax.ptMaxTrackSize.y = get_system_metrics( SM_CYMAXTRACK ); + minmax.ptMaxPosition.x = -xinc; + minmax.ptMaxPosition.y = -yinc; + + if ((win = get_win_ptr( hwnd )) && win != WND_DESKTOP && win != WND_OTHER_PROCESS) + { + if (!empty_point( win->max_pos )) minmax.ptMaxPosition = win->max_pos; + release_win_ptr( win ); + } + + send_message( hwnd, WM_GETMINMAXINFO, 0, (LPARAM)&minmax ); + + /* if the app didn't change the values, adapt them for the current monitor */ + + if (get_work_rect( hwnd, &rc_work )) + { + rc_primary = get_primary_monitor_rect( get_thread_dpi() ); + if (minmax.ptMaxSize.x == (rc_primary.right - rc_primary.left) + 2 * xinc && + minmax.ptMaxSize.y == (rc_primary.bottom - rc_primary.top) + 2 * yinc) + { + minmax.ptMaxSize.x = (rc_work.right - rc_work.left) + 2 * xinc; + minmax.ptMaxSize.y = (rc_work.bottom - rc_work.top) + 2 * yinc; + } + if (minmax.ptMaxPosition.x == -xinc && minmax.ptMaxPosition.y == -yinc) + { + minmax.ptMaxPosition.x = rc_work.left - xinc; + minmax.ptMaxPosition.y = rc_work.top - yinc; + } + } + + TRACE( "%d %d / %d %d / %d %d / %d %d\n", + minmax.ptMaxSize.x, minmax.ptMaxSize.y, + minmax.ptMaxPosition.x, minmax.ptMaxPosition.y, + minmax.ptMaxTrackSize.x, minmax.ptMaxTrackSize.y, + minmax.ptMinTrackSize.x, minmax.ptMinTrackSize.y ); + + minmax.ptMaxTrackSize.x = max( minmax.ptMaxTrackSize.x, minmax.ptMinTrackSize.x ); + minmax.ptMaxTrackSize.y = max( minmax.ptMaxTrackSize.y, minmax.ptMinTrackSize.y ); + + set_thread_dpi_awareness_context( context ); + return minmax; +} + /******************************************************************* * update_window_state * @@ -3671,6 +3765,9 @@ ULONG_PTR WINAPI NtUserCallHwndParam( HWND hwnd, DWORD_PTR param, DWORD code ) return get_class_word( hwnd, param ); case NtUserGetClientRect: return get_client_rect( hwnd, (RECT *)param ); + case NtUserGetMinMaxInfo: + *(MINMAXINFO *)param = get_min_max_info( hwnd ); + return 0; case NtUserGetWindowInfo: return get_window_info( hwnd, (WINDOWINFO *)param ); case NtUserGetWindowLongA: diff --git a/include/ntuser.h b/include/ntuser.h index de958caa735..274c0cf31c9 100644 --- a/include/ntuser.h +++ b/include/ntuser.h @@ -167,6 +167,7 @@ enum NtUserGetClassLongPtrW, NtUserGetClassWord, NtUserGetClientRect, + NtUserGetMinMaxInfo, NtUserGetWindowInfo, NtUserGetWindowLongA, NtUserGetWindowLongW,