[Previous][Up][Next] |
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:
Strictly speaking, only the GetKeyEvent and PollKeyEvent hooks must be implemented for the driver to function correctly.
The example 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.
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.
unit logkeys; interface Procedure StartKeyLogging; Procedure StopKeyLogging; Function IsKeyLogging : Boolean; Procedure SetKeyLogFileName(FileName : String); implementation uses sysutils,keyboard; var NewKeyBoardDriver, OldKeyBoardDriver : TKeyboardDriver; Active,Logging : Boolean; LogFileName : String; KeyLog : Text; Function TimeStamp : String; begin TimeStamp:=FormatDateTime('hh:nn:ss',Time()); end; Procedure StartKeyLogging; begin Logging:=True; Writeln(KeyLog,'Start logging keystrokes at: ',TimeStamp); end; Procedure StopKeyLogging; begin Writeln(KeyLog,'Stop logging keystrokes at: ',TimeStamp); Logging:=False; end; Function IsKeyLogging : Boolean; begin IsKeyLogging:=Logging; end; Function LogGetKeyEvent : TKeyEvent; Var K : TKeyEvent; begin K:=OldkeyboardDriver.GetKeyEvent(); If Logging then begin Write(KeyLog,TimeStamp,': Key event: '); Writeln(KeyLog,KeyEventToString(TranslateKeyEvent(K))); end; LogGetKeyEvent:=K; end; Procedure LogInitKeyBoard; begin OldKeyBoardDriver.InitDriver(); Assign(KeyLog,logFileName); Rewrite(KeyLog); Active:=True; StartKeyLogging; end; Procedure LogDoneKeyBoard; begin StopKeyLogging; Close(KeyLog); Active:=False; OldKeyBoardDriver.DoneDriver(); end; Procedure SetKeyLogFileName(FileName : String); begin If Not Active then LogFileName:=FileName; end; Initialization GetKeyBoardDriver(OldKeyBoardDriver); NewKeyBoardDriver:=OldKeyBoardDriver; NewKeyBoardDriver.GetKeyEvent:=@LogGetKeyEvent; NewKeyBoardDriver.InitDriver:=@LogInitKeyboard; NewKeyBoardDriver.DoneDriver:=@LogDoneKeyboard; LogFileName:='keyboard.log'; Logging:=False; SetKeyboardDriver(NewKeyBoardDriver); end.
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.