user32/edit: Fix WM_CHAR handler for double-byte characters.

After commit 2aa54a90bd, 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
This commit is contained in:
Akihiro Sagawa 2023-01-20 23:55:59 +09:00 committed by Alexandre Julliard
parent cbe3a39b64
commit c385b6475e
2 changed files with 21 additions and 4 deletions

View file

@ -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)

View file

@ -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]);