Skalierende Message Box

Statement zur DSGVO im Forum

Alles zur DSGVO und zur Umsetzung im Forum hier: Statement zur DSGVO (letztes Update: 30.05.2018)
  • Hallo,
    nach etlichen Updates, ist es soweit, meine Skalierende MessageBox noch einmal vorzustellen.


    Update: 18.07.2018

    -Danke an: alpines und autoiter

    Was kann die Message Box?
    -So viele Buttons wie du möchtest.

    -Die höhe skaliert mit dem Text den du eingibst. Wenn eine Line zu lang ist, verbreitert sich die messagebox.

    -Autoclose-Timeout. (Sekunden werden im Titel angezeigt)

    -Default Button festlegen.

    - Button Timeout (Sekunden werden im Button angezeigt)


    -Einstellen von:

    -Button-Breite

    -Button-Höhe

    -Abstand zwischen den Buttons

    -Abstand zwischen dem Rand der Box und dem ersten bzw. letzten Button

    -Abstand zwischen dem unteren Rand und den Buttons.
    -Abstand zwischen dem oberen Rand und dem Label bzw. Abstand zwischen dem ersten Button und dem unteren Rand des Labels.

    -Hintergrundfarbe

    -Transparenz

    -Textfarbe

    -Labelfarbe

    -Buttonfarbe

    -Icon

    -Button/ Label Style.

    -


    Hier ist die UDF: ScalingMessageBox.au3



    Hier mal was zum testen:

  • MessageBox("Title", "Button 1", "Button 2", "Button 3", "Button 4", "Button 5", 200, 30, 20, "Line1", "Line2", "Line3", "Line4", "Line5", 10)
    Switch $PressedButton

    Auf keinen Fall so den Button auswerten!!!


    NIEMALS sollte in Funktionen globale Variablen deklariert werden und schon gar nicht als Auswertung so wie du es gmacht hast.

    Warum? Der User kann bereits eine Variable mit dem Titel "PressedButton" (ist nicht abwegig) erstellt haben und wenn er dein Skript einbindet ist der Inhalt Geschichte.

    Lass dir wie die Standardmsgbox lieber den gedrückten Button als Rückgabewert der Funktion geben, das ist nicht nur viel sicherer, sondern sieht auch noch schöner aus und erleichtert das Lesen deines Codes!

  • Auf keinen Fall so den Button auswerten!!!


    NIEMALS sollte in Funktionen globale Variablen deklariert werden und schon gar nicht als Auswertung so wie du es gmacht hast.

    Warum? Der User kann bereits eine Variable mit dem Titel "PressedButton" (ist nicht abwegig) erstellt haben und wenn er dein Skript einbindet ist der Inhalt Geschichte.

    Lass dir wie die Standardmsgbox lieber den gedrückten Button als Rückgabewert der Funktion geben, das ist nicht nur viel sicherer, sondern sieht auch noch schöner aus und erleichtert das Lesen deines Codes!

    Okay danke, nur absolut keine Ahnung wie das geht. Ein Tipp?

  • Hmm, ich habe mir die ScalingMessageBox.au3 geladen. Eigentlich alles im grünen Bereich. Die Variable ist auch gar nicht global.

    Im Grunde bedeutet das aber, dass dein Beispiel auch gar nicht funktioniert.


    Außerdem bekomme ich Fehlermeldungen weil du in der Funktion Variablen, die als Parameter mitgegeben werden neu mit Local deklarierst. Das musst du entfernen (solche Variablen sind automatisch Loacal).

    Benutzt du kein SciTE oder hast du den Syntaxchck ausgeschaltet, das du das nicht siehst?

    (Bsp.: Local $ButtonWidth = 200).


    Eine Auswertung der Rückgabe einer Funktion (Return $VariableA) erfolgt etwa durch:

    Local $Answer = MessageBox("Title", "Button 1", "Button 2", "Button 3", "Button 4", "Button 5", 200, 30, 20, "Line1", "Line2", "Line3", "Line4", "Line5", 10)

  • Eben habe ich das Skript mal ausgeführt. Nach Klick auch Button eins verschwand die Box, es gab aber keine Rückmeldung.

    Dann ist mir aufgefallen, dass du versuchst den String auszuwerten:

    Code
    1. Switch $PressedButton
    2. case "Button1" ;--> Button 1 pressed.
    3. MsgBox(0, "Which button was pressed?", "Button 1 pressed", 10)

    Allerdings ist der Inhalt von $PressedButton nicht dieser String sondern nur 1. Du müsstest also nur die Zahlen auswerten. Hast du das kurz vor der Veröffentlichung geändert?

  • Eben habe ich das Skript mal ausgeführt. Nach Klick auch Button eins verschwand die Box, es gab aber keine Rückmeldung.

    Dann ist mir aufgefallen, dass du versuchst den String auszuwerten:

    Code
    1. Switch $PressedButton
    2. case "Button1" ;--> Button 1 pressed.
    3. MsgBox(0, "Which button was pressed?", "Button 1 pressed", 10)

    Allerdings ist der Inhalt von $PressedButton nicht dieser String sondern nur 1. Du müsstest also nur die Zahlen auswerten. Hast du das kurz vor der Veröffentlichung geändert?

    Das Beispiel war noch vor der Änderung die ich wegen alpines gemacht habe :D ist jetzt geändert.

  • Eigentlich alles im grünen Bereich. Die Variable ist auch gar nicht global.

    Guck mal bei den Switch-Monstern, da ist in jedem Case Global $PressedButton = "ButtonX".


    Okay danke, nur absolut keine Ahnung wie das geht. Ein Tipp?

    Wie autoiter das schon beschrieben hat kannst du innerhalb von Funktionen mit dem Statement Return Value (Value = Konstante, Variable, whatever) Werte returnen.

    Diese kannst du dann beim Funktionsaufruf mittels $return = Funktion(...) abfangen.


    PS: Wenn du User linken möchtest, nimm lieber die xTcisloVe (@-Funktion), damit kriegt der User direkt eine Benachrichtigung, dann musst du nicht die URL zum Profil linken.

  • Guck mal bei den Switch-Monstern, da ist in jedem Case Global $PressedButton = "ButtonX".

    Ah, ich hatte schon eine dahingehend korrigierte Version geladen. Das hat xTcisloVe geändert.

    Apropos Monster. Ja, es gibt in dieser Funktion einiges an Verbesserungspotential. Wenn xTcisloVe da Fragen hat, helfen wir ja gerne. Aber grundsätzlich mal danke fürs teilen.

  • Ah, ich hatte schon eine dahingehend korrigierte Version geladen. Das hat xTcisloVe geändert.

    Apropos Monster. Ja, es gibt in dieser Funktion einiges an Verbesserungspotential. Wenn xTcisloVe da Fragen hat, helfen wir ja gerne. Aber grundsätzlich mal danke fürs teilen.

    Ja z.B muss es ja möglich sein z.B den switch zu verkürzen also


    Code
    1. switch $msgcase $hGUIButton1, $hGUIButton2, $hGUIButton3, $hGUIButton4, $hGUIButton5, $GUI_EVENT_CLOSE
    2. Return            1, 2, 3, 4, 5, 6
    3. EndSwitch

    Ich weiß das geht so nicht, aber ich hoffe man versteht was ich meine

  • Du könntest ein Array erstellen und zu jedem Handle ein Returnwert speichern (oder ihn einfach berechnen) und dann returnen.

    Okay hab die Lösung gefunden, gibt es noch ne Möglichkeit das ins eins zu packen? Es ändert sich ja nur das:

    Code
    1. Case $hGUIButton1, $hGUIButton2, $hGUIButton3, $hGUIButton4, $hGUIButton5

    Dafür muss ich aber das machen:


  • switch $msgcase $hGUIButton1, $hGUIButton2, $hGUIButton3, $hGUIButton4, $hGUIButton5, $GUI_EVENT_CLOSE
    Return 1, 2, 3, 4, 5, 6
    EndSwitch

    Damit bist du schon mal knapp auf halbem Wege richtig...

    Wichtig ist es, zu wissen, dass die Controls (Button, Label, ...) bei der Erstellung immer mit einer aufsteigenden ID durchnummeriert werden. Um ein Return in ähnlicher Art zu realisieren, wie du es im Sinn hattest, kannst du die IDs in einem Array speichern und dann einfach mit Return $aArray[$iIndex] die Funktion verlassen.


    Hier mal eine kleine Hilfe für den Start...

  • Benutzt du SciTE als Entwicklungsumgebung?

    Nein, Notepad++ warum?


    Damit bist du schon mal knapp auf halbem Wege richtig...

    Wichtig ist es, zu wissen, dass die Controls (Button, Label, ...) bei der Erstellung immer mit einer aufsteigenden ID durchnummeriert werden. Um ein Return in ähnlicher Art zu realisieren, wie du es im Sinn hattest, kannst du die IDs in einem Array speichern und dann einfach mit Return $aArray[$iIndex] die Funktion verlassen.


    Hier mal eine kleine Hilfe für den Start...

    Vielen Dank für die umfangreiche Antwort.

    Das ist die Lösung die ich gewählt habe.


    Code
    1. Switch $msg
    2. Case $hGUIButton1, $hGUIButton2, $hGUIButton3, $hGUIButton4, $hGUIButton5
    3. GUIDelete()
    4. Return $msg-2
    5. Case $GUI_EVENT_CLOSE
    6. GUIDelete()
    7. Return 6
    8. EndSwitch

    Hier verstehe ich auch warum ich den richtigen Return Code bekomme, da ich getestet habe welchen Wert $msg hat, wenn ich Button 1 drücke und das habe ich dann einfach so fortgesetzt.

    Kannst du mir evtl. den Unterschied erklären und warum ich bei deiner Variante auf den richtigen Wert komme?

    Vielen vielen vielen Dank für das Beispiel mit dem Array, das wird mir so oft weiter helfen! Danke!

  • Meine Aktuelle Lösung ist:



    Das Problem ist aber das ich diese Funktion ja 5 mal brauche, also:



    Und es ändert sich ja nur das hier:



    Code
    1. Local $iIndex, $aArray = [[$GUI_EVENT_CLOSE, 0], [$hGUIButton1, 1], [$hGUIButton2, 2], [$hGUIButton3, 3], [$hGUIButton4, 4], [$hGUIButton5, 5]]
    2. Case $GUI_EVENT_CLOSE, $hGUIButton1, $hGUIButton2, $hGUIButton3, $hGUIButton4, $hGUIButton5

    Das muss sich doch anders als in 5 Funktionen realisieren lassen?

  • Hallo xTcisloVe  

    Nein, Notepad++ warum?

    Ich rate dir dringend zu einer für AutoIt besser geeigneten Entwicklungsumgebung. Das oben erwähnte SciTE4AutoIt3 oder ISN AutoIt Studio.

    SciTE4AutoIt3 kannst du dort laden wo du wohl auch AutoIt her hast.

    https://www.autoitscript.com/site/autoit/downloads/

    Hier den AutoIt Script Editor herunterladen. Einfach installieren -> fertig. In dieser Version von SciTE hast du viele eingebaute Tools, die dir bei der Arbeit mit AutoIt-Code helfen. Syntax-Check usw. Außerdem kannst du z.B. sehr gut die Hilfe erreichen. Wenn du dich etwa fragst, was macht _ArraySearch, dann genügt es, dass du den Befehl mit dem Mauszeiger anklickst und dann F1 drückst. Du landest direkt in der Hilfe zu dieser Funktion. Bei fast allen Funktionen findest du Beispielcode, den du direkt ausführen kannst, um dir die Wirkung genauer anzuschauen.

    Switch $msg
    Case $hGUIButton1, $hGUIButton2, $hGUIButton3, $hGUIButton4, $hGUIButton5

    Leider geht das bei deinem Code nicht so einfach. Es treten dann Probleme auf, wenn jemand weniger als 5 Buttons verwendet. Hier fehlt dann einfach ein Wert..

    Der Hinweis mit den Arrays war aber richtig. Nur solltest du, wenn du mal ernsthaft den Umbau planst, vielleicht noch früher mit auf Arrays setzen und schon den ganzen oberen Bereich mit der Erstellung der Controls mit Arrays und For To-Schleifen machen. Da kannst du vielleicht mal nach "GUI Controls dynamisch erstellen" oder so etwas suchen. Ist jetzt aber nicht sofort nötig.


    Damit dein Skript aber jetzt direkt immer funktioniert, kannst du die Buttons mit einem nie eintretenden Pseudo-Wert vorbelegen. (Das ist echt nicht elegand. Würde aber erst einmal funktionieren).

    Etwa so:

    Code
    1. If $hGUIButton1 = "" Then $hGUIButton1 = -999999
    2. If $hGUIButton2 = "" Then $hGUIButton2 = -999999
    3. If $hGUIButton3 = "" Then $hGUIButton3 = -999999
    4. If $hGUIButton4 = "" Then $hGUIButton4 = -999999
    5. If $hGUIButton5 = "" Then $hGUIButton5 = -999999

    Noch ein kleiner Hinweis. Bei UDF-Dateien, die man in andere Skripte einbinden soll. Ist es angebracht über den #include-Anweisungen die folgende Anweisung anzugeben: #include-once

    Das sorgt dafür, dass Dateien nur einmal eingebunden werden und nicht mehrfach, wenn die gleiche Anweisung etwa noch einmal im eigentlichen Skript vorhanden ist.


    PS: Ich würde statt deiner Variante Return $msg-2 doch eine der von Bitnugger vorgeschlagenen Varianten nehmen, weil sie eindeutiger sind. Wenn du mal etwas an dem Skript änderst, könnte es sein, dass die IDs nicht mehr zu dieser Auswertung passen.


    EDIT: Da war ich gerade am Schreiben als du den letzten Post gemacht hast. Einen Teil der Frage habe ich dir schon beantwortet. Wenn du die Buttons mit Werten vorbelegst brauchst du das nicht fünfmal wiederholen und fragen ob der Button benutzt wird.

    Allerdings gilt das nur, wenn jemand nicht einfach einen Button auslässt (etwa Button 1 benutzt, Button 2 nicht aber dann Button 3). Hier fehlt ein Fehler-Handling, über dass du dir noch Gedanken machen könntest. Andererseits denke ich, mit etwas gutem Willen macht niemand so etwas ;)

  • Vielen Dank.

    Ich hab den Script Editor installiert, nur nie benutzt. :D Mache ich ab jetzt.

    Das mit dem Pseudo Wert hab ich mir auch schon gedacht, hatte ich aber wohl falsch umgesetzt :D
    -Getestet, funktioniert. :D Danke.

    Meinst du das mit Fehlerhandling? Steht ganz am Anfang der Funktion:


    Code
    1. if $Button1 = "" Then
    2. MsgBox(0, "ERROR", "ERROR - Button 1 undefined or no button defined.", 10)
    3. Return
    4. EndIf



    PS: Sonntag werde ich wohl die ganzen Berechnungen neu schreiben mit Hilfe von Arrays, ich weiß jetzt schon wie also im Kopf funktioniert es :D

    Ich muss andere Grundlagen zur Berechnung nehmen, damit man die Werte variabler setzen kann, ohne das es komisch aussieht. :D

    Im Grunsatz finde ich das ganze schon solide. :D

    Würde auch gerne die Breite des GUI´s anhand der Länge, der längsten Textzeile berechnen. Und auch die breite der Buttons, ich muss nur noch heraus finden wie die zueinander stehen. Aber hört sich schon mal geil an :D

    Auch interessant wäre, nur eine Textzeile zu machen, die automatisch in die nächste übergeht sobald die breite des GUIs erreicht ist, die vorher anhand der Anzahl der Buttons berechnet wurde. Was eigtl. besser klingt. Mal sehen :D

  • Meinst du das mit Fehlerhandling? Steht ganz am Anfang der Funktion:

    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: