Fenstererkennung / Objekterkennung

OP #1772551
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.
#1772695
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.
Gast #1773016
Lesenswert?

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

Ziel war es, den Inhalt eines Fensters als Bitmap abzuspeichern.
Gast #1773025
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.
Gast #1773053
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".
#1775932
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?
Gast #1850561
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?
Gast #1859513
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.
Angehängte Dateien:

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren