C#和IME - 获取当前输入文本

Lau*_*ent 5 c# unicode ime

我使用日语IME作为示例,但在使用IME输入的其他语言中可能是相同的.

当用户使用IME将文本键入文本框时,将触发KeyDown和KeyUp事件.但是,在用户使用Enter键验证IME中的输入之前,TextBox.Text属性不会返回键入的文本.

因此,例如,如果用户键入5次あ然后验证,我将得到5个keydown/keyup事件,每次TextBox.Text返回""(空字符串),最后我将得到一个keydown/keyup为enter键和TextBox.Text将直接变成"あああああ".

在用户输入结束之前,如何在用户输入时获取用户输入?

(我知道如何在网页上的<input>字段的javascript中执行此操作,因此必须可以在C#中使用!)

Vin*_*abb 7

您可以使用它来获取当前组合.这适用于任何构图状态,适用于日语,中文和韩语.我只在Windows 7上测试过它,所以不确定它是否适用于其他版本的Windows.

至于事情是一样的,那么三者之间的事情实际上是非常不同的.

using System.Text;
using System;
using System.Runtime.InteropServices;

namespace Whatever {
    public class GetComposition {
        [DllImport("imm32.dll")]
        public static extern IntPtr ImmGetContext(IntPtr hWnd);
        [DllImport("Imm32.dll")]
        public static extern bool ImmReleaseContext(IntPtr hWnd, IntPtr hIMC);
        [DllImport("Imm32.dll", CharSet = CharSet.Unicode)]
        private static extern int ImmGetCompositionStringW(IntPtr hIMC, int dwIndex, byte[] lpBuf, int dwBufLen);

        private const int GCS_COMPSTR = 8;

        /// IntPtr handle is the handle to the textbox
        public string CurrentCompStr(IntPtr handle) {
            int readType = GCS_COMPSTR;

            IntPtr hIMC = ImmGetContext(handle);
            try {
                int strLen = ImmGetCompositionStringW(hIMC, readType, null, 0);

                if (strLen > 0) {
                    byte[] buffer = new byte[strLen];

                    ImmGetCompositionStringW(hIMC, readType, buffer, strLen);

                    return Encoding.Unicode.GetString(buffer);

                } else {
                    return string.Empty;
                }
            } finally {
                ImmReleaseContext(handle, hIMC);
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我见过的其他实现使用了StringBuilder,但使用字节数组要好得多,因为SB通常最终会产生一些垃圾.字节数组以UTF16编码.

通常,当你收到"WM_IME_COMPOSITION"消息时,你会想要调用GetComposition,如Dian所说.

调用ImmGetContext后调用ImmReleaseContext非常重要,这就是为什么它在finally块中.