1. Dashboard
  2. Mitglieder
    1. Letzte Aktivitäten
    2. Benutzer online
    3. Team
    4. Mitgliedersuche
  3. Forenregeln
  4. Forum
    1. Unerledigte Themen
  • Anmelden
  • Registrieren
  • Suche
Alles
  • Alles
  • Artikel
  • Seiten
  • Forum
  • Erweiterte Suche
  1. AutoIt.de - Das deutschsprachige Forum.
  2. Mitglieder
  3. aSeCa

Beiträge von aSeCa

  • Window Mover für Loupedeck

    • aSeCa
    • 17. Februar 2023 um 13:52

    Danke für die Insights und cool, dass du an sowas arbeitest! Habe wirklich viel gesucht, also der Bedarf an einer richtigen Lösung ist auf jeden Fall da und ungedeckt! ^^ Ich teste gerne mal, wenn du soweit bist ;)

    Ein Youtuber hatte vor knapp 1 Jahr einen Austausch mit Loupedeck und die meinten, dass sie auch an sowas arbeiten. Ergibt ja auch Sinn, weil das für Streamer noch wichtiger ist, als im Home Office und der größte Konkurrent es hat... Aber nach 1 Jahr immer noch nichts. Gibt bestimmt viele Randfälle, wenn man es "richtig" machen will. Aber selbst mit so einfachen Mitteln kann man ja schon vielen Menschen helfen. Vor allem werden so große Bildschirme immer beliebter.

    Das ist übrigens die Lösung von Stream Deck auf Github: https://github.com/BarRaider/streamdeck-windowsmover (hat aber leider bei mir nicht immer funktioniert, dass er die Fenster wiedererkannt hat)

  • Window Mover für Loupedeck

    • aSeCa
    • 17. Februar 2023 um 12:04

    Hey,

    ich habe sehr lange nichts mehr mit AutoIt gemacht, aber habe das Loupedeck neu (diese "Decks" sind ja nun im Home Office angekommen^^) und es gibt irgendwie keine guten Lösungen zum Anpassen von Größe und Position von Fenstern (beim Stream Deck gibt es ein "Window Mover" plugin). Da ich auch sonst nicht gut fündig geworden bin, wie ich das mit Shortcuts lösen kann, wollte ich scripten und da man mit Bordmitteln Argumente übergeben kann, dachte ich mir, dass ich das gleich ein wenig flexibler mache.

    Grundsätzlich könnte ich ja einfach alle Argumente für WinMove übergeben und es wäre eine "komplette" Lösung. Da ich aber nur 4 Positionen haben, wollte ich die auch mit drin haben, damit ich bei etlichen Fenstern und Makros dann nicht die starke Redundanz mit den Argumenten habe.

    Das Skript sieht nun so aus und macht (ungefähr), was es soll:

    Spoiler anzeigen
    AutoIt
    Opt("WinTitleMatchMode", 2) 
    
    #include <Array.au3>
    
    Global $iArguments = $CmdLine[0], $sName = $CmdLine[1]
    Global $iX, $iY, $iWidth, $iHeight
    
    Select
        Case $iArguments = 5; Name, x, y, width, height
            $iX = $CmdLine[2]
            $iY = $CmdLine[3]
            $iWidth = $CmdLine[4]
            $iHeight = $CmdLine[5]
        Case $iArguments = 2; Name; position
            Switch $CmdLine[2]
                Case "left"
                    $iX = 0
                    $iY = 0
                    $iWidth = 1280
                    $iHeight = 1392
                Case "center"
                    $iX = 1273
                    $iY = 0
                    $iWidth = 2574
                    $iHeight = 1399
                Case "rightSmall"
                    $iX = 3833
                    $iY = 718
                    $iWidth = 1294
                    $iHeight = 681
                Case "rightBig"
                    $iX = 3833
                    $iY = 0
                    $iWidth = 1294
                    $iHeight = 1399
            EndSwitch 
    EndSelect
    
    WinMove($sName, "", $iX, $iY, $iWidth, $iHeight)
    Alles anzeigen

    In Loupedeck sieht das dann so aus:

    pasted-from-clipboard.png

    An sich bin ich sehr zufrieden, aber ich es gibt ein kleines "Problem" und ich würde gerne grundsätzlich wissen, ob ihr noch eine Idee hättet, das "besser" zu machen :)

    Zu meiner Verwendung:

    Ich habe einen Samsung Odyssey G9, also einen 49 Zoll mit 5120x144 und ich habe ihn mit FanzyZones (Microsoft Power Tools) so aufgeteilt:

    Bei PiP binde ich rechts oben dann eine andere Quelle ein. Und ich möchte mit dem Deck halt automatisieren, dass ich dann mit einem Klick alles wieder in die richtige Position bringen kann. Ebenso will ich beim Start meines Rechners alles richtig platzieren (alles an Chats/Mails usw. ist rechts, Chrome mittig und links sind so OneNote, Miro und andere Dinge, die ich brauche).

    Jetzt ist es so, dass sich z. B. die PWA, die Chrome für WhatsApp und Gmail erstellt hat, sich leicht anders verhalten, als die anderen Tools und die "generellen Breiten/Höhen" passen irgendwie nicht immer und es entstehen kleine(!) Lücken oder Überlappungen...

    Dann hatte ich 2 Lösungen im Kopf, die ich beide nicht hinbekommen habe:

    - Automatisch mit DesktopHeight & Co die Zahlen automatisch berechnen => dafür brauchte ich z. B. die Höhe der Taskleiste, wofür ich das gefunden habe: Taskbar Eigenschaften, leider passte das Ergebnis aber nicht und nach der Ausrichtung fehlten ein paar Pixel zwischen Fensterende und Taskleiste)

    - Irgendwie diesen "Snap" in die Bereiche von FanzyZones shortcutten => Wenn man ein Fenster aktiviert und die Windowstaste mit Pfeil links/rechts verwendet, dann snapt das Fenster immer in die nächste Zone, leider habe ich keine Shortcuts gefunden, um direkt die Zonen anzuvisieren und das mit den Pfeiltasten klappt ja nur, wenn ich wüsste, in welcher Zone das Fenster grade ist und optisch wird das auch sehr wild... :D

    Also: Vielleicht hilft das Skript schon jemandem, ich hatte Google lange bemüht, um eine "fertige Lösung" zu finden und bestenfalls habt ihr noch ein Feedback für mich, das die Lösung nochmal etwas voran bringt!

  • Beschreibung von Punkten und ihren Kanten zu anderen Punkten

    • aSeCa
    • 10. August 2021 um 23:31

    Vielen Dank für deine Erklärungen!

    Ich habe jetzt alles soweit durch, dass er mir mögliche Besetzungen der Formation korrekt ausspuckt (per Stichprobe kontrolliert). Für die ersten Spieler mit einer ersten Formation dauert das knapp 2 Sekunden. Ich werde noch eine Vor-Validierung der Formationen machen, sodass ich nicht alle durch gehen muss und in den 2 Sekunden sind ja auch 2 größere Arbeitsschritte mit drin. Aber die Rekursion wird wohl einen Großteil davon benötigen und dann kann sich die Zeit schon schnell addieren, zumal noch die Berechnung der Chemie dazu kommt.

    Mein Ziel ist, zu jeder passenden Formation die nach der Chemie beste Aufstellung zu finden. Das heißt, dass ich theoretisch auch Zeit sparen könnte, wenn ich die Berechnung der Chemie direkt in der Rekursion mit mache, um dann bei einer bereits "perfekten Aufstellung" die Rekursion für die Formation schon beenden könnte...

    Nun ja, morgen kommen erstmal die anderen 25 Formationen mit in den Code und die Chemie-Berechnung und dann lasse ich das über alle Formationen laufen und das Ergebnis etwas besser ausgeben :)

    Hier auf jeden Fall mal der aktuelle Stand, falls das mal jemand gebrauchen kann oder auch gerne, falls mal jemand Lust hat drüber zu fliegen, für Feedback, wo ich Dinge "besser" machen könnte. ^^

    C
    #include <Array.au3>
    #include <String.au3>
    #include <StringConstants.au3>
    #include <WinHTTP.au3>
    #include <WinHTTPConstants.au3>
    
    ; Annahme: Es werden nur Positionen besetzt, die mit PositionChange auch besetzbar sind, keine "leicht positionsfremden Positionen", um Zeit zu sparen und weil sicherlich keiner mit 5 Spieler- Chemie spielen will
    ; Deswegen: Check einbauen, ob das Team "valide" ist (kein RM ohne LM,...)
    
    Global $UA =  "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.131 Safari/537.36"
    
    Global $HTTP_Host = "https://www.futbin.com"
    Global $HTTP_Agent = _WinHttpOpen($UA)
    Global $HTTP_Connect = _WinHttpConnect($HTTP_Agent, $HTTP_Host)
                                            
    Global $aLegalPositionChanges = [ _
            Array("GK"), _
            Array("CB"), _
            Array("LB", "LWB"), _
            Array("RB", "RWB"), _
            Array("CDM", "CM", "CAM", "CF", "ST"), _
            Array("RM", "RW", "RF"), _
            Array("LM", "LW", "LF")]                                        
    
    Global $aFormationNames[30] = ["3-4-1-2", "3-4-2-1", "3-1-4-2", "3-4-3", "3-5-2", "4-1-2-1-2", "4-1-2-1-2(2)", "4-1-4-1", "4-2-3-1", "4-2-3-1(2)", "4-2-2-2", "4-2-4", "4-3-1-2", "4-1-3-2", "4-3-2-1", "4-3-3", "4-3-3(2)", "4-3-3(3)", "4-3-3(4)", "4-3-3(5)", "4-4-1-1", "4-4-1-1(2)", "4-4-2", "4-4-2(2)", "4-5-1", "4-5-1(2)", "5-2-1-2", "5-2-2-1", "5-3-2", "5-4-1"]
    
    Global $aFormations = [ _
            Array( _
                Array("GK", 1, 2, 3), _ ; 3-4-1-2
                Array("CB", 0, 2, 6), _
                Array("CB", 0, 1, 3, 4, 5), _
                Array("CB", 0, 2, 8), _
                Array("CM", 2, 5, 6, 7), _
                Array("CM", 2, 4, 7, 8), _
                Array("LM", 1, 4, 9), _
                Array("CAM", 4, 5, 9, 10), _
                Array("RM", 3, 5, 10), _
                Array("ST", 6, 7, 10), _
                Array("ST", 7, 8, 9) _
            ), _
            Array( _
                Array("GK", 1, 2, 3), _ ; 3-4-2-1
                Array("CB", 0, 2, 6), _
                Array("CB", 0, 1, 3, 4, 5), _
                Array("CB", 0, 2, 7), _
                Array("CM", 2, 5, 6, 8), _
                Array("CM", 2, 4, 7, 9), _
                Array("LM", 1, 4, 8), _
                Array("RM", 3, 5, 10), _
                Array("LF", 4, 6, 9), _
                Array("RF", 5, 7, 9), _
                Array("ST", 8, 9) _
            ),  _
            Array( _
                Array("GK", 1, 2, 3), _ ; 3-1-4-2
                Array("CB", 0, 2, 4, 7), _
                Array("CB", 0, 1, 3, 4), _
                Array("CB", 0, 2, 4, 8), _
                Array("CDM", 1, 2, 3, 5, 6), _
                Array("CM", 4, 7), _
                Array("CM", 4, 8), _
                Array("LM", 1, 5, 9), _
                Array("RM", 3, 6, 10), _
                Array("ST", 7, 10), _
                Array("ST", 8, 9) _
            ),  _
            Array( _
                Array("GK", 1, 2, 3), _ ; 3-4-3
                Array("CB", 0, 2, 6), _
                Array("CB", 0, 1, 3, 4, 5), _
                Array("CB", 0, 2, 7), _
                Array("CM", 2, 5, 6, 9), _
                Array("CM", 2, 4, 7, 10), _
                Array("LM", 1, 4, 8), _
                Array("RM", 3, 5, 10), _
                Array("LW", 6, 9), _
                Array("ST", 4, 5, 8, 10), _
                Array("RW", 7, 9) _
            ),  _
            Array( _
                Array("GK", 1, 2, 3), _ ; 3-5-2
                Array("CB", 0, 2, 4, 6), _
                Array("CB", 0, 1, 3, 4, 5), _
                Array("CB", 0, 2, 5, 7), _
                Array("CDM", 1, 2, 5, 6, 8), _
                Array("CDM", 2, 3, 4, 7, 8), _
                Array("LM", 1, 4, 9), _
                Array("RM", 3, 5, 10), _
                Array("CAM", 4, 5, 9, 10), _
                Array("ST", 6, 8, 10), _
                Array("ST", 7, 8, 9) _
            )] 
    
    $aPlayersEleven = getTeamFromFutbinSquadId(9249882)
    _ArrayDisplay($aPlayersEleven)
    
    isPossibleFormation(0, $aPlayersEleven)
    
    ConsoleWrite(checkChemieBonusBetweenTwoPlayers(1, 6) & @CRLF) 
    
    $aPlayersPositions = getPlayersPossiblePositionsInFormation(0, $aPlayersEleven)
    
    
    Global $aAufstellungen = _comb_Permute_restricted($aPlayersPositions)
    MsgBox(0,"", @extended & " mögliche Aufstellungen gefunden")
    
    ;~ ; Formationen auf Konsole ausgeben:
    For $aAufstellung In $aAufstellungen
        For $iNr In $aAufstellung
            ConsoleWrite($iNr & @TAB)
        Next
        ConsoleWrite(@CRLF)
    Next
    
    _Exit()
    
    Func getPlayersPossiblePositionsInFormation($iFormationId, $aTeam)
        Local $aPlayersPositions[11], $aPositionVariations, $aPossibleRolesForSinglePlayer, $aPositionInFormation
        Local $aFormation = $aFormations[$iFormationId]
        
        For $i = 0 To UBound($aTeam) -1
            For $j = 0 To UBound($aLegalPositionChanges) -1
                Dim $aPositionVariations = $aLegalPositionChanges[$j]
                Dim $aTempPlayerPositions[0]
                
                For $k = 0 To UBound($aPositionVariations) -1
                    If StringCompare($aTeam[$i][1], $aPositionVariations[$k]) = 0 Then
        
                        $aPossibleRolesForSinglePlayer = $aPositionVariations ; All roles a specific player can take
                        
                        For $l = 0 To UBound($aFormation) -1 ; Knowing all roles of the player, compare the roles in the formation to save the positions in the formation, the player can take
                            For $m = 0 To UBound($aPossibleRolesForSinglePlayer) -1
                                Dim $aPositionInFormation = $aFormation[$l]
                                
                                If StringCompare($aPositionInFormation[0], $aPossibleRolesForSinglePlayer[$m]) = 0 Then 
                                    _ArrayAdd($aTempPlayerPositions, $l)
                                EndIf
                                
                            Next
                        Next
                    EndIf
                Next
            
                If UBound($aTempPlayerPositions) > 0 Then 
                    $aPlayersPositions[$i] = $aTempPlayerPositions
                EndIf
            Next
        Next
        
        Return $aPlayersPositions
    EndFunc
    
    
    Func isPossibleFormation($iFormationId, $aPlayer)
        Local $aOccupation[UBound($aLegalPositionChanges)][2] ; Formation / Team
        Local $aFormation = $aFormations[$iFormationId]
        Local $aPositionVariations, $aPositionInFormation
        
        For $i = 0 To UBound($aOccupation) -1    
            $aOccupation[$i][0] =  0
            $aOccupation[$i][1] =  0
            
            For $j = 0 To UBound($aPlayer) -1
                Dim $aPositionVariations = $aLegalPositionChanges[$i]
                
                For $k = 0 To UBound($aPositionVariations) -1
                    Dim $aPositionInFormation = $aFormation[$j]
                    
                    If $aPositionVariations[$k] = $aPositionInFormation[0] Then $aOccupation[$i][0] += 1
                    If $aPositionVariations[$k] = $aPlayer[$j][1] Then $aOccupation[$i][1] += 1
                Next
            Next
        Next
        
        For $i = 0 To UBound($aOccupation) -1
            If $aOccupation[$i][0] <> $aOccupation[$i][1] Then
                ConsoleWrite("Formation " & $aFormationNames[$i] & " unpassend" & @CRLF)
                Return False
            EndIf
        Next
        
        Return True
    EndFunc
    
    Func getTeamFromFutbinSquadId($iSquadId)
        Local $aPlayersEleven[11][8]
        
        $sHtml = _SimpleRequest("GET", "/21/squad/" & $iSquadId)
    
        ;id = cardlid 1-11 => Haupt-Spieler; 12-23 => Subs
        For $i = 1 To 11
            $aArray =  StringRegExp($sHtml, 'cardlid' & $i & '\"[^!]+data-player-commom=\"([^\"]+)\"[\s\d\w]+data-player-nation=\"([^\"]+)\"[\s\d\w]+data-player-club=\"([^\"]+)\"[\s\d\w]+data-player-league=\"([^\"]+)\"[^!]+data-formpos-original=\"([^\"]+)\"[^!]+Country:\s+([\w\s]+)[^!]+Club:\s+([\w\s]+)[^!]+League:\s+([\w\s]+)',  3)
    
            $aPlayersEleven[$i -1][0] = StringUpper($aArray[0]) ; Name
            $aPlayersEleven[$i -1][1] = $aArray[4] ; Position
            $aPlayersEleven[$i -1][2] = $aArray[1] ; Nation-ID
            $aPlayersEleven[$i -1][3] = $aArray[2] ; Club-ID
            $aPlayersEleven[$i -1][4] = $aArray[3] ; League-ID
            $aPlayersEleven[$i -1][5] = $aArray[5] ; Nation-Name
            $aPlayersEleven[$i -1][6] = $aArray[6] ; Club-Name
            $aPlayersEleven[$i -1][7] = $aArray[7] ; League-Name
        Next
        
        Return $aPlayersEleven
    EndFunc
        
    Func _SimpleRequest($sType = "GET", $sPath = "", $sPost = $WINHTTP_NO_REQUEST_DATA)
        $aResponse = _WinHttpSimpleSSLRequest($HTTP_Connect, $sType, $sPath, Default, $sPost, Default, True)
    
        Return $aResponse[1]
    EndFunc   ;==>_SimpleRequest
    
    Func _Exit()
        _WinHttpCloseHandle($HTTP_Connect)
        _WinHttpCloseHandle($HTTP_Agent)
        Exit
    EndFunc
    
    Func checkChemieBonusBetweenTwoPlayers($id_1, $id_2) ; Explanation (german): https://www.tonight.de/games/fifa/fifa-ultimate-team-fut-wie-funktioniert-chemie-teamchemie-spielerchemie-links-loyalitaet_77330.html
        ; bad link (-1; red), weak link (0; orange), strong link (+1; green), perfect link (+2; green)
        ; +1 for same nation, +1 for same club, +1 for same league
        ; if Icon: +1 for everyone / +2 for players with same nation / +3 for Icons with same nation
        Local $iChemie = -1
        
        If $aPlayersEleven[$id_1][4] = 2118 or $aPlayersEleven[$id_2][4] = 2118 Then ; Icons : Club = 112658 (FUT 21 ICONS); League = 2118 (Icons)
            If $aPlayersEleven[$id_1][4] = $aPlayersEleven[$id_2][4] and $aPlayersEleven[$id_1][2] = $aPlayersEleven[$id_2][2] Then Return 3
            If $aPlayersEleven[$id_1][2] = $aPlayersEleven[$id_2][2] Then Return 2
            Return 1
        Else ; Normal players
            If $aPlayersEleven[$id_1][2] = $aPlayersEleven[$id_2][2] Then $iChemie += 1
            If $aPlayersEleven[$id_1][3] = $aPlayersEleven[$id_2][3] Then $iChemie += 1
            If $aPlayersEleven[$id_1][4] = $aPlayersEleven[$id_2][4] Then $iChemie += 1
        EndIf
        
        Return $iChemie
    EndFunc
    
    Func Array($a = Null, $b = Null, $c = Null, $d = Null, $e = Null, $f = Null, $g = Null, $h = Null, $i = Null, $j = Null, $k = Null)
        Local $aTemp = [$a, $b, $c, $d, $e, $f, $g, $h, $i, $j, $k]
        
        ReDim $aTemp[@NumParams]
        
        Return $aTemp
    EndFunc   ;==>Array
    
    ; permute elements but for each element is defined on which positions it is allowed to appear
    ; $aArray = [$aPosElement1[...], $aPosElement2[...], ..., $aPosElementN[...]]
    ; return: Array[$N] with element indices
    Func _comb_Permute_restricted(ByRef $aArray, Const $iC = 0)
        Local Static $iRet, $aRet[0][0], $aSample[0], $N
    
        If $iC = 0 Then ; initialisiere in äußerer Rekursion
            $iRet = 0
            $N = UBound($aArray)
            Redim $aSample[$N]
            Redim $aRet[(__comb_factorial($N) > 16777216 ? 16777216 : __comb_factorial($N))]
    
            For $i = 0 To UBound($aSample) - 1    ; set every element to unset status (-1)
                $aSample[$i] = -1
            Next
        EndIf
    
        For $iPos In $aArray[$iC]
            If $aSample[$iPos] <> -1 Then ContinueLoop
            $aSample[$iPos] = $iC
    
            If $iC = $N -1 Then ; last element reached
                $aRet[$iRet] = $aSample
                $iRet += 1
    
                $aSample[$iPos] = -1
                Return
            EndIf
    
            _comb_Permute_restricted($aArray, $iC + 1)
            $aSample[$iPos] = -1
        Next
    
        If $iC = 0 Then
            Redim $aRet[$iRet]
            Return SetExtended($iRet, $aRet)
        EndIf
    EndFunc
    
    Func __comb_factorial(Const $x)
        If $x < 0 Or (Not IsInt($x)) Then Return SetError(1, $x, Null)
        Local $f = 1
    
        For $i = 1 To $x
            $f *= $i
        Next
    
        Return $f
    EndFunc   ;==>__comb_factorial
    Alles anzeigen

    Erster, erfolgreicher Lauf, mit drei wirklich möglichen Aufstellungen:

    ErfolgreicherFormationsLauf.png

  • Beschreibung von Punkten und ihren Kanten zu anderen Punkten

    • aSeCa
    • 10. August 2021 um 16:24

    Langsam? Aber gut, wahrscheinlich macht es bei meinem Use-Case nicht so den gewaltigen Unterschied, solange ich es "nur" bei den äußeren Funktionen nutze.

    Ich habe mit der Array-Funktion jetzt auch den Teil umgebaut, in dem ich meine Formationen beschreibe und ich verstehe eine Sache nicht:

    Code
    #include <Array.au3>
    
    Global $aFormations = [[ _
            Array("GK", 1, 2, 3), _ ; 3-4-1-2
            Array("CB", 0, 2, 6), _
            Array("CB", 0, 1, 3, 4, 5), _
            Array("CB", 0, 2, 8), _
            Array("CM", 2, 5, 6, 7), _
            Array("CM", 2, 4, 7, 8), _
            Array("LM", 1, 4, 9), _
            Array("CAM", 4, 5, 9, 10), _
            Array("RM", 3, 5, 10), _
            Array("ST", 6, 7, 10), _
            Array("ST", 7, 8, 9) _
            ], _
            [ _
            Array("GK", 1, 2, 3), _ ; 3-4-2-1
            Array("CB", 0, 2, 6), _
            Array("CB", 0, 1, 3, 4, 5), _
            Array("CB", 0, 2, 7), _
            Array("CM", 2, 5, 6, 8), _
            Array("CM", 2, 4, 7, 9), _
            Array("LM", 1, 4, 8), _
            Array("RM", 3, 5, 10), _
            Array("LF", 4, 6, 9), _
            Array("RF", 5, 7, 9), _
            Array("ST", 8, 9) _
            ]]
    
    ;~ $aTemp = $aFormations[0] ; Syntax-Fehler. ich erwarte eig., die erste Formation als eigenes Array zu kriegen
    $aTemp = $aFormations[0][0] ; Klappt und krige die erste Position der ersten Formation
    
    _ArrayDisplay($aTemp)
    
    Exit
    
    Func Array($a = Null, $b = Null, $c = Null, $d = Null, $e = Null, $f = Null, $g = Null, $h = Null, $i = Null, $j = Null, $k = Null)
        Local $aTemp = [$a, $b, $c, $d, $e, $f, $g, $h, $i, $j, $k]
    
        ReDim $aTemp[@NumParams]
    
        Return $aTemp
    EndFunc   ;==>Array
    Alles anzeigen

    Warum klappt mein auskommentierter Teil nicht? Meine Erwartung ist, dass ich ich das Array der ersten Formation bekomme. Das sind ja Arrays, in Arrays, in einem Array. An anderen Stellen ziehe ich auch ein Array aus einem Array und habe keine Probleme... Irgendwie stehe ich auf den Schlauch, wo mein Gedankenfehler ist oder ob ich das falsch definiert habe...

  • Beschreibung von Punkten und ihren Kanten zu anderen Punkten

    • aSeCa
    • 10. August 2021 um 14:05

    Mars Cool, vielen Dank! :) Mit allen Permutationen, ohne vorher die Reduzierung der möglichen Positionen zu machen, ist das wirklich ganz schön lang (bei mir 45 Sekunden). Deine "Loop-Lösung", die das direkt berücksichtigt, war die Richtung, die ich mir hätte vorstellen können (die Rekursion ist viel schwerer nachzuvollziehen ^^).

    Ich nehme auf jeden Fall die Idee mit, ein Array für die möglichen Positionen des Spielers in der Formation zu erstellen, bevor ich dann in die Permutationen gehe! Viel besser, als die Prüfung dann beim Durchgehen der ganzen Permutationen zu machen - das spart mir auf jeden Fall Frust, wenn ich nun direkt so weiter coden kann^^

    AspirinJunkie Danke für die alternative Lösung. Auch komplex für mich dem zu folgen, aber noch etwas besser "lesbar" für mich :) Damit werde ich auf jeden Fall mal etwas experimentieren!

    Mögt ihr mir noch erklären, warum ihr - und scheinbar unabhängig voneinander(?) - eine eigene Array-Funktion schreibt, statt das Array von AutoIt an dieser Stelle zu nutzen? Ist das so einfach die beste Variante, wenn man keine "gleich langen" Arrays hat und damit man nicht wie ich oben, manuell überall z. B. "Null" rein schreiben muss oder steckt da noch mehr dahinter? ^^

    *edit*

    Achso, ich verstehe... Durch das @NumParams wird dann nicht nur einfach automatisch aufgefüllt, sondern das Array (im Array) hat damit wirklich nur die Länge, die es braucht - das ist geschickt! ^^ Damit werde ich auch mal meine anderen Teile des Codes umstrukturieren!

  • Beschreibung von Punkten und ihren Kanten zu anderen Punkten

    • aSeCa
    • 10. August 2021 um 00:38

    Das darüber schreiben hilft mir auf jeden Fall schon mal :) Ich bin aber auch lange aus dem Programmieren raus und komme eher aus dem Bereich Wirtschaftsinformatik :D... Das hört sich nach komplexer Literatur an und deine Beschreibung erklärt ja, was der Algo tut und noch nicht wie...

    Gibt es da eine "Abkürzung"? :D Hast du zufällig ein AutoIt-Beispiel oder kennst du eine UDF, die man auf das Problem anpassen kann oder ähnliches?

    Ich habe jetzt bisher "fertig":

    • Team von der Kader-Seite laden
    • Formation/en mit dem Team vergleichen (inkl. möglicher Positions-Modifikatoren) und Aussage darüber treffen, ob die Formation geeignet ist (von 30 Formationen werden vllt. immer nur so 10 überhaupt geeignet sein, nach der Prüfung)
    • Den Einfluss eines benachbarten Spielers auf einen bestimmten Spieler berechnen
    • Prüfen, ob eine bestimmte Position in der Formation für einen Spieler geeignet ist (inkl. möglicher Positions-Modifikatoren)

    Jetzt kommt genau der schwierige Teil, bevor ich das dann nur noch auf alle "geeigneten Formationen" anwenden muss und noch ein paar andere Boni einrechne: Ich muss alle möglichen(!) Kombinationen der Spieler in einer Formation durchlaufen, um dann jeweils die Evaluationsfunktion anzuwenden.

    => Durch die Prüfung, ob ein Spieler für die Funktion geeignet ist (an Hand seiner Position), spare ich mir auch eine Prüfung, wie der Einfluss eines nächsten Spielers jetzt genau ist. Ich möchte einfach alle möglichen Kombinationen einmal durchgehen und dann durch rechnen.

    "Rekursion" ist bei mir auch lange her, aber kann ich dafür nicht irgendwie ganz "billig" alle Positionen mit allen Spielern durchgehen und alle geeigneten (gibt dann einen Ausstiegspunkt aus diesem Loop, wenn die Position für den Spieler nicht passend ist) landen dann in einem Ergebnis-Array? Und in dem Array rechne ich dann für jede Lösung die Chemie-Werte aus und die "beste Aufstellung" für diese Formation, wird dann in einem Ergebnis-Array dieser Formation zugeordnet.

    Das sind dann immer noch einige mögliche Kombinationen, auch wenn ich aus einigen früher raus springen kann und die Abgleiche alle sehr klein sind... Im Worst-Case wird ja auch das Ziel-Array trotzdem noch lang, auch wenn ich durch die Positions-Einschränkungen stark reduziere. Es gibt natürlich auch einen Ziel-Zustand, den ich vllt. als weiteren Ausstiegspunkt für die gesamte Formation noch einbauen kann: Jeder Spieler hat mindestens 9 Chemie; denn dann gibt es keine besseren Lösungen mehr, nur ggfs. andere gute Lösungen.

    => Sind wir fast schon wieder beim Bruteforce-Vorschlag, nur ohne die zufälligen Formationen, oder? hmmm ^^

    ==> Rekursion wäre hier das richtige Stichwort, oder? (muss mich morgen mit frischem Kopf nochmal rein denken) Habe ich irgendwas übersehen und muss vllt. doch noch was zu den nachbarschaftsbasierte Suchalgos in ungerichteten Graphen lesen? :D

  • Beschreibung von Punkten und ihren Kanten zu anderen Punkten

    • aSeCa
    • 9. August 2021 um 20:39

    BugFix Knoten(punkte) und Kanten sind doch ganz normale Bezeichnungen?!

    Mars Danke für deine Antwort :) Ich habe versucht, etwas mehr Kontext zu geben, daher hast du glaube ich über meine Frage schon hinaus gedacht ^^ Also auf die Kern-Frage, wie ich die Beschreibung der Formation am Besten abspeichere, ist dein Vorschlag eine Matrix für jede Position in dieser Formation in einem 2D-Array anzulegen und dann jeweils bei den Kanten zu sagen, ob sie "verbunden" sind?

    Vllt. habe ich es auch noch nicht ganz durchschaut, aber das kommt mir sehr kompliziert und rechenaufwendig vor. So muss ich ja auf jeden Fall pro Position immer schon mal ein großes Array durch-"loopen". Ist es da nicht schneller, an dem Punkt zu beschreiben, mit welchen anderen Punkten er verbunden ist? Wie gesagt, von den 11 Spielern, ist ein Spieler maximal mit 5 (das ist ein sehr seltener Fall) anderen Spielern direkt verbunden.

    Wenn ich jetzt einen RM-Spieler (Right Midfield) habe, gibt es im Prinzip auch nur zwei weitere Positionen, wo er sinnvoll spielen kann (RF = Right Forward und Right Winger). Dadurch erhoffe ich mir auch, dass die Anzahl der Versuche überschaubarer bleibt. Und entsprechen, dass ich auf "zufällige Werte" und "Bruteforce" verzichten kann.

    Also meine Ausgangslange sind 11 Spieler auf 11 Positionen (da ich das Tool ja als Basis nutze, habe ich das als Start-Wert parat). Jeder Spieler kann auf einer begrenzten Anzahl von Positionen spielen (max. 5, Torwart z. B. nur als Torwart) und jeder Spieler ist berechenbar besser ("Chemie"), wenn bestimmte andere Spieler neben ihm spielen (durch die 2-5- "neben ihm"-Verbindungen / -Kanten auch vorher eindeutig feststellbar).

    Das lässt sich sicherlich auch mit Bruteforce lösen und wahrscheinlich ist das sogar programmier-technisch das einfachste und von der Dauer (zumindest in anderen Sprachen) dann auch die "beste" Lösung. Aber da ich mit AutoIt unterwegs bin und das Ergebnis auch möglichst schnell kommen soll (man muss diese Variationen der Spieler für 30 Formationen machen und dann merkt der Nutzer vllt. "ist doof" und tauscht einen Spieler aus und wirft es wieder und wieder an, bis alles passt.
    Daher gehe ich davon aus, dass ich das "optimiert" lösen muss.

    Hier auch nochmal ein Beispiel einer Formation (3-4-1-2):

    FIFA_Beispiel.png

    Und mal vom Code, was ich als mögliche Darstellung im Kopf hatte:

    Code
    GLobal $aFormationNames[30] = ["3-4-1-2", "3-4-2-1", "3-1-4-2", "3-4-3", "3-5-2", "4-1-2-1-2", "4-1-2-1-2(2)", "4-1-4-1", "4-2-3-1", "4-2-3-1(2)", "4-2-2-2", "4-2-4", "4-3-1-2", "4-1-3-2", "4-3-2-1", "4-3-3", "4-3-3(2)", "4-3-3(3)", "4-3-3(4)", "4-3-3(5)", "4-4-1-1", "4-4-1-1(2)", "4-4-2", "4-4-2(2)", "4-5-1", "4-5-1(2)", "5-2-1-2", "5-2-2-1", "5-3-2", "5-4-1"]
    Global $aFormations[1][11][6] = [[["GK", 1, 2, 3, Null, Null], _
                                     ["CB", 0, 2, 6, Null, Null], _
                                     ["CB", 0, 1, 3, 4, 5], _
                                     ["CB", 0, 2, 8, Null, Null], _
                                     ["CM", 2, 5, 6, 7, Null], _
                                     ["CM", 2, 4, 7, 8, Null], _
                                     ["LM", 1, 4, 9, Null, Null], _
                                     ["CAM", 4, 5, 9, 10, Null], _
                                     ["RM", 3, 5, 10, Null, Null], _
                                     ["ST", 6, 7, 10, Null, Null], _
                                     ["ST", 7, 8, 9, Null, Null]]]
    Alles anzeigen
  • Beschreibung von Punkten und ihren Kanten zu anderen Punkten

    • aSeCa
    • 9. August 2021 um 17:11

    Hey zusammen,

    ich habe lange nicht mehr programmiert, aber wollte mir gerne ein kleines Tool für FIFA basteln: Einen "Chemie-Optimierer"

    Es gibt sowas auch als Web-Tool (https://www.futbooster.com), aber das dauert teilweise recht lang und ich würde gerne meine PC-Ressourcen dafür nutzen und ggfs. ein paar Ideen dazu einbauen. Also wollte ich mir erstmal eine vereinfachte Version davon mit AutoIt bauen.

    Damit ich keine Spieler-Datenbanken etc. brauche, hole ich mir einfach einen gepflegten Kader via Http von einer Website, wo man sich Kader zusammenstellen (aber halt nicht derartig optimieren) kann und habe mir dann erstmal eine Funktion gebaut, die sozusagen die Auswirkung der Kanten auf die Punkte berechnet.

    Jetzt bin ich mir aber so gar nicht sicher, wie ich die Formationen am Besten in AutoIt abbilden kann. Also eine Formation besteht aus 11 Punkten, die jeweils mit ganz klar definierten anderen Punkten über Kanten (2-5 Stück) verbunden sind. Eine Kante kann den Wert eines Punktes um -1, 0, +1 oder +2 verändern.

    Also muss ich jetzt irgendwie jede einzelne Formation programmier-technisch beschreiben, damit ich das später dann "durch-loopen" kann^^ Was ist der beste Weg für sowas? Einfach ein 11er Array (0-10) und jeweils die "ID" des Punktes, zu dem es eine Kante gibt, mit in das Array schreiben?
    Beispiel: Torwart ist 0, Innenverteidiger #1 ist 1, Innenverteidiger #2 ist 2 und der Torwart hat nur Kanten zu beiden Innenverteidigern:

    #aFormation_One[0] = ["TW", 1 ,2] ;

    => Ich muss den "Namen" des Punktes auch immer wissen, da Spieler von bestimmten Positionen nachher nur auf bestimmte andere Positionen verschoben werden dürfen, um rum zu probieren. TW = Torwart z. B. bleibt immer auf seinem Punkt, ein defensiver Mittelfeldspieler darf aber auch auf die Position offensives Mittelfeld, etc. Heißt, ich brauche immer "Name" des Punktes und das Wissen, zu welchen anderen Punkten es Kanten gibt.

    Oder gibt es da "bessere" Möglichkeiten, so etwas abzubilden, auch mit dem Wissen, dass das Tool die Kantenberechnung sehr schnell machen können muss, weil die Spieler dann diverse Male auf andere Positionen verschoben werden (Neuberechnung) und das ganze dann für 30 Formationen, bis das beste Ergebnis gefunden wurde.

    Ich hoffe, es ist nicht zu kompliziert beschrieben... ^^ Damit man das Drumherum bei Bedarf besser verstehen kann, hier auch der bisherige Code:

    C
    #include <Array.au3>
    #include <String.au3>
    #include <WinHTTP.au3>
    #include <WinHTTPConstants.au3>
    
    Global $UA =  "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.131 Safari/537.36"
    
    Global $HTTP_Host = "https://www.futbin.com"
    Global $HTTP_Agent = _WinHttpOpen($UA)
    Global $HTTP_Connect = _WinHttpConnect($HTTP_Agent, $HTTP_Host)
        
    
    $sHtml = _SimpleRequest("GET", "/21/squad/9249882")
    
    Global $PlayersEleven[11][8]
    
    ;id = cardlid 1-11 => Haupt-Spieler; 12-23 => Subs
    For $i = 1 To 11
        $aArray =  StringRegExp($sHtml, 'cardlid' & $i & '\"\s+data-formpos=\"(\w+)\"[^!]+data-player-commom=\"([^\"]+)\"[\s\d\w]+data-player-nation=\"([^\"]+)\"[\s\d\w]+data-player-club=\"([^\"]+)\"[\s\d\w]+data-player-league=\"([^\"]+)\"[^!]+Country:\s+([\w\s]+)[^!]+Club:\s+([\w\s]+)[^!]+League:\s+([\w\s]+)',  3)
    
        $PlayersEleven[$i -1][0] = StringUpper($aArray[1]) ; Name
        $PlayersEleven[$i -1][1] = $aArray[0] ; Position
        $PlayersEleven[$i -1][2] = $aArray[2] ; Nation-ID
        $PlayersEleven[$i -1][3] = $aArray[3] ; Club-ID
        $PlayersEleven[$i -1][4] = $aArray[4] ; League-ID
        $PlayersEleven[$i -1][5] = $aArray[5] ; Nation-Name
        $PlayersEleven[$i -1][6] = $aArray[6] ; Club-Name
        $PlayersEleven[$i -1][7] = $aArray[7] ; League-Name
    Next
    
    
    ;~ _ArrayDisplay($PlayersEleven)
    
    ConsoleWrite(checkChemieBonusBetweenTwoPlayers(1, 6) & @CRLF) 
    
    _Exit()
    
        
    Func _SimpleRequest($sType = "GET", $sPath = "", $sPost = $WINHTTP_NO_REQUEST_DATA)
        $aResponse = _WinHttpSimpleSSLRequest($HTTP_Connect, $sType, $sPath, Default, $sPost, Default, True)
    
        Return $aResponse[1]
    EndFunc   ;==>_SimpleRequest
    
    Func _Exit()
        _WinHttpCloseHandle($HTTP_Connect)
        _WinHttpCloseHandle($HTTP_Agent)
        Exit
    EndFunc
    
    Func checkChemieBonusBetweenTwoPlayers($id_1, $id_2) ; Explanation (german): https://www.tonight.de/games/fifa/fifa-ultimate-team-fut-wie-funktioniert-chemie-teamchemie-spielerchemie-links-loyalitaet_77330.html
        ; bad link (-1; red), weak link (0; orange), strong link (+1; green), perfect link (+2; green)
        ; +1 for same nation, +1 for same club, +1 for same league
        ; if Icon: +1 for everyone / +2 for players with same nation / +3 for Icons with same nation
        Local $iChemie = -1
        
        If $PlayersEleven[$id_1][4] = 2118 or $PlayersEleven[$id_2][4] = 2118 Then ; Icons : Club = 112658 (FUT 21 ICONS); League = 2118 (Icons)
            If $PlayersEleven[$id_1][4] = $PlayersEleven[$id_2][4] and $PlayersEleven[$id_1][2] = $PlayersEleven[$id_2][2] Then Return 3
            If $PlayersEleven[$id_1][2] = $PlayersEleven[$id_2][2] Then Return 2
            Return 1
        Else ; Normal players
            If $PlayersEleven[$id_1][2] = $PlayersEleven[$id_2][2] Then $iChemie += 1
            If $PlayersEleven[$id_1][3] = $PlayersEleven[$id_2][3] Then $iChemie += 1
            If $PlayersEleven[$id_1][4] = $PlayersEleven[$id_2][4] Then $iChemie += 1
        EndIf
        
        Return $iChemie
    EndFunc
    Alles anzeigen
  • Herausfinden, welcher Button die Funktion mit GUICtrlSetOnEvent aufgerufen hat

    • aSeCa
    • 8. Juni 2020 um 14:27

    Danke auch an dich! :)

    Ich benutze ISN AutoIt Studio, da ist das Erstellen der Forms echt bequem. Leider ist das für so dynamische Fälle etwas uncool, da ich dann den Überblick verliere, wo noch überall Controls sind (/sein werden).

    Daher schiebe ich das erstmal vor mir her und mache es per späterem Refactoring "schön" (/dynamisch).

    Dann wird mir der Array-Impuls auf jeden Fall helfen.

  • Herausfinden, welcher Button die Funktion mit GUICtrlSetOnEvent aufgerufen hat

    • aSeCa
    • 8. Juni 2020 um 13:49

    Danke dir! :) Damit habe ich es mit dem Testscript auf jeden Fall hinbekommen.

    Im Beispielscript erstelle ich sie ja nicht dynamisch, da wäre das dann so:

    C
    #include <GUIConstantsEx.au3>
    #include <WindowsConstants.au3>
    #include <MsgBoxConstants.au3>
    
    Opt("GUIOnEventMode", 1)
    
    Local $hGUI = GUICreate("Example", 300, 200)
    Local $idButton1 = GUICtrlCreateButton("Config_1", 120, 170, 85, 25)
    GUICtrlSetOnEvent($idButton1, "_test")
    Local $idButton2 = GUICtrlCreateButton("Config_2", 210, 170, 85, 25)
    GUICtrlSetOnEvent($idButton2, "_test")
    
    GUISetState(@SW_SHOW, $hGUI)
    
    While Sleep(50)
    WEnd
    
    Func _test()
    ;~     ConsoleWrite("Button 1 ID " & $idButton1 & @CRLF)
    ;~     ConsoleWrite("Button 2 ID " & $idButton2 & @CRLF)
    ;~     ConsoleWrite("---" & @CRLF)
    
        ConsoleWrite("Button Handle " & @GUI_CtrlHandle & @CRLF)
        ConsoleWrite("Button ID " & @GUI_CtrlId & @CRLF)
    
        If @GUI_CtrlId == $idButton1 Then
            ConsoleWrite("Button Nr. 1" & @CRLF)
        ElseIf @GUI_CtrlId == $idButton2 Then
            ConsoleWrite("Button Nr. 2" & @CRLF)
        Else
            ConsoleWrite("??? O.o" & @CRLF)
        EndIf
    
        Sleep(1000)
    
        GUIDelete($hGUI)
        Exit
    EndFunc
    Alles anzeigen

    Das hat die Frage dann auch direkt geklärt, super! :)

  • Herausfinden, welcher Button die Funktion mit GUICtrlSetOnEvent aufgerufen hat

    • aSeCa
    • 8. Juni 2020 um 13:18

    Hey,

    ich kann es zu schlecht in kurzen Worten beschreiben, um via Google etwas dazu zu finden. Ich hoffe, jemand kann mir helfen, ich glaube, ich habe das schon mal irgendwo gesehen.

    Ausgangslage: Eine GUI, die für verschiedene Objekte immer die gleiche Auswahlmöglichkeiten bietet, so auch einen "Bearbeiten"-Button.

    Ziel: Ich möchte natürlich nur eine "Bearbeiten-Funktion" haben, also würde ich mit GUICtrlSetOnEvent immer diese aufrufen. Jetzt soll aber das Bearbeiten natürlich nur genau auf das Objekt wirken, das ich bearbeiten möchte und dafür müsste ich "nachträglich" wissen, welcher Button diese Funktion aufgerufen hat. Das sollte natürlich dynamisch sein, ohne "Helper-Funktionen", ala "Config_1 ruft "Config(1)" auf und Config_2 ruft "Config(2)" auf" oder so.

    Minimal-Beispiel:

    C
    #include <GUIConstantsEx.au3>
    #include <WindowsConstants.au3>
    #include <MsgBoxConstants.au3>
    
    Opt("GUIOnEventMode", 1)
    
    Local $hGUI = GUICreate("Example", 300, 200)
    Local $idButton1 = GUICtrlCreateButton("Config_1", 120, 170, 85, 25)
    GUICtrlSetOnEvent($idButton1, "_test")
    Local $idButton2 = GUICtrlCreateButton("Config_2", 210, 170, 85, 25)
    GUICtrlSetOnEvent($idButton2, "_test")
    
    GUISetState(@SW_SHOW, $hGUI)
    
    While Sleep(50)
    WEnd
    
    Func _test()
        ConsoleWrite("Button Nr. " & "?" & @CRLF)
    
        Sleep(1000)
    
        GUIDelete($hGUI)
        Exit
    EndFunc
    Alles anzeigen

    => ich möchte, dass das "?" ersetzt wird, durch die "1" (oder "2).

    Danke für die Unterstützung!

  • Return (zur Hauptschleife)

    • aSeCa
    • 29. Juni 2019 um 12:09

    @Musa: Ja genau, danke :) Aber ich suche nach einer Alternativen, da ich gerne möglichst ala "Clean Code" viele Funktionsbausteine habe und den "Return wegen Fehler" dann über etliche Funktionen schleifen muss. Der Aufwand ist mir egal, aber das ist doch echt lästig viel Code... ^^ Muss doch irgendwas geben? :D Oder einen findigen Workaround, wenn keine Funktion das hergibt.

    alpines: Hm, ok, danke. Was heißt gut strukturiert? Ich habe einfach wenig Fehlerhandling bisher, aber viele Funktionen zu nutzen dient ja grade einer guten Struktur. Dein Hinweis zu "HandleMyError" hat mich aber auf eine Idee gebracht... Ich könnte natürlich einfach eine "Reparieren-Funktion" bauen, die das Skript wieder lauffähig macht und das beim Abfang des Fehlers starten... Und ich schaue mir auch die genannte Funktion mal an, aber ich weiß wo der Fehler auftaucht und warum.

    Die einfachste Variante wäre einfach gewesen, von Vorne anzufangen - aber ich dann muss ich doch mal gucken, wie mein Skript mit dem Fehler (den ich nicht vermeiden kann) umgehen soll. :)

    Danke für die Impulse.

    *edit* Ah, _HandleMyError() war auch genau das mit gemeint, das ist gar keine bestehende Funktion ^^!

  • Return (zur Hauptschleife)

    • aSeCa
    • 29. Juni 2019 um 09:31

    Hey zusammen,

    gibt es eine Möglichkeit, direkt zur Hauptschleife des Programms zurückzukehren? Also eine Art z. B. "Return(X)" (im Vergleich zu ExitLoop)?

    Ich frage, da ich, wenn ich einen Fehler abfange, gerne alles stoppen würde, was das Programm noch vor hat und er einfach alle Funktionen verlassen soll. Muss ich dafür den abgefangenen Fehler komplett durchreichen und immer wieder "returnen"?

    Es ist ja nicht so sauber, die Hauptschleife in eine Funktion zu packen und dann einfach nach Aufkommen des Fehlers dort rein zu schicken...

    Was habe ich für Möglichkeiten? Vielen Dank :)

  • Mehrere GUIs miteinander "verbinden"

    • aSeCa
    • 7. Mai 2019 um 21:33

    Hey, sehr cool, vielen Dank! Die UDF hat auf jeden Fall geholfen :) Gibt den kleinen "Bug", dass man, wenn man es in den Hintergrund bringt und dann nur einen der beiden "Fenster-Teile" nach vorne holt, dass das andere hinter anderen Fenstern verschwindet. Besonders lustig, wenn man 2 Bildschirme hat und auf dem einen dem Browser den Focus gibt, dann nur die Haupt-GUI anklickt und diese auf den anderen Bildschirm zieht: Dann ist die Haupt-GUI zu sehen und das angedockte Fenster ist verschwunden^^...

    Und im Thread hast du eine "_GUIDocking_ShutDown()" erwähnt, die es nicht gibt.

    Aber tut mir jetzt nicht so weh. :) Hat auf jeden Fall einige meiner Fragen gelöst, besten Dank.


    *edit*

    Scheint doch leider nicht rund zu laufen: GUI hängt sich immer auf, wenn ich via GuiCtrlSetOnEvent eine Anpassung an einer der GUIs mache.

    Im Player sehe ich auch nur eine GUI - Programminfo und Hilfe sind zwei weitere, die aber nicht docken.

  • Mehrere GUIs miteinander "verbinden"

    • aSeCa
    • 6. Mai 2019 um 23:04

    Hallo,

    ich habe eine GUI, die ich gerne um einen "toggle-baren Teil" erweitern möchte: Heißt, ich möchte etwas unten an die GUI dran heften und es auch wieder verschwinden lassen können. Ich habe dafür 2 GUIs erstellt und via "$BS_PUSHLIKE"-Checkbox mit GUICtrlSetOnEvent kann ich aus der Haupt-GUI die 2. GUI ein- und ausblenden.

    Jetzt würde ich es gerne so machen, dass die wirklich aneinander "kleben":

    • GUI 2 soll sich nur und immer mit der Haupt-GUI bewegen
    • GUI 2 soll genau unten an der Haupt-GUI andocken
    • GUI 2 soll senkrecht (nur nach unten!) vergrößerbar sein
    • GUI 2 soll senkrecht (nur nach oben!) wieder so weit verkleinerbar sein, bis zur Ursprungsgröße
    • GUI 2 soll waagerecht weder verkleiner-, noch vergrößerbar sein

    Ich habe mal eine Minimal-Version gebaut, vielen Dank für die Unterstützung :)

    C
    ; -- Created with ISN Form Studio 2 for ISN AutoIt Studio -- ;
    #include <StaticConstants.au3>
    #include <GUIConstantsEx.au3>
    #include <WindowsConstants.au3>
    #Include <GuiButton.au3>
    
    Opt("GUIOnEventMode", 1)
    Opt("TrayAutoPause", 0)
    Opt("TrayMenuMode", 7)
    
    $MainGUI = GUICreate("Test",1014,259,-1,-1,-1,-1)
    GUISetOnEvent($GUI_EVENT_CLOSE, "_Exit", $MainGUI)
    $cbDetails = GUICtrlCreateCheckbox("Details",479,211,58,21,$BS_PUSHLIKE,-1)
    
    Global $iHTMLObjectWidth = 1014, $iHTMLObjectHeight = 350
    
    GUICtrlSetOnEvent($cbDetails, "_DetailsButton")
    
    GUISetState(@SW_SHOW, $MainGUI)
    
    Global $DetailGUI = GUICreate("Test 2", $iHTMLObjectWidth, $iHTMLObjectHeight, (@DesktopWidth - $iHTMLObjectWidth) / 2, (@DesktopHeight - $iHTMLObjectHeight) / 2, $WS_OVERLAPPEDWINDOW + $WS_CLIPSIBLINGS + $WS_CLIPCHILDREN)
    GUISetOnEvent($GUI_EVENT_CLOSE, "closeDetails")
    
    While 1
        Switch GUIGetMsg()
            Case $GUI_EVENT_CLOSE
                ExitLoop
        EndSwitch
    WEnd
    
    Func showDetails()
        GUISetState(@SW_SHOW, $DetailGUI)
    EndFunc
    
    Func closeDetails()
        GUISetState(@SW_HIDE, $DetailGUI)
        GUICtrlSetState($cbDetails, $GUI_UNCHECKED)
    EndFunc
    
    Func _DetailsButton()
        If GUICtrlRead($cbDetails) = $GUI_CHECKED Then
            showDetails()
        Else
            closeDetails()
        EndIf
    
    EndFunc
    
    Func _Exit()
        Exit
    EndFunc
    Alles anzeigen

    Grüße

  • Erzeugen von komplexeren, formatierten Tabellen

    • aSeCa
    • 6. Mai 2019 um 07:33

    base64 encoden habe ich auch überlegt. Ich war mir nur nicht sicher, wie ich das dann an den HTML-Code übergebe. Die Datei steckt dann ja sozusagen "in der Variable" und der HTML-Code erwartet einen Pfad und kann das nicht verarbeiten, oder?

    Oder versteckt sich hinter "inline" noch ein Tipp, den ich nicht kenne/verstehe? :)

    Absolute Pfade sind ein Problem, wenn man das Tool auf einem anderen Gerät nutzen möchte, ohne etwas anzupassen. Mir fällt aber grade ein, dass ich ja einfach @ScriptDir nutzen können sollte... Immer wenn ich ein paar Monate nicht programmiert habe, ist das erstmal wieder so schleppend...^^'

    Danke dir!

  • Erzeugen von komplexeren, formatierten Tabellen

    • aSeCa
    • 5. Mai 2019 um 23:21

    Ja, cool. Das geht wohl, mal weiter mit probieren, danke :)

    Hast du einen TIpp bezüglich Bildern, die ich einfügen möchte? Da ich keine HTML-Datei habe, brauche ich scheinbar absolute Pfade, sry="pic.png" geht nicht, wenn das Bild im Skript-Verzeichnis liegt. Das ist natürlich schon sehr unpraktisch.

  • Erzeugen von komplexeren, formatierten Tabellen

    • aSeCa
    • 5. Mai 2019 um 20:37

    Ok, danke. :) Dann bleibe ich mal bei HTML. Habe mir da mal eine Vorlage gemacht und schaue dann mal, dass ich mir den Code über Schleifen etc. zusammenbastel. Mit den beiden gefundenen UDFs ließen sich auch nicht alle Ideen umsetzen.

    Mal schauen, ob sich das HTML-Element gut einbinden lässt. Die Tabelle wird jedes Mal anders groß sein, etc...

    Ich muss die HTML erst erzeugen lassen und dann einlesen, oder? Über Zwischenspeicher rendern etc. oder sowas geht nicht?! :)

  • Erzeugen von komplexeren, formatierten Tabellen

    • aSeCa
    • 5. Mai 2019 um 13:09

    Die Funktion kenne ich, dennoch Danke für deine Antwort. :)


    Mir geht es darum, ob mir jemand einen Tipp geben kann, was da die einfachste/sinnvollste Variante ist.

    Ich habe auch eine ListView-UDF gefunden: https://www.autoitscript.com/forum/topic/89…#comment-731575

    Und eine Table UDF: https://www.autoitscript.com/forum/topic/105814-table-udf/

    Und vllt. gibt es auch noch andere UDFs, um HTML auf der GUI anzeigen lassen zu können. Irgendwer hat sich ja bestimmt schon mal intensiver damit beschäftigt, was "aktuell" die beste Variante ist, um flexibel Berechnungen auf einer AutoIt-GUI anzeigen lassen zu können. :)

  • Erzeugen von komplexeren, formatierten Tabellen

    • aSeCa
    • 5. Mai 2019 um 08:13

    Hey zusammen,

    welches ist die einfachste Möglichkeit, in einer GUI Tabellen von erstmal unbekannter Größe zu erzeugen, in der Felder auch unterschiedlich formatierbar sein sollen (bei der Erzeugung, nicht unbedingt vom Nutzer anpassbar), inkl. Icons vor dem Text.

    Ich habe Beispiele gefunden, für die Formatierung, aber das scheint mir noch recht komplex zu sein, das alles auch flexibel aufzubauen. Vllt. gibt es ja noch einfachere Möglichkeiten, ich habe auch überlegt, ob man sich vllt. als GUI ein kleines Browserfenster macht und die Tabelle in HTML erzeugen lässt oder so!?

    Ziel ist, Daten aus dem Zwischenspeicher des Nutzers zu holen und die ordentlich visuell darzustellen.

    Hat jemand einen Tipp für mich? :)

    Danke und Grüße

Spenden

Jeder Euro hilft uns, Euch zu helfen.

Download

AutoIt Tutorial
AutoIt Buch
Onlinehilfe
AutoIt Entwickler
  1. Datenschutzerklärung
  2. Impressum
  3. Shoutbox-Archiv
Community-Software: WoltLab Suite™