TextBox への返答
    投稿で使用できる特殊コードの説明。(別タブで開きます。)
以下の返答は逆順(新しい順)に並んでいます。
        投稿者 魔界の仮面弁士  (社会人)
        
        投稿日時 
            2009/8/20 08:43:29
        
    
    
        >  投稿日時 2009/08/19 4:00:33 
> 投稿日時 2009/08/19 22:33:10
凄…。
> ImmGetCompositionString APIについて知識が不足している点が多く、現在調べを進めています。
他にも、変換中の部分確定された状態に対して、入力文字列内のカーソル位置や文節情報などを
取得する機能などがあります。
> 未確定の文字列でもtextchangeのようなイベントを発生させたいと考えています。
イベント制御込みだと、たとえばこんな感じでしょうか。
ここでは、NativeWindow を用いて TextBox のメッセージを捕まえていますが、
TextBox その物を継承する事でもメッセージを捕まえることができます。
    
> 投稿日時 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 Object, ByVal e As EventArgs) Handles Me.Load
        win = New Window()
        win.AssignHandle(TextBox1.Handle)
    End Sub
    Private Sub TextBox1_TextChanged(ByVal sender As Object, ByVal e As EventArgs) Handles TextBox1.TextChanged
        Label1.Text = TextBox1.Text
    End Sub
    Private Sub win_Typing(ByVal text As String) Handles 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 Integer) As 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
    
        投稿者 がもー  (学生)
        
        投稿日時 
            2009/8/20 07:33:10
        
    
    
        魔界の仮面弁士さん、早速の丁寧なご返答ありがとうございます。
ImmGetCompositionString APIについて知識が不足している点が多く、現在調べを進めています。
また私は、開発中のメールソフトにおける予測変換機能を現在制作しています。
具体的には、TextBoxに文字を入力すると前方一致検索を行い、
あらかじめメモ帳に登録した語句がListBoxに一覧表示されるようにしました。
コードの一部は以下のようになっています。
Dim yosoku As List(Of String)
Private Sub TextBox1_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TextBox1.TextChanged
If yosoku Is Nothing Then
ReadFile()
End If
Dim yosoku_No As String = TextBox1.Text
ListBox1.Items.Clear()
For i As Integer = 0 To yosoku.Count - 1
If yosoku_No = yosoku(i).Substring(0, Math.Min(yosoku_No.Length, yosoku(i).Length)) Then
ListBox1.Items.Add(yosoku(i).Substring(yosoku(i).IndexOf(",") + 1))
End If
Next
End Sub
このような機能でのTextboxで、未確定の文字列でもtextchangeのようなイベントを発生させたいと考えています。
この場合、魔界の仮面弁士さんに教えていただいたコードにはどのように組み合わせていけばいいのでしょうか。
初歩的な質問で申し訳ございません。ご指導宜しくお願い致します。
    
    
ImmGetCompositionString APIについて知識が不足している点が多く、現在調べを進めています。
また私は、開発中のメールソフトにおける予測変換機能を現在制作しています。
具体的には、TextBoxに文字を入力すると前方一致検索を行い、
あらかじめメモ帳に登録した語句がListBoxに一覧表示されるようにしました。
コードの一部は以下のようになっています。
Dim yosoku As List(Of String)
Private Sub TextBox1_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TextBox1.TextChanged
If yosoku Is Nothing Then
ReadFile()
End If
Dim yosoku_No As String = TextBox1.Text
ListBox1.Items.Clear()
For i As Integer = 0 To yosoku.Count - 1
If yosoku_No = yosoku(i).Substring(0, Math.Min(yosoku_No.Length, yosoku(i).Length)) Then
ListBox1.Items.Add(yosoku(i).Substring(yosoku(i).IndexOf(",") + 1))
End If
Next
End Sub
このような機能でのTextboxで、未確定の文字列でもtextchangeのようなイベントを発生させたいと考えています。
この場合、魔界の仮面弁士さんに教えていただいたコードにはどのように組み合わせていけばいいのでしょうか。
初歩的な質問で申し訳ございません。ご指導宜しくお願い致します。
        投稿者 魔界の仮面弁士  (社会人)
        
        投稿日時 
            2009/8/19 14:15:19
        
    
    
        これでどうでしょう。
    
Public Class Form1
    Private win As Window
    Private Sub Form1_Load(ByVal sender As Object, ByVal e As EventArgs) Handles Me.Load
        win = New Window()
        win.AssignHandle(TextBox1.Handle)
    End Sub
    Private Class Window
        Inherits NativeWindow
        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 Integer) As 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)
            'Console.WriteLine(m.ToString()) 
            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)
                    Console.WriteLine(buf.ToString(0, l \ 2))
                End If
            End If
            MyBase.WndProc(m)
        End Sub
    End Class
End Class
    
        投稿者 がもー  (学生)
        
        投稿日時 
            2009/8/19 13:00:33
        
    
    
        はじめまして。VB.NETを使用しています。
TextBoxかRichTextBoxでは、未確定状態の下線が引かれた文字列でも
TextChangedのようなイベントを発生させる事は可能なのでしょうか。
もし可能であれば、ご教授宜しくお願い致します。
    
TextBoxかRichTextBoxでは、未確定状態の下線が引かれた文字列でも
TextChangedのようなイベントを発生させる事は可能なのでしょうか。
もし可能であれば、ご教授宜しくお願い致します。
魔界の仮面弁士さんに教えていただいたコードに予測変換のコードを書き込み、
まだ多少修正しなければならない部分はあるのですが、未確定状態の文字列でも予測変換の候補を表示させることができました。
> 他にも、変換中の部分確定された状態に対して、入力文字列内のカーソル位置や文節情報などを
取得する機能などがあります。
そんな便利な機能もあるのですね。今後もImmGetCompositionString APIの知識を深め、より使いやすく充実した予測変換機能を制作したいと思います。
また機会がありましたらご指導を宜しくお願い致します。ありがとうございました!