日本語入力でないことが分かっている場合、[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
使い方は前回の単純なフォーカス移動のプログラムと同じです。