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.
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.
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%28VS.85%29.aspx Beides lässt sich mit Werkzeugen wie Spy++ herausfinden.
Dein Vorhaben schreit doch förmlich nach AutoIt (www.autoitscript.com). TD
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.
> 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.
@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".
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?
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?
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.
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.
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.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.