mikrocontroller.net

Forum: PC-Programmierung Fenstererkennung / Objekterkennung


Autor: Ben Inho (beninho)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

welche Möglichkeiten gibt es geöffnete Fenster zu erkennen? Hab mir 
überlegt als kleine Programmierübung ein Minesweeper-Lösungsprogramm zu 
schreiben. Am liebsten in C, evtl. auch C++. Jetzt frage ich mich, wie 
ich die einzelnen Felder erkennen kann. Oder wie ich zumindest schon mal 
das Minesweeper-Fenster erkennen kann.

Autor: Klaus Wachtler (mfgkw)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Es gibt eine Windows-Funktion EnumWindows(), mit der man sich
durch die Fenster hangeln kann.
Man muß sich selbst eine Funktion schreiben, die dann für
jedes gefundene Fenster einmal aufgerufen wird
(call back-Funktion). Diese kann sich dann über das Handle
des Fensters weitere Info holen (Titel etc.) und entscheiden,
ob es das gesuchte ist.

Autor: Rufus Τ. Firefly (rufus) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das ist eine Möglichkeit. Eine andere aber ist, Windows nach einem 
Fenster suchen zu lassen, wenn vom Fenster der Titel und/oder die 
Fensterklasse bekannt ist.

http://msdn.microsoft.com/en-us/library/ms633499%2...

Beides lässt sich mit Werkzeugen wie Spy++ herausfinden.

Autor: Tastendrücker (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Dein Vorhaben schreit doch förmlich nach AutoIt (www.autoitscript.com).

TD

Autor: Fenstergucker... (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das habe ich mal so gemacht:
while (!(GetKeyState(VK_SHIFT)&0x8000)) {}; // Mauszeiger auf gewünschtes Fenster setzen und auf SHIFT warten
POINT pt;
GetCursorPos(&pt);
hWnd=WindowFromPoint(pt);

Ziel war es, den Inhalt eines Fensters als Bitmap abzuspeichern.

Autor: MaWin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> while (!(GetKeyState(VK_SHIFT)&0x8000)) {};

Aktives blockieren eines Threads ?

100% Prozessorlast, weil man zu blöd ist, ein Ereignis (hier WM_KEYDOWN 
VK_SHIFT) programmtechnisch erfassen zu können ?

Das ist kein Vorbild, sicher nicht.

Autor: Fenstergucker... (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@MaWin
Trotz Deiner gemeinen Stichelei eine Antwort:

A. Mir Blödheit zu unterstellen ist eine Frechheit!
B. Hast Du schon mal ein kleines Programm geschrieben, weil Du in 5 
Minuten eine Lösung brauchtest, die letztendlich nur 1x eingesetzt 
wurde? Wenn Du in solchen Fällen immer alles absolut ideal 
programmierst, dann ziehe ich den Hut vor Dir und verbeuge mich so, dass 
mein Kopf fast den Fußboden berührt.
C. Ich habe nie behauptet, dieses Vorgehen sei vorbildlich. Um Dich zu 
zitieren: "sicher nicht".

Autor: Zwie Blum (zwieblum)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
MaWin schrieb:
>> while (!(GetKeyState(VK_SHIFT)&0x8000)) {};
>
> Aktives blockieren eines Threads ?
>
> 100% Prozessorlast, weil man zu blöd ist, ein Ereignis (hier WM_KEYDOWN
> VK_SHIFT) programmtechnisch erfassen zu können ?
>
> Das ist kein Vorbild, sicher nicht.

He, Windoofprofi, du weißt aber schon an welches Fenster WM_KEYDOWN 
geschickt wird, oder?

Autor: beninho (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke für die Vorschläge. Hab mich jetzt noch nicht wirklich damit 
beschäftigt, werde aber mal noch rumprobieren, vor allem Rufus Vorschlag 
klingt vielversprechend.
Ich habe mich jetzt mal willkürlich für C# entschieden, das hat auf den 
ersten Blick ein Stück einfacher als C++ ausgeschaut. Die Maus kann ich 
schon mal emulieren und damit die Felder öffnen.
Einen ersten einfachen Lösungsalgorithmus habe ich in C geschrieben.

Mein momentanes Problem ist jetzt, wie ich am besten die Zahlen, also 
den Bildschirminhalt abfragen bzw. die Bildschirmausgabe anzapfen kann. 
Ergoogeln konnte ich leider gar nichts in der Richtung. Meine einzige, 
sehr umständliche, Idee wäre, nach jedem Klick einen Screenshot zu 
machen und diesen als Bitmap abzuspeichern. Das muss doch irgendwie 
eleganter gehen?

Autor: Sven H. (dsb_sven)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wenn du C# nutzt solltest du für solche Windows Funktionen auf jeden 
Fall mal hier vorbei gucken:

http://www.pinvoke.net/

Da findest du (insbesondere bei user32 --> funktionen aus der 
user32.dll) viele Möglichkeiten mit Windows zu interagieren, die das 
.NET von Hause aus nicht mitbringt.

Autor: beninho (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich werd jetzt mal bei den Screenshots bleiben, Tastendrücken kann ich 
emulieren und danach versuche ich die Zwischenablage auszulesen. Mal 
schauen, ob das was wird.

Autor: beninho (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich bin immer noch an meinem Minesweeper-Solver. Dauert alles etwas, 
aber ich mache das ja auch eher nebenbei. Mein aktueller Stand:

Was so einigermaßen funktioniert:
1. Suche ein MineSweeper-Fenster mit FindWindow bzw. GetProcessesByName 
- Öffne eines, falls keines geöffnet ist.
2. Fenster in den Vordergrund bringen mit SetForegroundWindow
3. Größe und Position des Fensters bestimmen mit GetWindowInfo
4. Fenster an die Position (0,0) (= linkes, oberes Bildschirmeck) 
bringen
5. Screenshot des Fensters mit CopyFromScreen machen
(5b Screenshot mit .Save abspeichern)
6. Pixelfarbe einlesen mit GetPixel
7. Mausklicks emulieren mit mouse_event

Was noch fehlt:
- die Routinen, um die Felder zu erkennen und zu unterscheiden
- mit dem Lösungsalgorithmus verbinden
- Lösungsalgorithmus verbessern
- alles miteinander verbinden
- alles insgesamt verbessern

Mein momentanes Problem ist folgendes:
Ich verschiebe das Fenster (siehe 4.) und lasse mir die Koordinaten in 
Textboxes ausgeben (Code im Anhang). Die Koordinaten, die dort 
ausgegeben werden, sind allerdings die Koordinaten VOR dem Verschieben. 
Klicke ich ein 2.Mal auf den Button, führe den Code also ein 2.Mal aus, 
werden die richtigen Koordinaten ausgegeben. Für jemanden mit etwas 
Erfahrung ist der Fehler wahrscheinlich schnell gefunden, aber ich weiß 
nicht, was ich falsch mache.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.