Subsections

11 The KEYBOARD unit

kbdex

The KeyBoard unit implements a keyboard access layer which is system independent. It can be used to poll the keyboard state and wait for certain events. Waiting for a keyboard event can be done with the GetKeyEvent function, which will return a driver-dependent key event. This key event can be translated to a interpretable event by the TranslateKeyEvent function. The result of this function can be used in the other event examining functions.

A custom keyboard driver can be installed using the SetKeyboardDriver function. The current keyboard driver can be retrieved using the GetKeyboardDriver function. The last section of this chapter demonstrates how to make a keyboard driver.

1 Constants, Type and variables

1 Constants

The following constants define some error constants, which may be returned by the keyboard functions.

errKbdBase           = 1010;
errKbdInitError      = errKbdBase + 0;
errKbdNotImplemented = errKbdBase + 1;
The following constants denote special keyboard keys. The first constants denote the function keys:
const
  kbdF1        = $FF01;
  kbdF2        = $FF02;
  kbdF3        = $FF03;
  kbdF4        = $FF04;
  kbdF5        = $FF05;
  kbdF6        = $FF06;
  kbdF7        = $FF07;
  kbdF8        = $FF08;
  kbdF9        = $FF09;
  kbdF10       = $FF0A;
  kbdF11       = $FF0B;
  kbdF12       = $FF0C;
  kbdF13       = $FF0D;
  kbdF14       = $FF0E;
  kbdF15       = $FF0F;
  kbdF16       = $FF10;
  kbdF17       = $FF11;
  kbdF18       = $FF12;
  kbdF19       = $FF13;
  kbdF20       = $FF14;
Constants $15 till $1F are reserved for future function keys. The following constants denote the cursor movement keys:
  kbdHome      = $FF20;
  kbdUp        = $FF21;
  kbdPgUp      = $FF22;
  kbdLeft      = $FF23;
  kbdMiddle    = $FF24;
  kbdRight     = $FF25;
  kbdEnd       = $FF26;
  kbdDown      = $FF27;
  kbdPgDn      = $FF28;

  kbdInsert    = $FF29;
  kbdDelete    = $FF2A;
Constants $2B till $2F are reserved for future keypad keys. The following flags are also defined:
  kbASCII       = $00;
  kbUniCode     = $01;
  kbFnKey       = $02;
  kbPhys        = $03;
  kbReleased    = $04;
They can be used to check what kind of data a key event contains. The following shift-state flags can be used to determine the shift state of a key (i.e. which of the SHIFT, ALT and CTRL keys were pressed simultaneously with a key):
  kbLeftShift   = 1;
  kbRightShift  = 2;
  kbShift       = kbLeftShift or kbRightShift;
  kbCtrl        = 4;
  kbAlt         = 8;
The following constant strings are used in the key name functions FunctionKeyName and KeyEventToString:
SShift       : Array [1..3] of string[5] = ('SHIFT','CTRL','ALT');
LeftRight   : Array [1..2] of string[5] = ('LEFT','RIGHT');
UnicodeChar : String = 'Unicode character ';
SScanCode    : String = 'Key with scancode ';
SUnknownFunctionKey : String = 'Unknown function key : ';
SAnd         : String = 'AND';
SKeyPad      : Array [0..($FF2F-kbdHome)] of string[6] = 
               ('Home','Up','PgUp','Left',
                'Middle','Right','End','Down',
                'PgDn','Insert','Delete','',
                '','','','');
They can be changed to localize the key names when needed.

2 Types

The TKeyEvent type is the base type for all keyboard events:
  TKeyEvent = Longint;
The key stroke is encoded in the 4 bytes of the TKeyEvent type. The various fields of the key stroke encoding can be obtained by typecasting the TKeyEvent type to the TKeyRecord type:
  TKeyRecord = packed record
    KeyCode : Word;
    ShiftState, Flags : Byte;
  end;
The structure of a TKeyRecord structure is explained in table (keyevent) .

Table: Structure of TKeyRecord
Field Meaning
KeyCode Depending on flags either the physical representation of a key (under DOS scancode, ascii code pair), or the translated ASCII/unicode character.
ShiftState Shift-state when this key was pressed (or shortly after)
Flags Determine how to interpret KeyCode

The shift-state can be checked using the various shift-state constants, and the flags in the last byte can be checked using one of the kbASCII, kbUniCode, kbFnKey, kbPhys, kbReleased constants.

If there are two keys returning the same char-code, there's no way to find out which one was pressed (Gray+ and Simple+). If it needs to be known which was pressed, the untranslated keycodes must be used, but these are system dependent. System dependent constants may be defined to cover those, with possibily having the same name (but different value).

The TKeyboardDriver record can be used to install a custom keyboard driver with the SetKeyboardDriver function:

Type 
  TKeyboardDriver = Record
    InitDriver : Procedure;
    DoneDriver : Procedure;
    GetKeyEvent : Function : TKeyEvent;
    PollKeyEvent : Function : TKeyEvent;
    GetShiftState : Function : Byte;
    TranslateKeyEvent : Function (KeyEvent: TKeyEvent): TKeyEvent;
    TranslateKeyEventUniCode: Function (KeyEvent: TKeyEvent): TKeyEvent;
  end;
The various fields correspond to the different functions of the keyboard unit interface. For more information about this record see section kbddriver

2 Functions and Procedures


1 DoneKeyboard

Declaration
Procedure DoneKeyboard;
Description
DoneKeyboard de-initializes the keyboard interface if the keyboard driver is active. If the keyboard driver is not active, the function does nothing.

This will cause the keyboard driver to clear up any allocated memory, or restores the console or terminal the program was running in to its initial state before the call to InitKeyBoard. This function should be called on program exit. Failing to do so may leave the terminal or console window in an unusable state. Its exact action depends on the platform on which the program is running.

Errors
None.
See also
InitKeyBoard

For an example, see most other functions.


2 FunctionKeyName

Declaration
Function FunctionKeyName (KeyCode : Word) : String;
Description
FunctionKeyName returns a string representation of the function key with code KeyCode. This can be an actual function key, or one of the cursor movement keys.
Errors
In case KeyCode does not contain a function code, the SUnknownFunctionKey string is returned, appended with the KeyCode.
See also
ShiftStateToString KeyEventToString

Example
Program Example8;

{ Program to demonstrate the FunctionKeyName function. }

Uses keyboard;

Var
  K : TkeyEvent;

begin
  InitKeyboard;
  Writeln('Press function keys, press "q" to end.');
  Repeat
    K:=GetKeyEvent;
    K:=TranslateKeyEvent(K);
    If IsFunctionKey(k) then
      begin
      Write('Got function key : ');
      Writeln(FunctionKeyName(TkeyRecord(K).KeyCode));
      end;
  Until (GetKeyEventChar(K)='q');
  DoneKeyboard;
end.


3 GetKeyboardDriver

Declaration
Procedure GetKeyboardDriver (Var Driver : TKeyboardDriver);
Description
GetKeyBoardDriver returns in Driver the currently active keyboard driver. This function can be used to enhance an existing keyboarddriver.

For more information on getting and setting the keyboard driver section kbddriver.

Errors
None.
See also
SetKeyboardDriver


4 GetKeyEvent

Declaration
function GetKeyEvent: TKeyEvent;
Description
GetKeyEvent returns the last keyevent if one was stored in PendingKeyEvent, or waits for one if none is available. A non-blocking version is available in PollKeyEvent.

The returned key is encoded as a TKeyEvent type variable, and is normally the physical key scan code, (the scan code is driver dependent) which can be translated with one of the translation functions TranslateKeyEvent or TranslateKeyEventUniCode. See the types section for a description of how the key is described.

Errors
If no key became available, 0 is returned.
See also
PutKeyEvent, PollKeyEvent, TranslateKeyEvent, TranslateKeyEventUniCode

Example
program example1;

{ This program demonstrates the GetKeyEvent function }

uses keyboard;

Var
  K : TKeyEvent;

begin
  InitKeyBoard;
  Writeln('Press keys, press "q" to end.');
  Repeat
    K:=GetKeyEvent;
    Write('Got key event with ');
    Case GetKeyEventFlags(K) of
      kbASCII    : Writeln('ASCII key');
      kbUniCode  : Writeln('Unicode key');
      kbFnKey    : Writeln('Function key');
      kbPhys     : Writeln('Physical key');
      kbReleased : Writeln('Released key event');
    end;
    K:=TranslateKeyEvent(K);
    Writeln('Got key : ',KeyEventToString(K));
  Until (GetKeyEventChar(K)='q');
  DoneKeyBoard;
end.


5 GetKeyEventChar

Declaration
function GetKeyEventChar(KeyEvent: TKeyEvent): Char;
Description
GetKeyEventChar returns the charcode part of the given KeyEvent, if it contains a translated character key keycode. The charcode is simply the ascii code of the character key that was pressed.

It returns the null character if the key was not a character key, but e.g. a function key.

Errors
None.
See also
GetKeyEventUniCode, GetKeyEventShiftState, GetKeyEventFlags, GetKeyEventCode, GetKeyEvent

For an example, see GetKeyEvent


6 GetKeyEventCode

Declaration
function GetKeyEventCode(KeyEvent: TKeyEvent): Word;
Description
GetKeyEventCode returns the translated function keycode part of the given KeyEvent, if it contains a translated function key.

If the key pressed was not a function key, the null character is returned.

Errors
None.
See also
GetKeyEventUniCode, GetKeyEventShiftState, GetKeyEventFlags, GetKeyEventChar, GetKeyEvent

Example
Program Example2;

{ Program to demonstrate the GetKeyEventCode function. }

Uses keyboard;

Var
  K : TKeyEvent;

begin
  InitKeyBoard;
  Writeln('Press function keys, or press "q" to end.');
  Repeat
    K:=GetKeyEvent;
    K:=TranslateKeyEvent(K);
    If (GetKeyEventFlags(K)<>KbfnKey) then
      Writeln('Not a function key')
    else  
      begin
      Write('Got key (',GetKeyEventCode(K));
      Writeln(') : ',KeyEventToString(K));
      end;
  Until (GetKeyEventChar(K)='q');
  DoneKeyboard;
end.


7 GetKeyEventFlags

Declaration
function GetKeyEventFlags(KeyEvent: TKeyEvent): Byte;
Description
GetKeyEventFlags returns the flags part of the given KeyEvent.
Errors
None.
See also
GetKeyEventUniCode, GetKeyEventShiftState, GetKeyEventCode, GetKeyEventChar, GetKeyEvent

For an example, see GetKeyEvent


8 GetKeyEventShiftState

Declaration
function GetKeyEventShiftState(KeyEvent: TKeyEvent): Byte;
Description
GetKeyEventShiftState returns the shift-state values of the given KeyEvent. This can be used to detect which of the modifier keys Shift, Alt or Ctrl were pressed. If none were pressed, zero is returned.

Note that this function does not always return expected results; In a unix X-Term, the modifier keys do not always work.

Errors
None.
See also
GetKeyEventUniCode, GetKeyEventFlags, GetKeyEventCode, GetKeyEventChar, GetKeyEvent

Example
Program Example3;

{ Program to demonstrate the GetKeyEventShiftState function. }

Uses keyboard;

Var
  K : TKeyEvent;
  S : Byte;
  
begin
  InitKeyBoard;
  Write('Press keys combined with CTRL/SHIFT/ALT');
  Writeln(', or press "q" to end.');
  Repeat
    K:=GetKeyEvent;
    K:=TranslateKeyEvent(K);
    S:=GetKeyEventShiftState(K);
    If (S=0) then
      Writeln('No special keys pressed')
    else  
      begin
      Writeln('Detected special keys : ',ShiftStateToString(K,False));
      Writeln('Got key : ',KeyEventToString(K));
      end;
  Until (GetKeyEventChar(K)='q');
  DoneKeyboard;
end.


9 GetKeyEventUniCode

Declaration
function GetKeyEventUniCode(KeyEvent: TKeyEvent): Word;
Description
GetKeyEventUniCode returns the unicode part of the given KeyEvent if it contains a translated unicode character.
Errors
None.
See also
GetKeyEventShiftState, GetKeyEventFlags, GetKeyEventCode, GetKeyEventChar, GetKeyEvent

No example available yet.


10 InitKeyBoard

Declaration
procedure InitKeyboard;
Description
InitKeyboard initializes the keyboard driver. If the driver is already active, it does nothing. When the driver is initialized, it will do everything necessary to ensure the functioning of the keyboard, including allocating memory, initializing the terminal etc.

This function should be called once, before using any of the keyboard functions. When it is called, the DoneKeyboard function should also be called before exiting the program or changing the keyboard driver with SetKeyboardDriver.

Errors
None.
See also
DoneKeyboard, SetKeyboardDriver

For an example, see most other functions.


11 IsFunctionKey

Declaration
function IsFunctionKey(KeyEvent: TKeyEvent): Boolean;
Description
IsFunctionKey returns True if the given key event in KeyEvent was a function key or not.
Errors
None.
See also
GetKeyEvent

Example
program example1;

{ This program demonstrates the GetKeyEvent function }

uses keyboard;

Var
  K : TKeyEvent;

begin
  InitKeyBoard;
  Writeln('Press keys, press "q" to end.');
  Repeat
    K:=GetKeyEvent;
    K:=TranslateKeyEvent(K);
    If IsFunctionKey(K) then
      Writeln('Got function key : ',KeyEventToString(K))
    else
      Writeln('not a function key.');  
  Until (GetKeyEventChar(K)='q');
  DoneKeyBoard;
end.


12 KeyEventToString

Declaration
Function KeyEventToString(KeyEvent : TKeyEvent) : String;
Description
KeyEventToString translates the key event in KeyEvent to a human-readable description of the pressed key. It will use the constants described in the constants section to do so.
Errors
If an unknown key is passed, the scancode is returned, prefixed with the SScanCode string.
See also
FunctionKeyName, ShiftStateToString

For an example, see most other functions.


13 PollKeyEvent

Declaration
function PollKeyEvent: TKeyEvent;
Description
PollKeyEvent checks whether a key event is available, and returns it if one is found. If no event is pending, it returns 0.

Note that this does not remove the key from the pending keys. The key should still be retrieved from the pending key events list with the GetKeyEvent function.

Errors
None.
See also
PutKeyEvent, GetKeyEvent

Example
program example4;

{ This program demonstrates the PollKeyEvent function }

uses keyboard;

Var
  K : TKeyEvent;

begin
  InitKeyBoard;
  Writeln('Press keys, press "q" to end.');
  Repeat
    K:=PollKeyEvent;
    If k<>0 then
      begin
      K:=GetKeyEvent;
      K:=TranslateKeyEvent(K);
      writeln;
      Writeln('Got key : ',KeyEventToString(K));
      end
    else
      write('.');
  Until (GetKeyEventChar(K)='q');
  DoneKeyBoard;
end.


14 PollShiftStateEvent

Declaration
function PollShiftStateEvent: TKeyEvent;
Description
PollShiftStateEvent returns the current shiftstate in a keyevent. This will return 0 if there is no key event pending.
Errors
None.
See also
PollKeyEvent, GetKeyEvent

Example
program example6;

{ This program demonstrates the PollShiftStateEvent function }

uses keyboard;

Var
  K : TKeyEvent;

begin
  InitKeyBoard;
  Writeln('Press keys, press "q" to end.');
  Repeat
    K:=PollKeyEvent;
    If k<>0 then
      begin
      K:=PollShiftStateEvent;
      Writeln('Got shift state : ',ShiftStateToString(K,False));
      // Consume the key. 
      K:=GetKeyEvent;
      K:=TranslateKeyEvent(K);
      end
{    else
      write('.')};
  Until (GetKeyEventChar(K)='q');
  DoneKeyBoard;
end.


15 PutKeyEvent

Declaration
procedure PutKeyEvent(KeyEvent: TKeyEvent);
Description
PutKeyEvent adds the given KeyEvent to the input queue. Please note that depending on the implementation this can hold only one value, i.e. when calling PutKeyEvent multiple times, only the last pushed key will be remembered.
Errors
None
See also
PollKeyEvent, GetKeyEvent

Example
program example5;

{ This program demonstrates the PutKeyEvent function }

uses keyboard;

Var
  K,k2 : TKeyEvent;

begin
  InitKeyBoard;
  Writeln('Press keys, press "q" to end.');
  K2:=0;
  Repeat
    K:=GetKeyEvent;
    If k<>0 then
      begin
      if (k2 mod 2)=0 then
        K2:=K+1
      else
        K2:=0;
      K:=TranslateKeyEvent(K);
      Writeln('Got key : ',KeyEventToString(K));
      if (K2<>0) then
        begin
        PutKeyEvent(k2);
        K2:=TranslateKeyEVent(K2);
        Writeln('Put key : ',KeyEventToString(K2))
        end
      end
  Until (GetKeyEventChar(K)='q');
  DoneKeyBoard;
end.


16 SetKeyboardDriver

Declaration
Function SetKeyboardDriver (Const Driver : TKeyboardDriver) : Boolean;
Description
SetKeyBoardDriver sets the keyboard driver to Driver, if the current keyboard driver is not yet initialized. If the current keyboard driver is initialized, then SetKeyboardDriver does nothing. Before setting the driver, the currently active driver should be disabled with a call to DoneKeyboard.

The function returns True if the driver was set, False if not.

For more information on setting the keyboard driver, see section kbddriver.

Errors
None.
See also
GetKeyboardDriver, DoneKeyboard.


17 ShiftStateToString

Declaration
Function ShiftStateToString(KeyEvent : TKeyEvent; UseLeftRight : Boolean) : String;
Description
ShiftStateToString returns a string description of the shift state of the key event KeyEvent. This can be an empty string.

The shift state is described using the strings in the SShift constant.

Errors
None.
See also
FunctionKeyName, KeyEventToString

For an example, see PollShiftStateEvent.


18 TranslateKeyEvent

Declaration
function TranslateKeyEvent(KeyEvent: TKeyEvent): TKeyEvent;
Description
TranslateKeyEvent performs ASCII translation of the KeyEvent. It translates a physical key to a function key if the key is a function key, and translates the physical key to the ordinal of the ascii character if there is an equivalent character key.
Errors
None.
See also
TranslateKeyEventUniCode

For an example, see GetKeyEvent


19 TranslateKeyEventUniCode

Declaration
function TranslateKeyEventUniCode(KeyEvent: TKeyEvent): TKeyEvent;
Description
TranslateKeyEventUniCode performs Unicode translation of the KeyEvent. It is not yet implemented for all platforms.

Errors
If the function is not yet implemented, then the ErrorCode of the system unit will be set to errKbdNotImplemented
See also

No example available yet.

3 Keyboard scan codes

Special physical keys are encoded with the DOS scan codes for these keys in the second byte of the TKeyEvent type. A complete list of scan codes can be found in table (keyscans) . This is the list of keys that is used by the default key event translation mechanism. When writing a keyboard driver, either these constants should be returned by the various key event functions, or the TranslateKeyEvent hook should be implemented by the driver.

Table: Physical keys scan codes
Code Key Code Key Code Key
00 NoKey 3D F3 70 ALT-F9
01 ALT-Esc 3E F4 71 ALT-F10
02 ALT-Space 3F F5 72 CTRL-PrtSc
04 CTRL-Ins 40 F6 73 CTRL-Left
05 SHIFT-Ins 41 F7 74 CTRL-Right
06 CTRL-Del 42 F8 75 CTRL-end
07 SHIFT-Del 43 F9 76 CTRL-PgDn
08 ALT-Back 44 F10 77 CTRL-Home
09 ALT-SHIFT-Back 47 Home 78 ALT-1
0F SHIFT-Tab 48 Up 79 ALT-2
10 ALT-Q 49 PgUp 7A ALT-3
11 ALT-W 4B Left 7B ALT-4
12 ALT-E 4C Center 7C ALT-5
13 ALT-R 4D Right 7D ALT-6
14 ALT-T 4E ALT-GrayPlus 7E ALT-7
15 ALT-Y 4F end 7F ALT-8
16 ALT-U 50 Down 80 ALT-9
17 ALT-I 51 PgDn 81 ALT-0
18 ALT-O 52 Ins 82 ALT-Minus
19 ALT-P 53 Del 83 ALT-Equal
1A ALT-LftBrack 54 SHIFT-F1 84 CTRL-PgUp
1B ALT-RgtBrack 55 SHIFT-F2 85 F11
1E ALT-A 56 SHIFT-F3 86 F12
1F ALT-S 57 SHIFT-F4 87 SHIFT-F11
20 ALT-D 58 SHIFT-F5 88 SHIFT-F12
21 ALT-F 59 SHIFT-F6 89 CTRL-F11
22 ALT-G 5A SHIFT-F7 8A CTRL-F12
23 ALT-H 5B SHIFT-F8 8B ALT-F11
24 ALT-J 5C SHIFT-F9 8C ALT-F12
25 ALT-K 5D SHIFT-F10 8D CTRL-Up
26 ALT-L 5E CTRL-F1 8E CTRL-Minus
27 ALT-SemiCol 5F CTRL-F2 8F CTRL-Center
28 ALT-Quote 60 CTRL-F3 90 CTRL-GreyPlus
29 ALT-OpQuote 61 CTRL-F4 91 CTRL-Down
2B ALT-BkSlash 62 CTRL-F5 94 CTRL-Tab
2C ALT-Z 63 CTRL-F6 97 ALT-Home
2D ALT-X 64 CTRL-F7 98 ALT-Up
2E ALT-C 65 CTRL-F8 99 ALT-PgUp
2F ALT-V 66 CTRL-F9 9B ALT-Left
30 ALT-B 67 CTRL-F10 9D ALT-Right
31 ALT-N 68 ALT-F1 9F ALT-end
32 ALT-M 69 ALT-F2 A0 ALT-Down
33 ALT-Comma 6A ALT-F3 A1 ALT-PgDn
34 ALT-Period 6B ALT-F4 A2 ALT-Ins
35 ALT-Slash 6C ALT-F5 A3 ALT-Del
37 ALT-GreyAst 6D ALT-F6 A5 ALT-Tab
3B F1 6E ALT-F7    
3C F2 6F ALT-F8    
         

A list of scan codes for special keys and combinations with the SHIFT, ALT and CTRL keys can be found in table (speckeys) ; They are for quick reference only.

Table: Special keys scan codes
Key Code SHIFT-Key CTRL-Key Alt-Key
NoKey 00      
F1 3B 54 5E 68
F2 3C 55 5F 69
F3 3D 56 60 6A
F4 3E 57 61 6B
F5 3F 58 62 6C
F6 40 59 63 6D
F7 41 5A 64 6E
F8 42 5A 65 6F
F9 43 5B 66 70
F10 44 5C 67 71
F11 85 87 89 8B
F12 86 88 8A 8C
Home 47   77 97
Up 48   8D 98
PgUp 49   84 99
Left 4B   73 9B
Center 4C   8F  
Right 4D   74 9D
end 4F   75 9F
Down 50   91 A0
PgDn 51   76 A1
Ins 52 05 04 A2
Del 53 07 06 A3
Tab 8 0F 94 A5
GreyPlus     90 4E


4 Writing a keyboard driver

Writing a keyboard driver means that hooks must be created for most of the keyboard unit functions. The TKeyBoardDriver record contains a field for each of the possible hooks:
TKeyboardDriver = Record
  InitDriver : Procedure;
  DoneDriver : Procedure;
  GetKeyEvent : Function : TKeyEvent;
  PollKeyEvent : Function : TKeyEvent;
  GetShiftState : Function : Byte;
  TranslateKeyEvent : Function (KeyEvent: TKeyEvent): TKeyEvent;
  TranslateKeyEventUniCode: Function (KeyEvent: TKeyEvent): TKeyEvent;
end;
The meaning of these hooks is explained below:
InitDriver
Called to initialize and enable the driver. Guaranteed to be called only once. This should initialize all needed things for the driver.
DoneDriver
Called to disable and clean up the driver. Guaranteed to be called after a call to initDriver. This should clean up all things initialized by InitDriver.
GetKeyEvent
Called by GetKeyEvent. Must wait for and return the next key event. It should NOT store keys.
PollKeyEvent
Called by PollKeyEvent. It must return the next key event if there is one. Should not store keys.
GetShiftState
Called by PollShiftStateEvent. Must return the current shift state.
TranslateKeyEvent
Should translate a raw key event to a cOrrect key event, i.e. should fill in the shiftstate and convert function key scancodes to function key keycodes. If the TranslateKeyEvent is not filled in, a default translation function will be called which converts the known scancodes from the tables in the previous section to a correct keyevent.
TranslateKeyEventUniCode
Should translate a key event to a unicode key representation.
Strictly speaking, only the GetKeyEvent and PollKeyEvent hooks must be implemented for the driver to function correctly.

The following unit demonstrates how a keyboard driver can be installed. It takes the installed driver, and hooks into the GetKeyEvent function to register and log the key events in a file. This driver can work on top of any other driver, as long as it is inserted in the uses clause after the real driver unit, and the real driver unit should set the driver record in its initialization section. The following program demonstrates the use of the unit:

Example
program example9;

{ This program demonstrates the logkeys unit }

uses keyboard,logkeys;

Var
  K : TKeyEvent;

begin
  InitKeyBoard;
  Writeln('Press keys, press "q" to end, "s" toggles logging.');
  Repeat
    K:=GetKeyEvent;
    K:=TranslateKeyEvent(K);
    Writeln('Got key : ',KeyEventToString(K));
    if GetKeyEventChar(K)='s' then
      if IsKeyLogging then
        StopKeyLogging
      else
        StartKeyLogging;  
  Until (GetKeyEventChar(K)='q');
  DoneKeyBoard;
end.
Note that with a simple extension of this unit could be used to make a driver that is capable of recording and storing a set of keyboard strokes, and replaying them at a later time, so a 'keyboard macro' capable driver. This driver could sit on top of any other driver.


2002-04-25