Writing Form-Level Keyboard Handlers

See Also

Each KeyDown and KeyUp event is attached to a specific object. To write a keyboard handler that applies to all objects on the form, set the KeyPreview property of the form to True. When the KeyPreview property is set to True, the form recognizes the KeyPress, KeyUp, and KeyDown events for all controls on the form before the controls themselves recognize the events. This makes it very easy to provide a common response to a particular keystroke.

You can set the KeyPreview property of the form to True in the Properties window or through code in the Form_Load procedure:

Private Sub Form_Load
   Form1.KeyPreview = True
End Sub

You can test for the various key states on a form by declaring a ShiftKey variable and using the Select Case statement. The following procedure will print the message to the form regardless of which control has the focus.

Open a new project and add the variable ShiftKey to the Declarations section of the form:

Dim ShiftKey as Integer

Add a Textbox and a CommandButton control to the form. Add the following procedure to the form's KeyDown event:

Private Sub Form_KeyDown(KeyCode As Integer, _
      Shift As Integer)
   ShiftKey = Shift And 7
   Select Case ShiftKey
      Case 1 ' or vbShiftMask
         Print "You pressed the SHIFT key."
      Case 2 ' or vbCtrlMask
         Print "You pressed the CTRL key."
      Case 4 ' or vbAltMask
         Print "You pressed the ALT key."
   End Select
End Sub

If you have defined a shortcut key for a menu control, the Click event for that menu control occurs automatically when the user types that key, and no key event occurs.

Similarly, if there is a command button on the form with the Default property set to True, the ENTER key causes the Click event for that command button to occur instead of a key event. If there is a command button with the Cancel property set to True, the ESC key causes the Click event for that command button to occur instead of a key event.

For example, if you add a Click event procedure to the CommandButton and then set either the Default or Cancel properties to True, pressing the RETURN or ESC keys will override the KeyDown event. This procedure closes the application:

Private Sub Command1_Click()
   End
End Sub

Notice that the TAB key moves the focus from control to control and does not cause a key event unless every control on the form is disabled or has TabStop set to False.

When the KeyPreview property of the form is set to True, the form recognizes the keyboard events before the controls, but the events still occur for the controls. To prevent this, you can set the keyascii or keycode arguments in the form key-event procedures to 0. For example, if there is no default button on the form, you can use the ENTER key to move the focus from control to control:

Private Sub Form_KeyPress (KeyAscii As Integer)
Dim NextTabIndex As Integer, i As Integer
   If KeyAscii = 13 Then
      If Screen.ActiveControl.TabIndex = _
      Count - 1 Then
         NextTabIndex = 0
      Else
         NextTabIndex = Screen.ActiveControl._
         TabIndex + 1
      End If
      For i = 0 To Count - 1
         If Me.Controls(i).TabIndex = _
         NextTabIndex Then
            Me.Controls(i).SetFocus
            Exit For
         End If
      Next i
      KeyAscii = 0
   End If
End Sub

Because this code sets keyascii to 0 when it is 13, the controls never recognize the ENTER key being pressed, and their key-event procedures are never called.