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

Posted

技术标签:

【中文标题】C# 和 IME - 获取当前输入文本【英文标题】:C# and IME - getting the current input text 【发布时间】:2011-01-24 10:58:18 【问题描述】:

我以日文 IME 为例,但在使用 IME 进行输入的其他语言中可能相同。

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

因此,例如,如果用户键入 5 次 あ 然后验证,我将获得 5 个 keydown/keyup 事件,每次 TextBox.Text 返回“”(空字符串),最后我将获得一个 keydown/keyup对于回车键,TextBox.Text 会直接变成“あああああ”。

在用户最终验证之前,如何在用户输入时获取用户输入?

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

【问题讨论】:

它在 Windows 中吗?如果是,您可以拦截 WM_IME_COMPOSITION 消息并使用 ImmGetCompositionString 获取用户输入。 【参考方案1】:

您可以使用它来获取当前的构图。这适用于任何组合状态,适用于日语、中文和韩语。我只在 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);
            
        
    

我见过的其他实现使用 StringBuilder,但使用字节数组要好得多,因为 SB 通常也会在其中包含一些垃圾。字节数组以 UTF16 编码。

而且通常情况下,当您收到 Dian 所说的“WM_IME_COMPOSITION”消息时,您会想要调用 GetComposition。

在调用 ImmGetContext 之后调用 ImmReleaseContext 非常重要,这就是它在 finally 块中的原因。

【讨论】:

以上是关于C# 和 IME - 获取当前输入文本的主要内容,如果未能解决你的问题,请参考以下文章

文本和输入:创建一个IME:简介

Win32 Ime

C# winform中咋实现当文本框获得焦点时,如何切换到中文输入法或英文输入法啊?

在 Javascript 中按下输入之前检测 IME 输入

浅谈Android输入法(IME)架构

C#界面里Control.ImeMode 属性的使用