Benutzer mit den meisten Antworten
Ist SendKeys überhaupt meine richtige Methode?

Frage
-
Hallo,
mit SendKeys komme ich irgendwie nicht an mein Ziel.
Ich habe in meinem Programm ein anderes Programm gestartet das mit der Tastenkombination INsert + Q beendet wird. Wenn ich diese Kombination selbst aus der Tastatur eingebe geht das.
Wenn ich dasselbe mit einem Button versuche klappt es nicht.
Da wird immer nur Q wahrgenommen:
Mein Code sieht so aus:
SendKeys.Send("Q{INSERT}")
Eigentlich sollte man dabei nicht viel verkehrt machen können. Aber leider klappt das nicht.
Kann mir jemand sagen wie es richtig ist?
Vielen Dank im Voraus Liebe Grüße Stefan- Typ geändert Robert BreitenhoferModerator Mittwoch, 24. Juni 2009 06:50 Frage Anstatt Diskussion
- Bearbeitet Robert BreitenhoferModerator Donnerstag, 10. Juni 2010 11:01 Formatierung
Antworten
-
Hallo Stefan,
es dürfte wohl auch das Insert ankommen. Und die Reaktion dürfte ebenso sein wie bei eigener Tastaturbetätigung: Betätigen und Lösen der Q-Taste, danach Betätigen und Lösen der Einfügen-Taste. Darauf wird die Anwendung wahrscheinlich ebenso wenig wie von Dir erwartet reagieren.
Eine Mögliche Alternative zu SendKeys ist SendInput, Beispiele findest Du z. B. unter http://www.pinvoke.net/default.aspx/user32.SendInput
Viel Erfolg!- Als Antwort markiert Mathias Schiffer Freitag, 26. Juni 2009 08:29
-
Hallo giftzwockel,
Dieser Ausschnitt sendet INSERT+Q (also INSERT hält man gedrückt, dann SHIFT und q machen den Q).
Const VK_INSERT = &H2D Const VK_SHIFT = &H10 Const VK_q As Long = &H51 Const KEYEVENTF_KEYUP As Long = &H2 keybd_event(VK_INSERT, 0, 0, 0) '//Insert nach unten drucken keybd_event(VK_SHIFT, 0, 0, 0) '//Shift nach unten drucken keybd_event(VK_q, 0, 0, 0) '//q nach unten drucken keybd_event(VK_q, 0, KEYEVENTF_KEYUP, 0) '//q freilassen keybd_event(VK_SHIFT, 0, KEYEVENTF_KEYUP, 0) '//Shift freilassen keybd_event(VK_INSERT, 0, KEYEVENTF_KEYUP, 0) '//Insert freilassen
Die Deklaration für keybd_event ist:
Private Declare Sub keybd_event Lib "user32" (ByVal bVk As Byte, ByVal bScan As Byte, ByVal dwFlags As Integer, ByVal dwExtraInfo As Integer)
Erstmals muss man das Fenster dem man die Tasten senden möchten im Vordergrund aufrufen.
Grüße,
- Als Antwort markiert Giftzwockel Montag, 29. Juni 2009 09:18
Alle Antworten
-
Hallo Stefan,
es dürfte wohl auch das Insert ankommen. Und die Reaktion dürfte ebenso sein wie bei eigener Tastaturbetätigung: Betätigen und Lösen der Q-Taste, danach Betätigen und Lösen der Einfügen-Taste. Darauf wird die Anwendung wahrscheinlich ebenso wenig wie von Dir erwartet reagieren.
Eine Mögliche Alternative zu SendKeys ist SendInput, Beispiele findest Du z. B. unter http://www.pinvoke.net/default.aspx/user32.SendInput
Viel Erfolg!- Als Antwort markiert Mathias Schiffer Freitag, 26. Juni 2009 08:29
-
Hallo giftzwockel,
Es kann sein das Du Die SendKeys an das falsche Programm sendest weil das andere Programm hat nicht den Focus.
Versuch mal das Fenster im Vordergrund zu bringen und dann zu diesem Fenster SendKeys zu senden.
Als Beispiel habe ich meinem Calculator eine 5 gesendet. Du änderst wo Calculator in meinem Beispiel steht mit dem ganzen Namen Deines Fensters. Den Namen des Fensters sieht man mit Alt+Tab.
Private Declare Function FindWindow Lib "user32.dll" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Int32 Private Declare Function SetForegroundWindow Lib "USER32.DLL" (ByVal hWnd As IntPtr) As Boolean Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click Dim myHandle As IntPtr = FindWindow(vbNullString, "Calculator") '//Hier mit dem Namen des Fesnters ändern SetForegroundWindow(myHandle) SendKeys.Send("5") End Sub
Grüße,- Bearbeitet Robert BreitenhoferModerator Mittwoch, 24. Juni 2009 07:50 Code Formatfehler
-
Hallo,
das kligt interessant, sollte es aber nicht sein, denn das Programm, das da abläuft ist ein speicherredidentes Programm für Blinde. Es hat keine Maske und führt einfach Testenbefehle aus, die grundsätzlich immer funktioniren (wie auch immer das geht). Egal ob ich Word nutze oder die VB IDE, das Programm liest alles aus (Screenreader) und spricht es. Wenn ich die Ansage ändern möchte drücke ich auf der Tastatur die entsprechende Tastenkombination und es klappt. Grundsätzlich hat daher eigentlich IMMER ein anderes Programm den Focus.
Ist denn mein Code richtig?
Ich probiere das aber gerne noch mal mit:Private Declare Function FindWindow Lib "user32.dll" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Int32 Private Declare Function SetForegroundWindow Lib "USER32.DLL" (ByVal hWnd As IntPtr) As Boolean Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click Dim myHandle As IntPtr = FindWindow(vbNullString, "Calculator") '//Hier mit dem Namen des Fesnters ändern SetForegroundWindow(myHandle) SendKeys.Send("{INSERT}Q") End Sub
Oder muss das ggf. SendKeys.Send({INSERT}"Q") heißen??
Vielen Dank im Voraus Liebe Grüße Stefan -
Hallo noch mal,
ich denke, mein Problem lieght wohl daran, dass die Tasten nicht nacheinander sondern zeitgleich gedrückt werden müssen.
Um die gewünschte Funktion an der Tastatur auszuführen muss ich also die Einfügentaste gedrückt halten und die Taste Q zusätzlich kurz drücken.
Das was ich momentan mache vehält sich wahrscheinlich eher so, dass mein Programm die Tasteneingaben nacheinander abarbeitet. Bei Alt + D geht das ja, weil Alt alleine schon in die Menüleite geht. Bei der Anwedund, die ich beeinflussen möchte geht das nur in der besagten Kombi.
Hat jemand eine Idee?
Vielen Dank im Voraus Liebe Grüße Stefan -
Hallo Stefan,
ja, das stimmt (und stand so seit vorgestern auch in der ersten Antwort in diesem Thread). Neben dem dort vorgeschlagenen SendInput kannst Du auch dessen Vorgänger keybd_event verwenden und damit die Tastenaktionen sequentiell abarbeiten. keybd_event sieht einfacher zu verwenden aus (für Dich als Einsteiger sicherlich willkommen) und steht auch auf älteren (nicht NT-basierenden) Windows-Plattformen zur Verfügung.
Viel Erfolg! -
Hallo giftzwockel,
Dieser Ausschnitt sendet INSERT+Q (also INSERT hält man gedrückt, dann SHIFT und q machen den Q).
Const VK_INSERT = &H2D Const VK_SHIFT = &H10 Const VK_q As Long = &H51 Const KEYEVENTF_KEYUP As Long = &H2 keybd_event(VK_INSERT, 0, 0, 0) '//Insert nach unten drucken keybd_event(VK_SHIFT, 0, 0, 0) '//Shift nach unten drucken keybd_event(VK_q, 0, 0, 0) '//q nach unten drucken keybd_event(VK_q, 0, KEYEVENTF_KEYUP, 0) '//q freilassen keybd_event(VK_SHIFT, 0, KEYEVENTF_KEYUP, 0) '//Shift freilassen keybd_event(VK_INSERT, 0, KEYEVENTF_KEYUP, 0) '//Insert freilassen
Die Deklaration für keybd_event ist:
Private Declare Sub keybd_event Lib "user32" (ByVal bVk As Byte, ByVal bScan As Byte, ByVal dwFlags As Integer, ByVal dwExtraInfo As Integer)
Erstmals muss man das Fenster dem man die Tasten senden möchten im Vordergrund aufrufen.
Grüße,
- Als Antwort markiert Giftzwockel Montag, 29. Juni 2009 09:18
-
Ich vermute mal, dass die Shift-Taste nicht betätigt werden muss, da wohl die Taste Q und nicht das Zechen Q gemeint war, diese Aufrufe könnten (und ggf. müssten) also entfallen. Da die Zielanwendung einen globalen Keyboard-Hook zu nutzen scheint, wird man keines ihrer Fenster (so sie denn überhaupt eines hat) in den Vordergrund holen müssen: keybd_event wirkt nicht nur anwendungsweit oder auf das Vordergrundfenster bezogen, sondern systemweit.
Falls es sich um eine kritische Anwendung handeln sollte, müsste man ggf. mit GetAsyncKeyboardState vorher testen, in welchem Zustand sich die Tastatur gerade befinden. Für den "Normalfall" mag das aber entbehrlich erscheinen.
Viel Erfolg! -
Hallo,
falls ich das Forum nicht schon nerve (sorry ich bin genervt). Ich habe nun tausend Tipps und alles scheint mir einleuchtend, aber nichts funktioniert.
Der Einwand mit der Taste stimmt. Es ist dem Programm das ich abwürgen möchte völlig egal ob ich ein Q oder ein q in Kombination mit der Einfügen-Taste drücke. Wenn ich es selbts über die Tastatur eingebe öffnet es den Beenden-Dialog des Programms.
Hier
keybd_event(VK_INSERT, 0, 0, 0) '//Insert nach unten drucken
keybd_event(VK_SHIFT, 0, 0, 0) '//Shift nach unten drucken
keybd_event(VK_q, 0, 0, 0) '//q nach unten drucken
oder
keybd_event(VK_INSERT, 0, 0, 0) '//Insert nach unten drucken
keybd_event(VK_q, 0, 0, 0) '//q nach unten drucken
tut es das nicht.
Ich habe mal versuchsweise auf meinen Button nur die Funktion
keybd_event(VK_SHIFT, 0, 0, 0) '//Shift nach unten drucken
gelegt, ein Eingabefeld benutzt und normal geschrieben (kleinbuchstaben) dann den Button gedrückt und geschrieben (= Großbuchstaben) fein, so solls doch auch sein. Dann habe ich das mit
keybd_event(VK_q, 0, 0, 0) '//q nach unten drucken
keybd_event(VK_q, 0, KEYEVENTF_KEYUP, 0)
'//q freilassen
gemacht. Wenn ich die Arbeitsweise verstanden habe, sollte dann in meinem Textfeld ein q stehen wenn ich den Button drücke.
Tut es aber nicht.
Wenn ich noch viele Haare hätte, würde ich sie mir ausraufen. Was läuft bei mir falsch (bitte nicht schreiben, das ich zu programmieren versuche ;-) )
Vielen Dank im Voraus Liebe Grüße Stefan -
Hallo Stefan,
nicht aufregen ;-) - was passiert, ist ganz normal:
Der Fokus, anders gesagt das aktive und Eingaben empfangende Steuerelement, verlagert sich mit dem Anklicken Deines Buttons auf diesen Button. Das bedeutet folgerichtig, dass das Textfeld Tastatureingaben gar nicht mehr annimmt. Denn diese Rolle des annehmenden Kandidaten hat ja jetzt der Button. Du kannst das einfach nachvollziehen, indem Du das Textfeld anklickst und dann die Tab-Taste so oft betätigst, bis der Button den Fokus hat (erkennbar an der gepunkteten Rahmenlinie). Wenn Du nun die Taste Q betätigst, passiert ebenso rein gar nichts. Ganz normal.
Was das andere Problem angeht: Viele Anwendungen reagieren nicht auf das Niederdrücken von Tasten, sondern auf das Lösen dieser Tasten (so wie ein Mausklick sich durch das Niederdrücken und Loslassen einer Maustaste ergibt, ist ein "Tastendruck" eben auch mehr als nur das Niederhalten der entsprechenden Tasten). Nach Einbringen des Codes für das Lösen der Tasten in der richtigen Reihenfolge solltest Du eigentlich Erfolg haben (zumindest bis zum Beenden-Dialog des Programms, den Du wahrscheinlich gar nicht angezeigt wissen willst - aber eines nach dem anderen).
Viel Erfolg! -
Hallo,
ok, ich lasse die Haare dort wo sie sind und versuche mich an die Gesetzmäßigkeiten (nette Umschreibung für Tücken) des Programmieren zu gewöhnen.
Ich hätte ja auch mit dem Radfahren anfangen können ;-).
Wenn ichs richtig verstanden habe, muss ich experimentell herausfinden, ob die Funktion aufs Drücken oder Loslassen der Taste reagiert.
Gut, mach ich.
Mit dem Rest hast du natürlich Recht, natürlich wird mein nächster Versuch dem gelten, den Dialog (vesuchsweise) zu unterdrücken. Schlimm wäre es aber nicht, wenn der Dialog erscheint. Schließlich hat sich jemand dabei was gedacht.
...richtiger Weg?
Vielen Dank im Voraus Liebe Grüße Stefan