DOBON.NET DOBON.NETプログラミング掲示板過去ログ

Tabキーイベントを発生させたい

環境/言語:[Windows2000/VB.NET]
分類:[.NET]

いつもお世話になります。

KeyDownイベントでTabキー押下時もイベントを発生させるようにしたいのですが、分かりません。

Protected Overrides Function IsInputKey(ByVal keyData As System.Windows.Forms.Keys) As Boolean

    If keyData = Keys.Tab Then
        Return True
    End If
    Return MyBase.IsInputKey(keyData)

End Function

↑のようにオーバーライドしたのですが、上手くいきません。

どなたか教えて下さい。
フォーム上にコントロールがあり、そのコントロール上にフォーカスがある状態でタブキーを押した場合、キーが押されたことを示すメッセージはフォームではなく、そのコントロール宛に発行されます。
したがってIsInputKeyの処理はフォームではなく、各コントロールで行われなければいけません。
使用するコントロールをすべて派生させ、IsInputKeyをオーバーライドすればKeyDownイベントを発生させることができますが、もちろんこれは現実的な手段ではありません。

そこでアプリケーションにWindowsからメッセージが渡された時点でメッセージをチェックし、自分でKeyDownイベントを発生させるという方法はどうでしょう。

Private Function HaveControl(ByVal handle As IntPtr) As Boolean
'引数と同じハンドルを持つコントロールをこのフォームが所有しているかどうか調べます
If handle.Equals(Me.Handle) Then
Return True
Else
For Each ctrl As Control In Me.Controls
If ctrl.Handle.Equals(handle) Then
Return True
End If
Next
Return False
End If
End Function

Public Function PreFilterMessage(ByRef m As System.Windows.Forms.Message) As Boolean Implements System.Windows.Forms.IMessageFilter.PreFilterMessage
Dim keyData As Keys

Select Case m.Msg
Case &H100
'&H100はWM_KEYDOWNと同じ
'WM_KEYDOWNではMessage.WParamにはKeysと同じ値が入っています
keyData = CType(m.WParam.ToInt32(), Keys)

'タブキーが押されていて、かつタブキーが押されたコントロールがフォームもしくはフォームが所有するコントロールかどうかをチェックします
If keyData = Keys.Tab And Me.HaveControl(m.HWnd) Then
'イベントを発生させます
Me.OnKeyDown(New KeyEventArgs(keyData Or Control.ModifierKeys))
End If
Case &H101
'&H101はWM_KEYUPと同じ
'WM_KEYUPではMessage.WParamにはKeysと同じ値が入っています
keyData = CType(m.WParam.ToInt32(), Keys)

'タブキーが押されていて、かつタブキーが押されたコントロールがフォームもしくはフォームが所有するコントロールかどうかをチェックします
If keyData = Keys.Tab And Me.HaveControl(m.HWnd) Then
'イベントを発生させます
Me.OnKeyUp(New KeyEventArgs(keyData Or Control.ModifierKeys))
End If
End Select
End Function

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
'メッセージフィルタを追加します
Application.AddMessageFilter(Me)
End Sub

Private Sub Form1_Closing(ByVal sender As System.Object, ByVal e As System.ComponentModel.CancelEventArgs) Handles MyBase.Closing
'Dispose後にHaveControl()メソッドが呼び出されると例外が発生するので、フォームが閉じる前にメッセージフィルタを除きます
Application.RemoveMessageFilter(Me)
End Sub
肝心なことを忘れていました。

フォームはIMessageFilterインターフェイスの実装の宣言(implements IMessageFilter)をしてください。

フォームにIMessageFilterインターフェイスを実装させるのも少々妙な感じもしますが、プロテクテッドメソッドであるOnKeyDown/OnKeyUpを呼び出すためには必要です。
こんにちは。


Protected Overrides Function ProcessTabKey(ByVal forward As Boolean) _
   As Boolean

    Return False    '[Tab]を無効にする

End Function

フォーカスの遷移を自分(コード)で行うのなら、上記コードでOKなはずです。
ご参考までに...。

DOBON.NET | プログラミング道 | プログラミング掲示板