Hallo,
in letzter Zeit habe ich von einigen Anfragen gelesen, bei denen nach der Möglichkeit zum Mausklick auf nicht per ControlClick() erreichbare "Buttons" gefragt wurde.
Beispiele sind Buttons auf Webseiten, oder ganz einfach ein Icon irgendwo auf dem Desktop.
Wie kann man trotzdem auf diese Elemente klicken?
Das Prinzip ist einfach. Der zu klickende Button (Bildausschnitt) wird "fotografiert" und abgespeichert. Soll dieser Button nun per Script geklickt werden, dann navigiert man z.B. im Browser auf die entsprechende Webseite und sucht auf dem Screen nach dem abgespeicherten Bild.
Alles das macht PushTheButton.
Enthalten ist eine größenveränderliche "Bildschirmlupe" zum genauen Bestimmen des zu findenden Buttons und eine Testfunktion.
Man kann mit PushTheButton die Bildausschnitte einfach erstellen und diese in eigenen Scripten weiterverwenden. Auch die Funktionen zur Suche vom Bild im Bild sind soooo langsam nicht.
Tip: Um die Größe des Auswahlfensters schnell zu verändern, sollte man erst (per Mausrad oder den +-Tasten auf dem NumBlock) zoomen und dann erst mit Ctrl-Alt-Pfeiltasten die Fenstergrösse verändern.
Mittlerweile werden auch animierte Buttons gefunden....z.B. dieser kleine Kerl^^
[Blockierte Grafik: http://www.abload.de/thumb/_ptb_01p33m.jpg]
WICHTIG! Um eine schnelle Suche zu gewährleisten muss in der obersten Zeile des Zoomfensters mehr als eine Farbe sichtbar sein, wenn gespeichert wird!
IMPORTANT! It is significant for a quick search that in the top line of the Zoomwindow is more than only one colour if the Zoomwindow is to be saved
Andy
//Edit 6/11/2011
Kleiner Bug behoben, großes Danke an peethebee!
Weiterer Bug von mir gefunden, bisher nicht gefixt: Wenn gleichzeitig mit der Suchfunktion von PushTheButton eine Datei geöffnet ist, die denselben Namen wie der gespeicherte zu suchende "Button" hat, dann KANN ein Fehler auftreten. Also besser nicht den Button speichern, dann z.B. Irfanview den gespeicherten Button anzeigen lassen und anschliessend die Suchfunktion starten.
//EDIT 19/10/2009
- English Help available, change language at the traymenu
- mehrsprachige Hilfe, Sprache im Traymenu einstellbar
- Fensterhandling verändert
- INI-Datei hinzugefügt für Sprache und Programm-Einstellungen
//EDIT 27/09/2009
Neue Version 1.33 :
- die Fenstergröße ist nun mit der Maus veränderbar (Fensterrand unten und rechts und die "Ziehecke" unten rechts, diese Funktion ist noch "optimierbar"^^)
- die Suchgeschwindigkeit der Bitmaps ist extrem erhöht (ca. Faktor 8-10), wenn die prospeed.dll im Verzeichnis des Scriptes liegt. (es gibt auch noch andere dll´s wie z.B. von prog@ndy um Bitmaps zu suchen).
Ich habe von der prospeed.dll nur zwei Funktionen verwendet, und zwar die schnelle Suche bzw den Vergleich von Bytes im Speicher. Daher auch die Struktur-Ungetüme im Script, denn
die ansonsten superschnellen AutoIt-Stringbefehle haben einige sehr heftige Geschwindigkeitseinbußen ab einer bestimmten Größe von Strings.
Wenn mir jemand den Grund dafür nennen könnte, wäre ich dankbar. Ich dachte bisher, die Strings würden in "normalen" Bytearrays abgelegt und sind somit schnell zu scannen...oder ist Assembler doch wesentlich schneller als C? *grins*
Ansonsten werden die "normalen" AutoIt-Funktionen zur Suche verwendet, zum Testen sind auch diese schnell genug^^, die prospeed.dll ist also NICHT zwingend erforderlich!
- Betrieb mit mehreren Monitoren ist nun möglich, THX an Funkey!
- man kann nun einen Dateinamen zum Speichern des "Buttons" angeben.
- ausgelagert wurde die Funktion _PtB_clickBMP(), welche die Suche in (sichtbaren) Fenstern erlaubt, incl. aller möglichen Mausclicks auf die gesuchte Bitmap. Siehe die Demo in der Downloaddatei.
- neu hinzugekommen ist der Moviemode, es ist nun möglich ANIMIERTE Buttons abzuspeichern (Bilderfolge Picname_0001.Bmp usw) und natürlich auch wiederzufinden...
- im Traymenu können nun einige Parameter eingestellt werden, z.B. der Mausversatz, um ein "highlighten" von Buttons beim Mouseover zu vermeiden
TODO:
Die Buttons sollen komplett aus der GUI verschwinden, Kontextmenu ftw, auch eine "richtige" Hilfe soll es geben
Speichern/Lesen der Bitmaps wahlweise auch in den gängigen Formaten JPG, TIf usw. ist wohl nur eine Kleinigkeit
Bisher ist mir noch keine seriöse (hehe) Anwendung einer "unscharfen" Suche begegnet, das kann aber ohne großen Aufwand implementiert werden
Das komplette Script ist downzuloaden, u.a. findet man dort auch eine DEMO, welche "eigenmächtig" den Startbutton auf XP-Systemen findet^^
In der Demo sind auch die verwendeten Such-Funktionen, welche man natürlich in eigenen Programmen verwenden kann.
autoit.de/wcf/attachment/14530/
Anhang:
Für die interessierten zum Thema: Suche vom Bild im Bild
Spoiler anzeigen
Ich wende zwei Verfahren an, um den Bildausschnitt zu finden. Das jeweils günstigste (schnellste) Verfahren wird schon zum Zeitpunkt der Auswahl des Bildausschnitts getroffen! Daher ist die Suche auch mit gewöhnlichen AutoIt-Befehlen ziemlich schnell.
Beim Abspeichern des Bildausschnitts wird für jede Pixelfarbe im Auschnitt die Anzahl der Pixelfarben auf dem Screen gespeichert. Das Pixel mit der wenigsten Anzahl Farben auf dem Screen wird der "Hotspot".
Je nach Anzahl der Farben dieses Hotspots wird nun ein Verfahren der Bildersuche gewählt.
Wenn es nur sehr wenige Pixel mit der Farbe des Hotspots auf dem Screen gibt, dann wähle ich die -Pixelsuche
Ja, das altbekannte Pixelsearch() kommt zum Einsatz. Das "Hotspot"-Pixel wird im gesamten Bildschirminhalt gesucht, und der Bereich rund um das gefundene Pixel wird mittels PixelChecksum() mit dem Bildausschnitt verglichen.
Wenn aber die Farbe des Hotspots sehr oft auf dem Bildschirm vorkommt (z.B. schwarzer Text auf weißem Hintergrund), dann bietet sich die -Bitmapsuche an. Dafür hole ich etwas weiter aus^^
Im großen und ganzen sind die (24Bit-Windows BMP)-Bitmapdaten aufgrund ihrer Struktur (Freud lässt grüßen^^, DllStruct ist dein Freund) sehr einfach zu behandeln. Die Bitmapdaten liegen als Folge von Bytes vor, wobei jeweils 3 Bytes die Grundfarben für ein Pixel darstellen. Jedes Pixel wird also durch einen Blau-, Grün-, und Rot-Anteil dargestellt.
Die Bitmapdaten kann man sich als String mit der Länge Bildbreite*Bildhöhe*3 (3 Farbbits pro Pixel) vorstellen.
Also sieht der "Pixelstring" einer Bitmap etwa so aus: $Bitmap="BGRBGRBGRBGR....", wobei B der Blauanteil, G der Grünanteil und R der Rotanteil EINES Pixels ist.
Jede der einzelnen Farben kann 256 Abstufungen enthalten (ein Byte = 8 Bit). Um jetzt ein (oder auch mehrere aufeinanderfolgende) Pixel innerhalb der Bitmap zu finden, muss man nur im $Bitmap-String nach der Folge der 3 Farbbits suchen. Das geht in AutoIt sehr fix mit dem StringInstr()-Befehl.
Man unterteilt also den Bildausschnitt in "Bildzeilen", und sucht nun per StringInstr() in der gesamten Screen-Bitmap eine Übereinstimmung der ersten Zeile. Wenn eine Übereinstimmung gefunden wurde und die 2.Ausschnittzeile GENAU unter der Fundstelle liegt (das ist die Position im String, welche 3*Bildbreite "dahinter" liegt) und die nächste und die nächste usw. alle übereinstimmen, dann hat man den Bildausschnitt gefunden.
Das funktioniert natürlich nur dann sehr schnell, wenn die "oberste" Zeile des Bildausschnitts nicht sehr oft im gesamten Bildschirm vorkommt.
Beispiel dazu: Monochrombildschirm, X ist weiss, O ist schwarz
Wir haben den gesamten Bildschirminhalt
XXXXXXXXXXXX
XXXXXXXXXXXX
XXXXXXTXTXXX
XXXXXXTXTXXX
Es soll auf den folgenden "Button" geklickt werden (im Bildschirm in den untersten beiden Zeilen)
TXT
TXT
wenn ich nun als Bildausschnitt z.B.
XXTXTXX ;erste zeile
XXTXTXX ;zweite Zeile
auswähle, dann wird die erste Zeile sofort (per stringinstr()) im Gesamtbildschirm gefunden, die Prüfung auf die 2. Zeile ergibt den Treffer, der Button ist schnell gefunden
ABER
wenn als Bildausschnitt
XXX ;erste Zeile
TXT ;zweite Zeile
gewählt wird, dann dauert die Suche sehr lange. Denn wir erhalten sehr viele Treffer für die erste Zeile des Ausschnitts im Screen und müssen immer eine Zeile darunter nachschauen, ob dort auch die zweite Zeile übereinstimmt.
Also ist die Suchgeschwindigkeit direkt proportional zur Intelligenz dessen, der den Bildausschnitt auswählt^^. In der Regel findet aber die Testroutine den Ausschnitt in einigen Hundertstel-(!) bis maximal Zehntelekunden.
Die Suchroutine in PushTheButton scrollt sogar im aktuellen (Browser-)Fenster nach unten, um in der bis dahin "unsichtbaren" Bildschirmdarstellung den Button zu finden