13

I am trying to detect the keys "Control" and "t" being pressed simultaneously in VB.NET. The code I have so far is as follows:

Private Sub frmTimingP2P_KeyDown(sender As Object, e As System.Windows.Forms.KeyEventArgs) Handles Me.KeyDown
    If e.KeyValue = Keys.ControlKey And e.KeyValue = Keys.T Then
        MessageBox.Show("Ctrl + T")
    End If
End Sub

I can detect one key or the other by removing the and statement and the second keyvalue statement, but I don't really get anything when I try this. Is there another method?

Thanks

J2Tuner
  • 411
  • 1
  • 5
  • 17

7 Answers7

13

First of all, And in your code should be AndAlso since it’s a logical operator. And in VB is a bit operator. Next, you can use the Modifiers property to test for modifier keys:

If (e.KeyCode And Not Keys.Modifiers) = Keys.T AndAlso e.Modifiers = Keys.Control Then
    MessageBox.Show("Ctrl + T")
End If

The e.KeyCode And Not Keys.Modifiers in the first part of the condition is necessary to mask out the modifier key.

If e.Modifiers = Keys.Ctrl can also be written as If e.Control.

Alternatively, we can collate these two queries by asking directly whether the combination Ctrl+T was pressed:

If e.KeyCode = (Keys.T Or Keys.Ctrl) Then …

In both snippets we make use of bit masks.

Konrad Rudolph
  • 530,221
  • 131
  • 937
  • 1,214
  • 1
    Aha, gotcha. I do have one other question though. Which key do you typically want to use for the modifier? Or does it not matter? – J2Tuner Dec 10 '12 at 15:40
  • 2
    I believe `And` in VB is both a bit operator and a logical operator, depending on context. `AndAlso` is just a short-circuiting logical operator. – Kratz Dec 10 '12 at 15:41
  • 1
    @Kratz While technically correct, I believe strongly that using `AndAlso` exclusively as the conditional operator makes the code clearer and less error-prone. I consider it a (documented) compiler bug that `And` even works here. – Konrad Rudolph Dec 10 '12 at 16:01
  • 1
    @J2Tuner Depends on the modifier, doesn’t it? The keys actually have pretty fixed functions. For all kinds of *actions*, Control is the right key (on Windows!). Alt is used for menu shortcuts, and Alt-Gr for alternative graphs on the keyboard (where such exist). – Konrad Rudolph Dec 10 '12 at 16:02
  • 1
    The Keycode for control is Keys.Control not Keys.Ctrl – Chris Raisin Nov 11 '21 at 13:38
4

Private Sub frmMain_Zaporka_KeyDown(sender As Object, e As KeyEventArgs) Handles MyBase.KeyDown

Select Case e.KeyData
    Case (Keys.Control + Keys.Shift + Keys.F12)
        MsgBox("Control + Shift + F12")
    Case (Keys.Escape)
        Me.Close()
End Select

' or

If e.KeyCode = Keys.F12 AndAlso e.Modifiers = (Keys.Control Or Keys.Shift) Then
    MsgBox("Control + Shift + F12")
ElseIf e.KeyCode = Keys.Escape Then
    Me.Close()
End If

' or

Select Case e.KeyCode
    Case (Keys.F12 And e.Control And e.Shift)
        MsgBox("Control + Shift + F12")
    Case (Keys.Escape)
        Me.Close()
End Select

End Sub

Kuromuro
  • 41
  • 1
  • 1
    Answers that are code alone are general not great answers. You can improve this answer by adding some context to you code though. See the help section for more details: http://stackoverflow.com/help/how-to-answer – mdewitt Feb 26 '14 at 20:48
  • Great answer! Thanks buddy – Nesar Jan 23 '17 at 02:27
2

I had the same problem, but for me to get this to work I had to set the forms KeyPreview property to true. In Visual studio you can change this in the Forms [Design] Property window or changing the property on load.

Private Sub frmTimingP2P_Load(ByVal sender As System.Object, ByVal e As _ 
                               System.EventArgs) Handles MyBase.Load

    Me.KeyPreview = True

End Sub

then use by using:

Private Sub frmTimingP2P_KeyDown(ByVal Sender As Object, ByVal e As _ 
                        System.Windows.Forms.KeyEventArgs) Handles Me.KeyDown


        If (e.KeyCode = Keys.T AndAlso e.Modifiers = Keys.Control) Then
            MessageBox.Show("Ctrl + T")
        End If

End Sub

or other program logic as provided in the answers above.

user2348797
  • 373
  • 4
  • 9
  • 22
2

I'll save you from the long code. Here:

If e.Control And e.Alt And e.KeyCode = Keys.G Then
    MsgBox("Control Alt G")
End If
FloatingKiwi
  • 4,408
  • 1
  • 17
  • 41
Gerard Balaoro
  • 129
  • 2
  • 13
1

I dont have vb.net installed right now but try this on your keydown or keypress event:

If e.KeyCode = Keys.T AndAlso e.Control = True Then
MsgBox("Ctrl + T")
End If
Ruben_PH
  • 1,692
  • 7
  • 25
  • 42
  • `= True` makes no sense – leave it out. Furthermore, `e.Control` implies `e.KeyCode <> Keys.T`, since the `KeyCode` property has the bit mask for the control key set. – Konrad Rudolph Dec 10 '12 at 15:28
1

I actually found through experimentation that the KeyPreview setting is irrelevant when code is processed through the "KeyDown" or "KeyUp" routines we add into our code. Perhaps the automatic inbuilt code for keypress takes the KeyPreview setting into account, but ours does not even have to consider it.

I found the best approach is the one shown in KuroMoro's answer, using e.KeyData plus various "Case Statements". The following works beautifully to insert symbols into a textbox when certain keys are pressing with the Control key simultaneously.

Private Sub Comments_KeyUp(sender As Object, e As System.Windows.Forms.KeyEventArgs) Handles Comment.KeyDown, Response.KeyDown
    Select Case e.KeyData
        Case (Keys.S + Keys.Control)
            SendKeys.Send("♠")
        Case (Keys.H + Keys.Control)
            SendKeys.Send("♥")
        Case (Keys.D + Keys.Control)
            SendKeys.Send("♦")
        Case (Keys.C + Keys.Control)
            SendKeys.Send("♣")
    End Select
End Subcode
Chris Raisin
  • 384
  • 3
  • 7
1

Like Chris Raisin's approach, I use the KeyUp event. Otherwise, pressing the Control key can trigger an action before you press a second key. Here's an example of my code to test for CTRL-A in a listview control named lvSpectra:

Private Sub lvwSpectra_KeyUp(sender As Object, e As KeyEventArgs) Handles lvwSpectra.KeyUp
    If e.Control And e.KeyCode = Keys.A Then
        ' Do something
    End If
End Sub
Robert Cody
  • 179
  • 2
  • 10