Skalierende Message Box

  • Lade doch mal SciTE4AutoIt3 und öffne das Skript darin. Dann starte dein Beispiel mal nachdem du "Button 3" in "" geändert hast. Was zeigt dir die Konsole an?

    Das Problem ist hier mehr, dass du jeden weiteren Button nur auf sich selbst prüfst. Wenn der Button-Text nicht leer ist, gehst du davon aus, dass auch die vorigen gefüllt waren. Dein Skript stürzt ab.

    Das musst du nicht direkt korrigieren. Immerhin kannst du auch einen klar denkenden Nutzer erwarten. Aber es könnte schon sein, dass das mal jemand versucht, weil er vllt. einfach den Abstand zwischen den Buttons möchte oder so. Da fehlt etwas das Fehler-Handling dahingehend das sich mal ein Nutzer anders verhält als du erwartest. Aber das sind jetzt einfach Gedanken zu möglichen Verbesserungen (und möglichen Kürzungen des Skripts). Prinzipiell kann jemand, der das Skript hier findet und eine Message Box mit eigenen Buttons braucht, das Ding auch verwenden und ist glücklich. Daher will ich nicht vergessen zu sagen, danke fürs teilen :thumbup:

    Gerne doch, und danke für die Hilfe.

    Wenn ich den Button 3 rausnehme stürzt mein Script ab, weil der Button 3 = "" ist wurde er nicht berechnet und fehlt somit bei der Berechnung für die Position von Button 4 :D


    Du kannst gerne meinen letzten Post nochmal lesen, den hab ich mehrfach editiert.

    Gibt es ein Referenz wo ich den Zusammenhang zwischen GUI FONT und GUI Größe finde wäre das gut.

    Also GUI Größe = LängsteTextzeile (z.B 20 Zeichen) X GUIFONT(z.B 12) + (Textzeile Position 1 x 2 {z.B 20 x 2})

    Das man so immer den selben Abstand Links und Rechts erhält egal wie lang die Zeile ist.

  • Alles klar. Jetzt habe ich deine Edits gelesen. Ich wünsche dir viel Erfolg. Ich denke auch, die Arrays werden funktionieren und du schaffst das. Falls du Probleme hast und nicht weiter kommst, melde dich einfach hier

    Also GUI Größe = LängsteTextzeile (z.B 20 Zeichen) X GUIFONT(z.B 12) + (Textzeile Position 1 x 2 {z.B 20 x 2})

    Das kannst du einmal ganz einfach selber ermitteln. Dafür gibt es die Funktion StrinLen. Damit kannst du dir die Anzahl der Zeichen des Strings ausgeben lassen und entsprechend reagieren.

    (Wenn man alles bedenken möchte, müsste man auch noch weitere Parameter berücksichtigen. Etwa die verwendete Schriftart (bei dir jetzt kein Problem, weil du die gar nicht editierst, wenn ich das nicht übersehen habe) oder die Bildschirmskalierung (Wenn jemand die Texte in Windows als grundsätzlich größer skaliert eingestellt hat - machen bspw. Leute an Fernsehern oder mit Laptop mit sehr hoher Auflösung). Das war jetzt aber ein nicht soo wichtiger Hinweis.

    Was du dir mal anschauen könntest wäre: https://www.autoitscript.com/forum/topic/11…sion-16-aug-11/

    EDIT:

    Das man so immer den selben Abstand Links und Rechts erhält egal wie lang die Zeile ist.

    Dafür kannst du den Style: $SS_CENTER benutzen.

    Grüße autoiter

  • autoiter

    Hab mir mal einen "ErrorHandle" überlegt.

    Funktioniert wunderbar, ist aber wohl nicht ganz so elegant :D

  • Klingt sehr interessant, das wird den Job wohl erledigen. Ich hatte den GUI Font eingebaut und benutze ihn auch zur Berechnung, führt nur leider zu schlechten Ergebnissen wenn ich den User ihn ändern lasse.

    Okay $SS_CENTER ist gut , dann hab ich quasi GuiWidth = StrinLen($Line1) + z.B $ButtonSeperator(Sieht gut aus dann haben alle Buttons den selben Abstand zum Rand und zueinander.

    ich lege dann vorher die maximal breite des fensters mit anzahl der buttons und der buttongröße fest und mache dann einen Zeilenumbruch oder vergrößere die Zeile entsrechend?


    Ich will auch erstmal ausprobieren dann benutze ich den Link glaube ich erst. Mal sehen.


    edit: das mit den for schleifen muss ich auch noch lernen :D

    Einmal editiert, zuletzt von xTcisloVe (3. Juli 2018 um 19:18)

  • Kannst du so machen. Aber als Hinweis:

    AutoIt
    Local $ErrorHandle1 = 1
    Local $ErrorHandle2 = 1
    Local $ErrorHandle3 = 1
    Local $ErrorHandle4 = 1
    if $Button2 = "" Then Local $ErrorHandle1 = 0
    if $Button3 = "" Then Local $ErrorHandle2 = 0
    if $Button4 = "" Then Local $ErrorHandle3 = 0
    if $Button5 = "" Then Local $ErrorHandle4 = 0

    Hier deklarierst du ein Variable (bspw. $ErrorHandle1) Local. Danach prüfst du sie auf ihren Inhalt und deklarierst sie erneut Local.

    Damit erstellst du eine neue Variable!

    Das fällt dir hier noch nicht auf die Füße. Aber das wird dir zwangsläufig mal passieren. Schau dir mal die Hilfe zu Global, Local, usw. an. Die Hilfe gibt es hier im Forum übrigens auf Deutsch (Dashboard oben rechts).

    Wenn du einer bereits deklarierten Variable einen neuen Wert zuweisen möchtest, dann geht das hier so: $ErrorHandle1 = 0. Also einfach ohne Deklaration.

    Zu deiner Fehlerbehandlung ein Vorschlag.

    Für am besten hielte ich Controls in Arrays gespeichert. Aber das kannst du dir ja mal bei Gelegenheit anschauen.

    Es wäre z.B. möglich, dass du mit dem letzten möglichen Button beginnst, statt mit dem ersten. Dann vergibst du einen Pseudo-Wert wenn der Button nicht vergeben ist und entsprechend entweder die Größe 0 oder deine allgemeine Button-Größe. So solltest du das wohl unter einen Hut kriegen können. (Bei einem Array könnte das auch in einer For To-Schleife ablaufen. Bspw:For $i = UBound($aButtons) -1 To 0 Step -1

    Grüße autoiter

  • Du solltest dir mal die UDF _ExtMsgBox anschauen, denn aus dem Code kannst du sicher einiges für dein Projekt extrahieren, vor allem die Übergabe der Parameter.

    Hier mal ein Script (inkl. Demo) von @Yashied, dass ich an einigen Stellen korrigiert habe und mit dem die benötigte Breite und Höhe von Texten (auch mehrzeilige und auch mit Tabs) in Pixeln ermitteln werden kann.

    Einmal editiert, zuletzt von Bitnugger (5. Juli 2018 um 11:12)

  • Du solltest dir mal die UDF _ExtMsgBox anschauen, denn aus dem Code kannst du sicher einiges für dein Projekt extrahieren, vor allem die Übergabe der Parameter.

    Hier mal ein Script (inkl. Demo) von @Yashied, dass ich an einigen Stellen korrigiert habe und mit dem die benötigte Breite und Höhe von Texten (auch mehrzeilige und auch mit Tabs) in Pixeln ermitteln werden kann.

    Danke jetzt erst gelesen, ich werde es mir mal ansehen!

  • Dein UDF-Header sieht ein wenig merkwürdig aus, es wäre schöner wenn du ihn einheitlich gestaltest. Du verwendest nämlich die Standardmethode und dann noch was von dir.

    Statt den Author oben reinzuschreiben gehört er eigentlich in das Author-Feld.

    Aber das sind ja keine funktionalen Sachen, also gehen wir mal dahin:

    AutoIt
    MsgBox(0, "ERROR", "ERROR - Button 1 undefined or no button defined.", 10)

    Dein UDF zeigt MsgBoxen mit einem Timeout an wenn ein Fehler passiert ist, aber du sagst nirgends in deiner UDF oder bietest dem Programmierer die Möglichkeit den Timeout anzupassen ggf. wegzulassen.

    Das kann eventuell zu Inkonsistenzen im Programmworkflow führen, wenn der Programmierer davon ausgeht, dass der User die Nachricht wegklickt aber sie von alleine verschwindet etc.

    Deine Abfrage "0000" ist redundant, da dieser Fall niemals eintreten kann (siehe If-Verzweigung vorher).

    Das Sleep ist ebenfalls unnötig, du bremst damit nur das Skript aus, wenn du unbedingt das Konstrukt beibehalten willst lass die Zeile frei.

    Du returnst bei diesem Fehler "ERROR" aber bei dem Fehler davor war es "Error", das ist ebenfalls nicht gut, standardisiere deine Rückgaben oder verwende gleich SetError.

    Damit kannst du einfach 0 zurückgeben und im Error-Code die Fehlermeldung codieren.

    Du hättest das ganze schöner in einer For-Schleife zusammenfassen können, etwa so:

    Einfach die Texte in ein Array schreiben und durchlaufen, findest du einen leeren Eintrag läufst du das Array ab dem nächsten Eintrag bis zum Ende durch.

    Findest du dorte einen Eintrag der nicht leer ist, so ist ein Fehler aufgetreten.

    AutoIt
    if $Title = Default Then $Title = "Title"
    if $Title = "" Then $Title = "Title"

    Wieso fasst du die If-Abfragen nicht zusammen? If $Title = Default Or $Title = "" Then $Title = "Title" sieht doch viel schöner, kompakter und kürzer aus?

    AutoIt
    if not $Button_1 = "" Then
        Local $Button_1Left = $Button_Seperator
        Local $GUI_Width_Math = $Button_1Left
    EndIf

    Du vergleichst case-insensitiv $Button_1 mit dem Leerstring und negierst das Ergebnis. Würdest du einen case-sensitiven Vergleich verwenden würde ich das "Not" ja noch verstehen aber so

    hättest du lieber If $Button_1 <> "" Then verwenden können, der Ungleichoperator "<>" ist case-insensitiv.

    // NACHTRAG: Ich war mir unschlüssig aber habe nochmal nachgeschaut.

    Die Operatorrangfolge ist so gestaltet, dass das "Not" am stärksten bindet, d.h. erst wird der Inhalt von $Button_1 negiert (Strings sind grundsätzlich immer True soweit ich weiß, bis auf den Leerstring) und dann verglichen.

    Deine Wahrheitstabelle bleibt zwar nach wie vor richtig, aber ich bin mir 100%ig sicher, dass du das nicht wusstest. Strings auf keinen Fall so behandeln!

    Setze entweder eine Klammer um dem Vergleich (wenn du die Schreibweise so behalten willst) oder nimm den von mir vorgeschlagenen Ungleichoperator.

    AutoIt
    $hGUI = GUICreate($Title, $GUI_Width, $GUI_Height)

    Bisher hattest du schön die Konsistenz mit dem Local-Statement beibehalten aber hier fehlts. Technisch gesehen ist es nicht notwendig, da vom Interpreter automatisch der lokale Scope gewählt wird,

    aber der Vollständigkeit halber hättest du es hier auch noch hinsetzen können.

    AutoIt
    GUISetStyle(BitOR($WS_CAPTION, $WS_POPUPWINDOW) )

    Wieso setzt du die Styles nicht direkt beim Erstellen der GUI? Dafür ist der "style"-Parameter da?

    Hätte alles super in eine For-Schleife gepasst und hättest du den Arraytrick verwendet (den ich bisschen weiter oben in dieser Antwort gepostet hatte), hättest du das hier um einige Zeilen kürzen können.

    AutoIt
    $Msg = GUIGetMsg()

    Betreibe ich mein Skript im OnEventModus, dann wars das mit deiner UDF und ich kann keine Buttons mehr anklicken.

    Du musst abfragen in welchem Modus du dich befindest und je nach dem agieren (oder den Modus setzen und wiederherstellen.)

    Das sind jetzt so die Dinge die mir beim Überfliegen mal aufgefallen sind. Es wäre schön wenn du die UDF variabler gestalten würdest indem du X Buttons erlaubst und diese alle dynamisch erstellt und angepasst werden.

    5 Buttons hardzucoden ist nicht gerade die feine Art.

    AutoIt
    Return

    Das kann auch komplett weg, es existiert nämlich kein Codepfad, der das letzte Return in deiner Funktion noch auslösen könnte.

    Zur Funktionalität selbst (bis auf die Dinge dich angeprangert habe) bleibt mir nur eins zu sagen: Läuft wenn die Voraussetzungen gegeben sind.

    Das meiste was ich hier bemängle sind eher Stilsachen als Funktionalität, dennoch liest sich ein sauber formatierter Code der bestimmten Richtlinien folgt einfach schöner und ermöglicht

    dir den Wiedereinstieg nach ein paar Wochen wesentlich schneller wenn du nicht mehr weißt wo oben und unten ist.

    Damit will ich dir nicht einreden du sollst hier das machen was wir wollen sondern dir ein eigenes System überlegen (oder eins adaptieren) und damit arbeiten.

    Code einrücken, Variablen gut benennen, einfach ein bisschen Konsistenz reinbringen, dann sieht das ganze viel besser aus!

    Der Anfang ist für deinen Kenntnisstand in Ordnung aber es ist noch Luft nach oben.

    Also beim nächsten Mal weniger Pillen schmeißen und fleißiger coden. ;)

    Nachtrag beachten!!!

  • Hallo, danke für die Antwort.

    1. Ich habe den Timeout aus der Error Message raus genommen und beides auf "ERROR" gesetzt. Das mit dem Set error sehe ich mir gleich mal, wollte die for schleifen sowieso lernen.

    2. Ich habe auch gedacht "0000" wäre redundant, ist es aber nicht. Da ich hier nur Button 2-5 Abfrage kann der Fall "0000" sehr wohl eintreten, nämlich wenn der User nur 1 Button möchte, was dann eigtl. "10000" bedeuten würde, vlt. habe ich dich aber auch falsch verstanden.

    3. If $Title = Default Or $Title = "" Then $Title = "Title" - Weil ich es nicht wusste :D

    4. If $Button_1 <> "" Then weil ich es nicht wusste, gefällt mir sowieso besser.

    5. local $hGUI = GUICreate($Title, $GUI_Width, $GUI_Height) - hatte ich übersehen.

    6. GUISetStyle(BitOR($WS_CAPTION, $WS_POPUPWINDOW) ) - Hatte mich sowieso gefragt wofür ich den überhaupt setze?

    7. Ich hab die Buttons nicht in ein Array oder so gepackt, da meine heutige Herausforderung ist so viele Buttons zuzulassen wie der User möchte.

    8. Das mit dem Event Mode muss ich mir noch durchlesen, checke ich noch nicht. :D Oder reicht das:

    Opt("GUIOnEventMode", 0) ?


    Jetzt mache ich mich an die dynamischen buttons :P


    Edit: Das schmeißt mich nicht raus wenn ich die buttons falsch ordne, aber ich verstehe es auch noch nicht ganz muss ich mal rum probieren mit.

    Einmal editiert, zuletzt von xTcisloVe (8. Juli 2018 um 09:46)

  • 8. Das mit dem Event Mode muss ich mir noch durchlesen, checke ich noch nicht. Oder reicht das:

    Opt("GUIOnEventMode", 0) ?

    Setzen wenn du reinkommst und wiederherstellen wenn du rauskommst. Ich weiß allerdings nicht ob für Events registrierte Funktionen ihre Gültigkeit verlieren wenn du den OnEventMode rausnimmst und wieder aktivierst.

    Edit: Das schmeißt mich nicht raus wenn ich die buttons falsch ordne, aber ich verstehe es auch noch nicht ganz muss ich mal rum probieren mit.

    Ich habs ohne zu testen einfach in den Foreneditor getippt. Was meinst du denn mit falsch anordnen?

    Die Texte die in den Buttons stehen sind doch egal, du willst nur herausfinden ob nach einem leeren Button ein nichtleerer Button kommt und dann sofort abbrechen.

    Und das Array prüft nur von links nach rechts durch, die Anordnung in dem Array soll so bleiben wie sie ist.

    2. Ich habe auch gedacht "0000" wäre redundant, ist es aber nicht. Da ich hier nur Button 2-5 Abfrage kann der Fall "0000" sehr wohl eintreten, nämlich wenn der User nur 1 Button möchte, was dann eigtl. "10000" bedeuten würde, vlt. habe ich dich aber auch falsch verstanden.

    Ja wenn du es richtig formuliert hättest und die die Fälle rausnimmst die nicht erlaubt sind dann bräuchtest du das auch nicht, und so macht man es für gewöhnlich.

  • Setzen wenn du reinkommst und wiederherstellen wenn du rauskommst. Ich weiß allerdings nicht ob für Events registrierte Funktionen ihre Gültigkeit verlieren wenn du den OnEventMode rausnimmst und wieder aktivierst.

    Werde ich mir mal ansehen müssen.

    Ich habs ohne zu testen einfach in den Foreneditor getippt. Was meinst du denn mit falsch anordnen?

    Die Texte die in den Buttons stehen sind doch egal, du willst nur herausfinden ob nach einem leeren Button ein nichtleerer Button kommt und dann sofort abbrechen.

    Und das Array prüft nur von links nach rechts durch, die Anordnung in dem Array soll so bleiben wie sie ist.

    Da hast du recht, fällt aber jetzt flach.

    Ja wenn du es richtig formuliert hättest und die die Fälle rausnimmst die nicht erlaubt sind dann bräuchtest du das auch nicht, und so macht man es für gewöhnlich.

    Wollte ich erst, klang aber komplizierter :D


    Ich brauche das jetzt nicht mehr, da ich jetzt dynamische Buttons habe.

    Aktuell ist es aber so, das ich den Button Namen returne, den der User festgelegt hat. Also wenn er "Yes" drückt dann kommt "Yes" zurück.

    Das würde ich gerne anders gestalten.


  • Gib doch stattdessen den Index zurück, das erscheint mir logischer. Oder biete einen Switch an der entweder Index oder Name zurückgibt.

    Oder gib beides zurück. Schau dir mal SetError an.

    Stett Return $Return könntest du Return SetError(0, $iIndex, $Return) zurückgeben. @error wäre hier Null, @extended könnte der Index sein und $Return weiterhin der Text.

    Grüße autoiter

  • Oder gib beides zurück. Schau dir mal SetError an.

    Stett Return $Return könntest du Return SetError(0, $iIndex, $Return) zurückgeben. @error wäre hier Null, @extended könnte der Index sein und $Return weiterhin der Text.

    Daran dachte ich auch, aber realistisch gesehen braucht man ja keinen String zurückzugeben.

    Wenn man keinen Errorcode setzen will sollte man aber lieber der Form halber SetExtended nehmen (auch wenn da kein großer Unterschied ist).


    Ich verstehe gerade nicht was ihr meint aber mein Problem habe ich "gelöst" :D :D

    Gefällt mir aber nicht

    Einmal editiert, zuletzt von xTcisloVe (8. Juli 2018 um 15:53)

  • Deine anderen Cases werden niemals eintreten da die Switch-Anweisung immer (und ohne Ausnahme) in den 1. Case reinspringen wird.

    Wenn du nicht weißt was wir mit @extended meinen guck dir einfach mal die Funktion SetExtended in der Hilfe an.

    Wollte mit der Funktion oben nur schauen welchen Wert ich erhalte :D

    Ich habe gerade probleme damit den richtigen Rückgabewert überhaupt zu erhalten, keine ahnung wie ich den array erstellen soll oder ob ich ihn brauche... bastel seit 1 stunde an ner for schelife dafür aber klappt nicht :D

    Ich könnte doch mit _ArraySearch den SetExtended(z.B 1) machen je nach Button und dann Return @extended ?

    Aber ich komme gerade nicht dahinter

    Einmal editiert, zuletzt von xTcisloVe (8. Juli 2018 um 16:51)

  • Ich könnte doch mit _ArraySearch den SetExtended(z.B 1) machen je nach Button und dann Return @extended ?

    Nein.

    Du kannst mit _ArraySearch den Index ermitteln und mit SetExtended zurückgeben (Return SetExtended(Index, Text). @extended dient im aufrufenden Skript um die Rückgabe des extended-Wertes abzufragen.

    Führe mal folgenden Code aus:

    Code
    $Text = SetExtended(10, "Test-Text")
    
    MsgBox(0, "Inhalt der Variable $Text = " & $Text, "@extended = " & @extended)

    Grüße autoiter

  • Nein.

    Du kannst mit _ArraySearch den Index ermitteln und mit SetExtended zurückgeben (Return SetExtended(Index, Text). @extended dient im aufrufenden Skript um die Rückgabe des extended-Wertes abzufragen.

    Führe mal folgenden Code aus:

    Code
    $Text = SetExtended(10, "Test-Text")
    
    MsgBox(0, "Inhalt der Variable $Text = " & $Text, "@extended = " & @extended)

    Dann wäre im Fall von Button 1 ja

    Code
    switch @extended
        case 10 ;-> = Button 1 pressed.
    
    .....
    
    switch $Text
        case "Test-Text" ;-> = Button 1 pressed.
    ....


    Oder irre ich?

    Ich mein das ist auch aktuell nicht mein problem...

    Wenn ich button 1 drücke wie bekomme ich den return code 1?


    Das war mein letzter versuch aber das klappt halt nicht :D