Fenstererkennung / Objekterkennung

OP #1772551
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
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
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
> 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
@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
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
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 #1851164
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.
Gast #1859513
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

Eine eigene Frage? Dieser Thread ist über 16 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.