From: Rémi Bernon rbernon@codeweavers.com
--- dlls/win32u/dce.c | 13 ++--- dlls/win32u/defwnd.c | 98 ++++++++++++++++++------------------ dlls/win32u/win32u_private.h | 4 +- dlls/win32u/window.c | 58 ++++++++++++++------- 4 files changed, 98 insertions(+), 75 deletions(-)
diff --git a/dlls/win32u/dce.c b/dlls/win32u/dce.c index d7225edc995..5faea17a6a2 100644 --- a/dlls/win32u/dce.c +++ b/dlls/win32u/dce.c @@ -1328,25 +1328,26 @@ static HRGN send_ncpaint( HWND hwnd, HWND *child, UINT *flags )
if (whole_rgn) { + struct window_rects rects; UINT context; - RECT client, window, update; + RECT update; INT type;
context = set_thread_dpi_awareness_context( get_window_dpi_awareness_context( hwnd ));
/* check if update rgn overlaps with nonclient area */ type = NtGdiGetRgnBox( whole_rgn, &update ); - get_window_rects( hwnd, COORDS_SCREEN, &window, &client, get_thread_dpi() ); + get_window_rects( hwnd, COORDS_SCREEN, &rects, get_thread_dpi() );
if ((*flags & UPDATE_NONCLIENT) || - update.left < client.left || update.top < client.top || - update.right > client.right || update.bottom > client.bottom) + update.left < rects.client.left || update.top < rects.client.top || + update.right > rects.client.right || update.bottom > rects.client.bottom) { - client_rgn = NtGdiCreateRectRgn( client.left, client.top, client.right, client.bottom ); + client_rgn = NtGdiCreateRectRgn( rects.client.left, rects.client.top, rects.client.right, rects.client.bottom ); NtGdiCombineRgn( client_rgn, client_rgn, whole_rgn, RGN_AND );
/* check if update rgn contains complete nonclient area */ - if (type == SIMPLEREGION && EqualRect( &window, &update )) + if (type == SIMPLEREGION && EqualRect( &rects.window, &update )) { NtGdiDeleteObjectApp( whole_rgn ); whole_rgn = (HRGN)1; diff --git a/dlls/win32u/defwnd.c b/dlls/win32u/defwnd.c index b67a1a0ca8b..c8b9897644c 100644 --- a/dlls/win32u/defwnd.c +++ b/dlls/win32u/defwnd.c @@ -1905,51 +1905,51 @@ static void handle_nc_calc_size( HWND hwnd, WPARAM wparam, RECT *win_rect )
LRESULT handle_nc_hit_test( HWND hwnd, POINT pt ) { - RECT rect, client_rect; + struct window_rects rects; DWORD style, ex_style;
TRACE( "hwnd %p pt %d,%d\n", hwnd, (int)pt.x, (int)pt.y );
- get_window_rects( hwnd, COORDS_SCREEN, &rect, &client_rect, get_thread_dpi() ); - if (!PtInRect( &rect, pt )) return HTNOWHERE; + get_window_rects( hwnd, COORDS_SCREEN, &rects, get_thread_dpi() ); + if (!PtInRect( &rects.window, pt )) return HTNOWHERE;
style = get_window_long( hwnd, GWL_STYLE ); ex_style = get_window_long( hwnd, GWL_EXSTYLE );
- if (PtInRect( &client_rect, pt )) return HTCLIENT; + if (PtInRect( &rects.client, pt )) return HTCLIENT;
/* Check borders */ if (has_thick_frame( style, ex_style )) { - InflateRect( &rect, -get_system_metrics( SM_CXFRAME ), -get_system_metrics( SM_CYFRAME )); - if (!PtInRect( &rect, pt )) + InflateRect( &rects.window, -get_system_metrics( SM_CXFRAME ), -get_system_metrics( SM_CYFRAME )); + if (!PtInRect( &rects.window, pt )) { /* Check top sizing border */ - if (pt.y < rect.top) + if (pt.y < rects.window.top) { - if (pt.x < rect.left + get_system_metrics( SM_CXSIZE )) return HTTOPLEFT; - if (pt.x >= rect.right - get_system_metrics( SM_CXSIZE )) return HTTOPRIGHT; + if (pt.x < rects.window.left + get_system_metrics( SM_CXSIZE )) return HTTOPLEFT; + if (pt.x >= rects.window.right - get_system_metrics( SM_CXSIZE )) return HTTOPRIGHT; return HTTOP; } /* Check bottom sizing border */ - if (pt.y >= rect.bottom) + if (pt.y >= rects.window.bottom) { - if (pt.x < rect.left + get_system_metrics( SM_CXSIZE )) return HTBOTTOMLEFT; - if (pt.x >= rect.right - get_system_metrics( SM_CXSIZE )) return HTBOTTOMRIGHT; + if (pt.x < rects.window.left + get_system_metrics( SM_CXSIZE )) return HTBOTTOMLEFT; + if (pt.x >= rects.window.right - get_system_metrics( SM_CXSIZE )) return HTBOTTOMRIGHT; return HTBOTTOM; } /* Check left sizing border */ - if (pt.x < rect.left) + if (pt.x < rects.window.left) { - if (pt.y < rect.top + get_system_metrics( SM_CYSIZE )) return HTTOPLEFT; - if (pt.y >= rect.bottom - get_system_metrics( SM_CYSIZE )) return HTBOTTOMLEFT; + if (pt.y < rects.window.top + get_system_metrics( SM_CYSIZE )) return HTTOPLEFT; + if (pt.y >= rects.window.bottom - get_system_metrics( SM_CYSIZE )) return HTBOTTOMLEFT; return HTLEFT; } /* Check right sizing border */ - if (pt.x >= rect.right) + if (pt.x >= rects.window.right) { - if (pt.y < rect.top + get_system_metrics( SM_CYSIZE )) return HTTOPRIGHT; - if (pt.y >= rect.bottom-get_system_metrics( SM_CYSIZE )) return HTBOTTOMRIGHT; + if (pt.y < rects.window.top + get_system_metrics( SM_CYSIZE )) return HTTOPRIGHT; + if (pt.y >= rects.window.bottom-get_system_metrics( SM_CYSIZE )) return HTBOTTOMRIGHT; return HTRIGHT; } } @@ -1957,22 +1957,22 @@ LRESULT handle_nc_hit_test( HWND hwnd, POINT pt ) else /* No thick frame */ { if (has_dialog_frame( style, ex_style )) - InflateRect( &rect, -get_system_metrics( SM_CXDLGFRAME ), + InflateRect( &rects.window, -get_system_metrics( SM_CXDLGFRAME ), -get_system_metrics( SM_CYDLGFRAME )); else if (has_thin_frame( style )) - InflateRect(&rect, -get_system_metrics( SM_CXBORDER ), + InflateRect(&rects.window, -get_system_metrics( SM_CXBORDER ), -get_system_metrics( SM_CYBORDER )); - if (!PtInRect( &rect, pt )) return HTBORDER; + if (!PtInRect( &rects.window, pt )) return HTBORDER; }
/* Check caption */ if ((style & WS_CAPTION) == WS_CAPTION) { if (ex_style & WS_EX_TOOLWINDOW) - rect.top += get_system_metrics( SM_CYSMCAPTION ) - 1; + rects.window.top += get_system_metrics( SM_CYSMCAPTION ) - 1; else - rect.top += get_system_metrics( SM_CYCAPTION ) - 1; - if (!PtInRect( &rect, pt )) + rects.window.top += get_system_metrics( SM_CYCAPTION ) - 1; + if (!PtInRect( &rects.window, pt )) { BOOL min_or_max_box = (style & WS_SYSMENU) && (style & (WS_MINIMIZEBOX | WS_MAXIMIZEBOX)); if (ex_style & WS_EX_LAYOUTRTL) @@ -1981,26 +1981,26 @@ LRESULT handle_nc_hit_test( HWND hwnd, POINT pt ) if ((style & WS_SYSMENU) && !(ex_style & WS_EX_TOOLWINDOW) && get_nc_icon_for_window( hwnd )) { - rect.right -= get_system_metrics( SM_CYCAPTION ) - 1; - if (pt.x > rect.right) return HTSYSMENU; + rects.window.right -= get_system_metrics( SM_CYCAPTION ) - 1; + if (pt.x > rects.window.right) return HTSYSMENU; }
/* Check close button */ if (style & WS_SYSMENU) { - rect.left += get_system_metrics( SM_CYCAPTION ); - if (pt.x < rect.left) return HTCLOSE; + rects.window.left += get_system_metrics( SM_CYCAPTION ); + if (pt.x < rects.window.left) return HTCLOSE; }
if (min_or_max_box && !(ex_style & WS_EX_TOOLWINDOW)) { /* Check maximize box */ - rect.left += get_system_metrics( SM_CXSIZE ); - if (pt.x < rect.left) return HTMAXBUTTON; + rects.window.left += get_system_metrics( SM_CXSIZE ); + if (pt.x < rects.window.left) return HTMAXBUTTON;
/* Check minimize box */ - rect.left += get_system_metrics( SM_CXSIZE ); - if (pt.x < rect.left) return HTMINBUTTON; + rects.window.left += get_system_metrics( SM_CXSIZE ); + if (pt.x < rects.window.left) return HTMINBUTTON; } } else @@ -2009,26 +2009,26 @@ LRESULT handle_nc_hit_test( HWND hwnd, POINT pt ) if ((style & WS_SYSMENU) && !(ex_style & WS_EX_TOOLWINDOW) && get_nc_icon_for_window( hwnd )) { - rect.left += get_system_metrics( SM_CYCAPTION ) - 1; - if (pt.x < rect.left) return HTSYSMENU; + rects.window.left += get_system_metrics( SM_CYCAPTION ) - 1; + if (pt.x < rects.window.left) return HTSYSMENU; }
/* Check close button */ if (style & WS_SYSMENU) { - rect.right -= get_system_metrics( SM_CYCAPTION ); - if (pt.x > rect.right) return HTCLOSE; + rects.window.right -= get_system_metrics( SM_CYCAPTION ); + if (pt.x > rects.window.right) return HTCLOSE; }
if (min_or_max_box && !(ex_style & WS_EX_TOOLWINDOW)) { /* Check maximize box */ - rect.right -= get_system_metrics( SM_CXSIZE ); - if (pt.x > rect.right) return HTMAXBUTTON; + rects.window.right -= get_system_metrics( SM_CXSIZE ); + if (pt.x > rects.window.right) return HTMAXBUTTON;
/* Check minimize box */ - rect.right -= get_system_metrics( SM_CXSIZE ); - if (pt.x > rect.right) return HTMINBUTTON; + rects.window.right -= get_system_metrics( SM_CXSIZE ); + if (pt.x > rects.window.right) return HTMINBUTTON; } } return HTCAPTION; @@ -2036,8 +2036,8 @@ LRESULT handle_nc_hit_test( HWND hwnd, POINT pt ) }
/* Check menu bar */ - if (has_menu( hwnd, style ) && (pt.y < client_rect.top) && - (pt.x >= client_rect.left) && (pt.x < client_rect.right)) + if (has_menu( hwnd, style ) && (pt.y < rects.client.top) && + (pt.x >= rects.client.left) && (pt.x < rects.client.right)) return HTMENU;
/* Check vertical scroll bar */ @@ -2045,23 +2045,23 @@ LRESULT handle_nc_hit_test( HWND hwnd, POINT pt ) if (style & WS_VSCROLL) { if (ex_style & WS_EX_LEFTSCROLLBAR) - client_rect.left -= get_system_metrics( SM_CXVSCROLL ); + rects.client.left -= get_system_metrics( SM_CXVSCROLL ); else - client_rect.right += get_system_metrics( SM_CXVSCROLL ); - if (PtInRect( &client_rect, pt )) return HTVSCROLL; + rects.client.right += get_system_metrics( SM_CXVSCROLL ); + if (PtInRect( &rects.client, pt )) return HTVSCROLL; }
/* Check horizontal scroll bar */ if (style & WS_HSCROLL) { - client_rect.bottom += get_system_metrics( SM_CYHSCROLL ); - if (PtInRect( &client_rect, pt )) + rects.client.bottom += get_system_metrics( SM_CYHSCROLL ); + if (PtInRect( &rects.client, pt )) { /* Check size box */ if ((style & WS_VSCROLL) && ((ex_style & WS_EX_LEFTSCROLLBAR) - ? (pt.x <= client_rect.left + get_system_metrics( SM_CXVSCROLL )) - : (pt.x >= client_rect.right - get_system_metrics( SM_CXVSCROLL )))) + ? (pt.x <= rects.client.left + get_system_metrics( SM_CXVSCROLL )) + : (pt.x >= rects.client.right - get_system_metrics( SM_CXVSCROLL )))) return HTSIZE; return HTHSCROLL; } diff --git a/dlls/win32u/win32u_private.h b/dlls/win32u/win32u_private.h index 3d7e3b41592..73933acc14a 100644 --- a/dlls/win32u/win32u_private.h +++ b/dlls/win32u/win32u_private.h @@ -259,8 +259,8 @@ extern BOOL get_window_rect( HWND hwnd, RECT *rect, UINT dpi ); enum coords_relative; extern BOOL get_window_rect_rel( HWND hwnd, enum coords_relative rel, RECT *rect, UINT dpi ); extern BOOL get_client_rect_rel( HWND hwnd, enum coords_relative rel, RECT *rect, UINT dpi ); -extern BOOL get_window_rects( HWND hwnd, enum coords_relative relative, RECT *window_rect, - RECT *client_rect, UINT dpi ); +extern BOOL get_window_rects( HWND hwnd, enum coords_relative relative, + struct window_rects *rects, UINT dpi ); extern HWND *list_window_children( HDESK desktop, HWND hwnd, UNICODE_STRING *class, DWORD tid ); extern int map_window_points( HWND hwnd_from, HWND hwnd_to, POINT *points, UINT count, diff --git a/dlls/win32u/window.c b/dlls/win32u/window.c index 39d21907ca3..040411d3e79 100644 --- a/dlls/win32u/window.c +++ b/dlls/win32u/window.c @@ -1562,8 +1562,7 @@ static void mirror_rect( const RECT *window_rect, RECT *rect ) * * Get the window and client rectangles. */ -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, struct window_rects *rects, UINT dpi ) { WND *win = get_win_ptr( hwnd ); BOOL ret = TRUE; @@ -1587,8 +1586,9 @@ BOOL get_window_rects( HWND hwnd, enum coords_relative relative, RECT *window_re { rect = get_primary_monitor_rect( dpi ); } - if (window_rect) *window_rect = rect; - if (client_rect) *client_rect = rect; + rects->window = rect; + rects->client = rect; + rects->visible = rect; return TRUE; } if (win != WND_OTHER_PROCESS) @@ -1596,20 +1596,29 @@ BOOL get_window_rects( HWND hwnd, enum coords_relative relative, RECT *window_re UINT window_dpi = get_dpi_for_window( hwnd ); RECT window = win->window_rect; RECT client = win->client_rect; + RECT visible = win->visible_rect;
switch (relative) { case COORDS_CLIENT: OffsetRect( &window, -win->client_rect.left, -win->client_rect.top ); OffsetRect( &client, -win->client_rect.left, -win->client_rect.top ); + OffsetRect( &visible, -win->client_rect.left, -win->client_rect.top ); if (win->dwExStyle & WS_EX_LAYOUTRTL) + { mirror_rect( &win->client_rect, &window ); + mirror_rect( &win->client_rect, &visible ); + } break; case COORDS_WINDOW: OffsetRect( &window, -win->window_rect.left, -win->window_rect.top ); OffsetRect( &client, -win->window_rect.left, -win->window_rect.top ); + OffsetRect( &visible, -win->window_rect.left, -win->window_rect.top ); if (win->dwExStyle & WS_EX_LAYOUTRTL) + { mirror_rect( &win->window_rect, &client ); + mirror_rect( &win->window_rect, &visible ); + } break; case COORDS_PARENT: if (win->parent) @@ -1631,6 +1640,7 @@ BOOL get_window_rects( HWND hwnd, enum coords_relative relative, RECT *window_re { mirror_rect( &parent->client_rect, &window ); mirror_rect( &parent->client_rect, &client ); + mirror_rect( &parent->client_rect, &visible ); } release_win_ptr( parent ); } @@ -1656,12 +1666,14 @@ BOOL get_window_rects( HWND hwnd, enum coords_relative relative, RECT *window_re { OffsetRect( &window, win->client_rect.left, win->client_rect.top ); OffsetRect( &client, win->client_rect.left, win->client_rect.top ); + OffsetRect( &visible, win->client_rect.left, win->client_rect.top ); } } break; } - if (window_rect) *window_rect = map_dpi_rect( window, window_dpi, dpi ); - if (client_rect) *client_rect = map_dpi_rect( client, window_dpi, dpi ); + rects->window = map_dpi_rect( window, window_dpi, dpi ); + rects->client = map_dpi_rect( client, window_dpi, dpi ); + rects->visible = map_dpi_rect( visible, window_dpi, dpi ); release_win_ptr( win ); return TRUE; } @@ -1674,8 +1686,9 @@ other_process: req->dpi = dpi; if ((ret = !wine_server_call_err( req ))) { - if (window_rect) *window_rect = wine_server_get_rect( reply->window ); - if (client_rect) *client_rect = wine_server_get_rect( reply->client ); + rects->window = wine_server_get_rect( reply->window ); + rects->client = wine_server_get_rect( reply->client ); + rects->visible = rects->window; } } SERVER_END_REQ; @@ -1684,7 +1697,10 @@ other_process:
BOOL get_window_rect_rel( HWND hwnd, enum coords_relative rel, RECT *rect, UINT dpi ) { - return get_window_rects( hwnd, rel, rect, NULL, dpi ); + struct window_rects rects; + BOOL ret = get_window_rects( hwnd, rel, &rects, dpi ); + if (ret) *rect = rects.window; + return ret; }
/* see GetWindowRect */ @@ -1695,7 +1711,10 @@ BOOL get_window_rect( HWND hwnd, RECT *rect, UINT dpi )
BOOL get_client_rect_rel( HWND hwnd, enum coords_relative rel, RECT *rect, UINT dpi ) { - return get_window_rects( hwnd, rel, NULL, rect, dpi ); + struct window_rects rects; + BOOL ret = get_window_rects( hwnd, rel, &rects, dpi ); + if (ret) *rect = rects.client; + return ret; }
/* see GetClientRect */ @@ -1707,11 +1726,13 @@ BOOL get_client_rect( HWND hwnd, RECT *rect, UINT dpi ) /* see GetWindowInfo */ static BOOL get_window_info( HWND hwnd, WINDOWINFO *info ) { + struct window_rects rects;
- if (!info || !get_window_rects( hwnd, COORDS_SCREEN, &info->rcWindow, - &info->rcClient, get_thread_dpi() )) + if (!info || !get_window_rects( hwnd, COORDS_SCREEN, &rects, get_thread_dpi() )) return FALSE;
+ info->rcWindow = rects.window; + info->rcClient = rects.client; info->dwStyle = get_window_long( hwnd, GWL_STYLE ); info->dwExStyle = get_window_long( hwnd, GWL_EXSTYLE ); info->dwWindowStatus = get_active_window() == hwnd ? WS_ACTIVECAPTION : 0; @@ -1928,13 +1949,11 @@ static BOOL apply_window_pos( HWND hwnd, HWND insert_after, UINT swp_flags, stru
is_layered = new_surface && new_surface->alpha_mask;
- get_window_rects( hwnd, COORDS_SCREEN, &old_rects.window, NULL, get_thread_dpi() ); + get_window_rects( hwnd, COORDS_SCREEN, &old_rects, get_thread_dpi() ); if (IsRectEmpty( &valid_rects[0] ) || is_layered) valid_rects = NULL;
if (!(win = get_win_ptr( hwnd )) || win == WND_DESKTOP || win == WND_OTHER_PROCESS) return FALSE;
- old_rects.visible = win->visible_rect; - old_rects.client = win->client_rect; old_surface = win->surface; if (old_surface != new_surface) swp_flags |= SWP_FRAMECHANGED; /* force refreshing non-client area */ if (new_surface == &dummy_surface) swp_flags |= SWP_NOREDRAW; @@ -2215,7 +2234,7 @@ BOOL WINAPI NtUserUpdateLayeredWindow( HWND hwnd, HDC hdc_dst, const POINT *pts_ return FALSE; }
- get_window_rects( hwnd, COORDS_PARENT, &new_rects.window, &new_rects.client, get_thread_dpi() ); + get_window_rects( hwnd, COORDS_PARENT, &new_rects, get_thread_dpi() );
if (pts_dst) { @@ -2223,6 +2242,7 @@ BOOL WINAPI NtUserUpdateLayeredWindow( HWND hwnd, HDC hdc_dst, const POINT *pts_ offset.cy = pts_dst->y - new_rects.window.top; OffsetRect( &new_rects.client, offset.cx, offset.cy ); OffsetRect( &new_rects.window, offset.cx, offset.cy ); + OffsetRect( &new_rects.visible, offset.cx, offset.cy ); swp_flags &= ~SWP_NOMOVE; } if (size) @@ -2243,6 +2263,8 @@ BOOL WINAPI NtUserUpdateLayeredWindow( HWND hwnd, HDC hdc_dst, const POINT *pts_ new_rects.client.bottom += offset.cy; new_rects.window.right += offset.cx; new_rects.window.bottom += offset.cy; + new_rects.visible.right += offset.cx; + new_rects.visible.bottom += offset.cy; swp_flags &= ~SWP_NOSIZE; }
@@ -3137,7 +3159,7 @@ static BOOL calc_winpos( WINDOWPOS *winpos, struct window_rects *old_rects, stru win == WND_OTHER_PROCESS || win == WND_DESKTOP) return FALSE;
/* Calculate new position and size */ - get_window_rects( winpos->hwnd, COORDS_PARENT, &old_rects->window, &old_rects->client, get_thread_dpi() ); + get_window_rects( winpos->hwnd, COORDS_PARENT, old_rects, get_thread_dpi() ); old_rects->visible = win->visible_rect; *new_rects = *old_rects;
@@ -4360,7 +4382,7 @@ void update_window_state( HWND hwnd ) }
context = set_thread_dpi_awareness_context( get_window_dpi_awareness_context( hwnd )); - get_window_rects( hwnd, COORDS_PARENT, &new_rects.window, &new_rects.client, get_thread_dpi() ); + get_window_rects( hwnd, COORDS_PARENT, &new_rects, get_thread_dpi() ); valid_rects[0] = valid_rects[1] = new_rects.client;
surface = create_window_surface( hwnd, swp_flags, FALSE, &new_rects, &surface_rect );