好的,看起来 StackOverflow 上的 IME 专家并不多……或者没有人感兴趣。
无论如何,我想通了。
基本上,我必须捕获以下 Windows 消息:
WM_INPUTLANGCHANGE = 0x51
WM_KEYUP = 0x101
WM_CHAR = 0x102
WM_CONVERTREQUESTEX = 0x108
WM_IME_STARTCOMPOSITION = 0x10D
WM_IME_ENDCOMPOSITION = 0x10E
WM_IME_COMPOSITION = 0x10F
WM_IME_SETCONTEXT = 0x281
WM_IME_NOTIFY = 0x282
WM_IME_CONTROL = 0x283
WM_IME_COMPOSITIONFULL = 0x284
WM_IME_SELECT = 0x285
WM_IME_CHAR = 0x286
WM_IME_REQUEST = 0x0288
WM_IME_KEYDOWN = 0x290
WM_IME_KEYUP = 0x291
我正在陷印WM_KEYUP
和WM_CHAR
,因为如果我在合成韩文字符的过程中单击某处,我不会收到合成消息,但我仍然需要将该字符添加到我的文本框中。这是一个奇怪的行为,我想知道它是否是一个错误。
一旦发生这种情况,韩国人、中国人和日本人之间的行为就会不同。
韩语非常简单(不过我不确定汉字转换,因为我不知道如何使用它)。
基本上,对于所有语言,每当我得到 a 时WM_IME_COMPOSITION
,我都必须调用ImmGetCompositionString
Imm32.dll,正如我在回答这个问题时所描述的那样。然后我将其显示为正在进行的合成,但不要将其添加到我存储的文本中。
组合字符串后,来自 Windows 的消息对于每个 IME 都是不同的。每次,我都可以从WM_IME_COMPOSITION
消息中得到它。
在韩语中,LParam
将只是GCS_RESULTSTR
,并且WParam
将是输入的字符,我可以将其转换为char
在日语中,“LParam”将是GCS_RESULTREADSTR | GCS_RESULTREADCLAUSE | GCS_RESULTSTR0 | GCS_RESULTCLAUSE
. 我必须使用ImmGetCompositionString
从之前的 WM_IME_COMPOSITION 消息中存储的结果,因为此时它将是一个空字符串。
在中文中,LParam
将是GCS_RESULTREADCLAUSE | GCS_RESULTSTR0 | GCS_RESULTCLAUSE
。它与日语相同,除非先前存储ImmGetCompositionString
的内容为空,在这种情况下我需要转换WParam
为字符。
在所有这三种情况下,我都必须确保清除显示的正在进行的组合。
如果收到WM_IME_STARTCOMPOSITION
,我会设置一个合成标志(并显示正在进行的合成字符串)
如果我收到WM_IME_ENDCOMPOSITION
我清除该标志(并清除正在进行的合成字符串)。
有时我没有收到WM_IME_ENDCOMPOSITION
,所以我在收到时清除我的标志WM_CHAR
。
总而言之,这是一次非常有趣的学习体验,而且还在进行中——但 IME 现在终于可以在我的控制下使用了!我一直工作到凌晨 1 点才完成。