ChildGUI - zweite While-Schleife freezed random komplette Anwendung

  • Hallo zusammen,

    ich brauche mal wieder eure Hilfe.

    Eigentlich habe ich meinen Fehler bereits beseitigen können, aber nur durch Zufall und würde gerne verstehen warum es sich so verhält.

    Ich versuche in meiner GUI mithilfe eines Buttons ein zusätzliches Menü einzublenden, welches als eine Art Overlay über meine MainGUI gelegt wird.

    Eigentlich möchte ich genau das nachbauen was in der MetroGUI UDF gemacht wird.

    Aus persönlichen Gründen möchte ich MetroGUI aber nicht selbst nutzen.

    Um dieses Menü zu erstellen, wird in MetroGUI eine Child GUI erstellt und das mache ich ebenso.

    In der Child GUI werden einige Labels erstellt, die später auf ein OnEvent reagieren sollen (derzeit aber noch nichts machen).

    Derzeit stecke ich noch in einer frühen Phase fest, daher gibts auch noch keine weitere Funktion für dieses Menü.

    Sobald die Funktion für das Menü gecasted wird, wird die Child GUI erstellt und anschließend verweilt mein Script in einer neuen While-Schleife.

    Einmal wird das auch so in MetroGUI gemacht, zum Zweiten fand ich es sinnvoll dass damit mein Hauptscript pausiert wird.

    In der zweiten Schleife wurde ständig geprüft, ob die Child GUI noch aktiv ist (und bleibt in der Schleife), oder nicht mehr aktiv ist, dann wird die Child GUI wieder gelöscht , die Funktion gibt ein Return zurück und ich lande wieder in meinem Hauptscript.

    Mein Problem war folgendes:

    Sobald ich den Button gedrückt habe um die Funktion für meine Child GUI aufzurufen, passierte eine von zwei Verhaltensmuster und das leider zufällig und für mich unerklärlich.

    Verhaltensmuster 1:

    • Die Child GUI erschien mit ihren Labels und reagierte normal
    • Habe ich in meine MainGUI geklickt, oder außerhalb meiner kompletten Anwendung ist das Menü wieder geschlossen worden
    • (Genau so sollte sie sich verhalten)

    Verhaltensmuster 2:

    • Die Child GUI erschien zwar, aber es wurden KEINE labels erstellt (es existierte lediglich der Hintergrund der Child GUI)
    • Zudem war die Anwendung eingefroren... reagierte also nicht wenn ich in meine MainGUI geklickt habe (in der Loop Abfrage sollte erkannt werden, dass die Child GUI nicht mehr aktiv ist und diese schließen)
    • Klicke ich allerdings mit der Maus außerhalb meiner MainGUI, verschwand das Menü trotzdem (aber nur über diesen Weg)
    • Merkwürdigerweise befand ich mich, laut meinen Consolen Ausgaben auch in diesem Verhalten in meiner zweiten While-Schleife

    Jetzt würde ich gerne verstehen warum dieses Verhalten passiert, denn erklären kann ich es mir nicht.

    Es war wirklich zufällig was von den zwei Möglichkeiten passierte.

    Leider ist mein Script viel zu groß und Umfangreich, als das ich es hier posten könnte, aber die Funktion für die ChildGUI teile ich in abgewandelter Form.

    Achso... meine Lösung, womit alles so Funktioniert wie gewünscht ist folgende:

    Die ChildGUI habe ich Global markiert und deklariere sie vorher.

    Jetzt hab ich eine Funktion zum Checken der ChildGUI erstellt, die ständig in meiner Haupt-While-Schleife zusätzlich mit aufgerufen wird und prüft ob die ChildGUI existiert, wenn ja dann wird dort genauso geprüft ob diese aktiv ist, wie zuvor in der zweiten While-Schleife. Allerdings habe ich für diese Lösung die zweite While-Schleife gelöscht und nachdem das Menü erstellt wurde, beendet sich die Funktion für das Menü direkt wieder, damit ich in meine Haupt-While-Schleife lande.

    PS: Sorry fast vergessen.

    Ich befinde mich im OnEventMode.

    Einmal editiert, zuletzt von borsTiHD (12. Februar 2019 um 10:46) aus folgendem Grund: Beim Anpassen ein Fehler unterlaufen.

    • Offizieller Beitrag

    Jetzt würde ich gerne verstehen warum dieses Verhalten passiert, denn erklären kann ich es mir nicht.

    Kurz und knapp, gefunden hast du es ja selbst:

    Sowie du eine Funktion aufrufst, die eine (unendliche) Schleife ausführt, hast du natürlich nur noch ein 'Leben' in dieser Schleife. Du bist in der Funktion gefangen, keine anderen Ereignisse können registriert werden. Da hebelst du selbst die OnEvent-Funktionalität aus.

    Es darf nur eine MainLoop geben. In der ist alles abzuarbeiten.

  • Das ist mir zwar bewusst, aber das Verhalten kann ich mir dadurch leider weiterhin nicht erklären.

    Ich meine... wieso funktioniert es bei über 50% der Fälle mit der zweiten Schleife?

    Zudem wäre ja nur die Funktionalität meines Hauptscripts dadurch blockiert, aber die If Not WinActive($hGUI_Menu) sollte doch genauso in der zweiten Schleife funktionieren.

    Was mich aber noch weiter verunsichert ist, dass sich die ChildGUI zwar erstellt, aber im Fehlerfall "nur" die Hintergrundfarbe aufbaut... sämtliche Labels die ich in der For-Schleife erstelle sind nicht sichtbar. Durch mein _ConsoleLog (was im Grunde ein ConsoleWrite ist), sehe ich aber dass die Schleife trotzdem durchlaufen wird.

    Was zudem das Fass zum Überlaufen bringt (damit meine ich meinen Kopf ^^ ), ist die Tatsache, dass die MetroGUI UDF genau so damit umgeht, eine zweite Schleife produziert und für diese sogar temporär in den GUIMsg Modus wechselt. Wurde beispielsweise ein Item in dem Menü angegklickt, wechselt MetroGUI wieder zurück in den OnEvent Modus, schließt die Funktion und landet erst dann wieder im Hauptscript.

    Das macht mich richtig Konfus... ;(

    • Offizieller Beitrag

    und für diese sogar temporär in den GUIMsg Modus wechselt.

    Genau, so löst man das Problem, indem man die Auswerteroutinen trennt. In UDF sollte man interne Schleifen mit GUI-Auswertung immer in einem definierten Modus ausführen, d.h. gezielt zum OnEvent oder GuiGetMessage und nach Beenden zurück in den vorigen (vom User genutzen) Modus schalten. Ein Bsp. dafür ist z.B. _ArrayDisplay()

    Ich würde jetzt auch nicht mehr allzuviel Energie dafür aufwenden, warum in einem mit Fehlern behafteten Skript etwas nicht funktionierte. - Gleich die Fehlerquellen beseitigen.

    If Not WinActive($hGUI_Menu) sollte doch genauso in der zweiten Schleife funktionieren.

    Du hast den OnEventMode, dem es gewisssermassen schnurz ist, welche Schleife läuft, wenn ein Event ausgelöst wird. Aber da du in einem Outerloop & Innerloop läufst, ist niemals sicher welchem Event jetzt Vorrang gegeben wird. Saubere Trennung der Abläufe, damit DU genau weißt, was wann passieren muss und dein Skript das verarbeiten kann.

  • Hm... ok. Mir gefällt es zwar nicht, aber ich akzeptiere es einfach mal. :/

    Anders gesagt, bleibt mir wohl eh nichts anderes übrig.

    Allerdings hatte ich sogar zu Beginn den GuiGetMessage Modus temporär (nur für das Menü) drin, mit dem gleichen Problem. :|

    Aber davon mal abgesehen, habe ich gerade eine zweite Frage, was sogar früher ein ähnliches Symptom aufrufte.

    Ist das wechseln im Script zwischen GuiGetMessage/OnEvent nicht teufelszeug? Habe immer wieder gelesen das man ausschließlich in einem Modus bleiben soll.

    Ironischerweise hatte ich früher in meinem Script im Hauptabschnitt immer im OnEvent gearbeitet, aber für kleine Funktionen (beispielsweise für eine User Abfrage) kurzzeitig in den GuiGetMessage Modus gewechselt, mit eigenem Loop in der Funktion. Funktionierte damals auch wunderbar, bis zudem Zeitpunkt, an dem ich gerne Hover Effekte für meine selbsterstellten Buttons haben wollte.

    Um den Hover Effekt zu erzielen hatte ich vieles probiert... von eigenen Kreationen, bis hin zu verschiedenen UDFs. Derzeit nutzte ich die GUICtrl_SetOnHover UDF und bin sehr zufrieden damit. Jedoch bekam ich Probleme mit meinem OnEvent zu GuiGetMessage wechsel und die GUI frierte immer wieder ein, sobald ich einen Button betätigte, der eine GUI erstellte, die sich im GuiGetMessage Modus befand.

    Da ich zu dem Zeitpunkt nicht mehr auf den getesteten Hover Effekt verzichten wollte, hatte ich in den sauren Apfel gebissen und sämtliche Stellen, die bei mir in den GuiGetMessage wechselten auf den OnEvent umgeschrieben. Seit diesem Zeitpunkt erst lief bei mir das gesamte Script im OnEvent. ^^

    Im Nachinein würde ich dann sagen, das auch bei meinem obigen Problem aus dem ersten Post, wohl die UDF zu dem Phänomen führte (aber nur solange ich GuiGetMessage/OnEvent mischte - beim reinen OnEvent bleibt meine verdutztheit :P).

    €dit: Jedenfalls vielen Dank für deine Hilfsbereitschaft. :)

  • Ist das wechseln im Script zwischen GuiGetMessage/OnEvent nicht teufelszeug?

    Kann man schon machen, aber man verliert schnell den Überblick darüber, welche Fenster klickbar sind und welche nicht.

    Wenn man schon wechselt, sollte man darauf achten, dass alle anderen Fenster versteckt oder disabled sind, da ansonsten die Events nicht verarbeitet werden.

    Aber es ist nach wie vor das alte Problem, UDFs sind nicht konsistent. Einige arbeiten lieber mit einer Messageloop, einige widerum mit dem OnEventMode.

    Gäbe es eine einheitliche Wahl würde dieses Problem nicht existieren.

  • Ja verstehe, danke für die Erklärung.

    [...]Wenn man schon wechselt, sollte man darauf achten, dass alle anderen Fenster versteckt oder disabled sind, da ansonsten die Events nicht verarbeitet werden.[...]

    Kann es sein, das es deshalb zu diesem Verhalten kommt?

    Weil die MainGUI wurde bei mir in solchen Fällen nie versteckt, oder disabled.

  • Sorry fürs erneute Antworten, aber ich wollte nochmal kurz ein Feedback geben,

    Durch das "Enablen" und "Disablen" von den einzelnen GUIs in Verbindung mit GUISwitch() hat bei mir einige merkwürdige Verhalten entfernt.

    Danke nochmals euch Beiden für eure Hilfe. ;)

    Auf euch ist immer Verlass. :):thumbup:

    Thread kann geschlossen werden.