Search code examples
vb.netkeypresskeyevent

how to handle multiple KeyPress events


I need my win form - vb.net, to detect if Control + P is being pressed as well as Control + Shift + P as well as just the letter P being pressed.

i have ready how this should be done, and then wrote it into my application, however i can't get it to work so i assume im doing something fundamentally wrong.

my code

Private Sub Form1_KeyUp(sender As Object, e As KeyEventArgs) Handles DataGridView1.KeyUp, MyBase.KeyDown

        If e.KeyCode = Keys.F9 Then

            System.Diagnostics.Process.Start("calc.exe")

        End If

        If e.KeyCode = (Keys.P AndAlso Keys.ControlKey AndAlso Keys.ShiftKey) Then

            If PrintBatchStickersToolStripMenuItem.Enabled = False Then Exit Sub

            If DataGridView1.Rows.Count = 0 Then Exit Sub

            Dim rowIndex As Integer = 0
            rowIndex = DataGridView1.CurrentRow.Index

            PrintAllMatchingProductCodeToolStripMenuItem_Click(sender, e)

        ElseIf e.KeyCode = (Keys.P AndAlso Keys.ControlKey) Then

            If PrintBatchStickersToolStripMenuItem.Enabled = False Then Exit Sub


            If DataGridView1.Rows.Count = 0 Then Exit Sub

            Dim rowIndex As Integer = 0
            rowIndex = DataGridView1.CurrentRow.Index

            PrintBatchQTYToolStripMenuItem_Click(sender, e)

        ElseIf e.KeyCode = Keys.P Then

            If PrintBatchStickersToolStripMenuItem.Enabled = False Then Exit Sub

            If DataGridView1.Rows.Count = 0 Then Exit Sub

            Dim rowIndex As Integer = 0
            rowIndex = DataGridView1.CurrentRow.Index

            PrintSingleStickerToolStripMenuItem_Click(sender, e)

        End If

    End Sub

if i remove the brackets i can get it to detect the P key being pressed, but never the Control and the Shift or a combination of them two.

i added this to the KeyUp event as from my testing if i did this on keydown, and a user held down the keys, the code would loop over and over printing multiple copies of the sticker. and i need the code to only execute once.

keypress from my understanding wont handle the control and shift keys from what i could understand.

am i going wrong with the keyup, because the keys could be getting released at separate times? and if i cant use keyup how to do i handle not printing multiple times on keydown?


Solution

  • You need to use KeyData rather than KeyCode and you need to combine your Keys values properly:

    Select Case e.KeyData
        Case Key.P
            'P was pressed without modifiers.
        Case Keys.Control Or Key.P
            'Ctrl+P was pressed without other modifiers.
        Case Keys.Control Or Keys.Shift Or Keys.P
            'Ctrl+Shift+P was pressed without other modifiers.
    End Select
    

    It may seem odd to use Or rather than And but this is a bitwise operation, not a Boolean operation. If you understand how bitwise logic works, which you should, then it's obvious why Or is used.

    As an alternative:

    If e.KeyCode = Keys.P AndAlso Not e.Alt Then
        If e.Control Then
            If e.Shift Then
                'Ctrl+Shift+P was pressed without other modifiers.
            Else
                'Ctrl+P was pressed without other modifiers.
            End If
        Else
            'P was pressed without modifiers.
        End If
    End If