Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Wie kann ich Tastaturaktionen über meine Anwendung loggen? (https://www.delphipraxis.net/208840-wie-kann-ich-tastaturaktionen-ueber-meine-anwendung-loggen.html)

cckLoud 20. Sep 2021 13:43

Wie kann ich Tastaturaktionen über meine Anwendung loggen?
 
Hallo,

ich möchte für meine Anwendung eine Zeit"uberwachung" bauen. Da da ein heikles Thema ist, hier eine kurze Erklärung:

Mit meinem Programm werden Gutachten erstellt. Und manchmal rechnet der Gutachter nach Aufwand ab. Dsher wäre es nützlich für ihn, die Zeit, die er dazu am Rechner verbracht hat, nachzuweisen. Das könnte man einfach machen, indem man die Zeit aufzeichnet, in der das Gutachten "aktiv" ist - also einfach beim "Laden" Zeit merken und wen er das Programm beendet oder ein anderes Gutachten aufruft die Endezeit merken. Das ist aber nicht sehr hilfreich, da Pausen, oder wenn der Rechner nachts anbleibt usw. hier nicht berücksichtigt werden. Da könnte es dienlich sein, einfach zu schauen, wenn er was über die Tastatur eingibt und die Zeiterfassung darauf zu basieren.

Tastendrücke für ein Form abzufangen ist einfach (KeyPreview), das nutze ich mehrfach im Projekt. Wie aber sieht das aus, wenn mehrere Forms involviert sind (im Projekt um die 300) und Eingaben von jedem Form möglich sind? Muss ich da über Hooks gehen (die (möglicherweise) alle Tastaturereignisse auf dem Rechner reagiert?

freimatz 20. Sep 2021 14:07

AW: Wie kann ich Tastaturaktionen über meine Anwendung loggen?
 
Idee:
https://docwiki.embarcadero.com/Libr...tion.OnMessage
Und da Keybaord-Ereignisse filtern.

himitsu 20. Sep 2021 14:27

AW: Wie kann ich Tastaturaktionen über meine Anwendung loggen?
 
Delphi-Referenz durchsuchenTApplicationEvents

MSDN-Library durchsuchenWM_KEYDOWN
WM_KEYUP
usw.



bzw. siehe LastUserInput
MSDN-Library durchsuchenGetLastInputInfo

cckLoud 20. Sep 2021 14:59

AW: Wie kann ich Tastaturaktionen über meine Anwendung loggen?
 
Danke, auf TApplicationEvents bin ich nicht gestossen! Das könnte der Weg sein...

cckLoud 21. Sep 2021 05:18

AW: Wie kann ich Tastaturaktionen über meine Anwendung loggen?
 
Ja, das hat funktioniert. Ich habe das ganze in ein Objekt ausgelagert, das ich im Create des Main-Forms anlege (mit glbKeyLog := TKeyLog.Create;). Aktiviert wird das ganze mit "glbKeyLog.Active := true;".

Hier die Unit (das mit dem Timer ist, damit die Messagebearbeitung nicht durch die Bearbeitungslogik unterbrochen wird):

Code:
unit KeyLog;

interface
uses Vcl.Forms, Vcl.ExtCtrls, windows, messages, SysUtils;
type
   TKeyLog = class(TObject)
   private
      fActive: boolean;
      Timer: TTimer;
      Key: word;

      procedure OnTimer(Sender: TObject);
      procedure Process;
      procedure AppMessage(var Msg: TMsg; var Handled: Boolean);
   public
      constructor Create;
      property Active: boolean read fActive write fActive;
end;
var glbKeyLog: TKeyLog;
implementation

{ TFrameGebDatenGebaeude }

procedure TKeyLog.AppMessage(var Msg: TMsg; var Handled: Boolean);
begin
   if not fActive then
      exit;
// Geht beides, WM_KeyDown und WM_KEYUP
//   if Msg.message = WM_KeyDown then begin
   if Msg.message = WM_KEYUP then begin
      Key:=Msg.wParam;
      Timer.Enabled := true;
   end;
end;

constructor TKeyLog.Create;
begin
   fActive := false;
   Timer := TTimer.Create(Application);
   Timer.Interval := 1;
   Timer.OnTimer := OnTimer;
   Timer.Enabled := false;
   Application.OnMessage := AppMessage;
end;

procedure TKeyLog.OnTimer(Sender: TObject);
begin
   Timer.Enabled := false;
   Process;
end;

procedure TKeyLog.Process;
begin
   Application.MessageBox(pwidechar('Keystroke ' + chr(Key)), '');
end;

end.

Delphi.Narium 21. Sep 2021 10:16

AW: Wie kann ich Tastaturaktionen über meine Anwendung loggen?
 
Für den Fall, dass in Application.OnMessage schon was drinne stehen sollte, geht Dir das bei Deiner Implementierung verloren.

Damit Du unabhängiger wirst, speichere Dir doch den Inhalt von Application.OnMessage doch im Create in 'ner Variabel (fAppMessage oder so) und rufe die Routine dann in TKeyLog.AppMessage auf. Ungetestet sowas in der Art:
Delphi-Quellcode:
procedure TKeyLog.AppMessage(var Msg: TMsg; var Handled: Boolean);
begin
   if not fActive then begin
     if Assigned(fAppMessage) then fAppMessage(Msg, Handled);
     exit;
   end;
// Geht beides, WM_KeyDown und WM_KEYUP
//   if Msg.message = WM_KeyDown then begin
   if Msg.message = WM_KEYUP then begin
      Key := Msg.wParam;
      Timer.Enabled := true;
   end;
   if Assigned(fAppMessage) then fAppMessage(Msg, Handled);
end;

cckLoud 21. Sep 2021 15:38

AW: Wie kann ich Tastaturaktionen über meine Anwendung loggen?
 
Warum sollte da was verloren gehen, was meinst du damit? "Handled" ist auf false, also geht die Message weiter (erfolgreich bestätigt). Und ich brauche bei meinem Problem eigentlich nur die Zeit, zu der die Taste gedückt wurde. Und da kommt es auf ein paar Milisekunden auch nicht an, die der Timer-Event braucht, um durch die Message.Schleife zu kommen...

Delphi.Narium 21. Sep 2021 16:03

AW: Wie kann ich Tastaturaktionen über meine Anwendung loggen?
 
Wenn irgendwo im Programm eine Zuweisung der Art
Delphi-Quellcode:
Application.OnMessage := EineOnMessageRoutine;
erfolgte und Du machst später in Deinem
Delphi-Quellcode:
constructor TKeyLog.Create;
dann diese Zuweisung
Delphi-Quellcode:
Application.OnMessage := AppMessage;
, so wird die Routine
Delphi-Quellcode:
EineOnMessageRoutine
niemals beim Ereignis
Delphi-Quellcode:
OnMessage
aufgerufen werden und geht Dir damit verloren.

Es mag sein, dass das im konkreten Fall irrelevant ist, aber halt einfach zu prüfen, ob schon was zugewiesen wurde und das dann auch aufzurufen, ist nicht der große Aufwand, eventuell durch den Nichtaufruf auftretende Seiteneffekte zu erkennen und zu beheben, dürfte deutlich aufwändiger sein.

cckLoud 21. Sep 2021 18:53

AW: Wie kann ich Tastaturaktionen über meine Anwendung loggen?
 
Ja, ok, das ist aber klar. Wenn du eine Ereignisroutine überschreibst, dann kommt halt nur die letzte dran. Aber sowas ist halt normales Programmiergeschäft. Und da man sich hier abspricht, bzw., wie bei mir, allein programmiert und dabei (hoffentlich! :lol:) den Überblick behält, das tägliches Projekthandling.

Bei mir ist es als Entertainer tatsächlich einfacher, da ich WEISS, das der Event nirgends sonst benutzt wird!

himitsu 22. Sep 2021 12:12

AW: Wie kann ich Tastaturaktionen über meine Anwendung loggen?
 
Wie gesagt, nicht Application.OnMessage sondern TApplicationEvents.OnMessage verwenden.

Denn wenn du deinen TKeyLog mehrmahls erstellst oder jemand Anderes (z.B. Fremdkomponente oder eine andere Stelle, die du schonwieder vergessen hast),
dann blockiert/überschreibt man sich selber.


An Application.OnMessage kann sich nur Einer gleichzeitig dranhängen.
TApplicationEvents kann aber mehrmals verwendet werden.
z.B. auf eine/mehrere Forms eine/mehrere TApplicationEvents drauf oder eben Mehrere davon mit Create selbst erstellen.


Zitat:

Zitat von cckLoud (Beitrag 1495218)
da ich WEISS, das der Event nirgends sonst benutzt wird!

Und dann nutzt du von jemand Anderem eine Komponente oder Codestück
und jener Entwickler dachte genau das Gleiche.


Alle Zeitangaben in WEZ +1. Es ist jetzt 04:29 Uhr.

Powered by vBulletin® Copyright ©2000 - 2021, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2021 by Daniel R. Wolf