[Need Help]Warten bis ein Fenster offen ist
-
Hallo an alle ,
Gibt es eine möglichkeit ohne einen Sleep() befehl zu warten ,bis ein Bestimmtes Fenster geöffnet ist?Ich gebe grade mal ein Beispiel da es für viele unverständlich sein wird was ich meine .System("notepad.exe);
// Now i need a way to wait until the window is open
HWND hwnd = FindWindow(0,L"Editor");Ich brauche halt einen weg zu warten bis das Fenster auch offen ist ,damit ich mit FindWindow es auch finden kann, denn ohne den Sleep befehl ist das Programm natürlich zu schnell und öffnet das Programm ,da dieses aber erst eine kurze ladezeit braucht um aufzugehen findet er ohne Sleep kein Fenster ,da er wie gesagt zu schnell die Befehle abarbeitet.Da die Sleep methode aber wie ich finde sehr unelegant ist wäre die Frage ob es einen WinApi Befehl zum Watrten auf ein bestimmtes Fenster gibt.
-
Was genau gedenkst du zu tun, wofür musst du überhaupt das Fenster suchen? Bei solchen Ansätzen handelt es sich in aller Regel bestenfalls um extrem windige Hacks, auf keinen Fall jedoch um eine stabile und brauchbare Lösung. Um das zu illustieren: Selbst wenn es einen Weg gäbe, zu warten bist das Fenster offen ist, sobald der Titel des Fensters nicht mehr Editor ist, also z.B. sobald die Systemsprache nichtmehr English ist, bricht schon alles zusammen...
-
dot schrieb:
Was genau gedenkst du zu tun?
Ich habe nen Relogger angefangen zu schreiben für ein Spiel ,welcher wenn der Client sich schließt ihn dauerhaft jedes mal wenn das passiert wieder öffnet.
Im moment nutze ich die Sleep methode die ich sehr unelegant finde hier ist mal mein code ,TUT mir echt leid ,dass ich ihn nicht in nem codefenster poste ,da mir nie jmd gesagt hat wie ich das mache habs auch schon paarmal hier probiert aber klappt nienaja hier der code:
#include <iostream> #include <windows.h> int main () { int e; HWND hwnd; int i = 1; while (i==1) { hwnd = FindWindow(0,L"METIN2"); if (hwnd) { std::cout << hwnd << std::endl; std::cout << "Fenster wurde gefunden" <<std::endl; SetWindowTextA(hwnd,"NeuesFenster"); while ( e = IsWindow(hwnd)) { } system("start.bat"); Sleep(7000); } else { std::cout <<"Fenster nicht gefunden"<< std::endl; std::cout <<"Offne das Fenster" << std::endl; break; } } std::cin.get(); }
-
Naja, Sleep und eine Schleife ist eine Lösung, oder man könnte vielleicht mit nem globalen Message Hook auf die entsprechende WM_CREATE lauschen. Was du vor hast fällt eben in den Bereich der Dinge, die ein modernes Betriebsystem eigentlich aktiv zu unterbinden versucht, weshalb sich wohl kaum eine saubere Lösung dafür finden lässt...
Bezüglich "Codefenster": Pack den Code in Code Tags, also z.B.: [cpp]hier dein code[/cpp ].
-
dot schrieb:
Naja, Sleep und eine Schleife ist eine Lösung, oder man könnte vielleicht mit nem globalen Message Hook auf die entsprechende WM_CREATE lauschen. Was du vor hast fällt eben in den Bereich der Dinge, die ein modernes Betriebsystem eigentlich aktiv zu unterbinden versucht, weshalb sich wohl kaum eine saubere Lösung dafür finden lässt...
Bezüglich "Codefenster": Pack den Code in Code Tags, also z.B.: [cpp]hier dein code[/cpp ].
Vielen Dank für die erklärung das mit Code Tags klappt einwandfrei
Naja nur bei Sleep ist das Problem was ist , wenn der Anwender einen langsamen Pc hat und die Sleep zeit welche ich ja auch nicht zu lange machen will ,da das Programm sonst zu langsam wird nicht ausreicht.Dann würde es schon wieder nen Fehler geben. Gibt es keinen Befehl ,um z.b. wie mit System() erst ein Programm zu starten ,und dann darauf zu warten bis das fenster offen ist?Denn bei dem Spiel z.b. wo ich es für Programmiert habe lädt erstmal das hackshield ca 4sek durch ,und erst dann startet das Fenster.
-
DerNoob1993 schrieb:
Gibt es keinen Befehl ,um z.b. wie mit System() erst ein Programm zu starten ,und dann darauf zu warten bis das fenster offen ist?
Nein, das Problem dabei fängt schonmal damit an, zu definieren, was genau "das Fenster" überhaupt sein soll. Ein Prozess unter Windows kann beliebig viele Fenster haben, 1 und 0 sind genauso Möglichkeiten wie 2000. Eine typische Konsolenanwendung hat z.B. gar kein Fenster (das Konsolenfenster gehört einem Systemprozess). Es gibt also im Allgemeinen rein prinzipiell nicht "das Fenster" und die Frage nach einer Funktion, die auf "das Fenster" wartet ist damit von vorn herein sinnlos...
-
dot schrieb:
DerNoob1993 schrieb:
Gibt es keinen Befehl ,um z.b. wie mit System() erst ein Programm zu starten ,und dann darauf zu warten bis das fenster offen ist?
nein
Das ist allerdings sehr schade
Hab grad nen anderen einfall gehabt ich kann es ja einfach so umschreiben , dass wenn ich findWindow in ne endlos while schleife packe ,und dann wenn das fenster gefunden wird meine Befehle abarbeiten lasse, wenn es nicht gefunden wird mache ich ein ein break ,und springe wieder in die while schleife sodass er das Fenster von neuem sucht könnte funktionieren ^^Edit: Bei AutoIt gibts ja auch ne ähnliche Function die wartet ,bis ein Fenster gestartet wurde http://www.autohotkey.com/docs/commands/WinWaitActive.htm von daher dacht ich das wäre möglich ^^
-
Ich sagte nicht, dass es rein prinzipiell Unmöglich ist auf ein Fenster zu warten. Eine Möglichkeit, nämlich die Schleife mit Sleep und FindWindow, hast du ja auch selbst schon gefunden und ich bin mir sicher, dass es noch viele weitere gibt. Spontan könnte ich mir z.B. eben einen globalen Message Hook, der auf das WM_CREATE bzw. WM_ACTIVATE wartet, oder z.B. die Möglichkeit, CreateWindowEx per DLL Injection durch eine eigene Funktion zu ersetzen vorstellen. Es gibt aber sicherlich keine API Funktion, die direkt derartige Funktionalität bietet. Wieso schreibst du dein Programm eigentlich nicht einfach mit AutoIt?
-
dot schrieb:
Ich sagte nicht, dass es rein prinzipiell Unmöglich ist auf ein Fenster zu warten. Eine Möglichkeit, nämlich die Schleife mit Sleep und FindWindow, hast du ja auch selbst schon gefunden und ich bin mir sicher, dass es noch viele weitere gibt. Spontan könnte ich mir z.B. eben einen globalen Message Hook, der auf das WM_CREATE bzw. WM_ACTIVATE wartet, oder z.B. die Möglichkeit, CreateWindowEx per DLL Injection durch eine eigene Funktion zu ersetzen vorstellen. Es gibt aber sicherlich keine API Funktion, die direkt derartige Funktionalität bietet. Wieso schreibst du dein Programm eigentlich nicht einfach mit AutoIt?
Weil ich ne vernünftige Sprache lernen will
Es geht mir nicht nur um den Relogger das ist halt ne kleine Spielerei die ich nacher auch ab und zu verwenden kann ,sondern mehr darum einfach bisschen dabei auch zu lernen weil nur mein Buch zu büffeln hat kein Sinn man muss auch was mehr oder weniger sinnvolles Programmieren um es richtig zu lernen ,weil ich mal denke nur durch Bücher büffeln kann man nicht programmieren lernen man muss es auch tun.Und da ich grade C++ lerne und angefangen habe mich mit der WinApi zu beschäftigen ist sowas eigentlich gut geiignet um einzusteigen ^^.
-
Wenn du dich mit der WinAPI beschäftigen willst, dann würde ich dir dazu raten, etwas anderes zu machen, ka, z.B. ein kleines Zeichenprogramm oder so. Denn was dein momentanes Vorhaben betrifft, so gibt es da vermutlich genau zwei Möglichkeiten: Die handfeste Variante übersteigt die Fähigkeiten eines Anfängers vermutlich um einige Größenordnungen und die einfache Variante ist so unsauber, dass man dabei kaum was gutes lernen wird...
-
DerNoob1993 schrieb:
Und da ich grade C++ lerne und angefangen habe mich mit der WinApi zu beschäftigen ist sowas eigentlich gut geiignet um einzusteigen ^^.
Nee. Lass das bleiben. Wenn du C++ lernen willst, must du das richtig lernen, das kann man nicht "halb" oder nebenbei lernen. Auch learning by doing funktioniert hier kaum. Dir wird kaum was anderes übrig bleiben, als Bücher zu lesen und die Grundlagen intensiv zu lernen.
Auf WinApi kann man eigentlich sehr gut verzichten, außer für so spezielle Sachen wie das was du grad vorhast. Aber das braucht man im Real Life sehr selten, und wenn, dann schaut man sich das dann halt kurz an. Jetzt abgesehen von diesem Projekt wär mein Rat, die WinApi erstmal zu ignorieren.
-
Mechanics schrieb:
DerNoob1993 schrieb:
Und da ich grade C++ lerne und angefangen habe mich mit der WinApi zu beschäftigen ist sowas eigentlich gut geiignet um einzusteigen ^^.
Nee. Lass das bleiben. Wenn du C++ lernen willst, must du das richtig lernen, das kann man nicht "halb" oder nebenbei lernen. Auch learning by doing funktioniert hier kaum. Dir wird kaum was anderes übrig bleiben, als Bücher zu lesen und die Grundlagen intensiv zu lernen.
Auf WinApi kann man eigentlich sehr gut verzichten, außer für so spezielle Sachen wie das was du grad vorhast. Aber das braucht man im Real Life sehr selten, und wenn, dann schaut man sich das dann halt kurz an. Jetzt abgesehen von diesem Projekt wär mein Rat, die WinApi erstmal zu ignorieren.Naja alleine um später win32 anwendungen erstellen zu können muss ich mich nebenher auch bisschen mit der WinApi beschäftigen und ja natürlich lerne ich mit nem Buch c++ ,aber es muss meiner meinung nach ne gesunde mischung aus Bücher lesen , und bisschen selbst ausprobieren sein.
-
DerNoob1993 schrieb:
Gibt es eine möglichkeit ohne einen Sleep() befehl zu warten ,bis ein Bestimmtes Fenster geöffnet ist?Ich gebe grade mal ein Beispiel da es für viele unverständlich sein wird was ich meine .
System("notepad.exe);
// Now i need a way to wait until the window is open
HWND hwnd = FindWindow(0,L"Editor");Starte das Programm nicht mit System(..., sondern mit CreateProcess, Du bekommst dann ein Prozesshandle und kannst dann mit
http://msdn.microsoft.com/en-us/library/windows/desktop/ms687022(v=vs.85).aspx
warten, bis die Anwendung initialisiert ist.
-
Eigentlich braucht man dazu keine großen Tricks.
Es gibt ja WaitForInputIdle, das für so etwas ja gebaut wurde.
http://msdn.microsoft.com/en-us/library/windows/desktop/ms687022(v=vs.85).aspxDamit startet man einen Prozess und kan warten bis der Prozess eben auf eingaben wartet... dann sollten auch die Fenster da sein.
-
Belli schrieb:
DerNoob1993 schrieb:
Gibt es eine möglichkeit ohne einen Sleep() befehl zu warten ,bis ein Bestimmtes Fenster geöffnet ist?Ich gebe grade mal ein Beispiel da es für viele unverständlich sein wird was ich meine .
System("notepad.exe);
// Now i need a way to wait until the window is open
HWND hwnd = FindWindow(0,L"Editor");Starte das Programm nicht mit System(..., sondern mit CreateProcess, Du bekommst dann ein Prozesshandle und kannst dann mit
http://msdn.microsoft.com/en-us/library/windows/desktop/ms687022(v=vs.85).aspx
warten, bis die Anwendung initialisiert ist.Danke danach habe ich gesucht
Noch ne frage zu CreateProcess() ,da ich bisschen Probleme dabei habe alle Parameter zu verstehen .(CreateProcess(NULL , "Metin2.exe", NULL, NULL, TRUE, 0, NULL, NULL, &info, &processInfo)
Wenn ich das hier Eingebe ist der 2te Parameter ( der string "Metin2.exe") rot unterstrichen und es wird mir gesagt der Typ const char ist mit dem Parameter vom Typ LPCWSTR ungültig . Wie kann ich denn nun sonst meinen String ( den namen des Programms welches gestartet werden soll) an die Funktion übergeben ?
-
Hau ein L vor das ""-Literal:
FunctionXY(L"SomeString");
Oder fasse es in TEXT()/_T() ein. Letzeres ist die sauberere Variante, da du den Projekt-Zeichensatz ohne Probleme aendern koenntest. Allerdings sollte dafuer kein Bedarf sein, so dass alle 3 Varianten funktionieren. Such dir eine aus. :p
-
(CreateProcess(NULL , TEXT("Metin2.exe"), NULL, NULL, TRUE, 0, NULL, NULL, &info, &processInfo);
Wobei Du möglicherweise aber auch den vollen Pfad zum Programm angeben musst, also zB TEXT("c:\\Programme\\Spiele\\Metin2"), das hängt davon ab, wo die Datei liegt, wo Dein Programm liegt, wie das aktuelle Arbeitsverzeichnis ist, usw.
Also am besten voll qualifiziert angeben, dann bist Du auf der sicheren Seite.
-
Danke euch beiden das klappt schonmal ^^ allerdings habe ich wohl irgendwo noch was falsch gemacht , da beim ausführen der datei immer ne Fehlermeldung kommt das mein Programm nicht richtig funktioniert
hier ist mal mein testprogramm für die Funktion
#include <iostream> #include <Windows.h> int main() { PROCESS_INFORMATION processInfo ; STARTUPINFO info ; // Create the process CreateProcess(NULL ,L"C:\Metin3\Metin2.exe", NULL, NULL, TRUE, 0, NULL, NULL, &info, &processInfo); std::cin.get(); }
Wenn irgendjemand mir sagen könnte was ich da falsch gemacht habe wäre echt klasse ,da ich grad nicht durchblicke was ich falsch gemacht haben soll
Das hier gibt mein Compiler aus ( er erstellt die Datei aber gibt warnungen aus)
1>------ Erstellen gestartet: Projekt: CreateProcFunc, Konfiguration: Debug Win32 ------
1> CrateProcFunc.cpp
1>c:\users\marius\documents\visual studio 2010\projects\createprocfunc\crateprocfunc.cpp(14): warning C4129: 'M': Nicht erkannte Folge von Escapesequenz
1>c:\users\marius\documents\visual studio 2010\projects\createprocfunc\crateprocfunc.cpp(14): warning C4129: 'M': Nicht erkannte Folge von Escapesequenz
1> CreateProcFunc.vcxproj -> C:\Users\Marius\Documents\Visual Studio 2010\Projects\CreateProcFunc\Debug\CreateProcFunc.exe
========== Erstellen: 1 erfolgreich, Fehler bei 0, 0 aktuell, 0 übersprungen ==========
-
Mit dem Prozesshandle kannst Du übrigens auch sehr einfach auf das Ende des entsprechenden Prozesses warten (ich meine, diese Anforderung von Dir in einem anderen Thread gesehen zu haben - falls nicht, einfach ignorieren):
http://msdn.microsoft.com/en-us/library/windows/desktop/ms687032(v=vs.85).aspx
-
Mit \ sagst du dem Compiler, dass du Sonderzeichen willst. '\n' ist zum Beispiel ein Newline-Zeichen. Er weiß aber nicht was \M ist. Du willst \\ statt \ benutzen, das bedeutet dann, dass es das echte Zeichen \ und nicht das Sonderzeichen ist.
L"C:\\Metin3\\Metin2.exe"