Back to DFS's Pascal Page


Getting Single Keystrokes

Many operating systems buffer all keyboard input before making it available to a program. This is done so that the OS can control the editing of input, thus freeing the programmer from this responsibility. The input normally becomes accessible when the user types the ENTER key.

However, at times it is desirable to get and use individual keystrokes as they are typed. For example, this can occur when the user is presented with a menu or is controlling a game.

To make this possible, you need to circumvent the automatic buffering. The program below does this. You can trace through it to examine the codes as they are passed from the keyboard.

There are a couple of things of interest in the code:

  1. The string returned by the function Hex is assembled a character (hexadecimal digit) at a time and the zeroth character (which holds the length of a string) is explicitly set to the value 2.
  2. The first character returned by the function readkey is null if the keystroke is not in the ASCII character set. A second call to returns a value which indicates which special key has been typed.

It is left up to you to determine what the values are for the various special keystrokes.

program keyboardtest(input, output);
uses Crt; {Unit which contains ReadKey function}
const          {# signifies raw value for char}
   null = #0;
   EnterKey = #13;
var
   KeyStroke : array [1..2] of char;  {Storage for input}

function hex(value : integer) : string;
{Convert decimal value 0 to 255 to 2-digit hexadecimal number string}
const
   HexDigits : array [0..15] of char = '0123456789ABCDEF';
begin
   Hex[0] := #2;               {CHEAT: Set length of string to 2}
   Hex[1] := Hexdigits[value div 16]; {Handle high-order digit}
   Hex[2] := Hexdigits[value mod 16]; {Handle low-order digit}
end;

begin {Main}
   repeat
     writeln;
     KeyStroke[1] := null;
     KeyStroke[2] := null;
     KeyStroke[1] := readkey;
     if KeyStroke[1] = null then    {If first value returned is null...}
        KeyStroke[2] := readkey;    {second indicates which special key}
     write(ord(KeyStroke[1]):4, ord(KeyStroke[2]):4); {Print decimal values}
     if KeyStroke[1] = null then
        writeln(' Special Key')
     else if (KeyStroke[1] >= ' ') and (KeyStroke[1] <= '}') then
        writeln(' Normal Printable')
     else
        writeln(' Normal Non-Printable');
     write(hex(ord(KeyStroke[1])):4, hex(ord(KeyStroke[2])):4); {Print hex values}
     if (KeyStroke[1] >= ' ') and (KeyStroke[1] <= '}') then
        writeln(KeyStroke[1]:3)
     else
        writeln
   until KeyStroke[1] = EnterKey {Continue until ENTER key is pressed}
end.

© 1999 DFStermole
HTMLified 29 Dec 99