Author: Rafael Cotta
How can I detect if more than one key is pressed at the same time?
Answer:
You can use Windows API to detect multiple keystrokes. The name of the function
that give us this facility is GetKeyState. The higher order bit show us the state
of the key we pass as parameter to the function. On this sample I detect the states
of the arrow keys, spacebar, shift keys and ESC. This sample can detect up to four
keystrokes at the same time, but have some limitations, due to hardware limitations
(i think). This will detect UP + RIGHT + SPACE but wonīt detect UP + LEFT + SPACE.
I may be wrong, but this happens because of keyboards pins design. Thatīs why I
included the SHIFT state, because SHIFT keys will be detected with any combination
of arrow keys. To run this sample place on a blank form a Label and a Button. Click
the button to start, press ESC to stop.
1
2 {****************************************************************
3 * Multiple keystrokes detection using Windows API *
4 * Source written by Rafael Cotta (rcotta.geo@yahoo.com) *
5 * July 26th, 2001 *
6 ****************************************************************}
7
8 // To run this sample, create a blank form, and place a label
9 // and a timer on it.
10
11 unit Unit1;
12
13 interface
14
15 uses
16 Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
17 ExtCtrls, StdCtrls;
18
19 type
20 TForm1 = class(TForm)
21 Label1: TLabel;
22 Button1: TButton;
23 procedure Button1Click(Sender: TObject);
24 private
25 { Private declarations }
26 public
27 { Public declarations }
28 end;
29
30 function GetKeysPressed(): Cardinal;
31
32 var
33 Form1: TForm1;
34
35 implementation
36
37 {$R *.DFM}
38
39 {
40 Each bit on the function result represents
41 the state of a key, so
42
43 0000 0001 = UP
44 0000 0010 = DOWN
45 0000 0100 = LEFT
46 0000 1000 = RIGHT
47 0001 0000 = SPACE BAR
48 0010 0000 = ESC
49 0100 0000 = SHIFT
50 }
51
52 function GetKeysPressed(): Cardinal;
53 var
54 dwRet: Cardinal;
55 begin
56
57 dwRet := 0;
58
59 if ((GetKeyState(VK_UP) and $10000000) > 0) then
60 dwRet := dwRet + 1;
61 if ((GetKeyState(VK_DOWN) and $10000000) > 0) then
62 dwRet := dwRet + 2;
63 if ((GetKeyState(VK_LEFT) and $10000000) > 0) then
64 dwRet := dwRet + 4;
65 if ((GetKeyState(VK_RIGHT) and $10000000) > 0) then
66 dwRet := dwRet + 8;
67 if ((GetKeyState(32) and $10000000) > 0) then
68 dwRet := dwRet + 16; // SpaceBar
69 if ((GetKeyState(27) and $10000000) > 0) then
70 dwRet := dwRet + 32; // ESC
71 if ((GetKeyState(VK_SHIFT) and $10000000) > 0) then
72 dwRet := dwRet + 64; // ESC
73
74 GetKeysPressed := dwRet;
75
76 end;
77
78 procedure TForm1.Button1Click(Sender: TObject);
79 var
80 dwKeys: Cardinal;
81 begin
82 dwKeys := 0;
83
84 // While ESC is not pressed
85
86 while ((dwKeys and 32) = 0) do
87 begin
88 Application.ProcessMessages;
89 dwKeys := GetKeysPressed;
90
91 Label1.Caption := 'Keys pressed : ';
92
93 if ((dwKeys and 1) > 0) then
94 Label1.Caption := Label1.Caption + ' UP';
95
96 if ((dwKeys and 2) > 0) then
97 Label1.Caption := Label1.Caption + ' DOWN';
98
99 if ((dwKeys and 4) > 0) then
100 Label1.Caption := Label1.Caption + ' LEFT';
101
102 if ((dwKeys and 8) > 0) then
103 Label1.Caption := Label1.Caption + ' RIGHT';
104
105 if ((dwKeys and 16) > 0) then
106 Label1.Caption := Label1.Caption + ' SPACE';
107
108 if ((dwKeys and 32) > 0) then
109 Label1.Caption := Label1.Caption + ' ESC';
110
111 if ((dwKeys and 64) > 0) then
112 Label1.Caption := Label1.Caption + ' SHIFT';
113
114 end;
115
116 end;
117
118 end.
|