Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=56873
-- v13: comctl32/edit: Fix incorrect size for format rect when it is smaller than text. comctl32/tests: Add test for edit control format rect size. user32/edit: Fix incorrect size for format rect when it is smaller than text. user32/tests: Add test for edit control format rect size.
From: Jacob Czekalla jczekalla@codeweavers.com
--- dlls/user32/tests/edit.c | 49 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+)
diff --git a/dlls/user32/tests/edit.c b/dlls/user32/tests/edit.c index bbde9b16616..b0c95f07af3 100644 --- a/dlls/user32/tests/edit.c +++ b/dlls/user32/tests/edit.c @@ -3426,6 +3426,54 @@ static void test_dbcs_WM_CHAR(void) } }
+static void test_format_rect(void) +{ + HWND edit; + RECT rect, old_rect; + + static const struct + { + int style_ex; + RECT input; + int expected_equal; + } + tests[] = + { + {0, {0, 0, 0, 0}, 1}, + {0, {0, 0, 10, 10}, 1}, + {0, {1, 1, 10, 10}, 1}, + {0, {1, 1, 10, 250}, 1}, + {0, {1, 1, 250, 10}, 1}, + {0, {1, 1, 10, 1000}, 1}, + {0, {1, 1, 1000, 10}, 1}, + {0, {1, 1, 1000, 1000}, 0}, + {WS_EX_CLIENTEDGE, {0, 0, 0, 0}, 1}, + {WS_EX_CLIENTEDGE, {0, 0, 10, 10}, 1}, + {WS_EX_CLIENTEDGE, {1, 1, 10, 10}, 1}, + {WS_EX_CLIENTEDGE, {1, 1, 10, 250}, 1}, + {WS_EX_CLIENTEDGE, {1, 1, 250, 10}, 1}, + {WS_EX_CLIENTEDGE, {1, 1, 10, 1000}, 1}, + {WS_EX_CLIENTEDGE, {1, 1, 1000, 10}, 1}, + {WS_EX_CLIENTEDGE, {1, 1, 1000, 1000}, 0} + }; + + for (int i = 0; i < ARRAY_SIZE(tests); i++) + { + edit = create_editcontrol(ES_MULTILINE | WS_VISIBLE, tests[i].style_ex); + + SendMessageA(edit, EM_GETRECT, 0, (LPARAM)&old_rect); + SetWindowTextA(edit, "Test Test Test\r\n\r\nTest Test Test Test Test Test Test Test Test Test Test Test\r\n\r\nTest Test Test"); + SendMessageA(edit, EM_SETRECT, 0, (LPARAM)&tests[i].input); + SendMessageA(edit, EM_GETRECT, 0, (LPARAM)&rect); + + if (tests[i].expected_equal) + todo_wine ok(EqualRect(&old_rect, &rect), "Expected format rectangle to be equal to client rectangle.\n"); + else + todo_wine ok((rect.right - rect.left) > (old_rect.right - old_rect.left), "Expected format rect to be larger than client rectangle.\n"); + DestroyWindow(edit); + } +} + START_TEST(edit) { BOOL b; @@ -3464,6 +3512,7 @@ START_TEST(edit) test_EM_GETLINE(); test_wordbreak_proc(); test_dbcs_WM_CHAR(); + test_format_rect();
UnregisterWindowClasses(); }
From: Jacob Czekalla jczekalla@codeweavers.com
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=56873 --- dlls/user32/edit.c | 38 ++++++++++++++++++++++++++++++-------- dlls/user32/tests/edit.c | 4 ++-- 2 files changed, 32 insertions(+), 10 deletions(-)
diff --git a/dlls/user32/edit.c b/dlls/user32/edit.c index 39f429813d6..9adeefb1efa 100644 --- a/dlls/user32/edit.c +++ b/dlls/user32/edit.c @@ -2297,9 +2297,12 @@ static void EDIT_AdjustFormatRect(EDITSTATE *es) /* Windows doesn't care to fix text placement for SL controls */ es->format_rect.bottom = es->format_rect.top + es->line_height;
- /* Always stay within the client area */ - GetClientRect(es->hwndSelf, &ClientRect); - es->format_rect.bottom = min(es->format_rect.bottom, ClientRect.bottom); + if (!(es->style & ES_MULTILINE)) + { + /* Always stay within the client area */ + GetClientRect(es->hwndSelf, &ClientRect); + es->format_rect.bottom = min(es->format_rect.bottom, ClientRect.bottom); + }
if ((es->style & ES_MULTILINE) && !(es->style & ES_AUTOHSCROLL)) EDIT_BuildLineDefs_ML(es, 0, get_text_length(es), 0, NULL); @@ -2307,6 +2310,14 @@ static void EDIT_AdjustFormatRect(EDITSTATE *es) EDIT_SetCaretPos(es, es->selection_end, es->flags & EF_AFTER_WRAP); }
+static int EDIT_is_valid_format_rect(const EDITSTATE *es, const RECT *rc) +{ + if (IsRectEmpty(rc)) + return 0; + if (es->text_width > (rc->right - rc->left) || (es->line_height * es->line_count) > (rc->bottom - rc->top)) + return 0; + return 1; +}
/********************************************************************* * @@ -2319,12 +2330,23 @@ static void EDIT_AdjustFormatRect(EDITSTATE *es) static void EDIT_SetRectNP(EDITSTATE *es, const RECT *rc) { LONG_PTR ExStyle; - INT bw, bh; + INT bw, bh, too_large = 0; + RECT edit_rect; ExStyle = GetWindowLongPtrW(es->hwndSelf, GWL_EXSTYLE); - - CopyRect(&es->format_rect, rc); - - if (ExStyle & WS_EX_CLIENTEDGE) { + + if (EDIT_is_valid_format_rect(es, rc)) + { + CopyRect(&es->format_rect, rc); + GetClientRect(es->hwndSelf, &edit_rect); + if ((rc->bottom - rc->top) > (edit_rect.bottom - edit_rect.top)) + too_large = 1; + } + else + { + GetClientRect(es->hwndSelf, &es->format_rect); + } + + if (ExStyle & WS_EX_CLIENTEDGE && !too_large) { es->format_rect.left++; es->format_rect.right--; diff --git a/dlls/user32/tests/edit.c b/dlls/user32/tests/edit.c index b0c95f07af3..9316cff7d85 100644 --- a/dlls/user32/tests/edit.c +++ b/dlls/user32/tests/edit.c @@ -3467,9 +3467,9 @@ static void test_format_rect(void) SendMessageA(edit, EM_GETRECT, 0, (LPARAM)&rect);
if (tests[i].expected_equal) - todo_wine ok(EqualRect(&old_rect, &rect), "Expected format rectangle to be equal to client rectangle.\n"); + ok(EqualRect(&old_rect, &rect), "Expected format rectangle to be equal to client rectangle.\n"); else - todo_wine ok((rect.right - rect.left) > (old_rect.right - old_rect.left), "Expected format rect to be larger than client rectangle.\n"); + ok((rect.right - rect.left) > (old_rect.right - old_rect.left), "Expected format rect to be larger than client rectangle.\n"); DestroyWindow(edit); } }
From: Jacob Czekalla jczekalla@codeweavers.com
Wine-Debug: https://bugs.winehq.org/show_bug.cgi?id=56873 --- dlls/comctl32/tests/edit.c | 49 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+)
diff --git a/dlls/comctl32/tests/edit.c b/dlls/comctl32/tests/edit.c index bce0215ef19..66c6a9f6192 100644 --- a/dlls/comctl32/tests/edit.c +++ b/dlls/comctl32/tests/edit.c @@ -3791,6 +3791,54 @@ static void test_ime(void) DestroyWindow(hwnd); }
+static void test_format_rect(void) +{ + HWND edit; + RECT rect, old_rect; + + static const struct + { + int style_ex; + RECT input; + int expected_equal; + } + tests[] = + { + {0, {0, 0, 0, 0}, 1}, + {0, {0, 0, 10, 10}, 1}, + {0, {1, 1, 10, 10}, 1}, + {0, {1, 1, 10, 250}, 1}, + {0, {1, 1, 250, 10}, 1}, + {0, {1, 1, 10, 1000}, 1}, + {0, {1, 1, 1000, 10}, 1}, + {0, {1, 1, 1000, 1000}, 0}, + {WS_EX_CLIENTEDGE, {0, 0, 0, 0}, 1}, + {WS_EX_CLIENTEDGE, {0, 0, 10, 10}, 1}, + {WS_EX_CLIENTEDGE, {1, 1, 10, 10}, 1}, + {WS_EX_CLIENTEDGE, {1, 1, 10, 250}, 1}, + {WS_EX_CLIENTEDGE, {1, 1, 250, 10}, 1}, + {WS_EX_CLIENTEDGE, {1, 1, 10, 1000}, 1}, + {WS_EX_CLIENTEDGE, {1, 1, 1000, 10}, 1}, + {WS_EX_CLIENTEDGE, {1, 1, 1000, 1000}, 0} + }; + + for (int i = 0; i < ARRAY_SIZE(tests); i++) + { + edit = create_editcontrol(ES_MULTILINE | WS_VISIBLE, tests[i].style_ex); + + SendMessageA(edit, EM_GETRECT, 0, (LPARAM)&old_rect); + SetWindowTextA(edit, "Test Test Test\r\n\r\nTest Test Test Test Test Test Test Test Test Test Test Test\r\n\r\nTest Test Test"); + SendMessageA(edit, EM_SETRECT, 0, (LPARAM)&tests[i].input); + SendMessageA(edit, EM_GETRECT, 0, (LPARAM)&rect); + + if (tests[i].expected_equal) + todo_wine ok(EqualRect(&old_rect, &rect), "Expected format rectangle to be equal to client rectangle.\n"); + else + todo_wine ok((rect.right - rect.left) > (old_rect.right - old_rect.left), "Expected format rect to be larger than client rectangle.\n"); + DestroyWindow(edit); + } +} + START_TEST(edit) { ULONG_PTR ctx_cookie; @@ -3838,6 +3886,7 @@ START_TEST(edit) test_change_focus(); test_cue_banner(); test_ime(); + test_format_rect();
UnregisterWindowClasses();
From: Jacob Czekalla jczekalla@codeweavers.com
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=56873 --- dlls/comctl32/edit.c | 34 ++++++++++++++++++++++++++++------ dlls/comctl32/tests/edit.c | 4 ++-- 2 files changed, 30 insertions(+), 8 deletions(-)
diff --git a/dlls/comctl32/edit.c b/dlls/comctl32/edit.c index 4b950412617..7c27b7dbb6b 100644 --- a/dlls/comctl32/edit.c +++ b/dlls/comctl32/edit.c @@ -2222,9 +2222,12 @@ static void EDIT_AdjustFormatRect(EDITSTATE *es) /* Windows doesn't care to fix text placement for SL controls */ es->format_rect.bottom = es->format_rect.top + es->line_height;
- /* Always stay within the client area */ - GetClientRect(es->hwndSelf, &ClientRect); - es->format_rect.bottom = min(es->format_rect.bottom, ClientRect.bottom); + if (!(es->style & ES_MULTILINE)) + { + /* Always stay within the client area */ + GetClientRect(es->hwndSelf, &ClientRect); + es->format_rect.bottom = min(es->format_rect.bottom, ClientRect.bottom); + }
if ((es->style & ES_MULTILINE) && !(es->style & ES_AUTOHSCROLL)) EDIT_BuildLineDefs_ML(es, 0, get_text_length(es), 0, NULL); @@ -2232,6 +2235,14 @@ static void EDIT_AdjustFormatRect(EDITSTATE *es) EDIT_SetCaretPos(es, es->selection_end, es->flags & EF_AFTER_WRAP); }
+static int EDIT_is_valid_format_rect(const EDITSTATE *es, const RECT *rc) +{ + if (IsRectEmpty(rc)) + return 0; + if (es->text_width > (rc->right - rc->left) || (es->line_height * es->line_count) > (rc->bottom - rc->top)) + return 0; + return 1; +}
/********************************************************************* * @@ -2244,12 +2255,23 @@ static void EDIT_AdjustFormatRect(EDITSTATE *es) static void EDIT_SetRectNP(EDITSTATE *es, const RECT *rc) { LONG_PTR ExStyle; - INT bw, bh; + INT bw, bh, too_large = 0; + RECT edit_rect; ExStyle = GetWindowLongPtrW(es->hwndSelf, GWL_EXSTYLE);
- CopyRect(&es->format_rect, rc); + if (EDIT_is_valid_format_rect(es, rc)) + { + CopyRect(&es->format_rect, rc); + GetClientRect(es->hwndSelf, &edit_rect); + if ((rc->bottom - rc->top) > (edit_rect.bottom - edit_rect.top)) + too_large = 1; + } + else + { + GetClientRect(es->hwndSelf, &es->format_rect); + }
- if (ExStyle & WS_EX_CLIENTEDGE) { + if (ExStyle & WS_EX_CLIENTEDGE && !too_large) { es->format_rect.left++; es->format_rect.right--;
diff --git a/dlls/comctl32/tests/edit.c b/dlls/comctl32/tests/edit.c index 66c6a9f6192..92091df8fa6 100644 --- a/dlls/comctl32/tests/edit.c +++ b/dlls/comctl32/tests/edit.c @@ -3832,9 +3832,9 @@ static void test_format_rect(void) SendMessageA(edit, EM_GETRECT, 0, (LPARAM)&rect);
if (tests[i].expected_equal) - todo_wine ok(EqualRect(&old_rect, &rect), "Expected format rectangle to be equal to client rectangle.\n"); + ok(EqualRect(&old_rect, &rect), "Expected format rectangle to be equal to client rectangle.\n"); else - todo_wine ok((rect.right - rect.left) > (old_rect.right - old_rect.left), "Expected format rect to be larger than client rectangle.\n"); + ok((rect.right - rect.left) > (old_rect.right - old_rect.left), "Expected format rect to be larger than client rectangle.\n"); DestroyWindow(edit); } }
Hi,
It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated.
The tests also ran into some preexisting test failures. If you know how to fix them that would be helpful. See the TestBot job for the details:
The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=148180
Your paranoid android.
=== debian11 (32 bit report) ===
user32: input.c:4305: Test succeeded inside todo block: button_down_hwnd_todo 1: got MSG_TEST_WIN hwnd 00B00084, msg WM_LBUTTONDOWN, wparam 0x1, lparam 0x320032
=== debian11b (64 bit WoW report) ===
ddraw: ddraw2.c:3814: Test failed: Expected (0,0)-(640,480), got (0,0)-(1024,768). ddraw2.c:3839: Test failed: Expected (0,0)-(640,480), got (0,0)-(1024,768).
kernel32: comm.c:1586: Test failed: Unexpected time 1000, expected around 500
user32: input.c:4305: Test succeeded inside todo block: button_down_hwnd_todo 1: got MSG_TEST_WIN hwnd 0000000000A300DA, msg WM_LBUTTONDOWN, wparam 0x1, lparam 0x320032
Zhiyi Zhang (@zhiyi) commented about dlls/user32/edit.c:
static void EDIT_SetRectNP(EDITSTATE *es, const RECT *rc) { LONG_PTR ExStyle;
- INT bw, bh;
- INT bw, bh, too_large = 0;
Let's use BOOL for too_large with TRUE and FALSE instead of 0 and 1.