[PATCH 0/2] MR10809: comctl32: Fix VARHEIGHT rebar scaling when cyIntegral == 0
This is a test and fix for an edge case in the rebar component where `cyChild` is set to a larger value than `cyMaxChild` while `cyIntegral` is exactly 0 on a VARIABLEHEIGHT rebar. On Windows, at least the two Win11 machines I have acces to, the WinAPI seems to clamp the value to `cyMaxChild` so the test passes. On Wine, it does not clamp the value and the test fails, but passes with the fix. Specifically, Wine's behaviour results in the program EffectsEd3 from the modding tools of Call of Duty: World at War sizing its rebar height incorrectly, taking over the whole window and making the program unusable. With the fix, this is no longer the case and the program becomes usable. {width=255 height=189} - {width=351 height=185} -- https://gitlab.winehq.org/wine/wine/-/merge_requests/10809
From: Feli Rippmann <25101-Feli@users.noreply.gitlab.winehq.org> --- dlls/comctl32/tests/rebar.c | 39 ++++++++++++++++++++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) diff --git a/dlls/comctl32/tests/rebar.c b/dlls/comctl32/tests/rebar.c index d2c1e68d354..f7977d090e7 100644 --- a/dlls/comctl32/tests/rebar.c +++ b/dlls/comctl32/tests/rebar.c @@ -246,7 +246,7 @@ static void rbsize_add_band(rbsize_result_t *rbsr, int left, int top, int right, static rbsize_result_t *rbsize_results; -#define rbsize_results_num 27 +#define rbsize_results_num 29 static void rbsize_results_init(void) { @@ -430,6 +430,14 @@ static void rbsize_results_init(void) rbsize_add_band(&rbsize_results[26], 0, 0, 90, 65, 0x40, 90); rbsize_add_band(&rbsize_results[26], 90, 0, 163, 65, 0x40, 90); rbsize_add_band(&rbsize_results[26], 163, 0, 226, 65, 0x40, 90); + + rbsize_results[27] = rbsize_init(0, 0, 672, 0, 0, 0, 0); + + rbsize_results[28] = rbsize_init(0, 0, 672, 65, 56, 1, 3); + rbsize_add_row(&rbsize_results[28], 65); + rbsize_add_band(&rbsize_results[28], 0, 0, 90, 65, 0x40, 90); + rbsize_add_band(&rbsize_results[28], 90, 0, 180, 65, 0x40, 90); + rbsize_add_band(&rbsize_results[28], 180, 0, 672, 65, 0x40, 90); } static void rbsize_results_free(void) @@ -684,6 +692,35 @@ static void test_layout(void) DestroyWindow(hRebar); + /* VARHEIGHT resizing test with cyIntegral == 0 on a horizontal rebar */ + hRebar = create_rebar_control(0); + SetWindowLongA(hRebar, GWL_STYLE, GetWindowLongA(hRebar, GWL_STYLE) | RBS_AUTOSIZE); + check_sizes(); + rbi.fMask = RBBIM_CHILD | RBBIM_CHILDSIZE | RBBIM_SIZE | RBBIM_STYLE; + rbi.fStyle = RBBS_VARIABLEHEIGHT; + rbi.cxMinChild = 50; + rbi.cyMinChild = 10; + rbi.cyIntegral = 11; + rbi.cyChild = 70; + rbi.cyMaxChild = 200; + rbi.cx = 90; + rbi.hwndChild = build_toolbar(0, hRebar); + SendMessageA(hRebar, RB_INSERTBANDA, -1, (LPARAM)&rbi); + + rbi.cyChild = 50; + rbi.hwndChild = build_toolbar(0, hRebar); + SendMessageA(hRebar, RB_INSERTBANDA, -1, (LPARAM)&rbi); + + rbi.cyMinChild = 40; + rbi.cyChild = 111; /* Intentionally too large */ + rbi.cyIntegral = 0; + rbi.cyMaxChild = 65; + rbi.hwndChild = build_toolbar(0, hRebar); + SendMessageA(hRebar, RB_INSERTBANDA, -1, (LPARAM)&rbi); + check_sizes(); + + DestroyWindow(hRebar); + rbsize_results_free(); } -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10809
From: Feli Rippmann <25101-Feli@users.noreply.gitlab.winehq.org> --- dlls/comctl32/rebar.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/dlls/comctl32/rebar.c b/dlls/comctl32/rebar.c index 27270a9b63c..cb4763cff9b 100644 --- a/dlls/comctl32/rebar.c +++ b/dlls/comctl32/rebar.c @@ -465,7 +465,10 @@ static int round_child_height(const REBAR_BAND *lpBand, int cyHeight) { int cy = 0; if (lpBand->cyIntegral == 0) - return cyHeight; + { + cy = min(cyHeight, lpBand->cyMaxChild); + return cy; + } cy = max(cyHeight - (int)lpBand->cyMinChild, 0); cy = lpBand->cyMinChild + (cy/lpBand->cyIntegral) * lpBand->cyIntegral; cy = min(cy, lpBand->cyMaxChild); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10809
participants (2)
-
Feli Rippmann -
Feli Rippmann (@Feli)