This series tries to fix WM_PASTE tests error on edit control (both user32 & comctl32).
The test failures where systematic on a local Win10 for comctl32 (yet very rare on user32, perhaps one in 20 runs).
Since the failures are not systematic, it ought to be a synchronisation / timing issue.
Flushing the msg queue before starting the paste test cycle seems to fix the issue. - 0 occurence on comctl32 and user32 in 50 run (local VM) - 0 occurence on Testbot (comctl32) in 1 run.
It's hard to be fully conclusive about bug resolution, but it's at least a step into the right direction.
-- v2: comctl32/tests: Fix failing WM_PASTE tests for edit control on Win10+. user32/tests: Fix failing WM_PASTE tests for edit control on Win10+.
From: Eric Pouech eric.pouech@gmail.com
There are cases in Windows10+ where the WM_PASTE message doesn't paste the content of the clipboard.
This appeared in testing: - almost always just after (for a couple of milliseconds) setting new content into the clipboard and closing it. - in some unrelated rare occasions (like once for 400 runs).
It looks like another (installed) process had opened the clipboard and forbids the paste command. As WM_PASTE doesn't return success/error status, workaround it by wrapping the WM_PASTE command into a helper, and retry when the clipboard's content hasn't been pasted.
Wine-bug: https://bugs.winehq.org/show_bug.cgi?id=53276
Signed-off-by: Eric Pouech eric.pouech@gmail.com --- dlls/user32/tests/edit.c | 37 ++++++++++++++++++++++++------------- 1 file changed, 24 insertions(+), 13 deletions(-)
diff --git a/dlls/user32/tests/edit.c b/dlls/user32/tests/edit.c index 2afbbd5bea4..9e350043a46 100644 --- a/dlls/user32/tests/edit.c +++ b/dlls/user32/tests/edit.c @@ -3175,12 +3175,32 @@ static void test_EM_GETHANDLE(void) DestroyWindow(hEdit); }
+/* In Windows 10+, the WM_PASTE message isn't always successful. + * So retry in case of failures. + */ +#define check_paste(h, e) _check_paste(__LINE__, (h), (e)) +static void _check_paste(unsigned int line, HWND hedit, unsigned explen) +{ + /* only retry on windows platform */ + int tries = strcmp(winetest_platform, "wine") ? 3 : 1; + int len = 0; + + SendMessageA(hedit, WM_SETTEXT, 0, (LPARAM)""); + do + { + SendMessageA(hedit, WM_PASTE, 0, 0); + if ((len = SendMessageA(hedit, WM_GETTEXTLENGTH, 0, 0))) break; + Sleep(1); + } while (--tries > 0); + ok_(__FILE__, line)(len == explen, "Unexpected len %u in edit\n", len); +} + static void test_paste(void) { HWND hEdit, hMultilineEdit; HANDLE hmem, hmem_ret; char *buffer; - int r, len; + int r; static const char *str = "this is a simple text"; static const char *str2 = "first line\r\nsecond line";
@@ -3205,10 +3225,7 @@ static void test_paste(void) ok(r == TRUE, "expected %d, got %d\n", TRUE, r);
/* Paste single line */ - SendMessageA(hEdit, WM_SETTEXT, 0, (LPARAM)""); - r = SendMessageA(hEdit, WM_PASTE, 0, 0); - len = SendMessageA(hEdit, WM_GETTEXTLENGTH, 0, 0); - ok(strlen(str) == len, "got %d\n", len); + check_paste(hEdit, strlen(str));
/* Prepare clipboard data with multiline text */ hmem = GlobalAlloc(GMEM_MOVEABLE, 255); @@ -3228,16 +3245,10 @@ static void test_paste(void) ok(r == TRUE, "expected %d, got %d\n", TRUE, r);
/* Paste multiline text in singleline edit - should be cut */ - SendMessageA(hEdit, WM_SETTEXT, 0, (LPARAM)""); - r = SendMessageA(hEdit, WM_PASTE, 0, 0); - len = SendMessageA(hEdit, WM_GETTEXTLENGTH, 0, 0); - ok(strlen("first line") == len, "got %d\n", len); + check_paste(hEdit, strlen("first line"));
/* Paste multiline text in multiline edit */ - SendMessageA(hMultilineEdit, WM_SETTEXT, 0, (LPARAM)""); - r = SendMessageA(hMultilineEdit, WM_PASTE, 0, 0); - len = SendMessageA(hMultilineEdit, WM_GETTEXTLENGTH, 0, 0); - ok(strlen(str2) == len, "got %d\n", len); + check_paste(hMultilineEdit, strlen(str2));
/* Cleanup */ DestroyWindow(hEdit);
From: Eric Pouech eric.pouech@gmail.com
There are cases in Windows10+ where the WM_PASTE message doesn't paste the content of the clipboard.
This appeared in testing: - almost always just after (for a couple of milliseconds) setting new content into the clipboard and closing it. - in some unrelated rare occasions (like once for 400 runs).
It looks like another (installed) process had opened the clipboard and forbids the paste command. As WM_PASTE doesn't return success/error status, workaround it by wrapping the WM_PASTE command into a helper, and retry when the clipboard's content hasn't been pasted.
Wine-bug: https://bugs.winehq.org/show_bug.cgi?id=53276
Signed-off-by: Eric Pouech eric.pouech@gmail.com --- dlls/comctl32/tests/edit.c | 36 ++++++++++++++++++++++++------------ 1 file changed, 24 insertions(+), 12 deletions(-)
diff --git a/dlls/comctl32/tests/edit.c b/dlls/comctl32/tests/edit.c index 91d16e044a0..b465a0a383f 100644 --- a/dlls/comctl32/tests/edit.c +++ b/dlls/comctl32/tests/edit.c @@ -3179,6 +3179,26 @@ static void test_EM_GETHANDLE(void) DestroyWindow(hEdit); }
+/* In Windows 10+, the WM_PASTE message isn't always successful. + * So retry in case of failures. + */ +#define check_paste(h, e) _check_paste(__LINE__, (h), (e)) +static void _check_paste(unsigned int line, HWND hedit, unsigned explen) +{ + /* only retry on windows platform */ + int tries = strcmp(winetest_platform, "wine") ? 3 : 1; + int len = 0; + + SendMessageA(hedit, WM_SETTEXT, 0, (LPARAM)""); + do + { + SendMessageA(hedit, WM_PASTE, 0, 0); + if ((len = SendMessageA(hedit, WM_GETTEXTLENGTH, 0, 0))) break; + Sleep(1); + } while (--tries > 0); + ok_(__FILE__, line)(len == explen, "Unexpected len %u in edit\n", len); +} + static void test_paste(void) { static const char *str = "this is a simple text"; @@ -3186,7 +3206,7 @@ static void test_paste(void) HWND hEdit, hMultilineEdit; HANDLE hmem, hmem_ret; char *buffer; - int r, len; + int r;
hEdit = create_editcontrol(ES_AUTOHSCROLL | ES_AUTOVSCROLL, 0); hMultilineEdit = create_editcontrol(ES_AUTOHSCROLL | ES_AUTOVSCROLL | ES_MULTILINE, 0); @@ -3209,10 +3229,7 @@ static void test_paste(void) ok(r == TRUE, "expected %d, got %d\n", TRUE, r);
/* Paste single line */ - SendMessageA(hEdit, WM_SETTEXT, 0, (LPARAM)""); - r = SendMessageA(hEdit, WM_PASTE, 0, 0); - len = SendMessageA(hEdit, WM_GETTEXTLENGTH, 0, 0); - ok(strlen(str) == len, "got %d\n", len); + check_paste(hEdit, strlen(str));
/* Prepare clipboard data with multiline text */ hmem = GlobalAlloc(GMEM_MOVEABLE, 255); @@ -3233,15 +3250,10 @@ static void test_paste(void)
/* Paste multiline text in singleline edit - should be cut */ SendMessageA(hEdit, WM_SETTEXT, 0, (LPARAM)""); - r = SendMessageA(hEdit, WM_PASTE, 0, 0); - len = SendMessageA(hEdit, WM_GETTEXTLENGTH, 0, 0); - ok(strlen("first line") == len, "got %d\n", len); + check_paste(hEdit, strlen("first line"));
/* Paste multiline text in multiline edit */ - SendMessageA(hMultilineEdit, WM_SETTEXT, 0, (LPARAM)""); - r = SendMessageA(hMultilineEdit, WM_PASTE, 0, 0); - len = SendMessageA(hMultilineEdit, WM_GETTEXTLENGTH, 0, 0); - ok(strlen(str2) == len, "got %d\n", len); + check_paste(hMultilineEdit, strlen(str2));
/* Cleanup */ DestroyWindow(hEdit);
V2: - changing strategy as even if the message queue isn't empty, it isn't the root cause