[PATCH v5 0/1] 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} -- v5: comctl32: Clamp rebar height to cyMaxChild when cyIntegral == 0 too https://gitlab.winehq.org/wine/wine/-/merge_requests/10809
From: Feli Rippmann <25101-Feli@users.noreply.gitlab.winehq.org> --- dlls/comctl32/rebar.c | 2 +- dlls/comctl32/tests/rebar.c | 22 +++++++++++++++++++++- 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/dlls/comctl32/rebar.c b/dlls/comctl32/rebar.c index 27270a9b63c..15bc0d5aaec 100644 --- a/dlls/comctl32/rebar.c +++ b/dlls/comctl32/rebar.c @@ -465,7 +465,7 @@ static int round_child_height(const REBAR_BAND *lpBand, int cyHeight) { int cy = 0; if (lpBand->cyIntegral == 0) - return cyHeight; + return min(cyHeight, lpBand->cyMaxChild); cy = max(cyHeight - (int)lpBand->cyMinChild, 0); cy = lpBand->cyMinChild + (cy/lpBand->cyIntegral) * lpBand->cyIntegral; cy = min(cy, lpBand->cyMaxChild); diff --git a/dlls/comctl32/tests/rebar.c b/dlls/comctl32/tests/rebar.c index d2c1e68d354..18877165193 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 28 static void rbsize_results_init(void) { @@ -430,6 +430,10 @@ 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, 65, 56, 1, 1); + rbsize_add_row(&rbsize_results[27], 65); + rbsize_add_band(&rbsize_results[27], 0, 0, 672, 65, 0x40, 90); } static void rbsize_results_free(void) @@ -684,6 +688,22 @@ 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); + rbi.fMask = RBBIM_CHILD | RBBIM_CHILDSIZE | RBBIM_SIZE | RBBIM_STYLE; + rbi.fStyle = RBBS_VARIABLEHEIGHT; + rbi.cx = 90; + rbi.cyMinChild = 40; + rbi.cyMaxChild = 65; + rbi.cyIntegral = 0; + rbi.cyChild = 111; + 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
On Tue Jun 23 07:20:36 2026 +0000, Zhiyi Zhang wrote:
Let's just do `return min(cyHeight, lpBand->cyMaxChild);` I've redone the commit implementing your suggestion here and also corrected the band count parameter for the test. Please take a look at the new commit when you have time. Thanks!
-- https://gitlab.winehq.org/wine/wine/-/merge_requests/10809#note_144256
This merge request was approved by Zhiyi Zhang. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/10809
participants (3)
-
Feli Rippmann -
Feli Rippmann (@Feli) -
Zhiyi Zhang (@zhiyi)