投稿者 がもー  (学生) 投稿日時 2009/10/7 05:29:53
お世話になっています。
現在、VB.NETを使用して独自のメールソフトを開発しています。
先日TextBoxに入力した未確定状態の文字列についてご指導をいただいた者です。
http://rucio.groupsite.jp/commu/ThreadDetail.aspx?ThreadId=9284

現在も引き続き予測変換機能を制作しています。
ですが、以下の問題を解決することができません。

①TextBoxに入力した文字を確定すると、重複して表示されてしまう。
(例:TextBoxに【こんにちは】と入力→確定→【こんにちはこんにちは】)
②確定された文字の次に別の文字を入力すると、最初に入力した確定済の文字が消えてしまう。
(例:【こんにちは】と入力・確定→新たに【あ】と入力→【こんにちは】が消え、【あ】のみ表示)

先日ご指導いただいた内容を参考にして、以下のように現在記述しています。
Public Class Form1
    Private WithEvents win As Window
    Dim yosoku As List(Of String)
   
    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 win_Typing(ByVal text As StringHandles win.Typing

        TextBox1.Text = text

        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

    Sub ReadFile()

        yosoku = New List(Of String)()

        Dim yosokuFileName = Path.Combine(Application.StartupPath, "yosoku.txt")
        Dim fs As FileStream = New FileStream(yosokuFileName, FileMode.Open)
        Dim sr As StreamReader = New StreamReader(fs, Encoding.GetEncoding("shift_jis"))
        Dim Buffer As String

        Buffer = sr.ReadLine()

        Do Until Buffer Is Nothing
            yosoku.Add(Buffer)
            Buffer = sr.ReadLine()
        Loop

        sr.Close()

    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 IntegerByVal 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 'ImmGetContextで取得したハンドルを解放する 

        Protected Overrides Sub WndProc(ByRef m As Message)

            Const WM_IME_COMPOSITION As Integer = &H10F '変換が実行されたことを受信する(フラグはGCS_xxxxx) 
            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

長々と申し訳ございません。
ご指導よろしくお願いします。