PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : [.NET] simulierten Tastendruck halten mit Pinvoke


Gast
2009-08-17, 15:38:29
Hallo erstmal,

ich versuche gerade, einen Tastendruck zu simulieren, welcher einer für längere Zeit gedrückten Taste auf der Tastatur entspricht.
.NET alleine kann mir da vermutlich nicht helfen, die Sendkeys-Klasse simuliert ja nur einen einmaligen Tastendruck mit anschließendem KeyUp. Das ganze in eine Schleife zu packen und damit sehr oft hintereinander auszuführen ist leider keine Option.
Bleibt wohl noch Pinvoke. Kennt ihr irgendeine Win32 Funktion, die sowas direkt erledigen kann? Auf pinvoke.net bin ich auf die Funktion keybd_event() gestoßen, welche (eigentlich) sher leicht WM_KEYDOWN und KEYUP Messages auswerfen können sollte. Afaik benutzt der Tastaturtreiber auch genau diese Funktion.
Leider haut das ganze nicht ganz hin:


[DllImport("user32.dll")]
public static extern void keybd_event(byte bVk, byte bScan, int dwFlags, int dwExtraInfo);

keybd_event((byte)Keys.A, 0, 0, 0);


Das haut mir nur genau einmal den Buchstaben a raus, obwohl der Aufruf eigentlich nur KEYDOWN darstellen soll.

Habe auch schon andere Datentypen versucht, aber ändert nix:


[DllImport("user32.dll")]
private static extern void keybd_event(byte bVk, byte bScan, uint dwFlags, UIntPtr dwExtraInfo);

keybd_event((byte)Keys.A, 0, 0, UIntPtr.Zero);


Eigentlich sollte ja erst der Aufruf keybd_event((byte)Keys.A, 0, KEYEVENTF_KEYUP, UIntPtr.Zero); das ganze beenden, (wobei KEYEVENTF_KEYUP = 0x0002). Oder hab ich da was falsch verstanden?


Was ist falsch bei mir, oder habt ihr bessere Alternativen?

Gast
2009-08-17, 15:47:10
Und warum nicht sendmessage?

http://www.pinvoke.net/default.aspx/user32.SendMessage

Gast
2009-08-17, 17:05:07
Der Grund warum ich keybd_event() benutzen wollte ist erstens dieser Artikel (http://blog.m-ri.de/index.php/2007/12/27/die-unsitte-tastatureingaben-mit-wm_keydown-nachrichten-zu-simulieren/).
Außerdem will Sendmessage ein WindowHandle, ich wollte jedoch selbst - also manuell mit der Maus - ein Programm focusen und das darin enthaltene Control anwählen, welches von meinem Code beliefert werden soll (Alles andere stelle ich mir zu schwierig vor, wie soll man z.B. Sendmessage sagen, dass es den Firefox anwählt und die gedrückte Taste allerdings weder an URL-Leiste, noch an Suchmaschinenbox rechts oben, sondern an die Seitendurchsuchung unten liefern soll.. ich meine ich kriege ja nichtmal das mit dem Gedrückthalten hin. Deshalb ist manuell auch ok).
Außerdem, wenn sogar der Tastaturtreiber keybd_event() benutzt, dann müsste das ja schon brauchbar sein, zumindest war das meine Logik :E
SendInput soll so eine Mischung sein von beidem, aber wenn ich mir da den Pinvoke-Eintrag anschaue, sieht das eher noch komplizierter aus.

creave
2009-08-18, 18:51:31
[DllImport("user32.dll")]
public static extern void keybd_event(byte bVk, byte bScan, int dwFlags, int dwExtraInfo);

keybd_event((byte)Keys.A, 0, 0, 0);




Dein Code funktioniert bei mir bestens!

Das haut mir nur genau einmal den Buchstaben a raus, obwohl der Aufruf eigentlich nur KEYDOWN darstellen soll.



Du musst genauer differenzieren.
Deine gewünschte Taste wird nun dauerhaft gedrückt. Warum du in Texteingabefeldern bei manueller Betätigung der Tastatur ohne erneuten Tastenanschlag ständig den selben Buchstaben erhälst, liegt an deren Autorepeatfunktion. Die "Taste gedrückt halten", das kannst du aber erfolgreich mit obigem Code umsetzen.