AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Win32/Win64 API (native code) Globaler Tastaturhook für eine bestimmte Tastatur
Thema durchsuchen
Ansicht
Themen-Optionen

Globaler Tastaturhook für eine bestimmte Tastatur

Ein Thema von Exceeder · begonnen am 21. Sep 2022 · letzter Beitrag vom 23. Sep 2022
Antwort Antwort
Seite 1 von 2  1 2      
Exceeder

Registriert seit: 29. Mai 2006
24 Beiträge
 
#1

Globaler Tastaturhook für eine bestimmte Tastatur

  Alt 21. Sep 2022, 21:26
Hallo,

ich würde gerne über einen globalen Tastaturhook die Eingaben einen bestimmten Tastatur auswerten. Speziell habe ich hier so einen RFID-Reader, welcher sich als Tastatur ausgibt. Die Alternative könnte sein, diesen Reader direkt via USB irgendwie auszulesen. Dafür fehlt mir aktuell leider noch das Wissen. Falls das eine nicht geht, wäre das also auch eine gute Option. Es gibt auf der verlinkten Seite ein kleines Tool, mit dem man ein paar wenige Optionen des Readers anpassen kann.

Der Reader sendet 10 Zeichen (0-9), welche der ID der Karte entspricht und dann ein Return. Man kann das auf HEX oder so umstellen, aber das löst das Problem noch nicht so richtig. Die Zeichen zu lesen ist kein Problem, allerdings dürfen diese dann auch nicht einfach in anderen Eingabecontrols landen. Man kann dem Reader leider auch nicht mitteilen, dass man ein spezielles Anfangszeichen braucht. Die Option "Add user-defined byte" aus der Software hat leider keine Funktion.

Der Code hier funktioniert soweit, leider bekommt halt jedes Eingabecontrol welches gerade zufällig Aktiv ist den Code ebenfalls.

Code:
unit RfidTest;

interface

implementation

uses
  Winapi.Windows, Winapi.Messages;

var
  GlobalKeyboardHook: HHOOK;
  RfidCode: string;


function KeyboardHook(nCode: Integer; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall;
type
  PKeyboardLowLevelHookStruct = ^TKeyboardLowLevelHookStruct;
  TKeyboardLowLevelHookStruct = record
    KeyCode: Cardinal;
    ScanCode: Cardinal;
    Flags: Cardinal;
    Time: Cardinal;
    ExtraInfo: Cardinal;
  end;

var
  DllHook: PKeyboardLowLevelHookStruct;

begin
  if nCode = HC_ACTION then
  begin
    DllHook := PKeyboardLowLevelHookStruct(lParam);

    if (wParam = WM_KEYUP) or (wParam = WM_SYSKEYUP) then
    begin
      if (DllHook^.KeyCode >= Ord('0')) and (DllHook^.KeyCode <= Ord('9')) then
        RfidCode := RfidCode + Char(DllHook^.KeyCode)
      else if DllHook^.KeyCode = VK_RETURN then
      begin
        OutputDebugString(PWideChar('RFID-Code: ' + RfidCode));
        RfidCode := '';
      end;
    end;
  end;

  Result := CallNextHookEx(GlobalKeyboardHook, nCode, wParam, lParam);
end;



procedure InitGlobalKeyboardHook();
begin
  GlobalKeyboardHook := SetWindowsHookEx(WH_KEYBOARD_LL, @KeyboardHook, 0, 0);

  if GlobalKeyboardHook = 0
    then RaiseLastOSError;
end;


procedure KillGlobalKeyboardHook();
begin
  if (GlobalKeyboardHook <> 0) then
    UnhookWindowsHookEx(GlobalKeyboardHook);
end;

initialization
  InitGlobalKeyboardHook();

finalization
  KillGlobalKeyboardHook();

end.
Hat jemand vielleicht hilfreiche Ideen dazu parat?
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.184 Beiträge
 
Delphi 12 Athens
 
#2

AW: Globaler Tastaturhook für eine bestimmte Tastatur

  Alt 21. Sep 2022, 22:39
Ja klar ... das ist halt ein Lese-Hook ... und Anderen verbietest du das Lesen nicht.

Du könntest einen Tastatur-Treiber schreiben, jenen für dieses Gerät installieren und da dann vor allen Programmen das in Ruhe abfangen.



Von Tastaturzeugs hatten wir von Anfang an die Finger gelassen
und nur Geräte genommen, welche z.B. via DLL (USB/LAN/WLAN)
oder COM-Port mit uns reden wollen,
damit es keine Probleme gibt und das Gescannte immer dort landet, wo es hin soll.


Wir nutzen die Geräte von Feig (und Datafox)
Ihr letzter Delphi-Entwickler ist zwar vor Jahren ausgeschieden und deren Header-Unit war von vor D2009, aber ist ja nicht das Problem. (PDF's und C++Header gibt es genug)

EVO-Terminals https://www.datafox.de/produkte-loes...bersicht#c6993
CPR (und noch RWA) https://www.feig.de/produkte/identif...ie/#tischleser

Die Einfachste Lösung ist natürlich ein Comport, weil du da keine speziellen Schnittstellen/Komponenten brauchst.

Wenn du da nichts finden solltest (was es aber bestimmt geben wird), dann
gibt es z.B. nette RFID-Leser mit i²C oder SPI und auch direkt mit UART. Da eventuell noch ein kleiner Arduino davor, der dir das als mit 3 Zeilen Quellcode von da holt und via Comport in dein System durchreicht.
$2B or not $2B

Geändert von himitsu (21. Sep 2022 um 22:44 Uhr)
  Mit Zitat antworten Zitat
Der schöne Günther

Registriert seit: 6. Mär 2013
6.176 Beiträge
 
Delphi 10 Seattle Enterprise
 
#3

AW: Globaler Tastaturhook für eine bestimmte Tastatur

  Alt 22. Sep 2022, 10:01
Die TKeyboardLowLevelHookStruct scheint leider wirklich nichts herzugeben, dass man sehen könnte von welcher Tastatur das kommt. Ich weiß ja nicht, wie euer Anwendungsfall aussieht, aber das pragmatischste wäre vlt. man bastelt sich ein Popup-Overlay, das man bitte fokussiert, und dann ist der "Scanner-Modus" aktiv und die Eingaben aus der "Tastatur" landen nirgendwo anders.

Oder, wenn man sich doch irgendwie sicher sein kann, dass nun Content vom Scanner kommt, im Hook einfach einen Wert ungleich Null zurückgeben:
Zitat:
if the hook procedure processed the message, it may return a nonzero value to prevent the system from passing the message to the rest of the hook chain or the target window procedure.
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

Registriert seit: 20. Jan 2006
Ort: Lübbecke
11.475 Beiträge
 
Delphi 12 Athens
 
#4

AW: Globaler Tastaturhook für eine bestimmte Tastatur

  Alt 22. Sep 2022, 10:20
Eventuell bist du besser dran, wenn du mit Raw Input arbeitest.
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.184 Beiträge
 
Delphi 12 Athens
 
#5

AW: Globaler Tastaturhook für eine bestimmte Tastatur

  Alt 22. Sep 2022, 10:36
Oder, wenn man sich doch irgendwie sicher sein kann,
Dafür müsste aber das mit dem Startzeichen funktionieren,
sonst weißt du nicht, ob z.B. eine erse '0' vom Scanner oder dem Nutzer kommt.

Klar, man könnte sich auch ins IME hängen und nachträglich die Eingaben versuchen abzufangen,

aber am einfachsten/sichersten ist nunmal garnicht erst über die Tastatur zu gehen.



In Microsoft gibt es auch eine SmartCard-API und inzwischen auch ein paar Neuere,
welche diesen Reader ansteuern können dürften. (kann ich nich helfen ... hatte damals damit aufgegeben es hinzubekommen)
$2B or not $2B
  Mit Zitat antworten Zitat
WladiD

Registriert seit: 27. Jan 2006
Ort: Celle
141 Beiträge
 
Delphi 11 Alexandria
 
#6

AW: Globaler Tastaturhook für eine bestimmte Tastatur

  Alt 22. Sep 2022, 14:15
Eine vielleicht weniger praktikable, aber dafür pragmatische Lösung wäre, einen USB-Filter in einer VM einzurichten. Funktioniert in VirtualBox wunderbar, siehe Anhang. Die Tastatur ist dann im Host nicht mehr verwendbar. Wenn die VM auch noch "Headless" ist, dann dürfte das ziemlich sicher sein.

In der VM müsste dann irgendein kleines Tool laufen, welches die Eingaben an die Zielanwendung überträgt.

Eine Treiberlösung wäre aber wahrscheinlich eleganter.
Miniaturansicht angehängter Grafiken
2022-09-22-14_07_41-usb-filter.png  
Waldemar Derr
  Mit Zitat antworten Zitat
Exceeder

Registriert seit: 29. Mai 2006
24 Beiträge
 
#7

AW: Globaler Tastaturhook für eine bestimmte Tastatur

  Alt 22. Sep 2022, 14:23
Hallo,

ja das mit der Tastatur ist nicht ideal. Was sich erkennen lässt: Die einzelnen Zeichen werden alle mit Abstand von wenigen MS eingegeben. Sprich man könnte Zahlen erstmal abfangen, zwischenspeichern und zunächst verwerfen. Kommt dann kein weiteres Zeichen, müsste man die Zeichen mittels keybd_event wieder senden (sofern es nicht die Zeichenfolge von 10 Ziffern + Return war). Da habe ich gestern schon ein wenig herumexperimentiert. Natürlich braucht es eine Verzögerung von 50ms oder so. Ideal ist das alles nicht.

Unter Linux lässt sich dieser RFID-Reader übrigens einfach im Rahmen einer Phoniebox oder so verwenden. Da kommt man auch an die RAW-Inputs recht einfach dran (von dem Projekt sind die auch noch über, habe 6 Stück davon hier liegen).

Das Szenario hier ist sehr begrenzt. Im Prinzip geht es darum einen "Aufsatz" mit Sortiereinsätzen zu erkennen, welcher auf einem Lagerwagen gewechselt werden kann. Sprich das System soll erkennen können, welcher Aufsatz gerade aufgesteckt ist. Das muss also auch funktionieren, ohne das man in einen speziellen Modus wechselt.

Ich habe den Hersteller wegen eines Startzeichens geschrieben, mal sehen, ob da was kommt.

Für das Lesen von USB habe ich nichts passendes gefunden. Die Com-Port Komponente bei Torry ist ~20 Jahre alt und wurde vor 17 Jahres das letzte mal aktualisiert. Aber ich vermute auch, dass ich den Reader nicht in einen entsprechenden Modus versetzen kann. Gäbe es für die Smartcard-Api schon irgendwelchen Delphi-Code oder müsste man da "from scratch" anfangen?
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.184 Beiträge
 
Delphi 12 Athens
 
#8

AW: Globaler Tastaturhook für eine bestimmte Tastatur

  Alt 22. Sep 2022, 15:01
Comport, da findest du ein oder zwei Komponenten im GetIt.

AsyncPro (wo ist das denn hin?)
TComPortDrv
nrComm Lib
TMS Async

Ansonsten funktionieren die uralten TComport-Componenten auch weiterhin. (nutzen wir hier selber sowas)
Und zu Feig könnte ich auch noch bissl was abgeben. (ist aber jetzt noch nicht so hübsch, dass ich es öffentlich bereitstellen würde)
$2B or not $2B

Geändert von himitsu (22. Sep 2022 um 22:30 Uhr)
  Mit Zitat antworten Zitat
HolgerX

Registriert seit: 10. Apr 2006
Ort: Leverkusen
972 Beiträge
 
Delphi 6 Professional
 
#9

AW: Globaler Tastaturhook für eine bestimmte Tastatur

  Alt 22. Sep 2022, 20:37
Hmm..

Wenn Du mit Tastatur-Geräten arbeiten willst, kannst Du mit RawInputDevices arbeiten.
Dann erhälst du WM_INPUT Messages und kannst auch mit GetRawInputDeviceInfo Informationen zum Gerät erhalten (z.B. den HIDName per RIDI_DEVICENAME).

Wenn Du dann jedoch Eingaben des Gerätes Blockieren möchtest, kommst Du nicht um einen LowLevel Keyborthook (SetWindowsHookEx(WH_KEYBOARD..)) in einer DLL herum. Darin kannst Du dann der KeyboardHookProc() als Result 1 zurückgeben, so dass diese Taste als Verarbeitet gilt.

Hatte sowas mal testweise gebastelt, ist aber schon was her und ich weiß nicht mehr wo das Testtool abgeblieben ist..
(Ja ich Verwende Delphi 6 Pro und will NICHT wechseln!)
  Mit Zitat antworten Zitat
Exceeder

Registriert seit: 29. Mai 2006
24 Beiträge
 
#10

AW: Globaler Tastaturhook für eine bestimmte Tastatur

  Alt 23. Sep 2022, 10:21
Hallo,

stimmt, es gibt ja jetzt GetIt. Hab mit Turbo Pascal angefangen und lange Zeit in der alten Firma noch mit XE7 gearbeitet. Das hat sich noch nicht so in den Kopf gebrannt. Ich mache das im Moment eher als Hobby nebenbei und habe über diese Quelle gar nicht nachgedacht.

@HolgerX Für die Blockade einer Tastatureingabe benötigt man keine DLL. Das geht auch in jedem normalen Programm. Mein Code vom Eingangspost musst nur um ein Exit(1); ergänzt werden, dann sind keine Eingaben mehr möglich.

Ich schaue trotzdem mal, ob man mit der Methode GetRawInputDeviceInfo irgendwas erreichen kann. Wobei das eher so aussieht, als wenn man sich hier mit eher vorab Devices auflisten kann. Im Keydown bzw. Keyup Event steht dann ja leider keine Device ID zur Verfügung. Eventuell gibt es aber doch noch mehr Informationen. Ex, Ex2, Ex3 lässt grüßen. Mal gucken ob man TKeyboardLowLevelHookStruct also noch erweitern kann.
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 03:28 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz