System Delphi

Title: Interesting API calls part I : detecting simultaneous keystrokes
Question: 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 wont detect UP + LEFT + SPACE. I may be wrong, but this happens because of keyboards pins design.
Thats 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.
I hope this will be useful to you!
// ----------------------- Code starts here -----------------------
{****************************************************************
* Multiple keystrokes detection using Windows API *
* Source written by Rafael Cotta (rcotta.geo@yahoo.com) *
* July 26th, 2001 *
****************************************************************}
// To run this sample, create a blank form, and place a label
// and a timer on it.
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
ExtCtrls, StdCtrls;
type
TForm1 = class(TForm)
Label1: TLabel;
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
function GetKeysPressed () : Cardinal;
var
Form1: TForm1;
implementation
{$R *.DFM}
{
Each bit on the function result represents
the state of a key, so
0000 0001 = UP
0000 0010 = DOWN
0000 0100 = LEFT
0000 1000 = RIGHT
0001 0000 = SPACE BAR
0010 0000 = ESC
0100 0000 = SHIFT
}
function GetKeysPressed () : Cardinal;
var
dwRet : Cardinal;
begin
dwRet := 0;
if ((GetKeyState(VK_UP) and $10000000) 0) then dwRet := dwRet + 1;
if ((GetKeyState(VK_DOWN) and $10000000) 0) then dwRet := dwRet + 2;
if ((GetKeyState(VK_LEFT) and $10000000) 0) then dwRet := dwRet + 4;
if ((GetKeyState(VK_RIGHT) and $10000000) 0) then dwRet := dwRet + 8;
if ((GetKeyState(32) and $10000000) 0) then dwRet := dwRet + 16; // SpaceBar
if ((GetKeyState(27) and $10000000) 0) then dwRet := dwRet + 32; // ESC
if ((GetKeyState(VK_SHIFT) and $10000000) 0) then dwRet := dwRet + 64; // ESC
GetKeysPressed := dwRet;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
dwKeys : Cardinal;
begin
dwKeys := 0;
// While ESC is not pressed
while ((dwKeys and 32) = 0) do
begin
Application.ProcessMessages;
dwKeys := GetKeysPressed;
Label1.Caption := 'Keys pressed : ';
if ((dwKeys and 1) 0) then
Label1.Caption := Label1.Caption + ' UP';
if ((dwKeys and 2) 0) then
Label1.Caption := Label1.Caption + ' DOWN';
if ((dwKeys and 4) 0) then
Label1.Caption := Label1.Caption + ' LEFT';
if ((dwKeys and 8) 0) then
Label1.Caption := Label1.Caption + ' RIGHT';
if ((dwKeys and 16) 0) then
Label1.Caption := Label1.Caption + ' SPACE';
if ((dwKeys and 32) 0) then
Label1.Caption := Label1.Caption + ' ESC';
if ((dwKeys and 64) 0) then
Label1.Caption := Label1.Caption + ' SHIFT';
end;
end;
end.