User32 uses the input codepage in Unicode edit control. However, it uses ANSI codepage, i.e. CP_ACP, in ANSI version control.
Comctl32 is different from user32. It doesn't have A-W duality and uses the input codepage in it.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=54424
-- v3: comctl32/tests: Add WM_CHAR tests for edit control. user32/edit: Use CP_ACP for WM_CHAR convresion in ANSI version control. user32/tests: Fix WM_CHAR tests to use the input codepage.
From: Akihiro Sagawa sagawa.aki@gmail.com
User32 uses the input codepage in Unicode edit control. However, it uses ANSI codepage, i.e. CP_ACP, in ANSI version control.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=54424 --- dlls/user32/tests/edit.c | 45 +++++++++++++++++++++++----------------- dlls/user32/tests/msg.c | 2 +- 2 files changed, 27 insertions(+), 20 deletions(-)
diff --git a/dlls/user32/tests/edit.c b/dlls/user32/tests/edit.c index 78328ee1729..9964a3c8c7a 100644 --- a/dlls/user32/tests/edit.c +++ b/dlls/user32/tests/edit.c @@ -32,6 +32,8 @@ #define ID_EDITTEST2 99 #define MAXLEN 200
+extern DWORD get_input_codepage( void ); + static BOOL open_clipboard(HWND hwnd) { DWORD start = GetTickCount(); @@ -3366,51 +3368,56 @@ static void test_wordbreak_proc(void) DestroyWindow(hwnd); }
-static void test_dbcs_WM_CHAR(void) +static void test_WM_CHAR(void) { - WCHAR textW[] = { 0x4e00, 0x4e8c, 0x4e09, 0 }; /* one, two, three */ - unsigned char bytes[7]; + static const WCHAR textW[] = { 0x4e00, 0x4e8c, 0x00d7, '!', 0 }; /* one, two, x, ! */ + CPINFO cpinfo; HWND hwnd[2]; int i;
- WideCharToMultiByte(CP_ACP, 0, textW, -1, (char *)bytes, ARRAY_SIZE(bytes), NULL, NULL); - if (!IsDBCSLeadByte(bytes[0])) + GetCPInfo(CP_ACP, &cpinfo); + if (cpinfo.MaxCharSize > 2) { - skip("Skipping DBCS WM_CHAR test in this codepage\n"); + skip("Skipping legacy WM_CHAR test in UTF-8 codepage\n"); return; } - hwnd[0] = create_editcontrol(ES_AUTOHSCROLL | ES_AUTOVSCROLL, 0); - hwnd[1] = create_editcontrolW(ES_AUTOHSCROLL | ES_AUTOVSCROLL, 0); + hwnd[0] = CreateWindowExA(0, "EDIT", "", ES_AUTOHSCROLL, 0, 0, 300, 30, NULL, NULL, hinst, NULL); + hwnd[1] = CreateWindowExW(0, L"EDIT", L"", ES_AUTOHSCROLL, 0, 0, 300, 30, NULL, NULL, hinst, NULL);
for (i = 0; i < ARRAY_SIZE(hwnd); i++) { const unsigned char* p; - WCHAR strW[4]; - char str[7]; + WCHAR bufW[10], strW[10]; + char buf[10], str[10]; + DWORD cp; MSG msg; - BOOL r; int n;
winetest_push_context("%c", i ? 'W' : 'A');
- r = SetWindowTextA(hwnd[i], ""); - ok(r, "SetWindowText failed\n"); + cp = i ? get_input_codepage() : CP_ACP; + n = WideCharToMultiByte(cp, 0, textW, -1, buf, ARRAY_SIZE(buf), NULL, NULL); + ok(n > 0, "WideCharToMultiByte failed\n");
- for (p = bytes; *p; p++) + for (p = (unsigned char*)buf; *p; p++) PostMessageA(hwnd[i], WM_CHAR, *p, 1);
while (PeekMessageA(&msg, hwnd[i], 0, 0, PM_REMOVE)) DispatchMessageA(&msg);
+ n = MultiByteToWideChar(cp, 0, buf, -1, bufW, ARRAY_SIZE(bufW)); + ok(n > 0, "MultiByteToWideChar failed\n"); n = GetWindowTextW(hwnd[i], strW, ARRAY_SIZE(strW)); ok(n > 0, "GetWindowTextW failed\n"); - ok(!wcscmp(strW, textW), "got %s, expected %s\n", - wine_dbgstr_w(strW), wine_dbgstr_w(textW)); + ok(!wcscmp(strW, bufW), "got %s, expected %s\n", + wine_dbgstr_w(strW), wine_dbgstr_w(bufW));
+ n = WideCharToMultiByte(CP_ACP, 0, bufW, -1, buf, ARRAY_SIZE(buf), NULL, NULL); + ok(n > 0, "WideCharToMultiByte failed\n"); n = GetWindowTextA(hwnd[i], str, ARRAY_SIZE(str)); ok(n > 0, "GetWindowText failed\n"); - ok(!strcmp(str, (char*)bytes), "got %s, expected %s\n", - wine_dbgstr_a(str), wine_dbgstr_a((char *)bytes)); + ok(!strcmp(str, buf), "got %s, expected %s\n", + wine_dbgstr_a(str), wine_dbgstr_a(buf));
DestroyWindow(hwnd[i]);
@@ -3455,7 +3462,7 @@ START_TEST(edit) test_paste(); test_EM_GETLINE(); test_wordbreak_proc(); - test_dbcs_WM_CHAR(); + test_WM_CHAR();
UnregisterWindowClasses(); } diff --git a/dlls/user32/tests/msg.c b/dlls/user32/tests/msg.c index 6faaa2c2f40..dfe8801da15 100644 --- a/dlls/user32/tests/msg.c +++ b/dlls/user32/tests/msg.c @@ -15653,7 +15653,7 @@ static void test_SetForegroundWindow(void) DestroyWindow(hwnd); }
-static DWORD get_input_codepage( void ) +extern DWORD get_input_codepage( void ) { DWORD cp; int ret;
From: Akihiro Sagawa sagawa.aki@gmail.com
--- dlls/user32/edit.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/dlls/user32/edit.c b/dlls/user32/edit.c index 47c61f59c24..9361ff8e3d2 100644 --- a/dlls/user32/edit.c +++ b/dlls/user32/edit.c @@ -4977,7 +4977,7 @@ LRESULT EditWndProc_common( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam, B else { BYTE low = wParam; - DWORD cp = get_input_codepage(); + DWORD cp = es->is_unicode ? get_input_codepage() : CP_ACP; if (es->lead_byte) { char ch[2];
From: Akihiro Sagawa sagawa.aki@gmail.com
Comctl32 is different from user32. It doesn't have A-W duality and uses the input codepage in it. --- dlls/comctl32/tests/edit.c | 70 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+)
diff --git a/dlls/comctl32/tests/edit.c b/dlls/comctl32/tests/edit.c index f45b898dc12..eae3cae45e0 100644 --- a/dlls/comctl32/tests/edit.c +++ b/dlls/comctl32/tests/edit.c @@ -3764,6 +3764,75 @@ static void test_ime(void) DestroyWindow(hwnd); }
+static DWORD get_input_codepage( void ) +{ + DWORD cp; + int ret; + HKL hkl = GetKeyboardLayout( 0 ); + + ret = GetLocaleInfoW( LOWORD(hkl), LOCALE_IDEFAULTANSICODEPAGE | LOCALE_RETURN_NUMBER, + (WCHAR *)&cp, sizeof(cp) / sizeof(WCHAR) ); + if (!ret) cp = CP_ACP; + return cp; +} + +static void test_WM_CHAR(void) +{ + static const WCHAR textW[] = { 0x4e00, 0x4e8c, 0x00d7, '!', 0 }; /* one, two, x, ! */ + CPINFO cpinfo; + HWND hwnd[2]; + int i; + + GetCPInfo(CP_ACP, &cpinfo); + if (cpinfo.MaxCharSize > 2) + { + skip("Skipping legacy WM_CHAR test in UTF-8 codepage\n"); + return; + } + hwnd[0] = CreateWindowExA(0, "EDIT", "", ES_AUTOHSCROLL, 0, 0, 300, 30, NULL, NULL, hinst, NULL); + hwnd[1] = CreateWindowExW(0, L"EDIT", L"", ES_AUTOHSCROLL, 0, 0, 300, 30, NULL, NULL, hinst, NULL); + + for (i = 0; i < ARRAY_SIZE(hwnd); i++) + { + const unsigned char* p; + WCHAR bufW[10], strW[10]; + char buf[10], str[10]; + DWORD cp; + MSG msg; + int n; + + winetest_push_context("%c", i ? 'W' : 'A'); + + cp = get_input_codepage(); + n = WideCharToMultiByte(cp, 0, textW, -1, buf, ARRAY_SIZE(buf), NULL, NULL); + ok(n > 0, "WideCharToMultiByte failed\n"); + + for (p = (unsigned char*)buf; *p; p++) + PostMessageA(hwnd[i], WM_CHAR, *p, 1); + + while (PeekMessageA(&msg, hwnd[i], 0, 0, PM_REMOVE)) + DispatchMessageA(&msg); + + n = MultiByteToWideChar(cp, 0, buf, -1, bufW, ARRAY_SIZE(bufW)); + ok(n > 0, "MultiByteToWideChar failed\n"); + n = GetWindowTextW(hwnd[i], strW, ARRAY_SIZE(strW)); + ok(n > 0, "GetWindowTextW failed\n"); + ok(!wcscmp(strW, bufW), "got %s, expected %s\n", + wine_dbgstr_w(strW), wine_dbgstr_w(bufW)); + + n = WideCharToMultiByte(CP_ACP, 0, bufW, -1, buf, ARRAY_SIZE(buf), NULL, NULL); + ok(n > 0, "WideCharToMultiByte failed\n"); + n = GetWindowTextA(hwnd[i], str, ARRAY_SIZE(str)); + ok(n > 0, "GetWindowText failed\n"); + ok(!strcmp(str, buf), "got %s, expected %s\n", + wine_dbgstr_a(str), wine_dbgstr_a(buf)); + + DestroyWindow(hwnd[i]); + + winetest_pop_context(); + } +} + START_TEST(edit) { ULONG_PTR ctx_cookie; @@ -3811,6 +3880,7 @@ START_TEST(edit) test_change_focus(); test_cue_banner(); test_ime(); + test_WM_CHAR();
UnregisterWindowClasses();
On Tue Feb 14 14:03:47 2023 +0000, **** wrote:
Marvin replied on the mailing list:
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=129378 Your paranoid android. === debian11 (32 bit de report) === user32: msg.c:19232: Test failed: SendMessage from other thread 1: 1: the msg 0x0400 was expected, but got msg 0x0403 instead msg.c:19232: Test failed: SendMessage from other thread 1: 2: the msg sequence is not complete: expected 0000 - actual 0400
This doesn't relate to my update.
This merge request was closed by Akihiro Sagawa.