3 Stimmen

Wie kann man mit SendInput Tastenanschläge wiederholen?

Ich schreibe ein kleines Tool in VC++, um Tastenanschläge aufzuzeichnen und später wiederzugeben, einen Makro-Rekorder. Es funktioniert schon ganz gut, mit einer Tastatur-Hook-Funktion, die jeden einzelnen Tastendruck und jedes Loslass-Ereignis liest. Die Wiedergabe funktioniert mit der SendInput()-Funktion und funktioniert im Allgemeinen auch gut - außer bei sich wiederholenden Tastenanschlägen. Eine Taste mehrmals zu drücken, nachdem sie jedes Mal losgelassen wurde, ist kein Problem. Aber das Drücken und Halten einer Taste, um das Eingabezeichen zu wiederholen, kann zwar aufgezeichnet, aber nur in einigen Anwendungen wiedergegeben werden. Einige akzeptieren und geben das Zeichen mehrfach ein, andere nur einmal. (Es ist reproduzierbar, wer was tut.) Der Makrorecorder selbst sieht über seinen Überwachungshaken auch die nur einmal gedrückte Taste bei der Wiedergabe.

Wie kann ich also SendInput dazu bringen, mehrere aufeinanderfolgende Tastenanschläge einer einzigen Taste zu senden, ohne dazwischen selbst Ereignisse zum Loslassen von Tasten hinzuzufügen? Das Senden einer Sequenz von [drücken] [drücken] [drücken] ... [loslassen] funktioniert nicht immer.

2voto

YOU Punkte 113320

Sie könnten mehrere Tasten in einem SendInput-Aufruf senden, aber Sie müssen immer noch Keyup-Flags für jedes Zeichen setzen, um bei jeder Art von Tastendruck die gleichen Ergebnisse zu erzielen.

Wenn Sie "aa" senden müssen, können Sie wie folgt vorgehen.

INPUT input[4];

input[0].type = INPUT_KEYBOARD;
input[0].ki.wVk = 0;
input[0].ki.wScan = 'a';
input[0].ki.dwFlags = 0;

input[1].type = INPUT_KEYBOARD;
input[1].ki.wVk = 0;
input[1].ki.wScan = 'a';
input[1].ki.dwFlags = KEYEVENTF_KEYUP;

input[2].type = INPUT_KEYBOARD;
input[2].ki.wVk = 0;
input[2].ki.wScan = 'a';
input[2].ki.dwFlags = 0;

input[3].type = INPUT_KEYBOARD;
input[3].ki.wVk = 0;
input[3].ki.wScan = 'a';
input[3].ki.dwFlags = KEYEVENTF_KEYUP;

SendInput(4, input, sizeof(INPUT));

1voto

kevinarpe Punkte 18905

Ich bin mir nicht sicher über Ihre genau Abfolge von Tastenanschlägen, aber ich hatte kürzlich ein ähnliches Problem. Ich habe ein kleines Win32-Tool [1] geschrieben, das Tasten sendet, wenn eine globale Schnelltaste gedrückt wird. Wenn sich Zeichen wiederholten, z. B. "aaabc", gingen die wiederholten Zeichen verloren. Ich habe viele Kombinationen von KeyDown und KeyUp ausprobiert, aber die wiederholten Zeichen gingen immer verloren.

Dann habe ich diesen Blogbeitrag gefunden: https://batchloaf.wordpress.com/2014/10/02/using-sendinput-to-type-unicode-characters/

Der Autor geht zwar nicht speziell auf die Wiederholung von Zeichen ein, aber er hat mich dazu inspiriert, es zu versuchen SendInput() mit nur einem einzeln INPUT Struktur. Diese Technik funktioniert bei mir sehr gut.

Kurz gesagt:

  1. Rufen Sie an. SendInput() mit nur einem einzigen INPUT Struktur.
  2. Um eine einzelne getippte (reguläre) Taste zu simulieren, z.B., z versuchen Sie dies:
    • Einzelnes KeyDown-Ereignis senden: ki.dwFlags = KEYEVENTF_UNICODE
    • Einzelnes KeyUp-Ereignis senden: ki.dwFlags = KEYEVENTF_UNICODE | KEYEVENTF_KEYUP

[1] https://github.com/kevinarpe/win32/tree/master/send_input

0voto

Anthony M. Powers Punkte 1227

Viele Leute haben Probleme damit, dass Keyup- und Keydown-Aufrufe "entlassen" oder "fallengelassen" werden. Viele Leute haben ihre Probleme gelöst, indem sie einen kleinen Puffer zwischen den beiden Aufrufen einbauten, um sicherzustellen, dass alle Befehle übertragen werden:

sendinput  alt keydown
sendinput  3  keydown
sleep 50
sendinput 3 keyup
sendinput alt keyup

Außerdem gibt es eine SendInput.SendWait Befehl....

Prost

0voto

karoberts Punkte 9688

Soweit ich weiß, funktioniert es so, dass, wenn eine Taste nach unten gedrückt wird und für eine bestimmte Zeit (die Wiederholungsverzögerung) keine Taste nach oben gedrückt wird, die Taste als "wiederholend" betrachtet wird, bis eine Taste nach oben gedrückt wird.

Da das Senden von Drücken, Drücken, Drücken, Loslassen nicht immer funktioniert, haben Sie versucht, die Zeit zwischen dem Drücken der Taste und dem Hochziehen der Taste aufzuzeichnen und dann die Befehle in dieser Zeit zu wiederholen? Das wird dann zwar zu Echtzeit, sollte aber die gleichen Wiederholungsaktionen auslösen.

Ich kann mir keinen anderen Weg vorstellen, um die gleiche Anzahl von "Tastenwiederholungen" wie im Original zu erhalten, da diese nicht als einzelne Tastendrücke aufgezeichnet werden.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X