2

I tried working on events onKeyDown and onKeyUp. The program works perfectly when only two keys are pressed.

For combinations of more then 2 keys, if 2 keys are already pressed (and so they are down), the pressure of another key isn't caught and so the combination FGH is seen as FG corresponding to a different braille symbol.

Moreover, when 3 or more keys are pressed together the numbers of onKeyDown events caught aren't always the same.

JasonMArcher
  • 14,195
  • 22
  • 56
  • 52
gFEB
  • 29
  • 1
  • even if you would implement an own Keyboardhook, there will be technical limitations from Hardwareside .... http://www.tomshardware.co.uk/forum/50383-10-pressing-multiple-keys-keyboard-problem – bummi Nov 17 '12 at 20:20
  • 1
    That's a hardware limitation of most keyboards. Search for "key rollover" and "keyboard matrix". Get a better keyboard. – CodesInChaos Nov 17 '12 at 21:24
  • Yep. It's called "N-key rollover", and most USB keyboards cannot support it due to limitations in USB. – Warren P Nov 17 '12 at 23:22

3 Answers3

0

With GetKeyboardState you can retrieve a full array of the state of each key. To catch multiple keypresses like the braille symbols, you'd have to call it in a high sequence, for example from a TTimer with a really small Interval, or from a class inheriting from TThread. Also chances are with two or more buttons to get pressed, the key-down will not register on all keys at exactly the same time, so you'll have to keep track and only take combination that fits a criterium, for example that existed the longest.

Stijn Sanders
  • 35,982
  • 11
  • 45
  • 67
  • Won't help. For many if more than two keys are pressed at the same time, things can get weird. – CodesInChaos Nov 17 '12 at 21:25
  • @CodesInChaos I think that limit is nowhere near just 2 keys. – GolezTrol Nov 17 '12 at 21:28
  • @GolezTrol With cheap keyboards there are many 3 key combinations that don't register and lock the input. Which combinations that are depends on the keyboard matrix. Try pressing three letters at the same time, it probably won't work correctly, no matter the api. – CodesInChaos Nov 17 '12 at 21:34
  • May be. In that case, you'll have to spend a couple of euro's extra when building a braille keyboard. – GolezTrol Nov 17 '12 at 21:46
0

Use GetAsyncKeyState. It doesn't only return the current state of the keys, but also whether the key has been pressed since the last call. There is a limit on the number of keys that can be pressed simultaneously. I think that limit is around 8 keys, but it may differ between hardware, drivers and OS version.

GolezTrol
  • 114,394
  • 18
  • 182
  • 210
  • The problem is that when i press more than 2 keys, no onKeyDown is catched as if i hadn't pressed anything. – gFEB Nov 17 '12 at 22:43
  • Maybe you can use a timer to check periodically (use small intervals!) The advantage of GetAsyncKeyState is that it remembers keypresses inbetween calls, even if they key was pressed and released in the mean time. So you don't have to miss any keys. – GolezTrol Nov 18 '12 at 07:31
0

You can expect some troubles with cheap keyboards! Here you have a simple test program to test your keyboard. (Don't forget to define forms OnKeyDown and OnKeyUp events.)

type
  TForm8 = class(TForm)
    procedure FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
    procedure FormKeyUp(Sender: TObject; var Key: Word; Shift: TShiftState);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form8: TForm8;

implementation

{$R *.dfm}

procedure TForm8.FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
var
  State   :TKeyboardState;
  n       :integer;
  s       :string;
begin
  GetKeyboardState(State);
  s := '';
  for n := Low(byte) to High(byte) do
    if State[n] and 128 <> 0 then
      s := s + 'VK(' + IntToStr(n) + ') ';
  Caption :=  s;
end;

procedure TForm8.FormKeyUp(Sender: TObject; var Key: Word; Shift: TShiftState);
var
  State   :TKeyboardState;
  n       :integer;
  s       :string;
begin
  GetKeyboardState(State);
  s := '';
  for n := Low(byte) to High(byte) do
    if State[n] and 128 <> 0 then
      s := s + 'VK(' + IntToStr(n) + ') ';
  Caption :=  s;
end;

end.
GJ.
  • 10,810
  • 2
  • 45
  • 62