日本語入力でのエンターキーの処理

日本語入力でないことが分かっている場合、[Enter]キーが押されたら次のコントロールにフォーカスを移すプログラムは前回ご紹介しました。

日本語入力の途中では、これではいけません。
この場合の[キー]は、キーを押したとき発生する[KeyDown]、[KeyPress]、[KeyUp]イベントです。
(日本語入力でない)通常の場合は、[Enter]キーを押したときイベントハンドラーに送られてくる[KeyEventArgs]の[KeyValue]は[Keys.Enter]ですが、日本語入力の「途中では」(KeyUpイベント以外では)別のコードが送られてきます(この時のKeyValueの値が何であったか忘れました)。
日本語入力の途中で[Enter]を押して、漢字やひらがな等日本語を確認した後は、上でいう「通常の状態」になり、再度[Enter]を押すと[KeyDown]、[KeyPress]、[KeyUp]に[Keys.Enter]が送られてきます。

したがって、連続した[KeyDown]、[KeyPress]、[KeyUp]イベントで、何れも[Keys.Enter]が送られてくれば次のコントロールに移動し、それ以外は移動しないことにすればいいのです。

あとは、これをどのようにコード化するかです。

私たちはinteger二つが入るQueue(行列)を使いました。
[KeyDown]等のイベントが発生したとき、次々にこのキューに確認のコードを入れていきます。そして連続した[KeyDown]、[KeyPress]、[KeyUp]イベントが[Keys.Enter]を受け取ったことを確認すれば、コントロールを移動します。

Enum EnterKeyCode
    Down
    Press
    Up
    NG
End Enum

Public Class clsCheckEnterKey

    Private Shared que As New Queue(Of Integer)(2)

    Shared Sub TestEnter(ByVal sender As Object, ByVal KeyCode As Integer)
      If KeyCode = EnterKeyCode.Up Then
          If que.Count = 2 Then
              If que.Dequeue = EnterKeyCode.Down Then
                  If que.Dequeue = EnterKeyCode.Press Then
                      sender.findform.SelectNextControl(CType(sender, Control), _
                          True, True, True, True)
                   End If
              End If
          End If
      End If
      If que.Count = 2 Then
          que.Dequeue()
      End If
      que.Enqueue(KeyCode)
    End Sub
End Class

これをイベントハンドラーからコールする形にします。

    Public Shared Sub KeyDown _
	(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs)
        If e.KeyValue = Keys.Enter Then
            clsCheckEnterKey.TestEnter(sender, EnterKeyCode.Down)
        Else
            clsCheckEnterKey.TestEnter(sender, EnterKeyCode.NG)
        End If
    End Sub

    Public Shared Sub KeyUp _
	(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs)
        If e.KeyValue = Keys.Enter Then
            clsCheckEnterKey.TestEnter(sender, EnterKeyCode.Up)
        Else
            clsCheckEnterKey.TestEnter(sender, EnterKeyCode.NG)
        End If
    End Sub

    Public Shared Sub KeyPress _
	(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyPressEventArgs)
        If Asc(e.KeyChar) = Keys.Enter Then
            clsCheckEnterKey.TestEnter(sender, EnterKeyCode.Press)
        Else
            clsCheckEnterKey.TestEnter(sender, EnterKeyCode.NG)
        End If
    End Sub

更に特定のコントロールにイベントハンドラーとして登録します。
このコードは(9月18日付けでご紹介しました)[CtrlBindingCollection]からコールします。

    Public Shared Sub SetEnterKeyHandler(ByRef ctrl As Control)
    AddHandler ctrl.KeyDown, AddressOf KeyDown
    AddHandler ctrl.KeyPress, AddressOf KeyPress
       AddHandler ctrl.KeyUp, AddressOf KeyUp
    End Sub

使い方は前回の単純なフォーカス移動のプログラムと同じです。

error: コピーできません !!