これを使用して、現在の構成を取得できます。これは、どの構成状態でも機能し、日本語、中国語、韓国語でも機能します。Windows 7 でのみテストしたので、他のバージョンの Windows で動作するかどうかはわかりません。
物事が同じであるということに関しては、まあ、実際には3つの間で物事がひどく異なります.
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 を使用していましたが、バイト配列を使用する方がはるかに優れています。バイト配列は UTF16 でエンコードされます。
通常、Dian が言ったように、"WM_IME_COMPOSITION" メッセージを受け取るたびに GetComposition を呼び出す必要があります。
ImmGetContext を呼び出した後に ImmReleaseContext を呼び出すことは非常に重要です。これが、finally ブロック内にある理由です。