AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Projekte SendInputHelper - Ein Wrapper, der den Umgang mit SendInput vereinfacht

SendInputHelper - Ein Wrapper, der den Umgang mit SendInput vereinfacht

Ein Thema von WladiD · begonnen am 1. Okt 2010 · letzter Beitrag vom 6. Dez 2023
Antwort Antwort
Seite 2 von 3     12 3   
WladiD
Registriert seit: 27. Jan 2006
Hallo DP-Mitglieder,

vor einigen Tagen bestand bei mir Bedarf, Tastatureingaben zu simulieren, wofür die Windows-Funktion MSDN-Library durchsuchenSendInput ja auch implementiert wurde. Doch das Array aufzubauen, welches die Funktion erwartet, ist ein Graus. So muss z.B. für jede Taste einmal der gedrückt und dann wieder der losgelassen Status einzeln angegeben werden. Es ist schon klar, dass es so sein soll, damit man die Kontrolle hat, aber es ist sehr mühsam und schreit geradezu nach einer Klasse die das ganze etwas vereinfacht.

Ich lege am einfachsten mit einem Beispiel los. Notepad starten:

Delphi-Quellcode:
uses SendInputHelper;

with TSendInputHelper.Create do
begin
  AddShortCut([ssWin], 'r'); // [Win] + [R]
  AddDelay(100); // Verzögerung in ms
  AddText('cmd', TRUE); // TRUE = AppendReturn
  
  Flush; // Erst hier werden die zuvor hinzugefügten
         // Eingaben gebündelt abgesetzt.
  Free;
end;
Jeder der mit SendInput schon mal gearbeitet hat, wird wissen, was das für eine Vereinfachung mit sich bringt. Desweiteren wird der Caps-Lock-Zustand in der Methode Flush neutralisiert, soll heißen, dass im obigen Beispiel auch wirklich 'cmd' und nicht 'CMD' gesendet wird, wenn der Benutzer die Feststelltaste (wohl aus versehen) aktiviert hat.

Ich weiß, es ist eigentlich kein "richtiges" Projekt, doch ich sehe es einfach mal als eines an und habe es auch bei sourceforge veröffentlicht:

SendInputHelper auf GitHub

Dort ist auch ein umfangreicheres Beispiel (auch compiliert) dabei.

mfg

Geändert von WladiD (25. Jul 2019 um 11:23 Uhr) Grund: Repository umgezogen
 
mkinzler

 
Delphi 11 Alexandria
 
#11
  Alt 25. Okt 2012, 12:11
Wird ein Fehler gemeldet? Wenn ja welcher?
Markus Kinzler
  Mit Zitat antworten Zitat
PeterPanino

 
Delphi 10.4 Sydney
 
#12
  Alt 25. Okt 2012, 13:17
Wird ein Fehler gemeldet? Wenn ja welcher?
Nein, es wird kein Fehler gemeldet, das Zeichen wird einfach nicht gesendet. Übrigens auch nicht die übrigen Zeichen mit "Akzent": éèáà.

Ich habe eine Tastatur mit deutschem Layout. Windows 7 x64 SP1 Deutsch
  Mit Zitat antworten Zitat
PeterPanino

 
Delphi 10.4 Sydney
 
#13
  Alt 26. Okt 2012, 13:46
Wird ein Fehler gemeldet? Wenn ja welcher?
Nein, es wird kein Fehler gemeldet, das Zeichen wird einfach nicht gesendet. Übrigens auch nicht die übrigen Zeichen mit "Akzent": éèáà.

Ich habe eine Tastatur mit deutschem Layout. Windows 7 x64 SP1 Deutsch
Ich kann TSendInputHelper zur Zeit leider nicht debuggen, weil die Delphi IDE im Debug-Modus immer abstürzt (unabhängig davon welches Projekt).
  Mit Zitat antworten Zitat
PeterPanino

 
Delphi 10.4 Sydney
 
#14
  Alt 26. Okt 2012, 21:06
SendInputHelper hat ein Problem: Es verwendet TShiftState als Klassenmitglied. Das führt zu Problemen mit anderen Klassen, welche System.Classes.TShiftState verwenden.

Wie kann man dieses Problem lösen?
  Mit Zitat antworten Zitat
PeterPanino

 
Delphi 10.4 Sydney
 
#15
  Alt 26. Okt 2012, 21:15
Eine Möglichkeit wäre, dass man SendInputHelper in der uses-Klausel VOR System.Classes einfügt. Aber dann funktionieren alle SendInputHelper Methoden nicht mehr, welche einen TShiftState Parameter verwenden, z.B.:

procedure TSendInputHelper.AddShortCut(ShiftState:TShiftState; ShortChar:Char);

Ein verzwicktes Problem! Wie könnte man es lösen?
  Mit Zitat antworten Zitat
PeterPanino

 
Delphi 10.4 Sydney
 
#16
  Alt 26. Okt 2012, 23:42
Ein möglicher Workaround: Eine eigene Bridge- oder Worker-Unit erzeugen, in der die SendInputHelper-Aufrufe gekapselt werden, z.B.:
Delphi-Quellcode:
unit SIHWorker;

interface

uses
  SendInputHelper;

procedure SendShortCut(DummyShiftState: Integer; ShortChar: Char);

implementation

var
  SIH: TSendInputHelper;

procedure SendShortCut(DummyShiftState: Integer; ShortChar: Char);
begin
  case DummyShiftState of
    1: SIH.AddShortCut([ssShift], ShortChar);
    2: SIH.AddShortCut([ssCtrl], ShortChar);
    3: SIH.AddShortCut([ssAlt], ShortChar);
  end;
  SIH.Flush;
end;

{ Todo: weitere SendInputHelper-Aufrufe }

initialization
  SIH := TSendInputHelper.Create;

finalization
  SIH.Free;

end.
Zusätzlich sollte noch in SendInputHelper.pas TShiftState durch TSIHShiftState ersetzt werden.

Jetzt kann man die Methoden von SendInputHelper indirekt über SIHWorker aufrufen und braucht so SendInputHelper nicht mehr in anderen Units zu deklarieren (was zu den besagten Fehlern führen würde).

Geändert von PeterPanino (27. Okt 2012 um 12:25 Uhr)
  Mit Zitat antworten Zitat
PeterPanino

 
Delphi 10.4 Sydney
 
#17
  Alt 28. Okt 2012, 00:57
Nachdem ich eine Lösung für das TShiftState-Problem aufgezeigt habe, habe ich jetzt endlich den Fehler gefunden, bei dem keine Akzentzeichen (z.B. éèáà usw.) ausgegeben wurden. Ich habe jetzt die Delphi XE3 IDE zum Debuggen verwendet, und die stürzt im Debug-Modus nicht ab, obwohl AQtime installiert ist!
Delphi-Quellcode:
if not((Ord(SendChar) > 0) and (Ord(SendChar) < 127)) then // war: 255
begin
  Result := GetUnicodeChar(SendChar, Press, Release);
  Exit;
end;
Der Fehler liegt darin, dass Waldemar die Unicode-Zeichenbehandlung erst ab Ord(SendChar) = 255 angesetzt hat. Akzentzeichen wie é sind jedoch auf einer deutschen Tastatur mit den Umschalttasten Shift/Ctrl/Alt(/AltGr) nicht erreichbar (und nur diese sind im Rückgabewert von VkKeyScan kodiert), deshalb hat das nachfolgende VkKeyScan(SendChar) immer einen falschen ScanCode von 65535 (!) ergeben, wodurch natürlich kein Zeichen gesendet wurde. Die deutschen Umlaute sind zwar auch 8-bittig kodiert (haben also einen ASCII-Wert im Bereich 128-255), sind jedoch mit den Umschalttasten auf einer deutschen Tastatur erreichbar und liefern deshalb bei VkKeyScan einen korrekten Wert zurück. Bei Verwendung einer US-Tastatur würde VkKeyScan aber auch bei den deutschen Umlauten einen falschen Wert zurückgeben. Es ist also richtig, bei VkKeyScan vom kleinsten gemeinsamen Nenner - nämlich 7-bit ASCII - auszugehen!
  Mit Zitat antworten Zitat
PeterPanino

 
Delphi 10.4 Sydney
 
#18
  Alt 28. Okt 2012, 20:31
Verbesserung: SendInputHelper-Methoden, die kein TShiftState als Parameter übergeben, können von außen direkt über die Objekt-Variable SIH aufgerufen werden. Deshalb muss die Objekt-Variable SIH im Interface-Teil deklariert werden!
Delphi-Quellcode:
unit SIHWorker;

interface

uses
  SendInputHelper;

procedure SendShortCutChar(DummyShiftState: Integer; ShortChar: Char);

var
  SIH: TSendInputHelper;

implementation

procedure SendShortCutChar(DummyShiftState: Integer; ShortChar: Char);
begin
  case DummyShiftState of
    1:
      SIH.AddShortCut([ssShift], ShortChar);
    2:
      SIH.AddShortCut([ssCtrl], ShortChar);
    3:
      SIH.AddShortCut([ssAlt], ShortChar);
  end;
  SIH.Flush;
end;

(*
SendInputHelper-Methoden, die kein TShiftState als Parameter übergeben,
können von außen direkt über die Objekt-Variable SIH aufgerufen werden.
Deshalb muss die Objekt-Variable SIH im Interface-Teil deklariert werden!
*)


initialization

SIH := TSendInputHelper.Create;

finalization

SIH.Free;

end.
  Mit Zitat antworten Zitat
Benutzerbild von ATS3788
ATS3788

 
Delphi XE Starter
 
#19
  Alt 31. Mär 2016, 10:56
Nach so viele Jahre

Danke
Martin MIchael
  Mit Zitat antworten Zitat
WladiD

 
Delphi 10.4 Sydney
 
#20
  Alt 25. Jul 2019, 11:31
Nachdem ich eine Lösung für das TShiftState-Problem aufgezeigt habe, habe ich jetzt endlich den Fehler gefunden, bei dem keine Akzentzeichen (z.B. éèáà usw.) ausgegeben wurden. Ich habe jetzt die Delphi XE3 IDE zum Debuggen verwendet, und die stürzt im Debug-Modus nicht ab, obwohl AQtime installiert ist!
Delphi-Quellcode:
if not((Ord(SendChar) > 0) and (Ord(SendChar) < 127)) then // war: 255
begin
  Result := GetUnicodeChar(SendChar, Press, Release);
  Exit;
end;
Der Fehler liegt darin, dass Waldemar die Unicode-Zeichenbehandlung erst ab Ord(SendChar) = 255 angesetzt hat. Akzentzeichen wie é sind jedoch auf einer deutschen Tastatur mit den Umschalttasten Shift/Ctrl/Alt(/AltGr) nicht erreichbar (und nur diese sind im Rückgabewert von VkKeyScan kodiert), deshalb hat das nachfolgende VkKeyScan(SendChar) immer einen falschen ScanCode von 65535 (!) ergeben, wodurch natürlich kein Zeichen gesendet wurde. Die deutschen Umlaute sind zwar auch 8-bittig kodiert (haben also einen ASCII-Wert im Bereich 128-255), sind jedoch mit den Umschalttasten auf einer deutschen Tastatur erreichbar und liefern deshalb bei VkKeyScan einen korrekten Wert zurück. Bei Verwendung einer US-Tastatur würde VkKeyScan aber auch bei den deutschen Umlauten einen falschen Wert zurückgeben. Es ist also richtig, bei VkKeyScan vom kleinsten gemeinsamen Nenner - nämlich 7-bit ASCII - auszugehen!
Hi PeterPanino,

sicherlich ist es nach all den Jahren nicht mehr relevant, aber ich wollte hier mal erwähnen, das dieser Fehler jetzt beseitigt ist. Auch habe ich das Set TShiftState nach TSIHShiftState umbenannt, damit es keine Namenskonflikte mit anderen Bibliotheken geben kann.

Das Repository befindet sich schon seit einigen Jahren auf GitHub:
https://github.com/WladiD/SendInputHelper
Waldemar Derr
  Mit Zitat antworten Zitat
Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

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 22:36 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