简体   繁体   中英

How to catch Ctrl + Alt + RShftKey

For some time I'm trying to catch Ctrl + Alt + Right Shift Key under common VBNET key handler. Here are my tests:

    If e.Control And e.Alt And e.KeyCode = Keys.Space Then
        MsgBox("CTRL + ALT + SPACE") ' This work
    End If

    If e.Control And e.Shift And e.KeyCode = Keys.F10 Then
        MsgBox("CTRL + SHIFT + F10") ' This work
    End If

    If e.Control And e.Alt And e.KeyCode = Keys.ShiftKey Then
        MsgBox("CTRL + ALT + SHIFT") ' This work
    End If

    If e.Alt And e.Shift And e.KeyCode = Keys.LWin Then
        MsgBox("ALT + SHIFT + LEFT WINDOWS") ' This work
    End If

    If e.Control And e.Alt And e.KeyCode = Keys.RShiftKey Then
        MsgBox("CTRL + ALT + RIGHT SHIFT") ' This don't work
    End If

Windows 7, WinForms, VB2008, NET framework 2.0

Why I can't catch Ctrl + Alt + Right Shift Key in described situation?
Or, how do I catch Ctrl + Alt + Right Shift Key combination?

There is no way to detect difference between Shifts using standard VB.NET approach. You will have to hook into Windows API for that:

 <System.Runtime.InteropServices.DllImport("user32.dll")> _
    Private Shared Function GetAsyncKeyState(vKey As Keys) As Short
    End Function

    Private Sub Form2_KeyDown(sender As Object, e As KeyEventArgs) Handles Me.KeyDown

        If e.Control And e.Alt And e.Shift Then

            If Convert.ToBoolean(GetAsyncKeyState(Keys.LShiftKey)) Then
                MsgBox("CTRL + ALT + LEFT SHIFT")
            ElseIf Convert.ToBoolean(GetAsyncKeyState(Keys.RShiftKey)) Then
                MsgBox("CTRL + ALT + RIGHT SHIFT")
            End If

        End If

    End Sub

Well, this is tricky since these are all modifier keys and the user could press them in any order. You'll need to do some filtering to ensure that a 4th key press doesn't again produce a match, a problem with the accepted answer. And the right-shift key is difficult, it is reported as Keys.Shift when pressed. That requires pinvoke to check if the key is down.

This worked well:

Private Sub Form1_KeyDown(sender As Object, e As KeyEventArgs) Handles MyBase.KeyDown
    If Control.ModifierKeys = (Keys.Control Or Keys.Alt Or Keys.Shift) Then
        If e.KeyCode = Keys.ControlKey Or e.KeyCode = Keys.Menu Or e.KeyCode = Keys.ShiftKey Then
            If GetKeyState(Keys.RShiftKey) < 0 And GetKeyState(Keys.LShiftKey) >= 0 Then
                MessageBox.Show("yada")
            End If
        End If
    End If
End Sub

Private Declare Function GetKeyState Lib "user32.dll" (ByVal key As Keys) As Short

This works by first verifying that all three modifier keys are down. Then it checks that the last key was pressed was one of the three keys, the filtering that ensures you don't get too many matches. Finally it checks if the right-shift key is down and it didn't get there by pressing the left-shift as well.

Take a look at this:

    If e.Control And e.Alt And e.KeyCode = Keys.ShiftKey Then
        MsgBox("CTRL + ALT + SHIFT") ' This work
        Debug.Print("CTRL + ALT + SHIFT" & GetAsyncKeyState(Keys.ShiftKey) & GetAsyncKeyState(Keys.RShiftKey)) 
    End If

    If e.Control And e.Alt And e.KeyCode = Keys.RShiftKey Then
        MsgBox("CTRL + ALT + RIGHT SHIFT") ' This don't work
        Debug.Print("CTRL + ALT + RIGHT SHIFT " & GetAsyncKeyState(Keys.ShiftKey) & GetAsyncKeyState(Keys.RShiftKey))
    End If

You will see that the value for Keys.ShiftKey is the same for left and right. The test for Keys.RShiftKey changes. The DECLARE from above is required for the API call.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM