投稿者 魔界の仮面弁士  (社会人) 投稿日時 2009/8/20 08:43:29
>  投稿日時 2009/08/19 4:00:33 
>  投稿日時 2009/08/19 22:33:10
凄…。


> ImmGetCompositionString APIについて知識が不足している点が多く、現在調べを進めています。
他にも、変換中の部分確定された状態に対して、入力文字列内のカーソル位置や文節情報などを
取得する機能などがあります。

> 未確定の文字列でもtextchangeのようなイベントを発生させたいと考えています。
イベント制御込みだと、たとえばこんな感じでしょうか。

ここでは、NativeWindow を用いて TextBox のメッセージを捕まえていますが、
TextBox その物を継承する事でもメッセージを捕まえることができます。

Public Class Form1
    Private WithEvents win As Window

    Private Sub Form1_Load(ByVal sender As ObjectByVal e As EventArgs) Handles Me.Load
        win = New Window()
        win.AssignHandle(TextBox1.Handle)
    End Sub

    Private Sub TextBox1_TextChanged(ByVal sender As ObjectByVal e As EventArgs) Handles TextBox1.TextChanged
        Label1.Text = TextBox1.Text
    End Sub

    Private Sub win_Typing(ByVal text As StringHandles win.Typing
        Label2.Text = text
    End Sub

    Private Class Window
        Inherits NativeWindow

        Public Event Typing(ByVal text As String)

        Private Declare Function ImmGetContext Lib "imm32" (ByVal hWnd As IntPtr) As IntPtr
        Private Declare Auto Function ImmGetCompositionString Lib "imm32" _
            (ByVal hIMC As IntPtr, _
             ByVal dwIndex As Integer, _
             ByVal lpBuf As System.Text.StringBuilder, _
             ByVal dwBufLen As IntegerAs Integer
        Private Declare Function ImmReleaseContext Lib "imm32.dll" _
            (ByVal hWnd As IntPtr, ByVal hIMC As IntPtr) As Integer

        Protected Overrides Sub WndProc(ByRef m As Message)
            Const WM_IME_COMPOSITION As Integer = &H10F
            Const GCS_COMPSTR As Integer = 8
            If m.Msg = WM_IME_COMPOSITION Then
                If (m.LParam.ToInt32() And GCS_COMPSTR) <> 0 Then
                    Dim imc As IntPtr = ImmGetContext(Handle)
                    Dim length As Integer = ImmGetCompositionString(imc, GCS_COMPSTR, Nothing, 0)
                    Dim buf As New System.Text.StringBuilder(length)
                    Dim l As Integer = ImmGetCompositionString(imc, GCS_COMPSTR, buf, length)
                    ImmReleaseContext(Handle, imc)
                    RaiseEvent Typing(buf.ToString(0, l \ 2))
                End If
            End If
            MyBase.WndProc(m)
        End Sub
    End Class
End Class