The idea Cronodragon suggested me was:
[pascal]
unit UBEInput;

interface

uses
Contnrs, UBELogger;

type
{ .: TDeviceType :. }
TDeviceType = (dtKeyboard, dtMouse, dtJoystick);

{ .: TInputDevice :. }
TInputDevice = class(TObject)
private
{ Private declarations }
FDeviceType: TDeviceType;
public
{ Public declarations }
constructor Create(); virtual;

procedure Update(); virtual; abstract;

property DeviceType: TDeviceType read FDeviceType write FDeviceType;
end;

{ .: TKeyboardDevice :. }
TKeyboardDevice = class(TInputDevice)
private
{ Private declarations }
FKeys: array[0..255] of Boolean;
public
{ Public declarations }
constructor Create(); override;

procedure Update(); override;

property DeviceType;
end;

{ .: TDeviceManager :. }
TDeviceManager = class(TObject)
private
{ Private declarations }
FDevices: TObjectList;
public
{ Public declarations }
constructor Create();
destructor Destroy(); override;

procedure AddDevice(const ADevice: TInputDevice);
procedure UpdateDevices();

function IsPressed(ADeviceType: TDeviceType; AButton: Byte): Boolean;
end;

implementation

{ TInputDevice }

constructor TInputDevice.Create;
begin
inherited Create();
end;

{ TKeyboardDevice }

constructor TKeyboardDevice.Create;
begin
inherited Create();

DeviceType := dtKeyboard;
end;

procedure TKeyboardDevice.Update;
begin

end;

{ TDeviceManager }

procedure TDeviceManager.AddDevice(const ADevice: TInputDevice);
begin
FDevices.Add(ADevice);
end;

constructor TDeviceManager.Create;
begin
inherited Create();

FDevices := TObjectList.Create(True);
end;

destructor TDeviceManager.Destroy;
begin
FDevices.Free();

inherited Destroy();
end;

function TDeviceManager.IsPressed(ADeviceType: TDeviceType;
AButton: Byte): Boolean;
var
I: Integer;
begin
for I := 0 to FDevices.Count -1 do
case ADeviceType of
dtKeyboard:
if (FDevices.Items[I] is TKeyboardDevice) then
Result := TKeyboardDevice(FDevices.Items[I]).FKeys[AButton];
end;
end;

procedure TDeviceManager.UpdateDevices;
var
I: Integer;
begin
for I := 0 to FDevices.Count -1 do
TInputDevice(FDevices.Items[I]).Update();
end;

end.
[/pascal]

What do you think of it? And how do I read the pressed keys? :?