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