components used: TImage TPaintBox TTimer

the ASCII codes in this tutorial will work with borland kylix, but virtual-key codes will not

download source code

We've already covered keyboard control with DelphiX, but you're probably thinking, 'Shouldn't there be a way to do this without DelphiX?'. Well there is, and it's pretty simple too.

Depending on what you're wanting to do, we have two options. The first would be to use ASCII codes and the second would be to make use of Delphi's VK_... command. The later of the two will not work in Kylix as it is specific to the Windows operating system. Still, let's discuss both of these options.

ASCII
For every single key on the keyboard, including control keys, and also lower and uppercase letters, an ASCII code exists. We can use this fact to allow our program to check to see if a particular key has been pressed. Obviously we need to know the ASCII code for the key we're looking to check for, but never fear for below you will find a list that shows just that. I've included most keys that you'll need, and its decimal value.

Key

Decimal Value

Key

Decimal Value

A
B
C
D
E
F
G
H
I
J
K
L
M
N
O
P
Q
R
S
T
U
V
W
X
Y
Z

0
1
2
3
4
5
6
7
8
9

65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90

48
49
50
51
52
53
54
55
56
57

Numpad +
Numpad -

Insert
Delete
Home
End
Page Up
Page Down

Esc
Caps Lock
Shift
Ctrl
Alt
Spacebar
Return
Backspace

Left Arrow
Up Arrow
Right Arrow
Down Arrow


F1
F2
F3
F4
F5
F6
F7
F8
F9
F10
F11
F12

107
109

45
46
36
35
33
34

27
20
16
17
18
32
13
8

37
38
39
40


112
113
114
115
116
117
118
119
120
121
122
123

If there is something that is not listed here that you would want to use you can actually find out its ASCII value by simply creating a new application and putting the following code in your OnKeyDown procedure:

ShowMessage(VarToStr(Key));

This will have the effect of bringing up a window telling you the ASCII value of the key you just pressed. Simple.

Anyway, getting back to the task at hand, if you've been following the DelphiX tutorials you've already come across one of these ASCII codes in tutorial three on animation. There we used one of these codes to allow us to quit our application as soon as the user pressed Esc. The code for this looked like that shown below.

procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
begin
 if
key = 27 then close;
end;

Here we used the FormKeyDown procedure which allowed us to take the ASCII code number of the Esc key (27), and close our program when the key is pressed. However if you recall, earlier I said that every key on the keyboard has an ASCII code. While this is true, in Delphi an OnKeyDown procedure will not distinguish between upper and lower case letters, instead always returning the number for the upper case letter. If you want to be able to tell the difference between a user pressing say a 'A' and an 'a' then you need to use the OnKeyPress event. The disadvantage of using an OnKeyPress event is that it cannot check to see if other keys are being pressed at the same time (such as the Shift or Ctrl key), and only one event is processed on every press of a key. Also, if we don't use OnKeyPress, we can process both an OnKeyDown and OnKeyUp event so that we can make something different happen when the user lets go of the key.

The way we tell if a key is being pressed is also different between the OnKeyPress event and an OnKeyDown/Up event. Say we wanted to have our sprite moving left when the user holds down the 'a' key and right when the user holds down the 'd' key, we'd do the following with an OnKeyPress event:

procedure TForm1.FormKeyPress(Sender: TObject; var Key: Char);
begin
 if
Key = 'a' then Sprite.Left := Sprite.Left - 1;
 if Key = 'd' then Sprite.Left := Sprite.Left + 1;
end;

You can see that we've actually specified the letter which we want to check for here, not its ASCII code. If the user had left Caps Lock on then this procedure would not do anything as the Key value being returned would be 'A' not 'a' and 'D' not 'd'. With the OnKeyDown event, we refer to a key by its ASCII code as follows:

procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
begin
 if
key = 65 then Image1.Left := Image1.Left - 1;
 if key = 68 then Image1.Left := Image1.Left + 1;}
end;

For most of you, the OnKeyDown and OnKeyUp events are the best to go for as it is not usually desirable to check for upper or lowercase letters, but the ability to check for multiple keys being pressed at the same time, is.

So you can see that handling keyboard events is very simple, as long as you have an ASCII code to hand. It is however often easier to remember the VK_ commands which we'll discuss next.

Virtual Key-Codes (VK)
With this command we can check for a wide variety of keys being pressed. For example, we can check if the left arrow key has being pressed by adapting our OnKeyDown procedure to look like the following.

procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
begin
 if
Key = vk_left then Image1.Left := Image1.Left - 1;
end;

Far simpler to remember I'm sure you'll agree, but if you're a Kylix user you'll have to stick to the ASCII codes. We are limited in what we can do here though because Delphi only lets us use certain control keys, not any alphabetical, numerical or other character keys, except for the ones on the numpad. The online 'help' that comes with Delphi only tells you about a few of the supported VK commands namely, VK_UP, DOWN, LEFT, RIGHT, INSERT, DELETE, HOME, END, NEXT and PRIOR. Most of these are self-explanatory in their description, but NEXT and PRIOR are less so. PRIOR refers to the 'Page Up' key, and NEXT the 'Page Down' key. So what are the others you can use? Well, the list is fairly extensive as you can see below. I've included the ones we've already mentioned, for completeness. You should find all the keys you might want (and a few you probably won't) below. The Windows SDK help shows you all these and a few more, but many are not actually supported by Delphi.

VK_UP
VK_DOWN
VK_LEFT
VK_RIGHT
VK_INSERT
VK_DELETE
VK_HOME
VK_END
VK_NEXT
VK_PRIOR

VK_BACK
VK_RETURN
VK_SHIFT
VK_CONTROL
VK_MENU
VK_CAPITAL
VK_SPACE

VK_PAUSE
VK_SCROLL
VK_NUMLOCK

VK_NUMPAD 0 - 9
VK_MULTIPLY
VK_DIVIDE
VK_ADD
VK_SUBTRACT
VK_DECIMAL

VK_F1 - F24

VK_LWIN
VK_RWIN
VK_APPS

Up Arrow Key
Down Arrow Key
Left Arrow Key
Right Arrow Key
Insert Key
Delete Key
Home Key
End Key
Page Down
Page Up

Backspace Key
Return or Enter Key
Shift Key
Control Key
Alt Key
Caps Lock
Space Bar

Pause Key
Scroll Lock
Num Lock

Numbers 0 - 9 on the numpad
Multiply Key( * ) on the numpad
Divide Key( / ) on the numpad
Add Key( + ) on the numpad
Subtract Key( - ) on the numpad
Decimal Key( . ) on the numpad

F1 - 24 (if you have them!)

Left Win Key (if available)
Right Win Key (if available)
Apps Windows Key (if available)

Maybe you'll finally find a good use for the Scroll Lock Key! It should be noted that you can't use these VK combinations with the OnKeyPress event.

Before I finish, you'll find that the source code for this tutorial is a version of the last tutorial's code which allows us to now control our pacman sprite with the keys. All we've done here is take the StartX := StartX + 1; line out of our OnTimer procedure and placed it in an OnKeyDown procedure like that shown below.

procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
begin
 if
Key = 37 then StartX := StartX - 1; // Left
 if Key = 38 then StartY := StartY - 1; // Up
 if Key = 39 then StartX := StartX + 1; // Right
 if Key = 40 then StartY := StartY + 1; // Down
end;

Simple. Now you're in control. It can jerk a bit, but putting the interval of the TTimer down to about 1 will help a little. We'll come up with a better way of doing things in the tutorial after next. I've used the ASCII codes of the arrow keys instead of the VK commands so that the code works with both Kylix and Delphi, but it's up to you what you use if you're using just Delphi. So that about raps it up really. As always, if you have any questions, please e-mail me or leave a message on the board.

download source code

Subscribe to the feed delphigamedev.com NEWS Feed
archived news | mailing list

[ all tutorials found at delphigamedev.com are Copyright © 2008 Ben Watt ]