Reactions 2
Up
Now we will try to make a reaction timer that responds to key presses on the keyboard rather than clicks on command buttons. You will learn:
bulletabout the ASCII code by which all keyboard characters are associated with certain numbers
bullethow to write code to detect and respond to keypresses

Make a new Standard EXE project and save it immediately (using File/Save Project not Ctrl-S) into a new folder "Reactions2". Give the Form file and Project File the same name as the folder, as usual. Add two labels to the form and set properties as follows:

bulletForm:
caption = Reaction Timer 2 by (YOUR NAME HERE)
bulletTop label:
name = lblMessage
caption: as below
font: size 18 Arial
alignment: center
bulletBottom label:
name = lblTime
caption: empty
font: size 28 Arial
alignment: center

In the following code, the most important lines are:

Private Sub Form_KeyPress(KeyAscii As Integer)
If KeyAscii = 81 Or KeyAscii = 113 Then

Since there are no controls on the form other than labels, keypress events generated by the user pressing keys are passed directly to the form. If a form includes any other visible and enabled controls, then you must set the form's KeyPreview property to true in order to be able to detect keypresses with a Form_KeyPress procedure (otherwise the KeyPress event is handled by the other controls on the form). 

Each time a key is pressed it passes a certain number to Visual Basic, called its ASCII code ('American Standard Code for Information Interchange'). When the character 'Q' is typed, for example, the number 81 is sent to VB, and when the character 'q' is typed the number 113 is sent. To see the full ASCII table look up 'ASCII' in the VB Help System.

The code below responds to the user typing 'Q' or 'q' by ending the program. When any other key is pressed (it doesn't have to be the space bar) the Select Case code is run. Type the code very carefully...

Private Sub Form_KeyPress(KeyAscii As Integer)
static endtime, starttime
If KeyAscii = 81 Or KeyAscii = 113 Then ' "Q" or "q"
	End
End If
Select Case lblMessage.Caption
Case "Press the space bar, or 'q' to quit."
	lblMessage.Caption = "Ready . ."
	lblTime.Caption = ""
	DoEvents ' let the computer update the captions
	endtime = Timer() + 3 + Rnd * 3 'wait between 3 and 6 seconds
	Do Until Timer() >= endtime
	Loop
	starttime = Timer()
	lblMessage.Caption = "Press the space bar NOW!"
Case "Press the space bar NOW!"
	lblTime.Caption = Format((Timer() - starttime), "0.00")
	If Val(lblTime.Caption) = 0 Then
		lblTime.Caption = "You cheated!"
		DoEvents ' update label caption immediately
		Beep
	End If
	lblMessage.Caption = "Press the space bar, or 'q' to quit."
End Select
End Sub
Try your best to understand the code (you won't learn much if all you do is copy and paste it). 

Declaring a variable to be static ensures that the value of the variable will not be 'forgotten' between successive activations of the procedure.

One line uses the Format() function to specify that times are to be shown to 2 decimal places. See the VB help system for more on this function.

You might find the code a little easier to understand if you replace the line

	If KeyAscii = 81 Or KeyAscii = 113 Then

with this one:

	If Chr(KeyAscii) = "Q" Or Chr(KeyAscii) = "q" Then

This line makes use of the Chr() function which converts ASCII integers into the corresponding characters, removing the need to look up or remember the numerical values in the ASCII table. If you think the Chr() function is neat, you might like to know that there is another function, called Asc(), which does exactly the opposite, converting characters into their ASCII integer equivalent. For example, Asc("Q")  returns 81.

Up