- 日時: 2013/02/12 20:07
- 名前: VBレスキュー(花ちゃん)
- ***********************************************************************************
* カテゴリー:[キー操作][イベント][] * * キーワード:キー認識,キーイベント,キーコード,KeyData,KeyCode ,押された,テンキー * *********************************************************************************** タイトル:フォームでキーイベントを受取る 記 事 No:11047 投 稿 日:2013/02/05(Tue) 16:47 元質問者:佐藤hs ----------------------------------------------------------------------------------- 下の様にしましたが、F1キーは認識されますが、CTRLキーが認識されません。何故でしょうか? Private Sub Form1_KeyDown(ByVal sender As Object, ByVal _ e As System.Windows.Forms.KeyEventArgs) Handles Me.KeyDown If e.KeyData = Keys.ControlKey Then MsgBox("Controlキーが押されました。") End If If e.KeyData = Keys.F1 Then MsgBox("F1キーが押されました。") End If End Sub
上記について、Hongliang さんが、記事No.11048 で回答されているのでそちらもご覧下さい。
----------------------------------------------------------------------------------- タイトル:どのキーが押されたかを取得する方法色々(468) - VB2010 動作確認:Windows Vista / Windows 7 / VB2010 Pro SP1Rel / Framework 4.0 SP1Rel で [Option Compare Text][Option Explicit On][Option Infer On][Option Strict On]で確認 投 稿 日:2013/02/07 投 稿 者:VBレスキュー(花ちゃん) ----------------------------------------------------------------------------------- 下記が全てではありませんし、下記の方法では取得できない特殊キーもあります。 使用目的に合わせて色々試して(どのイベント内で取得するかも含め)見て下さい。 (一部期待通りに動作しない悪い例の場合もあります。) e.Shift / e.Control / e.Alt 等を使って比較される場合は、3つのキーの状態をすべて 指定して比較する必要があります。 If e.Control Then のようなコードでは、期待通り(Control キーを単独で押している)の動作を してくれません。 詳しくは、下記リンク等の MSDN の各解説サイトをご覧ください。 http://msdn.microsoft.com/ja-jp/library/system.windows.forms.keyeventargs.keycode.aspx
又、今回は、KeyDown イベントで取得していますが、.NET Framework 2.0 からは PreviewKeyDown イベントが追加されたのでそちらも試して見て下さい。 (9.PreviewKeyDown イベントでの取得 に追加) http://msdn.microsoft.com/ja-jp/library/system.windows.forms.control.previewkeydown.aspx
NumLock、CapsLock、ScrollLockキーが有効かどうかを判定する方法について 下記を参照して下さい。 http://msdn.microsoft.com/ja-jp/library/cc720817.aspx
Imports System.Runtime.InteropServices
Public Class Form1
Private Sub TextBox1_KeyDown(sender As Object, _ e As System.Windows.Forms.KeyEventArgs) Handles TextBox1.KeyDown '1.押されたキーを取得 'e.KeyCode プロパティ :KeyDown イベント又は KeyUp イベントのキーボード コードを取得します。 'e.KeyData プロパティ :KeyDown イベント又は KeyUp イベントのキー データを取得します。 'e.KeyValue プロパティ:KeyDown イベント又は KeyUp イベントのキーボード値を取得します。
Dim msg As String = String.Format("KeyCode = {0}" & vbCrLf & _ "KeyData = {1}" & vbCrLf & _ "KeyValue = {2}" _ , e.KeyCode.ToString, e.KeyData.ToString, e.KeyValue.ToString) MessageBox.Show(msg) End Sub
Private Sub TextBox2_KeyDown(sender As Object, _ e As System.Windows.Forms.KeyEventArgs) Handles TextBox2.KeyDown '2.Shift キー が押された事を取得 '(Ctrl キー や Alt キー の場合も同様です。キーコードを変えて試して下さい。) '(Shift キー / CTRLShift キー / ALTShift キー を同時に押した場合も試して下さい。)
'e.Shift プロパティ:Shift キーが押されたかどうかを示す値を取得します。 If e.Shift Then '(1)× この場合、Shift + CTRL + ALT でも反応します。従ってそれでも問題が無い場合に使用して下さい。 MessageBox.Show("(1)× If e.Shift Then") End If
If e.Shift = True And e.Control = False And e.Alt = False Then '(2)○ この場合は、Shift キー 単独で押され時に反応します。 MessageBox.Show("(2)○ If (e.Shift = True And e.Control = False And e.Alt = False) Then") End If
If e.KeyCode = Keys.ShiftKey Then '(3)× この場合、Shift + CTRL + ALT でも反応します。従ってそれでも問題が無い場合に使用して下さい。 MessageBox.Show("(3)× If e.KeyCode = Keys.ShiftKey Then") End If
If e.KeyCode = Keys.Shift Then '(4)× これでは取得できません。 MessageBox.Show("(4) If e.KeyCode = Keys.Shift Then") End If
If e.KeyData = (Keys.ShiftKey Or Keys.Shift) Then '(5)○ この場合は、Shift キー 単独で押され時に反応します。 MessageBox.Show("(5)○ If e.KeyData = (Keys.ShiftKey Or Keys.Shift) Then") End If
'e.Modifiers プロパティ:KeyDown イベント又は KeyUp イベントの修飾フラグを取得します。 'このフラグは、Ctrl キー、Shift キー、および Alt キーのどの組み合わせが押されたのかを示します。 If e.Modifiers = Keys.Shift Then '(6)◎ この場合は、Shift キー 単独で押され時に反応します。 MessageBox.Show("(6)◎ If e.Modifiers = Keys.Shift Then") End If
If e.KeyValue = 16 Then '(7)× この場合、Shift + CTRL + ALT でも反応します。従ってそれでも問題が無い場合に使用して下さい。 MessageBox.Show("(7)× If e.KeyValue = 16 Then") End If
End Sub
Private Sub TextBox3_KeyDown(sender As Object, _ e As System.Windows.Forms.KeyEventArgs) Handles TextBox3.KeyDown '3.Ctrl キー + Alt キーが押された事を取得 '(2.の結果を踏まえて試した分です。)
If (e.Shift = False And e.Control = True And e.Alt = True) Then MessageBox.Show("(1)○ If (e.Shift = False And e.Control = True And e.Alt = True) Then") End If
If e.KeyData = (Keys.Control Or Keys.Alt) Then MessageBox.Show("(2)◎ If e.KeyData = (Keys.Control Or Keys.Alt) Then") End If
If e.Modifiers = (Keys.Alt Or Keys.Control) Then MessageBox.Show("(3)◎ If e.Modifiers = (Keys.Alt Or Keys.Control) Then") End If
End Sub
Private Sub TextBox4_KeyDown(sender As Object, _ e As System.Windows.Forms.KeyEventArgs) Handles TextBox4.KeyDown '4.Ctr キー + Alt キー + A キー が押された事を取得 '(3.の結果を踏まえて試した分です。) 'これで、Shift + CTRL + ALT + 任意のキー の場合でも理解できるかと思いますので 'これ以上の組み合わせのテストは省略します。
If e.KeyCode = Keys.A And (e.Shift = False And e.Control = True And e.Alt = True) Then MessageBox.Show("(1)○ If e.KeyCode = Keys.A And (e.Shift = False And e.Control = True And e.Alt = True) Then") End If
If e.KeyData = (Keys.Control Or Keys.Alt Or Keys.A) Then MessageBox.Show("(2)◎ If e.KeyData = (Keys.Control Or Keys.Alt Or Keys.A) Then") End If
If e.KeyCode = Keys.A AndAlso e.Modifiers = (Keys.Alt Or Keys.Control) Then MessageBox.Show("(3)○ If e.KeyCode = Keys.A AndAlso e.Modifiers = (Keys.Alt Or Keys.Control) Then") End If
End Sub
#Region "左右どちらの Shift / Ctrl / Alt キーが押されたかを取得関係"
''' <summary> ''' 仮想キーの押下状態を取得する(1064) ''' </summary> ''' <param name="nVirtKey">仮想キーコードを指定します</param> ''' <returns>指定された仮想キーの状態を表し、 ''' 最上位ビットが 1 のときはキーが押されていることを、0 のときは ''' キーが押されていないことを示します</returns> ''' <remarks></remarks> <DllImport("User32.dll", CharSet:=CharSet.Auto)> _ Private Shared Function GetKeyState( _ ByVal nVirtKey As Integer) As Integer End Function
Private Sub TextBox5_KeyDown(sender As Object, _ e As System.Windows.Forms.KeyEventArgs) Handles TextBox5.KeyDown '5.左右どちらの Shift / Ctrl / Alt キーが押されたかを取得する。 'VB2010 らしい簡単な方法があるのかなと思って調べて見たのですが見当たらないので。 If GetKeyState(Keys.LShiftKey) < 0 Then MessageBox.Show("左の Shift キーが押されました。") ElseIf GetKeyState(Keys.RShiftKey) < 0 Then MessageBox.Show("右の Shift キーが押されました。") End If
If GetKeyState(Keys.LControlKey) < 0 Then MessageBox.Show("左の Control キーが押されました。") ElseIf GetKeyState(Keys.RControlKey) < 0 Then MessageBox.Show("右の Control キーが押されました。") End If
If GetKeyState(Keys.LMenu) < 0 Then MessageBox.Show("左の Alt キーが押されました。") ElseIf GetKeyState(Keys.RMenu) < 0 Then MessageBox.Show("右の Alt キーが押されました。") End If End Sub
#End Region
#Region "標準のキーボードの Enter キーかテンキーの Enter キーのどちらが押されたかを取得関係"
'PeekMessage 関数がメッセージを処理した後、そのメッセージをキューから削除しません。 Private Const PM_NOREMOVE As Integer = &H0
<StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Auto)> _ Public Structure POINTAPI Public x As Integer 'x座標 Public y As Integer 'y座標 End Structure
<StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Auto)> _ Public Structure MSG Public hwnd As IntPtr 'ウィンドウハンドル Public message As Integer 'メッセージID Public wParam As Integer 'WParamフィールド(メッセージID毎に異なる) Public lParam As Integer 'LParamフィールド(メッセージID毎に異なる) Public time As Integer '時間 Public pt As POINTAPI 'カーソル位置(スクリーン座標) End Structure
''' <summary> ''' 呼び出し側スレッドのメッセージ キューから、メッセージを取得します。 ''' </summary> ''' <param name="lpMsg">MSG構造体へのポインタを指定します</param> ''' <param name="hwnd">メッセージを取得するウィンドウのハンドルを指定します。</param> ''' <param name="wMsgFilterMin">取得するメッセージの範囲の最小値を指定します。</param> ''' <param name="wMsgFilterMax">取得するメッセージの範囲の最大値を指定します。</param> ''' <param name="wRemoveMsg">取得したメッセージを、メッセージ キューから削除するかを定数で指定します。</param> ''' <returns>メッセージを取得したときは、TRUE が返ります。</returns> ''' <remarks></remarks> <DllImport("User32.dll", SetLastError:=True, CharSet:=CharSet.Auto)> _ Public Shared Function PeekMessage( _ ByRef lpMsg As MSG, _ ByVal hwnd As IntPtr, _ ByVal wMsgFilterMin As Integer, _ ByVal wMsgFilterMax As Integer, _ ByVal wRemoveMsg As Integer) As Boolean End Function
Private Sub TextBox6_KeyDown(sender As Object, _ e As System.Windows.Forms.KeyEventArgs) Handles TextBox6.KeyDown '6.どちらの Enter キー(標準/テンキー)が押されたかを取得 'VB2010 らしい簡単な方法があるのかなと思って調べて見たのですが見当たらないので。
Dim nMsg As MSG Dim pm As Boolean 'メッセージを取得(あれば1が返る) pm = PeekMessage(nMsg, Me.Handle, 0, 0, PM_NOREMOVE) If pm <> False And nMsg.wParam = Keys.Return Then 'lParam の 24 ビットめをチェックします。キーが拡張キーならば 'ビット 24 は 1 になり、そうでなければ 0 が返ります。 If CBool(nMsg.lParam And &H1000000) Then MsgBox("テンキー側の ENTER キーが押されました") Else MsgBox("標準キーボード側の ENTER キーが押されました") End If End If
End Sub
#End Region
'下記のイベントでは、Tab キーの検出ができます。 Private Sub TextBox9_PreviewKeyDown(sender As Object, e As _ System.Windows.Forms.PreviewKeyDownEventArgs) Handles TextBox9.PreviewKeyDown '9.PreviewKeyDown イベントでの取得(.NET Framework 2.0 以降で追加) 'PreviewKeyDown イベント:キーが押された場合、KeyDown イベントの前に発生します。 'MSDN のPreviewKeyDown イベントの解説の項を読んでおいて下さい。
Dim msg As String = String.Format("KeyCode = {0}" & vbCrLf & _ "KeyData = {1}" & vbCrLf & _ "KeyValue = {2}" _ , e.KeyCode.ToString, e.KeyData.ToString, e.KeyValue.ToString) MessageBox.Show(msg)
End Sub
End Class
各コントロールの配置図及び実行図(画像をクリックすると元のサイズで見る事ができます。)
|