From 66c8ded4548bd1d886431152bc8a7e5cacc411d1 Mon Sep 17 00:00:00 2001 From: Katayama Hirofumi MZ Date: Sun, 9 Apr 2023 15:19:19 +0900 Subject: [PATCH] [COMCTL32][USER32] EDIT: CompForm and CandForm (#5226) The changes of this PR are on EDIT controls. - Delete composition_len and composition_start members. - Add EDIT_ImmSetCompositionWindow helper function. - At EDIT_SetCaretPos, set the position of the composition window. - We don't use internal composition string. Rely on the composition window. - Improve WM_IME_STARTCOMPOSITION, WM_IME_COMPOSITION and WM_IME_ENDCOMPOSITION message handling. CORE-11700 --- dll/win32/comctl32/edit.c | 71 +++++++++++++++++++++++-- win32ss/user/user32/controls/edit.c | 81 ++++++++++++++++++++++++++--- 2 files changed, 142 insertions(+), 10 deletions(-) diff --git a/dll/win32/comctl32/edit.c b/dll/win32/comctl32/edit.c index 2e7322077fa..b37bf8cffb5 100644 --- a/dll/win32/comctl32/edit.c +++ b/dll/win32/comctl32/edit.c @@ -150,8 +150,10 @@ typedef struct /* * IME Data */ +#ifndef __REACTOS__ /* Rely on the composition window */ UINT composition_len; /* length of composition, 0 == no composition */ int composition_start; /* the character position for the composition */ +#endif /* * Uniscribe Data */ @@ -1711,6 +1713,33 @@ static LRESULT EDIT_EM_Scroll(EDITSTATE *es, INT action) } +#ifdef __REACTOS__ +static void EDIT_ImmSetCompositionWindow(EDITSTATE *es, POINT pt) +{ + COMPOSITIONFORM CompForm; + HIMC hIMC = ImmGetContext(es->hwndSelf); + if (!hIMC) + { + ERR("!hIMC\n"); + return; + } + + CompForm.ptCurrentPos = pt; + if (es->style & ES_MULTILINE) + { + CompForm.dwStyle = CFS_RECT; + CompForm.rcArea = es->format_rect; + } + else + { + CompForm.dwStyle = CFS_POINT; + SetRectEmpty(&CompForm.rcArea); + } + + ImmSetCompositionWindow(hIMC, &CompForm); + ImmReleaseContext(es->hwndSelf, hIMC); +} +#endif /********************************************************************* * * EDIT_SetCaretPos @@ -1720,8 +1749,19 @@ static void EDIT_SetCaretPos(EDITSTATE *es, INT pos, BOOL after_wrap) { LRESULT res = EDIT_EM_PosFromChar(es, pos, after_wrap); +#ifdef __REACTOS__ + HKL hKL = GetKeyboardLayout(0); + POINT pt = { (short)LOWORD(res), (short)HIWORD(res) }; + SetCaretPos(pt.x, pt.y); + + if (!ImmIsIME(hKL)) + return; + + EDIT_ImmSetCompositionWindow(es, pt); +#else TRACE("%d - %dx%d\n", pos, (short)LOWORD(res), (short)HIWORD(res)); SetCaretPos((short)LOWORD(res), (short)HIWORD(res)); +#endif } @@ -2076,7 +2116,11 @@ static INT EDIT_PaintText(EDITSTATE *es, HDC dc, INT x, INT y, INT line, INT col BkColor = GetBkColor(dc); TextColor = GetTextColor(dc); if (rev) { +#ifdef __REACTOS__ + if (TRUE) +#else if (es->composition_len == 0) +#endif { SetBkColor(dc, GetSysColor(COLOR_HIGHLIGHT)); SetTextColor(dc, GetSysColor(COLOR_HIGHLIGHTTEXT)); @@ -2101,7 +2145,11 @@ static INT EDIT_PaintText(EDITSTATE *es, HDC dc, INT x, INT y, INT line, INT col ret = size.cx; } if (rev) { +#ifdef __REACTOS__ + if (TRUE) +#else if (es->composition_len == 0) +#endif { SetBkColor(dc, BkColor); SetTextColor(dc, TextColor); @@ -4256,6 +4304,7 @@ static void EDIT_GetCompositionStr(HIMC hIMC, LPARAM CompFlag, EDITSTATE *es) } } +#ifndef __REACTOS__ /* We don't use internal composition string. Rely on the composition window */ /* check for change in composition start */ if (es->selection_end < es->composition_start) es->composition_start = es->selection_end; @@ -4273,6 +4322,7 @@ static void EDIT_GetCompositionStr(HIMC hIMC, LPARAM CompFlag, EDITSTATE *es) es->selection_start = es->composition_start; es->selection_end = es->selection_start + es->composition_len; +#endif heap_free(lpCompStrAttr); heap_free(lpCompStr); @@ -4298,6 +4348,7 @@ static void EDIT_GetResultStr(HIMC hIMC, EDITSTATE *es) ImmGetCompositionStringW(hIMC, GCS_RESULTSTR, lpResultStr, buflen); +#ifndef __REACTOS__ /* check for change in composition start */ if (es->selection_end < es->composition_start) es->composition_start = es->selection_end; @@ -4307,6 +4358,7 @@ static void EDIT_GetResultStr(HIMC hIMC, EDITSTATE *es) EDIT_EM_ReplaceSel(es, TRUE, lpResultStr, buflen / sizeof(WCHAR), TRUE, TRUE); es->composition_start = es->selection_end; es->composition_len = 0; +#endif heap_free(lpResultStr); } @@ -4316,11 +4368,16 @@ static void EDIT_ImeComposition(HWND hwnd, LPARAM CompFlag, EDITSTATE *es) HIMC hIMC; int cursor; +#ifdef __REACTOS__ + if (es->selection_start != es->selection_end) + EDIT_EM_ReplaceSel(es, TRUE, NULL, 0, TRUE, TRUE); +#else if (es->composition_len == 0 && es->selection_start != es->selection_end) { EDIT_EM_ReplaceSel(es, TRUE, NULL, 0, TRUE, TRUE); es->composition_start = es->selection_end; } +#endif hIMC = ImmGetContext(hwnd); if (!hIMC) @@ -5015,26 +5072,34 @@ static LRESULT CALLBACK EDIT_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPAR break; case WM_IME_STARTCOMPOSITION: - es->composition_start = es->selection_end; - es->composition_len = 0; #ifdef __REACTOS__ if (FALSE) /* FIXME: Condition */ return TRUE; - result = DefWindowProcW(hwnd, WM_IME_STARTCOMPOSITION, wParam, lParam); + result = DefWindowProcW(hwnd, msg, wParam, lParam); +#else + es->composition_start = es->selection_end; + es->composition_len = 0; #endif break; case WM_IME_COMPOSITION: EDIT_ImeComposition(hwnd, lParam, es); +#ifdef __REACTOS__ + result = DefWindowProcW(hwnd, msg, wParam, lParam); +#endif break; case WM_IME_ENDCOMPOSITION: +#ifdef __REACTOS__ + result = DefWindowProcW(hwnd, msg, wParam, lParam); +#else if (es->composition_len > 0) { EDIT_EM_ReplaceSel(es, TRUE, NULL, 0, TRUE, TRUE); es->selection_end = es->selection_start; es->composition_len= 0; } +#endif break; case WM_IME_COMPOSITIONFULL: diff --git a/win32ss/user/user32/controls/edit.c b/win32ss/user/user32/controls/edit.c index c9e4faaed53..9a38353eb59 100644 --- a/win32ss/user/user32/controls/edit.c +++ b/win32ss/user/user32/controls/edit.c @@ -47,14 +47,16 @@ #include #ifdef __REACTOS__ #include -#define ImmGetContext IMM_FN(ImmGetContext) #define ImmGetCompositionStringW IMM_FN(ImmGetCompositionStringW) -#define ImmReleaseContext IMM_FN(ImmReleaseContext) -#define ImmLockIMC IMM_FN(ImmLockIMC) -#define ImmUnlockIMC IMM_FN(ImmUnlockIMC) -#define ImmNotifyIME IMM_FN(ImmNotifyIME) +#define ImmGetCompositionWindow IMM_FN(ImmGetCompositionWindow) +#define ImmGetContext IMM_FN(ImmGetContext) #define ImmIsIME IMM_FN(ImmIsIME) +#define ImmLockIMC IMM_FN(ImmLockIMC) +#define ImmNotifyIME IMM_FN(ImmNotifyIME) +#define ImmReleaseContext IMM_FN(ImmReleaseContext) #define ImmSetCompositionFontW IMM_FN(ImmSetCompositionFontW) +#define ImmSetCompositionWindow IMM_FN(ImmSetCompositionWindow) +#define ImmUnlockIMC IMM_FN(ImmUnlockIMC) #endif WINE_DEFAULT_DEBUG_CHANNEL(edit); @@ -154,8 +156,10 @@ typedef struct /* * IME Data */ +#ifndef __REACTOS__ /* Rely on the composition window */ UINT composition_len; /* length of composition, 0 == no composition */ int composition_start; /* the character position for the composition */ +#endif /* * Uniscribe Data */ @@ -1864,6 +1868,33 @@ static LRESULT EDIT_EM_Scroll(EDITSTATE *es, INT action) } +#ifdef __REACTOS__ +static void EDIT_ImmSetCompositionWindow(EDITSTATE *es, POINT pt) +{ + COMPOSITIONFORM CompForm; + HIMC hIMC = ImmGetContext(es->hwndSelf); + if (!hIMC) + { + ERR("!hIMC\n"); + return; + } + + CompForm.ptCurrentPos = pt; + if (es->style & ES_MULTILINE) + { + CompForm.dwStyle = CFS_RECT; + CompForm.rcArea = es->format_rect; + } + else + { + CompForm.dwStyle = CFS_POINT; + SetRectEmpty(&CompForm.rcArea); + } + + ImmSetCompositionWindow(hIMC, &CompForm); + ImmReleaseContext(es->hwndSelf, hIMC); +} +#endif /********************************************************************* * * EDIT_SetCaretPos @@ -1873,8 +1904,19 @@ static void EDIT_SetCaretPos(EDITSTATE *es, INT pos, BOOL after_wrap) { LRESULT res = EDIT_EM_PosFromChar(es, pos, after_wrap); +#ifdef __REACTOS__ + HKL hKL = GetKeyboardLayout(0); + POINT pt = { (short)LOWORD(res), (short)HIWORD(res) }; + SetCaretPos(pt.x, pt.y); + + if (!ImmIsIME(hKL)) + return; + + EDIT_ImmSetCompositionWindow(es, pt); +#else TRACE("%d - %dx%d\n", pos, (short)LOWORD(res), (short)HIWORD(res)); SetCaretPos((short)LOWORD(res), (short)HIWORD(res)); +#endif } @@ -2229,7 +2271,11 @@ static INT EDIT_PaintText(EDITSTATE *es, HDC dc, INT x, INT y, INT line, INT col BkColor = GetBkColor(dc); TextColor = GetTextColor(dc); if (rev) { +#ifdef __REACTOS__ + if (TRUE) +#else if (es->composition_len == 0) +#endif { SetBkColor(dc, GetSysColor(COLOR_HIGHLIGHT)); SetTextColor(dc, GetSysColor(COLOR_HIGHLIGHTTEXT)); @@ -2254,7 +2300,11 @@ static INT EDIT_PaintText(EDITSTATE *es, HDC dc, INT x, INT y, INT line, INT col ret = size.cx; } if (rev) { +#ifdef __REACTOS__ + if (TRUE) +#else if (es->composition_len == 0) +#endif { SetBkColor(dc, BkColor); SetTextColor(dc, TextColor); @@ -4478,6 +4528,7 @@ static void EDIT_GetCompositionStr(HIMC hIMC, LPARAM CompFlag, EDITSTATE *es) } } +#ifndef __REACTOS__ /* We don't use internal composition string. Rely on the composition window */ /* check for change in composition start */ if (es->selection_end < es->composition_start) es->composition_start = es->selection_end; @@ -4495,6 +4546,7 @@ static void EDIT_GetCompositionStr(HIMC hIMC, LPARAM CompFlag, EDITSTATE *es) es->selection_start = es->composition_start; es->selection_end = es->selection_start + es->composition_len; +#endif HeapFree(GetProcessHeap(),0,lpCompStrAttr); HeapFree(GetProcessHeap(),0,lpCompStr); @@ -4521,6 +4573,7 @@ static void EDIT_GetResultStr(HIMC hIMC, EDITSTATE *es) ImmGetCompositionStringW(hIMC, GCS_RESULTSTR, lpResultStr, buflen); lpResultStr[buflen/sizeof(WCHAR)] = 0; +#ifndef __REACTOS__ /* check for change in composition start */ if (es->selection_end < es->composition_start) es->composition_start = es->selection_end; @@ -4530,6 +4583,7 @@ static void EDIT_GetResultStr(HIMC hIMC, EDITSTATE *es) EDIT_EM_ReplaceSel(es, TRUE, lpResultStr, TRUE, TRUE); es->composition_start = es->selection_end; es->composition_len = 0; +#endif HeapFree(GetProcessHeap(),0,lpResultStr); } @@ -4539,11 +4593,16 @@ static void EDIT_ImeComposition(HWND hwnd, LPARAM CompFlag, EDITSTATE *es) HIMC hIMC; int cursor; +#ifdef __REACTOS__ + if (es->selection_start != es->selection_end) + EDIT_EM_ReplaceSel(es, TRUE, empty_stringW, TRUE, TRUE); +#else if (es->composition_len == 0 && es->selection_start != es->selection_end) { EDIT_EM_ReplaceSel(es, TRUE, empty_stringW, TRUE, TRUE); es->composition_start = es->selection_end; } +#endif hIMC = ImmGetContext(hwnd); if (!hIMC) @@ -5333,26 +5392,34 @@ LRESULT WINAPI EditWndProc_common( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lP break; case WM_IME_STARTCOMPOSITION: - es->composition_start = es->selection_end; - es->composition_len = 0; #ifdef __REACTOS__ if (FALSE) /* FIXME: Condition */ return TRUE; result = DefWindowProcT(hwnd, msg, wParam, lParam, unicode); +#else + es->composition_start = es->selection_end; + es->composition_len = 0; #endif break; case WM_IME_COMPOSITION: EDIT_ImeComposition(hwnd, lParam, es); +#ifdef __REACTOS__ + result = DefWindowProcT(hwnd, msg, wParam, lParam, unicode); +#endif break; case WM_IME_ENDCOMPOSITION: +#ifdef __REACTOS__ + result = DefWindowProcT(hwnd, msg, wParam, lParam, unicode); +#else if (es->composition_len > 0) { EDIT_EM_ReplaceSel(es, TRUE, empty_stringW, TRUE, TRUE); es->selection_end = es->selection_start; es->composition_len= 0; } +#endif break; case WM_IME_COMPOSITIONFULL: