Module: wine Branch: master Commit: c385b6475e6ad07227a1ef29593170af1c3cbf99 URL: https://gitlab.winehq.org/wine/wine/-/commit/c385b6475e6ad07227a1ef29593170a...
Author: Akihiro Sagawa sagawa.aki@gmail.com Date: Fri Jan 20 23:55:59 2023 +0900
user32/edit: Fix WM_CHAR handler for double-byte characters.
After commit 2aa54a90bd24f6aa422a2eb832a54d9afe585259, a double-byte character is sent to the edit control by double WM_CHAR messages. However, its WM_CHAR handler (ANSI version) can't process a double- byte character properly because the handler converts WM_CHAR to WCHAR one by one. This fix queues the double-byte lead byte as it comes in and then uses it afterwards for the WCHAR conversion.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=54337
---
dlls/user32/edit.c | 21 +++++++++++++++++++-- dlls/user32/tests/edit.c | 4 ++-- 2 files changed, 21 insertions(+), 4 deletions(-)
diff --git a/dlls/user32/edit.c b/dlls/user32/edit.c index 74411d385e2..47c61f59c24 100644 --- a/dlls/user32/edit.c +++ b/dlls/user32/edit.c @@ -113,6 +113,7 @@ typedef struct should be sent to the first parent. */ HWND hwndListBox; /* handle of ComboBox's listbox or NULL */ INT wheelDeltaRemainder; /* scroll wheel delta left over after scrolling whole lines */ + BYTE lead_byte; /* DBCS lead byte store for WM_CHAR */ /* * only for multi line controls */ @@ -4975,8 +4976,24 @@ LRESULT EditWndProc_common( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam, B charW = wParam; else { - CHAR charA = wParam; - MultiByteToWideChar(CP_ACP, 0, &charA, 1, &charW, 1); + BYTE low = wParam; + DWORD cp = get_input_codepage(); + if (es->lead_byte) + { + char ch[2]; + ch[0] = es->lead_byte; + ch[1] = low; + MultiByteToWideChar(cp, 0, ch, 2, &charW, 1); + } + else if (IsDBCSLeadByteEx(cp, low)) + { + es->lead_byte = low; + result = 1; + break; + } + else + MultiByteToWideChar(cp, 0, (char *)&low, 1, &charW, 1); + es->lead_byte = 0; }
if (es->hwndListBox) diff --git a/dlls/user32/tests/edit.c b/dlls/user32/tests/edit.c index 0409b3fde7c..78328ee1729 100644 --- a/dlls/user32/tests/edit.c +++ b/dlls/user32/tests/edit.c @@ -3404,12 +3404,12 @@ static void test_dbcs_WM_CHAR(void)
n = GetWindowTextW(hwnd[i], strW, ARRAY_SIZE(strW)); ok(n > 0, "GetWindowTextW failed\n"); - todo_wine ok(!wcscmp(strW, textW), "got %s, expected %s\n", + ok(!wcscmp(strW, textW), "got %s, expected %s\n", wine_dbgstr_w(strW), wine_dbgstr_w(textW));
n = GetWindowTextA(hwnd[i], str, ARRAY_SIZE(str)); ok(n > 0, "GetWindowText failed\n"); - todo_wine ok(!strcmp(str, (char*)bytes), "got %s, expected %s\n", + ok(!strcmp(str, (char*)bytes), "got %s, expected %s\n", wine_dbgstr_a(str), wine_dbgstr_a((char *)bytes));
DestroyWindow(hwnd[i]);