Pro Schlüssel soll ein Button erzeugt werden.

  • Hallo Community,

    seit heute bin ich hier der neue und wie es sich für nen "Frischling" gehört, hab ich auch gleich eine Frage.
    Ich schreibe ein Programm, dass auf einem ROOT läuft. Ich hab die "alpha-Version darauf schon laufen und es funktioniert super.

    Leider ist es zu unflexibel. Es ist maßgeschneidert auf den aktuellen Zustand des ROOTs. Will ich da Änderungen vornehmen
    (was hinzufügen oder wegnehmen), dann kann das Programm nicht mehr richtig arbeiten. Ist nicht Sinn der Sache, bei jeder Änderung wieder
    das Script rauszupacken, im Code rumzufriemeln und dann wieder zu kompilieren...

    Also zum Eingemachten:

    Das Programm soll mir meine Gameserver steuern. Die Informationen, die es braucht, holt es sich aus einer INI-Datei.
    Um es flexibler zu gestalten, wär es sinnvoll, für jeden vorhandenen Schlüssel in der INI automatisch einen neuen Button zu erstellen.
    Und genau das ist mein Problem.

    [autoit]

    #include <GUIConstantsEx.au3>
    #include <WindowsConstants.au3>
    #include <needs\gamecheck.au3>

    [/autoit][autoit][/autoit][autoit]

    ; ### Scriptoptionen.
    Opt("GUIOnEventMode", 1)
    Opt('MustDeclareVars', 1)

    [/autoit][autoit][/autoit][autoit]

    ; ### Variablen scriptbasierend werden deklariert.
    Local $ini = @ScriptDir & "\needs\server.ini"
    Local $font, $titel, $mainwindow, $sect, $i, $button, $name, $game, $von_links, $von_oben, $game

    [/autoit][autoit][/autoit][autoit]

    ; ### Benutzeroberfläche wird erstellt.
    $font = "Comic Sans MS"
    $titel = "Serverwatcher"
    $mainwindow = GUICreate ("Serverwatcher v1.5 alpha", 800, 600)
    GUISetState (@SW_SHOW)
    GUISetOnEvent ($GUI_EVENT_CLOSE, "ProgrammBeenden")
    GUISetBkColor (0xA6C5E9)
    GUICtrlSetDefColor (0xFF0000)
    GUISetFont (20, 400, 4, $font)
    GUICtrlCreateLabel ($titel, 180, 30)
    GUICtrlSetDefColor (0x000000)
    GUISetFont (10, 400, 0, $font)

    [/autoit][autoit][/autoit][autoit]

    $i = "1"
    $sect = IniReadSection($ini, $i)
    If Not @error Then
    $von_links = 80
    $von_oben = 130
    $name = IniRead($ini, $i, "Servername intern", "")
    $game = IniRead($ini, $i, "Game", "")
    $button = GUICtrlCreateButton($name, $von_links, $von_oben, 150)
    GUICtrlSetOnEvent($button, "gamecheck")
    EndIf

    [/autoit][autoit][/autoit][autoit]

    $i = "2"
    $sect = IniReadSection($ini, $i)
    If Not @error Then
    $von_links = 80
    $von_oben = 130 + 20 * $i
    $name = IniRead($ini, $i, "Servername intern", "")
    $game = IniRead($ini, $i, "Game", "")
    $button = GUICtrlCreateButton($name, $von_links, $von_oben, 150)
    GUICtrlSetOnEvent($button, "gamecheck")
    EndIf

    [/autoit][autoit][/autoit][autoit]

    $i = "3"
    $sect = IniReadSection($ini, $i)
    If Not @error Then
    $von_links = 80
    $von_oben = 130 + 20 * $i
    $name = IniRead($ini, $i, "Servername intern", "")
    $game = IniRead($ini, $i, "Game", "")
    $button = GUICtrlCreateButton($name, $von_links, $von_oben, 150)
    GUICtrlSetOnEvent($button, "gamecheck")
    EndIf

    [/autoit][autoit][/autoit][autoit]

    Func ProgrammBeenden()
    Exit
    EndFunc

    [/autoit][autoit][/autoit][autoit]

    While 1
    Sleep(1000)
    WEnd

    [/autoit]


    Die Funktion gamecheck() wird dann von einem anderemScript durchgeführt, welches ein "Select Case Szenario" enthällt:

    [autoit]

    #include <cod4.au3>
    Local $game

    [/autoit][autoit][/autoit][autoit]

    gamecheck()

    [/autoit][autoit][/autoit][autoit]

    Func gamecheck()
    Select
    Case $game = "cod4"
    cod4()

    Case $game = "cod6"
    ;~ cod6()

    Case $game = "coduo"
    ;~ coduo()

    Case $game= "ts3"
    ;~ ts3()

    Case $game = "homefront"
    ;~ homefront()

    EndSelect
    EndFunc

    [/autoit]


    Anschliessend wird dann die Funktion aufgerufen, für die das Select-Case-Szenario zutrifft. Zu Testzwecken hab ich als Aktion eine MsgBox die mir dann eine Meldung ausgibt, wie der Server zu starten ist (Parameter).

    Und das grosse Problem hierbei:
    Mir werden 3 Buttons angezeigt, doch nur der 1. hat den tatsächlichen Namen, wie er sein muss, die beiden anderen sind fast nur striche ohne Namen.
    Wenn ich diese dann anklicke, dann bekomm ich eine Meldung, die gar nicht zutreffen sollte. Versuch ich das nur mit einem Eintrag im ersten Quellcode, dann funktioniert es.

    Auch beim Start des ersten Scripts wird mir, bevor die Programmoberfläche angezeigt wird, die Meldung angezeigt, die nur erscheinen dürfte, wenn ich auf den Button klicke.
    WTF, i need help!

  • Du machst es die zu kompliziert. Lies mit IniReadSectionNames() die Namen aller Sektionnen aus. Du erhälst ein Array. Dann durchläufst du dieses Array in einre For Schleife und holst dir mit IniReadSection() die Schlüssel - Werte Paare der einzelnen Sektionen. IniReadSection() gibt dir hier bereits ein 2d Array mit allen Werten zurück. Es besteht also kein Grund, nochmal ein IniRead() auf einen bestimmten Schlüssel anzuwenden. (z.B: Zeile 31/32)

    Inwieweit du das nutzen kannst, bleibt allerdings fraglich. Die Grenze der Flexibilität erreichst du spätestens dann, wenn sich die einzelnen Funktionen, die durch gamecheck() aufgerufen werden, so stark voneinander untescheiden, dass du sie nicht zu einer einzelnen zusammenfassen kannst.

    Hab leider im Moment kein AutoIt zur Hand aber vlt. hilft dir der kleine Schnipsel:

    Spoiler anzeigen
    [autoit]

    $aSections = IniReadSectionNames($sIni)
    If IsArray($aSections) Then
    For $i = 1 To $aSections[0]
    $aSection = IniReadSection($sIni, $aSections[$i])
    If IsArray($aSection) Then
    ReDim $aButtons[UBound($aButtons) + 1]
    $aButtons[$i] = GUICtrlCreateButton($aSection[1][1], $left, $top)
    $top += 30
    EndIf
    Next
    EndIf

    [/autoit]