1
votes

j have a main program that works with barcode reader and keyboard without keypad. When in this program any number keys or the return key is pressed (or simulated via barcode reader) j need to check in my application (that runs idden in try bar) if the insert code is stored in a database. To do this i tried with global hotkey. Here the sample project

Type
TForm1 = class(TForm)
  procedure FormCreate(Sender: TObject);
  procedure FormDestroy(Sender: TObject);
private
{ Private declarations }
  id0, id1, id2, id3  : Integer;
  id4, id5, id6, id7  : Integer;
  id8,id9,IdEnter     : Integer;
  Code                : string;
  procedure WMHotKey(var Msg: TWMHotKey); message WM_HOTKEY;
public
{ Public declarations }
end;

Var
Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
const
  K_0   = $30;
  K_1   = $31;
  K_2   = $32;
  K_3   = $33;
  K_4   = $34;
  K_5   = $35;
  K_6   = $36;
  K_7   = $37;
  K_8   = $38;
  K_9   = $39;

begin
  // Register from 0 to 9 and Enter
  id0 := GlobalAddAtom('K0');
  RegisterHotKey(Handle, id0, 0, K_0);
  id1 := GlobalAddAtom('K1');
  RegisterHotKey(Handle, id1, 0, K_1);
  id2 := GlobalAddAtom('K2');
  RegisterHotKey(Handle, id2, 0, K_2);
  id3 := GlobalAddAtom('Key3');
  RegisterHotKey(Handle, id3, 0, K_3);
  id4 := GlobalAddAtom('Key4');
  RegisterHotKey(Handle, id4, 0, K_4);
  id5 := GlobalAddAtom('Key5');
  RegisterHotKey(Handle, id5, 0, K_5);
  id6 := GlobalAddAtom('Key6');
  RegisterHotKey(Handle, id6, 0, K_6);
  id7 := GlobalAddAtom('Key7');
  RegisterHotKey(Handle, id7, 0, K_7);
  id8 := GlobalAddAtom('Key8');
  RegisterHotKey(Handle, id8, 0, K_8);
  id9 := GlobalAddAtom('Key9');
  RegisterHotKey(Handle, id9, 0, K_9);
  IdEnter := GlobalAddAtom('KeyEnter');
  RegisterHotKey(Handle, idEnter, 0, VK_RETURN);
  Code:='';
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  UnRegisterHotKey(Handle, id0);
  GlobalDeleteAtom(id0);
  UnRegisterHotKey(Handle, id1);
  GlobalDeleteAtom(id1);
  UnRegisterHotKey(Handle, id2);
  GlobalDeleteAtom(id2);
  UnRegisterHotKey(Handle, id3);
  GlobalDeleteAtom(id3);
  UnRegisterHotKey(Handle, id4);
  GlobalDeleteAtom(id4);
  UnRegisterHotKey(Handle, id5);
  GlobalDeleteAtom(id5);
  UnRegisterHotKey(Handle, id6);
  GlobalDeleteAtom(id6);
  UnRegisterHotKey(Handle, id7);
  GlobalDeleteAtom(id7);
  UnRegisterHotKey(Handle, id8);
  GlobalDeleteAtom(id8);
  UnRegisterHotKey(Handle, id9);
  GlobalDeleteAtom(id9);
  UnRegisterHotKey(Handle, IdEnter);
  GlobalDeleteAtom(IdEnter);
end;

procedure TForm1.WMHotKey(var Msg: TWMHotKey);
begin
  if Msg.HotKey = id0 then Code:= Code +'0';
  if Msg.HotKey = id1 then Code:= Code +'1';
  if Msg.HotKey = id2 then Code:= Code +'2';
  if Msg.HotKey = id3 then Code:= Code +'3';
  if Msg.HotKey = id4 then Code:= Code +'4';
  if Msg.HotKey = id5 then Code:= Code +'5';
  if Msg.HotKey = id6 then Code:= Code +'6';
  if Msg.HotKey = id7 then Code:= Code +'7';
  if Msg.HotKey = id8 then Code:= Code +'8';
  if Msg.HotKey = id9 then Code:= Code +'9';
  if Msg.HotKey = IdEnter then
  begin
    ShowMessage('ENTER pressed ! ' + #13 + Code); 
    Code:='';
  end;
end;

end.

This works, if any number keys is pressed the string will increase and if return is pressed the message is displyed BUT in any other windows application (notepad, i.e. and in main program) this keys seem to be disabled (maybe because are hotkeys).

Please can someone have any idea(s) on how to get the code typed in the main program (not my one) in a second program (my one)??

Thank's for all your appreciate reply

Regard

Daniele

1

1 Answers

1
votes

When you called RegisterHotKey you told the system that your process it to handle all presses of the registered key. So it's only natural that the key only has effect in your process and is ignored by other processes. That is by design.

What you need to do instead is to use a keyboard hook. The simplest one to write is the low-level keyboard hook. This is simple because it does not require injection. Use SetWindowsHookEx passing WH_KEYBOARD_LL.