Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=56873
-- v3: comctl32/edit: Fix incorrect size for format rect when it is smaller than text.
From: Jacob Czekalla jczekalla@codeweavers.com
--- dlls/user32/tests/edit.c | 50 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+)
diff --git a/dlls/user32/tests/edit.c b/dlls/user32/tests/edit.c index bbde9b16616..47472ea4634 100644 --- a/dlls/user32/tests/edit.c +++ b/dlls/user32/tests/edit.c @@ -3426,6 +3426,55 @@ static void test_dbcs_WM_CHAR(void) } }
+static void test_format_rect(void) +{ + HWND edit; + RECT rect, expected_rect; + + struct state_tests + { + int style; + int style_ex; + RECT input; + RECT expected; + } + tests[] = + { + {ES_MULTILINE | WS_VISIBLE, 0, {0, 0, 0, 0}, {0}}, + {ES_MULTILINE | WS_VISIBLE, 0, {0, 0, 10, 10}, {0}}, + {ES_MULTILINE | WS_VISIBLE, 0, {1, 1, 10, 10}, {0}}, + {ES_MULTILINE | WS_VISIBLE, 0, {1, 1, 10, 250}, {0}}, + {ES_MULTILINE | WS_VISIBLE, 0, {1, 1, 250, 10}, {0}}, + {ES_MULTILINE | WS_VISIBLE, 0, {1, 1, 10, 1000}, {0}}, + {ES_MULTILINE | WS_VISIBLE, 0, {1, 1, 1000, 10}, {0}}, + {ES_MULTILINE | WS_VISIBLE, 0, {1, 1, 1000, 1000}, {2, 2, 999, 994}}, + {ES_MULTILINE | WS_VISIBLE, WS_EX_CLIENTEDGE, {0, 0, 0, 0}, {0}}, + {ES_MULTILINE | WS_VISIBLE, WS_EX_CLIENTEDGE, {0, 0, 10, 10}, {0}}, + {ES_MULTILINE | WS_VISIBLE, WS_EX_CLIENTEDGE, {1, 1, 10, 10}, {0}}, + {ES_MULTILINE | WS_VISIBLE, WS_EX_CLIENTEDGE, {1, 1, 10, 250}, {0}}, + {ES_MULTILINE | WS_VISIBLE, WS_EX_CLIENTEDGE, {1, 1, 250, 10}, {0}}, + {ES_MULTILINE | WS_VISIBLE, WS_EX_CLIENTEDGE, {1, 1, 10, 1000}, {0}}, + {ES_MULTILINE | WS_VISIBLE, WS_EX_CLIENTEDGE, {1, 1, 1000, 10}, {0}}, + {ES_MULTILINE | WS_VISIBLE, WS_EX_CLIENTEDGE, {1, 1, 1000, 1000}, {2, 2, 999, 994}} + }; + + for (int i = 0; i < ARRAY_SIZE(tests); i++) + { + edit = create_editcontrol(tests[i].style, tests[i].style_ex); + if (IsRectEmpty(&tests[i].expected)) + SendMessageA(edit, EM_GETRECT, 0, (LPARAM)&expected_rect); + else + expected_rect = tests[i].expected; + 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); + todo_wine ok (EqualRect(&expected_rect, &rect), "Expected rect {%ld, %ld, %ld, %ld}, but got {%ld, %ld, %ld, %ld}.\n", + expected_rect.left, expected_rect.top, expected_rect.right, expected_rect.bottom, + rect.left, rect.top, rect.right, rect.bottom); + DestroyWindow(edit); + } +} + START_TEST(edit) { BOOL b; @@ -3464,6 +3513,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 | 51 ++++++++++++++++++++++++++++++++++------ dlls/user32/tests/edit.c | 2 +- 2 files changed, 45 insertions(+), 8 deletions(-)
diff --git a/dlls/user32/edit.c b/dlls/user32/edit.c index 39f429813d6..c59783463cf 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,24 @@ static void EDIT_AdjustFormatRect(EDITSTATE *es) EDIT_SetCaretPos(es, es->selection_end, es->flags & EF_AFTER_WRAP); }
+static int EDIT_is_valid_format_rect(EDITSTATE *es, const RECT *rc) +{ + RECT edit_rect; + int text_height = es->line_height * es->line_count; + + GetClientRect(es->hwndSelf, &edit_rect); + if (rc->top >= rc->bottom) + return 0; + if (rc->left >= rc->right) + return 0; + if (text_height > (rc->bottom - rc->top)) + return 0; + if (es->text_width > (rc->right - rc->left)) + return 0; + if ((rc->bottom - rc->top) > (edit_rect.bottom - edit_rect.top)) + return -1; + return 1; +}
/********************************************************************* * @@ -2319,12 +2340,28 @@ static void EDIT_AdjustFormatRect(EDITSTATE *es) static void EDIT_SetRectNP(EDITSTATE *es, const RECT *rc) { LONG_PTR ExStyle; - INT bw, bh; + INT bw, bh, res; ExStyle = GetWindowLongPtrW(es->hwndSelf, GWL_EXSTYLE); + + res = EDIT_is_valid_format_rect(es, rc); + if (res == 0) + { + GetClientRect(es->hwndSelf, &es->format_rect); + } + else if (res == -1) + { + CopyRect(&es->format_rect, rc); + es->format_rect.left += 1; + es->format_rect.top += 1; + es->format_rect.right -= 1; + es->format_rect.bottom += 1; + } + else + { + CopyRect(&es->format_rect, rc); + } - CopyRect(&es->format_rect, rc); - - if (ExStyle & WS_EX_CLIENTEDGE) { + if (ExStyle & WS_EX_CLIENTEDGE && res != -1) { es->format_rect.left++; es->format_rect.right--; diff --git a/dlls/user32/tests/edit.c b/dlls/user32/tests/edit.c index 47472ea4634..a5cfd7f0d82 100644 --- a/dlls/user32/tests/edit.c +++ b/dlls/user32/tests/edit.c @@ -3468,7 +3468,7 @@ static void test_format_rect(void) 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); - todo_wine ok (EqualRect(&expected_rect, &rect), "Expected rect {%ld, %ld, %ld, %ld}, but got {%ld, %ld, %ld, %ld}.\n", + ok (EqualRect(&expected_rect, &rect), "Expected rect {%ld, %ld, %ld, %ld}, but got {%ld, %ld, %ld, %ld}.\n", expected_rect.left, expected_rect.top, expected_rect.right, expected_rect.bottom, rect.left, rect.top, rect.right, rect.bottom); DestroyWindow(edit);
From: Jacob Czekalla jczekalla@codeweavers.com
Wine-Debug: https://bugs.winehq.org/show_bug.cgi?id=56873 --- dlls/comctl32/tests/edit.c | 50 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+)
diff --git a/dlls/comctl32/tests/edit.c b/dlls/comctl32/tests/edit.c index bce0215ef19..e32c8aa0fd9 100644 --- a/dlls/comctl32/tests/edit.c +++ b/dlls/comctl32/tests/edit.c @@ -3791,6 +3791,55 @@ static void test_ime(void) DestroyWindow(hwnd); }
+static void test_format_rect(void) +{ + HWND edit; + RECT rect, expected_rect; + + struct state_tests + { + int style; + int style_ex; + RECT input; + RECT expected; + } + tests[] = + { + {ES_MULTILINE | WS_VISIBLE, 0, {0, 0, 0, 0}, {0}}, + {ES_MULTILINE | WS_VISIBLE, 0, {0, 0, 10, 10}, {0}}, + {ES_MULTILINE | WS_VISIBLE, 0, {1, 1, 10, 10}, {0}}, + {ES_MULTILINE | WS_VISIBLE, 0, {1, 1, 10, 250}, {0}}, + {ES_MULTILINE | WS_VISIBLE, 0, {1, 1, 250, 10}, {0}}, + {ES_MULTILINE | WS_VISIBLE, 0, {1, 1, 10, 1000}, {0}}, + {ES_MULTILINE | WS_VISIBLE, 0, {1, 1, 1000, 10}, {0}}, + {ES_MULTILINE | WS_VISIBLE, 0, {1, 1, 1000, 1000}, {2, 2, 999, 999}}, + {ES_MULTILINE | WS_VISIBLE, WS_EX_CLIENTEDGE, {0, 0, 0, 0}, {0}}, + {ES_MULTILINE | WS_VISIBLE, WS_EX_CLIENTEDGE, {0, 0, 10, 10}, {0}}, + {ES_MULTILINE | WS_VISIBLE, WS_EX_CLIENTEDGE, {1, 1, 10, 10}, {0}}, + {ES_MULTILINE | WS_VISIBLE, WS_EX_CLIENTEDGE, {1, 1, 10, 250}, {0}}, + {ES_MULTILINE | WS_VISIBLE, WS_EX_CLIENTEDGE, {1, 1, 250, 10}, {0}}, + {ES_MULTILINE | WS_VISIBLE, WS_EX_CLIENTEDGE, {1, 1, 10, 1000}, {0}}, + {ES_MULTILINE | WS_VISIBLE, WS_EX_CLIENTEDGE, {1, 1, 1000, 10}, {0}}, + {ES_MULTILINE | WS_VISIBLE, WS_EX_CLIENTEDGE, {1, 1, 1000, 1000}, {2, 2, 999, 999}} + }; + + for (int i = 0; i < ARRAY_SIZE(tests); i++) + { + edit = create_editcontrol(tests[i].style, tests[i].style_ex); + if (IsRectEmpty(&tests[i].expected)) + SendMessageA(edit, EM_GETRECT, 0, (LPARAM)&expected_rect); + else + expected_rect = tests[i].expected; + 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); + todo_wine ok (EqualRect(&expected_rect, &rect), "Expected rect {%ld, %ld, %ld, %ld}, but got {%ld, %ld, %ld, %ld}.\n", + expected_rect.left, expected_rect.top, expected_rect.right, expected_rect.bottom, + rect.left, rect.top, rect.right, rect.bottom); + DestroyWindow(edit); + } +} + START_TEST(edit) { ULONG_PTR ctx_cookie; @@ -3838,6 +3887,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 | 49 +++++++++++++++++++++++++++++++++----- dlls/comctl32/tests/edit.c | 2 +- 2 files changed, 44 insertions(+), 7 deletions(-)
diff --git a/dlls/comctl32/edit.c b/dlls/comctl32/edit.c index 4b950412617..923c70c6f15 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,24 @@ static void EDIT_AdjustFormatRect(EDITSTATE *es) EDIT_SetCaretPos(es, es->selection_end, es->flags & EF_AFTER_WRAP); }
+static int EDIT_is_valid_format_rect(EDITSTATE *es, const RECT *rc) +{ + RECT edit_rect; + int text_height = es->line_height * es->line_count; + + GetClientRect(es->hwndSelf, &edit_rect); + if (rc->top >= rc->bottom) + return 0; + if (rc->left >= rc->right) + return 0; + if (text_height > (rc->bottom - rc->top)) + return 0; + if (es->text_width > (rc->right - rc->left)) + return 0; + if ((rc->bottom - rc->top) > (edit_rect.bottom - edit_rect.top)) + return -1; + return 1; +}
/********************************************************************* * @@ -2244,12 +2265,28 @@ static void EDIT_AdjustFormatRect(EDITSTATE *es) static void EDIT_SetRectNP(EDITSTATE *es, const RECT *rc) { LONG_PTR ExStyle; - INT bw, bh; + INT bw, bh, res; ExStyle = GetWindowLongPtrW(es->hwndSelf, GWL_EXSTYLE);
- CopyRect(&es->format_rect, rc); + res = EDIT_is_valid_format_rect(es, rc); + if (res == 0) + { + GetClientRect(es->hwndSelf, &es->format_rect); + } + else if (res == -1) + { + CopyRect(&es->format_rect, rc); + es->format_rect.left += 1; + es->format_rect.top += 1; + es->format_rect.right -= 1; + es->format_rect.bottom -= 1; + } + else + { + CopyRect(&es->format_rect, rc); + }
- if (ExStyle & WS_EX_CLIENTEDGE) { + if (ExStyle & WS_EX_CLIENTEDGE && res != -1) { es->format_rect.left++; es->format_rect.right--;
diff --git a/dlls/comctl32/tests/edit.c b/dlls/comctl32/tests/edit.c index e32c8aa0fd9..26d7b6aeb06 100644 --- a/dlls/comctl32/tests/edit.c +++ b/dlls/comctl32/tests/edit.c @@ -3833,7 +3833,7 @@ static void test_format_rect(void) 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); - todo_wine ok (EqualRect(&expected_rect, &rect), "Expected rect {%ld, %ld, %ld, %ld}, but got {%ld, %ld, %ld, %ld}.\n", + ok (EqualRect(&expected_rect, &rect), "Expected rect {%ld, %ld, %ld, %ld}, but got {%ld, %ld, %ld, %ld}.\n", expected_rect.left, expected_rect.top, expected_rect.right, expected_rect.bottom, rect.left, rect.top, rect.right, rect.bottom); 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=147870
Your paranoid android.
=== w7u_2qxl (32 bit report) ===
comctl32: edit.c:3836: Test failed: Expected rect {2, 2, 999, 999}, but got {2, 2, 999, 994}. edit.c:3836: Test failed: Expected rect {2, 2, 999, 999}, but got {2, 2, 999, 994}.
=== w7u_adm (32 bit report) ===
comctl32: edit.c:3836: Test failed: Expected rect {2, 2, 999, 999}, but got {2, 2, 999, 994}. edit.c:3836: Test failed: Expected rect {2, 2, 999, 999}, but got {2, 2, 999, 994}.
=== w7u_el (32 bit report) ===
comctl32: edit.c:3836: Test failed: Expected rect {2, 2, 999, 999}, but got {2, 2, 999, 994}. edit.c:3836: Test failed: Expected rect {2, 2, 999, 999}, but got {2, 2, 999, 994}.
=== w8 (32 bit report) ===
comctl32: edit.c:3836: Test failed: Expected rect {2, 2, 999, 999}, but got {2, 2, 999, 994}. edit.c:3836: Test failed: Expected rect {2, 2, 999, 999}, but got {2, 2, 999, 994}.
=== w8adm (32 bit report) ===
comctl32: edit.c:3836: Test failed: Expected rect {2, 2, 999, 999}, but got {2, 2, 999, 994}. edit.c:3836: Test failed: Expected rect {2, 2, 999, 999}, but got {2, 2, 999, 994}.
=== w864 (32 bit report) ===
comctl32: edit.c:3836: Test failed: Expected rect {2, 2, 999, 999}, but got {2, 2, 999, 994}. edit.c:3836: Test failed: Expected rect {2, 2, 999, 999}, but got {2, 2, 999, 994}.
=== w1064v1507 (32 bit report) ===
comctl32: edit.c:3836: Test failed: Expected rect {2, 2, 999, 999}, but got {2, 2, 999, 994}. edit.c:3836: Test failed: Expected rect {2, 2, 999, 999}, but got {2, 2, 999, 994}.
=== w7pro64 (64 bit report) ===
comctl32: edit.c:3836: Test failed: Expected rect {2, 2, 999, 999}, but got {2, 2, 999, 994}. edit.c:3836: Test failed: Expected rect {2, 2, 999, 999}, but got {2, 2, 999, 994}.
=== w864 (64 bit report) ===
comctl32: edit.c:3836: Test failed: Expected rect {2, 2, 999, 999}, but got {2, 2, 999, 994}. edit.c:3836: Test failed: Expected rect {2, 2, 999, 999}, but got {2, 2, 999, 994}.
=== w1064v1507 (64 bit report) ===
comctl32: edit.c:3836: Test failed: Expected rect {2, 2, 999, 999}, but got {2, 2, 999, 994}. edit.c:3836: Test failed: Expected rect {2, 2, 999, 999}, but got {2, 2, 999, 994}.
=== w10pro64_ja (64 bit report) ===
user32: edit.c:3471: Test failed: Expected rect {2, 2, 999, 994}, but got {2, 2, 999, 992}. edit.c:3471: Test failed: Expected rect {2, 2, 999, 994}, but got {2, 2, 999, 992}.
=== debian11 (32 bit report) ===
comctl32: edit.c:3836: Test failed: Expected rect {2, 2, 999, 999}, but got {2, 2, 999, 994}. edit.c:3836: Test failed: Expected rect {2, 2, 999, 999}, but got {2, 2, 999, 994}.
user32: input.c:4305: Test succeeded inside todo block: button_down_hwnd_todo 1: got MSG_TEST_WIN hwnd 01090080, msg WM_LBUTTONDOWN, wparam 0x1, lparam 0x320032
=== debian11 (32 bit ar:MA report) ===
comctl32: edit.c:3836: Test failed: Expected rect {2, 2, 999, 999}, but got {2, 2, 999, 994}. edit.c:3836: Test failed: Expected rect {2, 2, 999, 999}, but got {2, 2, 999, 994}.
=== debian11 (32 bit de report) ===
comctl32: edit.c:3836: Test failed: Expected rect {2, 2, 999, 999}, but got {2, 2, 999, 994}. edit.c:3836: Test failed: Expected rect {2, 2, 999, 999}, but got {2, 2, 999, 994}.
=== debian11 (32 bit fr report) ===
comctl32: edit.c:3836: Test failed: Expected rect {2, 2, 999, 999}, but got {2, 2, 999, 994}. edit.c:3836: Test failed: Expected rect {2, 2, 999, 999}, but got {2, 2, 999, 994}.
=== debian11 (32 bit he:IL report) ===
comctl32: edit.c:3836: Test failed: Expected rect {2, 2, 999, 999}, but got {2, 2, 999, 994}. edit.c:3836: Test failed: Expected rect {2, 2, 999, 999}, but got {2, 2, 999, 994}.
=== debian11 (32 bit hi:IN report) ===
comctl32: edit.c:3836: Test failed: Expected rect {2, 2, 999, 999}, but got {2, 2, 999, 994}. edit.c:3836: Test failed: Expected rect {2, 2, 999, 999}, but got {2, 2, 999, 994}.
=== debian11 (32 bit ja:JP report) ===
comctl32: edit.c:3836: Test failed: Expected rect {2, 2, 999, 999}, but got {2, 2, 999, 992}. edit.c:3836: Test failed: Expected rect {2, 2, 999, 999}, but got {2, 2, 999, 992}.
user32: edit.c:3471: Test failed: Expected rect {2, 2, 999, 994}, but got {2, 2, 999, 992}. edit.c:3471: Test failed: Expected rect {2, 2, 999, 994}, but got {2, 2, 999, 992}.
=== debian11 (32 bit zh:CN report) ===
comctl32: edit.c:3836: Test failed: Expected rect {2, 2, 999, 999}, but got {2, 2, 999, 994}. edit.c:3836: Test failed: Expected rect {2, 2, 999, 999}, but got {2, 2, 999, 994}.
=== debian11b (32 bit WoW report) ===
comctl32: edit.c:3836: Test failed: Expected rect {2, 2, 999, 999}, but got {2, 2, 999, 994}. edit.c:3836: Test failed: Expected rect {2, 2, 999, 999}, but got {2, 2, 999, 994}.
=== debian11b (64 bit WoW report) ===
comctl32: edit.c:3836: Test failed: Expected rect {2, 2, 999, 999}, but got {2, 2, 999, 994}. edit.c:3836: Test failed: Expected rect {2, 2, 999, 999}, but got {2, 2, 999, 994}.
user32: input.c:4305: Test succeeded inside todo block: button_down_hwnd_todo 1: got MSG_TEST_WIN hwnd 00000000039D00D0, msg WM_LBUTTONDOWN, wparam 0x1, lparam 0x320032