-- v2: riched20/tests: Add retry loop around OpenClipboard() to avoid access denial. riched20: Ensure clipboard has been pasted before testing the result. riched20: Support SFF_SELECTION when streaming in plain text. riched20/tests: Add tests when pasting in plain text mode.
From: Eric Pouech eric.pouech@gmail.com
Signed-off-by: Eric Pouech eric.pouech@gmail.com --- dlls/riched20/tests/editor.c | 5 +++++ 1 file changed, 5 insertions(+)
diff --git a/dlls/riched20/tests/editor.c b/dlls/riched20/tests/editor.c index 07af9ab5dbd..14a7558ee17 100644 --- a/dlls/riched20/tests/editor.c +++ b/dlls/riched20/tests/editor.c @@ -1409,6 +1409,7 @@ static void test_EM_SETTEXTMODE(void) { HWND hwndRichEdit = new_richedit(NULL); CHARFORMAT2A cf2, cf2test; + unsigned int len; CHARRANGE cr; int rc = 0;
@@ -1480,6 +1481,10 @@ static void test_EM_SETTEXTMODE(void) /*Paste the italicized "wine" into the control*/ SendMessageA(hwndRichEdit, WM_PASTE, 0, 0);
+ len = SendMessageA(hwndRichEdit, WM_GETTEXTLENGTH, 0, 0); + todo_wine + ok(len == 8 /*winewine*/, "Unexpected text length %u\n", len); + /*Select a character from the first "wine" string*/ cr.cpMin = 2; cr.cpMax = 3;
From: Eric Pouech eric.pouech@gmail.com
Signed-off-by: Eric Pouech eric.pouech@gmail.com --- dlls/riched20/editor.c | 14 +++++++++++--- dlls/riched20/tests/editor.c | 1 - 2 files changed, 11 insertions(+), 4 deletions(-)
diff --git a/dlls/riched20/editor.c b/dlls/riched20/editor.c index 7b4f4b3cdf3..704546f1e95 100644 --- a/dlls/riched20/editor.c +++ b/dlls/riched20/editor.c @@ -1609,9 +1609,17 @@ static LRESULT ME_StreamIn(ME_TextEditor *editor, DWORD format, EDITSTREAM *stre { style = editor->pBuffer->pDefaultStyle; ME_AddRefStyle(style); - set_selection_cursors(editor, 0, 0); - ME_InternalDeleteText(editor, &editor->pCursors[1], - ME_GetTextLength(editor), FALSE); + if (format & SFF_SELECTION) + { + ME_GetSelection(editor, &selStart, &selEnd); + ME_InternalDeleteText(editor, selStart, to - from, FALSE); + } + else + { + set_selection_cursors(editor, 0, 0); + ME_InternalDeleteText(editor, &editor->pCursors[1], + ME_GetTextLength(editor), FALSE); + } from = to = 0; ME_ClearTempStyle(editor); editor_set_default_para_fmt( editor, &editor->pCursors[0].para->fmt ); diff --git a/dlls/riched20/tests/editor.c b/dlls/riched20/tests/editor.c index 14a7558ee17..8fe64f1a9b5 100644 --- a/dlls/riched20/tests/editor.c +++ b/dlls/riched20/tests/editor.c @@ -1482,7 +1482,6 @@ static void test_EM_SETTEXTMODE(void) SendMessageA(hwndRichEdit, WM_PASTE, 0, 0);
len = SendMessageA(hwndRichEdit, WM_GETTEXTLENGTH, 0, 0); - todo_wine ok(len == 8 /*winewine*/, "Unexpected text length %u\n", len);
/*Select a character from the first "wine" string*/
From: Eric Pouech eric.pouech@gmail.com
The patch does reduce error failures locally.
For the record: - WM_PASTE in undo operations haven't been transformed (as it requires UNDO stack manipulation in a coherent way across platforms)
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=47888
Signed-off-by: Eric Pouech eric.pouech@gmail.com --- dlls/riched20/tests/editor.c | 52 ++++++++++++++++++++++++++++++------ 1 file changed, 44 insertions(+), 8 deletions(-)
diff --git a/dlls/riched20/tests/editor.c b/dlls/riched20/tests/editor.c index 8fe64f1a9b5..ec06d7a7fc2 100644 --- a/dlls/riched20/tests/editor.c +++ b/dlls/riched20/tests/editor.c @@ -1405,6 +1405,42 @@ static void test_EM_SETCHARFORMAT(void) DestroyWindow(hwndRichEdit); }
+/* As the clipboard is a shared resource, it happens (on Windows) that the WM_PASTE + * is a no-op; likely because another app has opened the clipboard for inspection. + * In this case, WM_PASTE does nothing, and doesn't return an error code. + * So retry pasting a couple of times. + * Don't use this function if the paste operation shouldn't change the content of the + * editor (clipboard is empty, edit control is read only...). + * Also impact on undo stack is not managed. + */ +#define send_paste(a) _send_paste(__LINE__, (a)) +static void _send_paste(unsigned int line, HWND wnd) +{ + unsigned len = SendMessageA(wnd, WM_GETTEXTLENGTH, 0, 0); + int retries; + + for (retries = 0; retries < 7; retries++) + { + if (retries) Sleep(15); + SendMessageA(wnd, WM_PASTE, 0, 0); + if (SendMessageA(wnd, WM_GETTEXTLENGTH, 0, 0) > len) return; + } + ok_(__FILE__, line)(0, "Failed to paste clipboard content\n"); + { + char classname[256]; + HWND clipwnd = GetOpenClipboardWindow(); + /* Provide a hint as to the source of interference: + * - The class name would typically be CLIPBRDWNDCLASS if the + * clipboard was opened by a Windows application using the + * ole32 API. + * - And it would be __wine_clipboard_manager if it was opened in + * response to a native application. + */ + GetClassNameA(clipwnd, classname, ARRAY_SIZE(classname)); + trace("%p (%s) opened the clipboard\n", clipwnd, classname); + } +} + static void test_EM_SETTEXTMODE(void) { HWND hwndRichEdit = new_richedit(NULL); @@ -1479,7 +1515,7 @@ static void test_EM_SETTEXTMODE(void) SendMessageA(hwndRichEdit, WM_SETTEXT, 0, (LPARAM)"wine");
/*Paste the italicized "wine" into the control*/ - SendMessageA(hwndRichEdit, WM_PASTE, 0, 0); + send_paste(hwndRichEdit);
len = SendMessageA(hwndRichEdit, WM_GETTEXTLENGTH, 0, 0); ok(len == 8 /*winewine*/, "Unexpected text length %u\n", len); @@ -1525,7 +1561,7 @@ static void test_EM_SETTEXTMODE(void) SendMessageA(hwndRichEdit, WM_SETTEXT, 0, (LPARAM)"wine");
/*Paste italicized "wine" into the control*/ - SendMessageA(hwndRichEdit, WM_PASTE, 0, 0); + send_paste(hwndRichEdit);
/*Select text from the first "wine" string*/ cr.cpMin = 1; @@ -1671,7 +1707,7 @@ static void test_TM_PLAINTEXT(void) /*Paste the plain text "wine" string, which should take the insert formatting, which at the moment is bold italics*/
- SendMessageA(hwndRichEdit, WM_PASTE, 0, 0); + send_paste(hwndRichEdit);
/*Select the first "wine" string and retrieve its formatting*/
@@ -4851,7 +4887,7 @@ static void test_EM_GETMODIFY(void) SendMessageA(hwndRichEdit, EM_SETMODIFY, FALSE, 0); SendMessageA(hwndRichEdit, EM_SETSEL, 0, 2); SendMessageA(hwndRichEdit, WM_COPY, 0, 0); - SendMessageA(hwndRichEdit, WM_PASTE, 0, 0); + send_paste(hwndRichEdit); result = SendMessageA(hwndRichEdit, EM_GETMODIFY, 0, 0); ok (result != 0, "EM_GETMODIFY returned zero, instead of non-zero when pasting identical text\n"); @@ -4861,7 +4897,7 @@ static void test_EM_GETMODIFY(void) SendMessageA(hwndRichEdit, EM_SETSEL, 0, 2); SendMessageA(hwndRichEdit, WM_COPY, 0, 0); SendMessageA(hwndRichEdit, EM_SETSEL, 0, 3); - SendMessageA(hwndRichEdit, WM_PASTE, 0, 0); + send_paste(hwndRichEdit); result = SendMessageA(hwndRichEdit, EM_GETMODIFY, 0, 0); ok (result != 0, "EM_GETMODIFY returned zero, instead of non-zero when pasting different text\n"); @@ -5561,7 +5597,7 @@ static void test_WM_PASTE(void) (MapVirtualKeyA('C', MAPVK_VK_TO_VSC) << 16) | 1); release_key(VK_CONTROL); SendMessageA(hwndRichEdit, WM_SETTEXT, 0, 0); - SendMessageA(hwndRichEdit, WM_PASTE, 0, 0); + send_paste(hwndRichEdit); SendMessageA(hwndRichEdit, WM_GETTEXT, 1024, (LPARAM)buffer); result = strcmp(buffer,"testing"); ok(result == 0, @@ -5582,7 +5618,7 @@ static void test_WM_PASTE(void) ok(result == 0, "test paste: strcmp = %i, actual = '%s'\n", result, buffer); SendMessageA(hwndRichEdit, WM_SETTEXT, 0, 0); - SendMessageA(hwndRichEdit, WM_PASTE, 0, 0); + send_paste(hwndRichEdit); SendMessageA(hwndRichEdit, WM_GETTEXT, 1024, (LPARAM)buffer); result = strcmp(buffer,"cut\r\n"); ok(result == 0, @@ -5632,7 +5668,7 @@ static void test_WM_PASTE(void)
/* Paste multi-line text into single-line control */ hwndRichEdit = new_richedit_with_style(NULL, 0); - SendMessageA(hwndRichEdit, WM_PASTE, 0, 0); + send_paste(hwndRichEdit); SendMessageA(hwndRichEdit, WM_GETTEXT, 1024, (LPARAM)buffer); result = strcmp(buffer, "testing paste"); ok(result == 0,
From: Eric Pouech eric.pouech@gmail.com
Reusing existing helper from user32 & comctl32.
https://bugs.winehq.org/show_bug.cgi?id=47888
Signed-off-by: Eric Pouech eric.pouech@gmail.com --- dlls/riched20/tests/richole.c | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-)
diff --git a/dlls/riched20/tests/richole.c b/dlls/riched20/tests/richole.c index d648354729e..fc0a13b506f 100644 --- a/dlls/riched20/tests/richole.c +++ b/dlls/riched20/tests/richole.c @@ -4907,6 +4907,35 @@ static void test_character_movement(void) ITextRange_Release(range); }
+static BOOL open_clipboard(HWND hwnd) +{ + DWORD start = GetTickCount(); + while (1) + { + BOOL ret = OpenClipboard(hwnd); + if (ret || GetLastError() != ERROR_ACCESS_DENIED) + return ret; + if (GetTickCount() - start > 100) + { + char classname[256]; + DWORD le = GetLastError(); + HWND clipwnd = GetOpenClipboardWindow(); + /* Provide a hint as to the source of interference: + * - The class name would typically be CLIPBRDWNDCLASS if the + * clipboard was opened by a Windows application using the + * ole32 API. + * - And it would be __wine_clipboard_manager if it was opened in + * response to a native application. + */ + GetClassNameA(clipwnd, classname, ARRAY_SIZE(classname)); + trace("%p (%s) opened the clipboard\n", clipwnd, classname); + SetLastError(le); + return ret; + } + Sleep(15); + } +} + #define CLIPBOARD_RANGE_CONTAINS(range, start, end, expected) _clipboard_range_contains(range, start, end, expected, __LINE__, 0); #define TODO_CLIPBOARD_RANGE_CONTAINS(range, start, end, expected) _clipboard_range_contains(range, start, end, expected, __LINE__, 1); static void _clipboard_range_contains(ITextRange *range, LONG start, LONG end, const char *expected, int line, int todo) @@ -4921,7 +4950,7 @@ static void _clipboard_range_contains(ITextRange *range, LONG start, LONG end, c hr = ITextRange_Copy(range, NULL); ok_(__FILE__,line)(hr == S_OK, "Copy failed: 0x%08lx\n", hr);
- clipboard_open = OpenClipboard(NULL); + clipboard_open = open_clipboard(NULL); ok_(__FILE__,line)(clipboard_open, "OpenClipboard failed: %ld\n", GetLastError()); global = GetClipboardData(CF_TEXT); ok_(__FILE__,line)(global != NULL, "GetClipboardData failed: %p\n", global);
V2: - failure was due to a bug in wine for wm_paste handling in plain text mode. - added test case & fix for it - V1 patches untouched
Huw Davies (@huw) commented about dlls/riched20/tests/editor.c:
- Don't use this function if the paste operation shouldn't change the content of the
- editor (clipboard is empty, edit control is read only...).
- Also impact on undo stack is not managed.
- */
+#define send_paste(a) _send_paste(__LINE__, (a)) +static void _send_paste(unsigned int line, HWND wnd) +{
- unsigned len = SendMessageA(wnd, WM_GETTEXTLENGTH, 0, 0);
- int retries;
- for (retries = 0; retries < 7; retries++)
- {
if (retries) Sleep(15);
SendMessageA(wnd, WM_PASTE, 0, 0);
if (SendMessageA(wnd, WM_GETTEXTLENGTH, 0, 0) > len) return;
- }
It would be cleaner to use `EM_[GS]ETMODIFY` for this check.
Also note, the commit msg prefix should include `"/tests"`.