Tech-Ecke / Delphi Inhalt / Maus- und Tastendruck auf/in fremder Anwendung simulieren |
|
Maus- und Tastendruck auf/in
fremder Anwendung simulieren
Wenn man sich in diversen Delphi-Foren auf die Suche nach "Tastedruck in fremder Anwendung simulieren" macht, so findet man eigentlich nur haufenweise Fragmente die einen als Anfänger mehr verwirren, als weiterhelfen. Dabei ist das Prinzip, wie man auf eine Fremde Anwendung zugreift zunächst mal nicht sonderlich schwer zu verstehen. Alles dreht sich um den Handle Wie die Oberfläche von Windows selbst, entstehen die allermeisten Anwendungen in einer objektorientierten Programmierumgebung. Diese bestehen aus einer Ansammlung von mehr oder weniger logisch ;-) verknüpften Objekten, wie Buttons, Editfeld, Listbox... usw. Beim Start der Anwendung wird jedem dieser Objekte, vom Betriebsystem eine eindeutige ID, in Form des Handle zugewiesen. Der Handle selbst ist ein Wert, der demnach ein bestimmtes Objekt im System eindeutig identifiziert. Über diesen kann man nun innerhalb des Systems direkt auf das entsprechende Objekt zugreifen, ohne dessen genaue Lage zu kennen. Genau hier setzt die hier beschriebene Methode an. Einzige Hürde ist nun den Handle herauszubekommen. Dank einer genialen Anwendung namens "WinSpy" von Thomas Stutz ist dies jedoch selbst für einen Anfänger kein großes Problem...
Handle einer Anwendung auslesen Möchte man in einer fremden
Anwendung, ein Ereignis auf ein Objekt auslösen, so benötigt man,
wie bereits erwähnt dessen Handle. An diesen kommt man z.B. über
den Objekt-Name ran. Jedoch kann man nicht direkt ein
x-beliebiges Objekt direkt auslesen, sondern man muss sich über
dessen Fenster und eventuell noch über weitere Objekte, bis an das gewünschte
Objekt heranpirschen. Zur besseren Verständnis mal ein
theoretisches Beispiel: Wir erzeugen in Delphi eine Form und
platzieren dort einen Button drauf. Möchte man nun extern in der
Laufenden Anwendung auf diesen Button zugreifen, so führt der
Weg zum Button über die Form, also das Anwendungsfenster. Liegt
dieser Button jedoch in einer GroupBox, so führt der
Weg von der Form über die GroupBox zum Button usw. Man
benötigt also zunächst den Objektnamen der Form, dann den der
GorupBox und dann den des Buttons. Ok, ist ja alles schön und
gut, aber woher bekomme ich denn jetzt die Objektnamen einer
Anwendung, die ich nicht geschrieben habe... Genau hier kommt WinSpy zum Einsatz, denn mit WinSpy
lässt sich der Objektname inklusive Handle, über ein 'Pipettenwerkzeug'
kinderleicht abgreifen. Aber damit
nicht genug, per Knopfdruck liefert das Programm auch
gleich ein komplettes Delphi-Source-Gerüst, auf dem man weiter
aufbauen kann. Zunächst geht es darum, den Objektnamen bzw. Handle der Anwendung zu finden, bevor man sich an die einzelnen Objekte in der Anwendung zu schaffen macht. OK, nachdem man Notepad (Start/Programme/Zubehör/Editor) und WinSpy gestartet hat, klickt man in WinSpy auf die Pipette (Fenster auswählen), hält die Maustaste gedrückt und zieht das erscheinende Fadenkreuz auf den oberen Fensterrahmen vom Notepad. Bitte nicht in das Eingabefeld!
Nun zeigt WinSpy, neben anderen Informationen auch den Objektname und den Handle für Notepad an. Jetzt kann man sich über "Tools/Code Generator..." einen Delphi-Code ausgeben lassen, welcher als Grundgerüst für die nächsten Schritte dienen soll. Der Code sollte wie folgt aussehen (ohne die grau hinterlegten Bemerkungen):
In dem Ausgabefenster des Codes befindet sich links oben der Button "Ausführen", betätigt man diesen, so erscheint für einen kurzen Augenblick ein flackerndes Rechteck um das ausgewählte Objekt. Dies geschieht mit dem Befehl FlashControl(). Man kann den Code auch hier schon editieren und testen, jedoch ist es ja Ziel den Code im eigenen Delphi Programm zu verwenden. Um den Code in Delphi zu übernehmen sollte man die grau hinterlegten Bemerkungen umsetzen.
Bei einem TButtonClick-Event sollte das in Delphi dann so aussehen:
Wird dieser Code nun ausgeführt (Notepad natürlich gestartet) , so erscheint, wenn alles geklappt hat folgendes Fenster.
Jetzt kommt der Tastendruck Ist man hier angelangt, so kann man nun Tastendrucksimulationen an das Notepad-Fenster senden. Zunächst wollen wir mal die Taste F5 simulieren, was im Notepad auch über das Menü, "Bearbeiten/Uhrzeit/Datum" erreicht wird. Hierzu ersetzen wir: ShowMessage('Window Handle: ' + IntToStr(wndMain)); gegen -> PostMessage(wndMain, WM_KEYDOWN, VK_F5, 0);
Window Child So, mit dem Fenster als solches kann man ja nicht viel anfangen, deshalb senden wir jetzt einmal eine Tastendrucksimulationen in das Editfeld von Notepad. Dazu benötigen man, wie Anfangs erklärt, neben dem Hande des Hauptfensters auch den Handle des Editfeldes. Das Editfeld, sowie alle Komponenten die darunter hängen (auch weitere Fenster) werden als "Window Child" bezeichnet. Hierzu bedienen wir uns wieder dem WinSpy, klicken aber diesmal direkt auf das Editfeld, dann wieder "Tools/Generator...", wodurch uns folgender Code ausgegeben wird:
Auch hier ist wieder das Gleiche abzuändern wie im ersten Beispiel, damit man es in seinem Delphi-Code verwenden kann. Das Ganze sieht dann in Delphi, hinter einem TButtonClick-Event so aus:
Um nun den Buchstaben "W" in das Editfeld zu schreiben, ersetzt man: ShowMessage('Window Handle: ' + IntToStr(wndChild)); gegen -> PostMessage(wndChild, WM_CHAR, Ord('W'), 0);
Senden eines kompletten Strings Möchte man durch mehrere Tastendrucksimulation einen ganzen String senden, so könnte das wie folgt aussehen:
Mausklicksimulation Bislang
haben wir ja nur einen Tastendruck simuliert und nun wird es Zeit für einen Mausklick. Zugleich kommt dann auch die nächste
Stufe, das "Window Child" dran, wofür man eine eigene Function
benötigt. Die Funktion (irgendwo vor dem eigentlichen Code im eigenen Programm platzieren):
Der eigentliche Code:
Möchte man nun auf den Abbrechen-Button, welcher sich hier als Button3 entpuppt einen Mausklick simulieren, so ersetzt man: ShowMessage('Window Handle: ' + IntToStr(wndChild)); gegen -> SendMessage(wndChild, BM_CLICK,0,0)
Zugabe Im Grunde
beschreiben diese Beispiele mal den generellen Weg, wie man an
einen Handle ran kommt und wie man über diesen einen Tastendruck
bzw. Mausklick lossendet. Der Handle wird übrigens für jede
Anwendung immer gleich ermittelt, sofern dies möglich ist. Die
Simulation eines Ereignisses, kann jedoch von Anwendung zu
Anwendung unterschiedlich aussehen und genau hier beginnt die
ganze Sache mit unter nervig zu werden. Zwei der häufigsten
Befehle wurden in den Beispielen bereits verwendet:
Weitere, interessante Befehle in diesem Zusammenhang sind:
Ereignisse
|
|||||||||||||||||||||||||||||||||||||||||
Die Option Drucken funktioniert erst ab Netscape V4.0 bzw. I-Explorer 5.0 !
[letzte Aktualisierung 24.01.2009]