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. fee

Beiträge von fee

  • Farben Sortieren / Gruppieren

    • fee
    • 7. April 2023 um 18:03

    Danke UEZ , vielleicht kann ich sowas irgendwann mal in PureBasic brauchen, wenn ich das wiederum portiert bekomme, FreeBasic hab ich nämlich nicht.

  • Farben Sortieren / Gruppieren

    • fee
    • 7. April 2023 um 02:18

    Möglicherweise habe ich das zur Sortierung in Beitrag #16 passende JavaScript gefunden. Nach Berichtigung der Kodierung mit Notepad++ und JSFormat des Plugins JSTool müsste die Funktion ab Zeile 902 bis Zeile 909 im Dateianhang und natürlich einigen Unterfunktionen darunter und darüber für die Farbsortierung zuständig sein. :/

    Jetzt braucht es nur noch jemand mit Muse, Zeit und guten JavaScript-Kenntnissen, um das wirklich sauber übersetzen und meine Vermutung überprüfen zu können. Ich habe leider weder Zeit dafür noch gute JavaScript-Kenntnisse. X/

    Dateien

    VectorLibrary.7z 33,29 kB – 219 Downloads
  • Schreiben in Registry - kein Fehler, Eintrag wird erstellt, ist aber im Reg-Editor nicht sichtbar?

    • fee
    • 29. März 2023 um 21:35

    Soll die erste Tabelle etwa die transponierte Version der zweiten sein?

    Also, entweder verstehe ich sie dann nicht oder sie ist inhaltlich falsch.

    Erklärung? Oder besser einen ScreenShot aus Excel, falls die hier schlecht umsetzbare Formatierung nicht nur die drei rechten redundanten Zellen der Kopfzeile betrifft.

    Bei der zweiten Tabelle aufpassen, dass die beiden hinzugefügten Zeilen ohne rowspan sind und in den HTML-Code-Tagattributen der X-Bit-Zellen jetzt rowspan="3" steht (siehe fehlende Zeilentrennlinien), auch in der Hilfedatei.

    Edit: Sollten wir das nicht besser per PN weitermachen? Sonst entfremden wir dieses Thema hier vollends!

  • Schreiben in Registry - kein Fehler, Eintrag wird erstellt, ist aber im Reg-Editor nicht sichtbar?

    • fee
    • 29. März 2023 um 03:13

    Tweaky : Oder so (jeweils die ... als … [Auslassungspunkte; Alt+0133], die Liste als <ul><li>…</li></ul>, die Tabelle als <table><thead><tr><th>…</th></tr></thead><tbody><tr><td>…</td></tr></tbody></table> und die Negation im Satz nach der Tabelle hat bei mir den Aha-Effekt ausgelöst):

    Hilfetext-Vorschlag

    Registry-Zweige:

    • 64 Bit: HKLM\SOFTWARE\…
    • 32 Bit: HKLM\SOFTWARE\WOW6432Node\…
    AutoIt-Skript Registrierungs-Editor
    Ausführungs-Modus Angabe im Quellcode Verwendeter Zweig
    32 Bit HKLM\SOFTWARE\… HKLM\SOFTWARE\WOW6432Node\…
    HKLM64\SOFTWARE\… HKLM\SOFTWARE\…
    64 Bit HKLM\SOFTWARE\… HKLM\SOFTWARE\…
    HKLM64\SOFTWARE\… HKLM\SOFTWARE\…

    HKLM64 ist also nur für 32-Bit-AutoIt-Skripte (x86) wichtig und auch nur dann, wenn von dort aus NICHT in WOW6432Node geschrieben werden soll.

    Außerdem wäre es vielleicht noch interessant, nach dem ersten oder zweiten Satz in den Bemerkungen der Reg*()-Funktionen mit einzubringen, dass HK oder HKEY schlicht Handle (to a) KEY (siehe Absatz-Ende) bedeutet. Wusste ich bis vorgestern nicht.

    Gruß, fee

  • Schreiben in Registry - kein Fehler, Eintrag wird erstellt, ist aber im Reg-Editor nicht sichtbar?

    • fee
    • 28. März 2023 um 18:33

    Guten Abend.

    Tweaky: Dein Textvorschlag ist ja mittlerweile in der deutschen Hilfe gelandet, war aber für mich trotzdem nicht ausreichend verständlich, unter welchen Architektur-Umständen/-Kombinationen ein Registry-Eintrag gelesen werden kann oder nicht. Deshalb bastelte ich mir schnell ein Test-Skriptchen und kam zu einer lauffähigen Lösung.

    Hätte der letzte Absatz aus Beitrag #7 von AspirinJunkie vom Sinn her und vor allem der letzte Satz dort nach dem Doppelpunkt auch in der Hilfe gestanden, wäre das Thema für mich gleich klar verständlich gewesen, auch ohne Verweis auf die Microsoft-Website, die einen noch mehr verwirrt, auch weil dort beispielsweise Keys mit Tasten übersetzt wird.

    Wäre also schön und nett, wenn ihr diesen Absatz sinngemäß in die Hilfe für die Reg*()-Funktionen mit aufnehmen könntet.

    Gruß, fee

    Edit: Mein Zusatztext-Vorschlag aus dem Beitrag von AspirinJunkie zusammengeschustert:

    Das Skript wird als x86-Programm ausgeführt? Dann ist:

    • HKLM\SOFTWARE der 64 Bit-Zweig und
    • HKLM\SOFTWARE\WOW6432Node der 32 Bit-Zweig

    HKLM64 ist demnach anzugeben, wenn von einem x86-Skript aus NICHT in WOW6432Node geschrieben werden soll.

  • Farben Sortieren / Gruppieren

    • fee
    • 18. März 2023 um 21:06

    UEZ , gerne und auch Danke fürs Lob. :)

    Den Code im SourceCode habe ich auch nicht finden können. Ich vermute, der ist in PHP geschrieben, weil die Seite jedes Mal neu geladen wird. Da kommt man dann nicht ran, außer man fragt den Admin.

    eukalyptus : Sehr schön, das SortByHUEGroup_LABLightness_V2, so sind wenigstens die Farben gut gruppiert.

  • Farben Sortieren / Gruppieren

    • fee
    • 18. März 2023 um 07:52

    Hallo,

    vielleicht kann jemand die Formeln von CIEDE2000 verstehen und umsetzen. Möglicherweise können die Farben damit besser sortiert werden. Jedenfalls sehen diese Sortierungen für mich recht ordentlich aus.

    Übrigens, um sich den Weg zum Ziel zu erleichtern und für jeden Versuch/Jedermann immer die gleichen Ausgangsfarben zu haben, könnte man z. B. SRandom(80) oberhalb der Random()-Schleife (Zeile 13) setzen.

    Ich für meinen Teil bin nicht weit gekommen:

    AutoIt
    ;Coded by UEZ build 2023-03-16
    #include <Array.au3>
    #include <GDIPlus.au3>
    #include <GUIConstantsEx.au3>
    #include <WindowsConstants.au3>
    _GDIPlus_Startup()
    
    Global $hGUI = GUICreate("GDI+ Color Sorting / Grouping Test", 800, 80); 520)
    GUISetState()
    Global $hGraphic = _GDIPlus_GraphicsCreateFromHWND($hGUI)
    Global $hPen = _GDIPlus_PenCreate(0)
    _GDIPlus_GraphicsClear($hGraphic)
    SRandom(80)
    
    Global $aColortable[511], $i, $y = 0
    For $i = 0 To UBound($aColortable) - 1
      $aColortable[$i] = Int(Random() * 0x1000000)
    Next
    
    ; For $i = 0 To UBound($aColortable) - 1
    ;   Do
    ;     $iColor = Int(Random() * 0xFFFFFF)
    ;     $a = RGB2HSV($iColor)
    ;   Until $a[2] > 0.98 And $a[1] > 0.98
    ;   $aColortable[$i] = $iColor
    ; Next
    
    DrawColors($y, "Random")
    
    ; _ArraySort($aColortable)
    ; $y += 40
    ; DrawColors($y, "Default Array Sort")
    
    ; SortByCMYK($aColortable)
    ; $y += 40
    ; DrawColors($y, "CMYK")
    
    ; SortByLum($aColortable)
    ; $y += 40
    ; DrawColors($y, "Luminosity")
    
    ; SortByDistance($aColortable)
    ; $y += 40
    ; DrawColors($y, "Distance")
    
    ; SortByHSL($aColortable)
    ; $y += 40
    ; DrawColors($y, "HSL by L")
    
    ; SortByHSV($aColortable)
    ; $y += 40
    ; DrawColors($y, "HSV by V")
    
    ; SortByHSL($aColortable, 1)
    ; $y += 40
    ; DrawColors($y, "HSL / HSV by H")
    
    ; SortByHSL2($aColortable)
    ; $y += 40
    ; DrawColors($y, "HSV 2")
    
    ; SortByGroupingHSL($aColortable)
    ; $y += 40
    ; DrawColors($y, "Grouping HSL by dist.")
    
    ; SortByGroupingHSV($aColortable)
    ; $y += 40
    ; DrawColors($y, "Grouping HSV by LAB")
    
    ; SortByLAB($aColortable)
    ; $y += 40
    ; DrawColors($y, "LAB")
    
    SortByBrightColor($aColortable)
    $y += 40
    DrawColors($y, "Brightness Colorness")
    
    While GUIGetMsg() <> $GUI_EVENT_CLOSE
      Sleep(10)
    WEnd
    
    _GDIPlus_PenDispose($hPen)
    _GDIPlus_GraphicsDispose($hGraphic)
    _GDIPlus_Shutdown()
    GUIDelete()
    Exit
    
    Func DrawColors($y, $txt = 0, $array = $aColortable)
      If UBound($array, 2) Then
        For $i = 0 To UBound($array) - 1
          _GDIPlus_PenSetColor($hPen, BitOR(0xFF000000, $array[$i][0]))
          _GDIPlus_GraphicsDrawLine($hGraphic, $i, $y, $i, $y + 32, $hPen)
        Next
      Else
        For $i = 0 To UBound($array) - 1
          _GDIPlus_PenSetColor($hPen, BitOR(0xFF000000, $array[$i]))
          _GDIPlus_GraphicsDrawLine($hGraphic, $i, $y, $i, $y + 32, $hPen)
        Next
      EndIf
      If $txt Then _GDIPlus_GraphicsDrawString($hGraphic, $txt, $i + 8, $y + 4, "Arial", 16, Default, 0xFFFFFFFF)
    EndFunc
    
    Func SortByCMYK(ByRef $aColortable) ;http://www.easyrgb.com/en/math.php
      Local $aColortable2[UBound($aColortable)][6]
      Local $a, $i
      For $i = 0 To UBound($aColortable) - 1
        $a = RGA2CMYK($aColortable[$i])
        $aColortable2[$i][0] = $aColortable[$i]
        $aColortable2[$i][1] = $a[0] ;C
        $aColortable2[$i][2] = $a[1] ;M
        $aColortable2[$i][3] = $a[2] ;Y
        $aColortable2[$i][4] = $a[3] ;K
        $aColortable2[$i][5] = Sqrt($a[0] ^ 2 + $a[1] ^ 2 + $a[2] ^ 2 + $a[3] ^ 2)
      Next
      Local $aSort[] = [5, 3]
      _ArraySort_MultiColumn($aColortable2, $aSort, 1, 0)
      For $i = 0 To UBound($aColortable2) - 1
        $aColortable[$i] = $aColortable2[$i][0]
      Next
      Dim $aColortable2[0]
    EndFunc
    
    Func SortByLum(ByRef $aColortable)
      Local $aColortable2[UBound($aColortable)][4], $a, $i, $r, $g, $b, $lum, $h2, $lum2, $v2, $repetitions = 1
      For $i = 0 To UBound($aColortable) - 1
        $r = BitShift(BitAND($aColortable[$i], 0xFF0000), 16)
        $g = BitShift(BitAND($aColortable[$i], 0xFF00), 8)
        $b = BitAND($aColortable[$i], 0xFF)
        $lum = Sqrt(0.241 * $r + 0.691 * $g + 0.068 * $b)
        $a = RGB2HSV($aColortable[$i])
        $h2 = Int($a[0] * $repetitions)
        $lum2 = Int($lum * $repetitions)
        $v2 = Int($a[2] * $repetitions)
    ;~         If Mod($h2, 2) = 1 Then
    ;~             $v2 = $repetitions - $v2
    ;~             $lum2 = $repetitions - $lum
    ;~         EndIf
        $aColortable2[$i][0] = $aColortable[$i]
        $aColortable2[$i][1] = $h2 ;H
        $aColortable2[$i][2] = $lum2 ;S
        $aColortable2[$i][3] = $v2 ;V
      Next
    ;~     Local $aSort[] = [2, 3]
    ;~     _ArraySort_MultiColumn($aColortable2, $aSort, 0, 0)
    ;~     DrawColors(96, "Test", $aColortable2)
      Local $aSort2[][] = [[2, 0], [3, 0]]
      _ArrayMultiColSort($aColortable2, $aSort2)
      For $i = 0 To UBound($aColortable2) - 1
        $aColortable[$i] = $aColortable2[$i][0]
      Next
      Dim $aColortable2[0]
    EndFunc
    
    Func SortByLAB(ByRef $aColortable, $iStartRGB = 0) ;by eukalyptus
      Local $iDim = UBound($aColortable), $iDim2 = UBound($aColortable, 2)
      Local $aLAB[$iDim][2], $i
    
      If $iDim2 Then
        For $i = 0 To $iDim - 1
          $aLAB[$i][0] = _RGB2LAB($aColortable[$i][0])
        Next
      Else
        For $i = 0 To $iDim - 1
          $aLAB[$i][0] = _RGB2LAB($aColortable[$i])
        Next
      EndIf
    
      Local $aLastLAB = _RGB2LAB($iStartRGB)
    
      Local $aSort[$iDim], $fD, $fMin, $iIdx
      For $i = 0 To $iDim - 1
        $fMin = 2 ^ 32
        $iIdx = -1
        For $j = 0 To $iDim - 1
          If $aLAB[$j][1] Then ContinueLoop
          $fD = Sqrt((($aLAB[$j][0])[0] - $aLastLAB[0]) ^ 2 + (($aLAB[$j][0])[1] - $aLastLAB[1]) ^ 2 + (($aLAB[$j][0])[2] - $aLastLAB[2]) ^ 2)
          If $fD < $fMin Then
            $fMin = $fD
            $iIdx = $j
          EndIf
        Next
        $aSort[$i] = $iIdx
        $aLastLAB = $aLAB[$iIdx][0]
        $aLAB[$iIdx][1] = True
      Next
    
      $aTmp = $aColortable
      For $i = 0 To $iDim - 1
        If $iDim2 Then
          $aColortable[$i][0] = $aTmp[$aSort[$i]][0]
        Else
          $aColortable[$i] = $aTmp[$aSort[$i]]
        EndIf
      Next
    EndFunc
    
    Func _RGB2LAB($iRGB) ;by eukalyptus
      Local $aRGB[3], $i
      $aRGB[0] = BitAND(BitShift($iRGB, 16), 0xFF) / 255
      $aRGB[1] = BitAND(BitShift($iRGB, 8), 0xFF) / 255
      $aRGB[2] = BitAND($iRGB, 0xFF) / 255
    
      For $i = 0 To 2
        If $aRGB[$i] > 0.04045 Then
          $aRGB[$i] = (($aRGB[$i] + 0.055) / 1.055) ^ 2.4
        Else
          $aRGB[$i] = $aRGB[$i] / 12.92
        EndIf
        $aRGB[$i] *= 100
      Next
    
      Local $aXYZ[3]
      $aXYZ[0] = ($aRGB[0] * 0.4124 + $aRGB[1] * 0.3576 + $aRGB[2] * 0.1805) / 95.047
      $aXYZ[1] = ($aRGB[0] * 0.2126 + $aRGB[1] * 0.7152 + $aRGB[2] * 0.0722) / 100.0
      $aXYZ[2] = ($aRGB[0] * 0.0193 + $aRGB[1] * 0.1192 + $aRGB[2] * 0.9505) / 108.883
    
      For $i = 0 To 2
        If $aXYZ[$i] > 0.008856 Then
          $aXYZ[$i] = $aXYZ[$i] ^ 0.3333333333333333
        Else
          $aXYZ[$i] = (7.787 * $aXYZ[$i]) + (16 / 116)
        EndIf
      Next
    
      Local $aLAB[3]
      $aLAB[0] = (116 * $aXYZ[1]) - 16
      $aLAB[1] = 500 * ($aXYZ[0] - $aXYZ[1])
      $aLAB[2] = 200 * ($aXYZ[1] - $aXYZ[2])
    
      Return $aLAB
    EndFunc
    
    Func SortByDistance(ByRef $aColortable, $iDir = 0)
      Local $i, $aTmp[2], $swapped
      If $iDir = 0 Then ;sort ascending
        If UBound($aColortable, 2) Then
          Do ;bubblesort -> slow!
            $swapped = 0
            For $i = 0 To UBound($aColortable) - 2
              Distance($aColortable[$i][0], $aColortable[$i + 1][0])
              If @extended Then
                $aTmp[0] = $aColortable[$i][0]
                $aColortable[$i][0] = $aColortable[$i + 1][0]
                $aColortable[$i + 1][0] = $aTmp[0]
                $swapped = 1
              EndIf
            Next
          Until $swapped = 0
        Else
          Do ;bubblesort -> slow!
            $swapped = 0
            For $i = 0 To UBound($aColortable) - 2
              Distance($aColortable[$i], $aColortable[$i + 1])
              If @extended Then
                $aTmp[0] = $aColortable[$i]
                $aColortable[$i] = $aColortable[$i + 1]
                $aColortable[$i + 1] = $aTmp[0]
                $swapped = 1
              EndIf
            Next
          Until $swapped = 0
        EndIf
      Else ;sort descending
        If UBound($aColortable, 2) Then
          Do ;bubblesort -> slow!
            $swapped = 0
            For $i = UBound($aColortable) - 1 To 1 Step -1
              Distance($aColortable[$i][0], $aColortable[$i - 1][0])
              If @extended Then
                $aTmp[0] = $aColortable[$i][0]
                $aColortable[$i][0] = $aColortable[$i - 1][0]
                $aColortable[$i - 1][0] = $aTmp[0]
                $swapped = 1
              EndIf
            Next
          Until $swapped = 0
        Else
          Do ;bubblesort -> slow!
            $swapped = 0
            For $i = UBound($aColortable) - 1 To 1 Step -1
              Distance($aColortable[$i], $aColortable[$i - 1])
              If @extended Then
                $aTmp[0] = $aColortable[$i]
                $aColortable[$i] = $aColortable[$i - 1]
                $aColortable[$i - 1] = $aTmp[0]
                $swapped = 1
              EndIf
            Next
          Until $swapped = 0
        EndIf
      EndIf
    EndFunc
    
    Func SortByHSL(ByRef $aColortable, $sc = 3)
      Local $aColortable2[UBound($aColortable)][5]
      Local $a, $i
      For $i = 0 To UBound($aColortable) - 1
        $a = RGB2HSL($aColortable[$i])
        $aColortable2[$i][0] = $aColortable[$i]
        $aColortable2[$i][1] = $a[0] ;H
        $aColortable2[$i][2] = $a[1] ;S
        $aColortable2[$i][3] = $a[2] ;L
        $aColortable2[$i][4] = Sqrt($a[0] ^ 2 + $a[1] ^ 4 + $a[2] ^ 8) ;Sqrt(($a[0] / 360) ^ 2 + $a[1] ^ 2 + $a[2] ^ 2)
      Next
      $sc = Max(Min($sc, 4), 1)
      _ArraySort($aColortable2, 0, 0, 0, $sc)
      For $i = 0 To UBound($aColortable2) - 1
        $aColortable[$i] = $aColortable2[$i][0]
      Next
      Dim $aColortable2[0]
    EndFunc
    
    Func SortByHSV(ByRef $aColortable, $sc = 3)
      Local $aColortable2[UBound($aColortable)][4]
      Local $a, $i
      For $i = 0 To UBound($aColortable) - 1
        $a = RGB2HSV($aColortable[$i])
        $aColortable2[$i][0] = $aColortable[$i]
        $aColortable2[$i][1] = $a[0]
        $aColortable2[$i][2] = $a[1]
        $aColortable2[$i][3] = $a[2]
      Next
      $sc = Max(Min($sc, 3), 1)
      _ArraySort($aColortable2, 0, 0, 0, $sc)
      For $i = 0 To UBound($aColortable2) - 1
        $aColortable[$i] = $aColortable2[$i][0]
      Next
      Dim $aColortable2[0]
    EndFunc
    
    Func SortByGroupingHSL(ByRef $aColortable, $sc = 2, $sortmode = 2)
      Local $red[0][2], $orange[0][2], $yellow[0][2], $lime[0][2], $green[0][2], $turqoise[0][2], $cyan[0][2], $cobalt[0][2], $blue[0][2], $violet[0][2], $magenta[0][2], $crimson[0][2], $grey[0][2], $i, $j, $col
      $sc = Max(Min($sc, 2), 0)
      For $i = 0 To UBound($aColortable) - 1
        $col = $aColortable[$i]
        Switch RGBtoColorGroup($col)
          Case "red"
            _ArrayAdd($red, $aColortable[$i] & "|" & RGB2HSL($col)[$sc])
          Case "orange"
            _ArrayAdd($orange, $aColortable[$i] & "|" & RGB2HSL($col)[$sc])
          Case "yellow"
            _ArrayAdd($yellow, $aColortable[$i] & "|" & RGB2HSL($col)[$sc])
          Case "lime"
            _ArrayAdd($lime, $aColortable[$i] & "|" & RGB2HSL($col)[$sc])
          Case "green"
            _ArrayAdd($green, $aColortable[$i] & "|" & RGB2HSL($col)[$sc])
          Case "turqoise"
            _ArrayAdd($turqoise, $aColortable[$i] & "|" & RGB2HSL($col)[$sc])
          Case "cyan"
            _ArrayAdd($cyan, $aColortable[$i] & "|" & RGB2HSL($col)[$sc])
          Case "cobalt"
            _ArrayAdd($cobalt, $aColortable[$i] & "|" & RGB2HSL($col)[$sc])
          Case "blue"
            _ArrayAdd($blue, $aColortable[$i] & "|" & RGB2HSL($col)[$sc])
          Case "violet"
            _ArrayAdd($violet, $aColortable[$i] & "|" & RGB2HSL($col)[$sc])
          Case "magenta"
            _ArrayAdd($magenta, $aColortable[$i] & "|" & RGB2HSL($col)[$sc])
          Case "crimson"
            _ArrayAdd($crimson, $aColortable[$i] & "|" & RGB2HSL($col)[$sc])
          Case "grey"
            _ArrayAdd($grey, $aColortable[$i] & "|" & RGB2HSL($col)[$sc])
        EndSwitch
      Next
      $sortmode = Max(Min($sortmode, 2), 1)
      Switch $sortmode
        Case 1
          _ArraySort($red, 0, 0, 0, 1)
          _ArraySort($orange, 0, 0, 0, 1)
          _ArraySort($yellow, 0, 0, 0, 1)
          _ArraySort($lime, 0, 0, 0, 1)
          _ArraySort($green, 0, 0, 0, 1)
          _ArraySort($turqoise, 0, 0, 0, 1)
          _ArraySort($cyan, 0, 0, 0, 1)
          _ArraySort($cobalt, 0, 0, 0, 1)
          _ArraySort($blue, 0, 0, 0, 1)
          _ArraySort($violet, 0, 0, 0, 1)
          _ArraySort($magenta, 0, 0, 0, 1)
          _ArraySort($crimson, 0, 0, 0, 1)
          _ArraySort($grey, 0, 0, 0, 1)
        Case 2
          SortByDistance($red, 1)
          SortByDistance($orange)
          SortByDistance($yellow, 1)
          SortByDistance($lime)
          SortByDistance($green, 1)
          SortByDistance($turqoise)
          SortByDistance($cyan, 1)
          SortByDistance($cobalt)
          SortByDistance($blue, 1)
          SortByDistance($violet)
          SortByDistance($magenta, 1)
          SortByDistance($crimson)
          SortByDistance($grey, 1)
      EndSwitch
      $i = 0
      For $j = 0 To UBound($crimson) - 1
        $aColortable[$i] = $crimson[$j][0]
        $i += 1
      Next
      For $j = 0 To UBound($red) - 1
        $aColortable[$i] = $red[$j][0]
        $i += 1
      Next
      For $j = 0 To UBound($orange) - 1
        $aColortable[$i] = $orange[$j][0]
        $i += 1
      Next
      For $j = 0 To UBound($yellow) - 1
        $aColortable[$i] = $yellow[$j][0]
        $i += 1
      Next
      For $j = 0 To UBound($lime) - 1
        $aColortable[$i] = $lime[$j][0]
        $i += 1
      Next
      For $j = 0 To UBound($green) - 1
        $aColortable[$i] = $green[$j][0]
        $i += 1
      Next
      For $j = 0 To UBound($turqoise) - 1
        $aColortable[$i] = $turqoise[$j][0]
        $i += 1
      Next
      For $j = 0 To UBound($cyan) - 1
        $aColortable[$i] = $cyan[$j][0]
        $i += 1
      Next
      For $j = 0 To UBound($cobalt) - 1
        $aColortable[$i] = $cobalt[$j][0]
        $i += 1
      Next
      For $j = 0 To UBound($blue) - 1
        $aColortable[$i] = $blue[$j][0]
        $i += 1
      Next
      For $j = 0 To UBound($violet) - 1
        $aColortable[$i] = $violet[$j][0]
        $i += 1
      Next
      For $j = 0 To UBound($magenta) - 1
        $aColortable[$i] = $magenta[$j][0]
        $i += 1
      Next
      For $j = 0 To UBound($grey) - 1
        $aColortable[$i] = $grey[$j][0]
        $i += 1
      Next
    EndFunc
    
    Func SortByGroupingHSV(ByRef $aColortable, $sc = 2, $sortmode = 3)
      Local $red[0][2], $orange[0][2], $yellow[0][2], $lime[0][2], $green[0][2], $turqoise[0][2], $cyan[0][2], $cobalt[0][2], $blue[0][2], $violet[0][2], $magenta[0][2], $crimson[0][2], $grey[0][2], $i, $j, $col
      $sc = Max(Min($sc, 2), 0)
      For $i = 0 To UBound($aColortable) - 1
        $col = $aColortable[$i]
        Switch RGBtoColorGroup($col)
          Case "red"
            _ArrayAdd($red, $aColortable[$i] & "|" & RGB2HSV($col)[$sc])
          Case "orange"
            _ArrayAdd($orange, $aColortable[$i] & "|" & RGB2HSV($col)[$sc])
          Case "yellow"
            _ArrayAdd($yellow, $aColortable[$i] & "|" & RGB2HSV($col)[$sc])
          Case "lime"
            _ArrayAdd($lime, $aColortable[$i] & "|" & RGB2HSV($col)[$sc])
          Case "green"
            _ArrayAdd($green, $aColortable[$i] & "|" & RGB2HSV($col)[$sc])
          Case "turqoise"
            _ArrayAdd($turqoise, $aColortable[$i] & "|" & RGB2HSV($col)[$sc])
          Case "cyan"
            _ArrayAdd($cyan, $aColortable[$i] & "|" & RGB2HSV($col)[$sc])
          Case "cobalt"
            _ArrayAdd($cobalt, $aColortable[$i] & "|" & RGB2HSV($col)[$sc])
          Case "blue"
            _ArrayAdd($blue, $aColortable[$i] & "|" & RGB2HSV($col)[$sc])
          Case "violet"
            _ArrayAdd($violet, $aColortable[$i] & "|" & RGB2HSV($col)[$sc])
          Case "magenta"
            _ArrayAdd($magenta, $aColortable[$i] & "|" & RGB2HSV($col)[$sc])
          Case "crimson"
            _ArrayAdd($crimson, $aColortable[$i] & "|" & RGB2HSV($col)[$sc])
          Case "grey"
            _ArrayAdd($grey, $aColortable[$i] & "|" & RGB2HSV($col)[$sc])
        EndSwitch
      Next
      $sortmode = Max(Min($sortmode, 3), 1)
      Switch $sortmode
        Case 1
          _ArraySort($red, 0, 0, 0, 1)
          _ArraySort($orange, 0, 0, 0, 1)
          _ArraySort($yellow, 0, 0, 0, 1)
          _ArraySort($lime, 0, 0, 0, 1)
          _ArraySort($green, 0, 0, 0, 1)
          _ArraySort($turqoise, 0, 0, 0, 1)
          _ArraySort($cyan, 0, 0, 0, 1)
          _ArraySort($cobalt, 0, 0, 0, 1)
          _ArraySort($blue, 0, 0, 0, 1)
          _ArraySort($violet, 0, 0, 0, 1)
          _ArraySort($magenta, 0, 0, 0, 1)
          _ArraySort($crimson, 0, 0, 0, 1)
          _ArraySort($grey, 0, 0, 0, 1)
        Case 2
          SortByDistance($red, 1)
          SortByDistance($orange)
          SortByDistance($yellow, 1)
          SortByDistance($lime)
          SortByDistance($green, 1)
          SortByDistance($turqoise)
          SortByDistance($cyan, 1)
          SortByDistance($cobalt)
          SortByDistance($blue, 1)
          SortByDistance($violet)
          SortByDistance($magenta, 1)
          SortByDistance($crimson)
          SortByDistance($grey, 1)
        Case 3
          SortByLAB($red)
          SortByLAB($orange)
          SortByLAB($yellow)
          SortByLAB($lime)
          SortByLAB($green)
          SortByLAB($turqoise)
          SortByLAB($cyan)
          SortByLAB($cobalt)
          SortByLAB($blue)
          SortByLAB($violet)
          SortByLAB($magenta)
          SortByLAB($crimson)
          SortByLAB($grey)
      EndSwitch
      $i = 0
      For $j = 0 To UBound($red) - 1
        $aColortable[$i] = $red[$j][0]
        $i += 1
      Next
      For $j = 0 To UBound($orange) - 1
        $aColortable[$i] = $orange[$j][0]
        $i += 1
      Next
      For $j = 0 To UBound($yellow) - 1
        $aColortable[$i] = $yellow[$j][0]
        $i += 1
      Next
      For $j = 0 To UBound($lime) - 1
        $aColortable[$i] = $lime[$j][0]
        $i += 1
      Next
      For $j = 0 To UBound($green) - 1
        $aColortable[$i] = $green[$j][0]
        $i += 1
      Next
      For $j = 0 To UBound($turqoise) - 1
        $aColortable[$i] = $turqoise[$j][0]
        $i += 1
      Next
      For $j = 0 To UBound($cyan) - 1
        $aColortable[$i] = $cyan[$j][0]
        $i += 1
      Next
      For $j = 0 To UBound($cobalt) - 1
        $aColortable[$i] = $cobalt[$j][0]
        $i += 1
      Next
      For $j = 0 To UBound($blue) - 1
        $aColortable[$i] = $blue[$j][0]
        $i += 1
      Next
      For $j = 0 To UBound($violet) - 1
        $aColortable[$i] = $violet[$j][0]
        $i += 1
      Next
      For $j = 0 To UBound($magenta) - 1
        $aColortable[$i] = $magenta[$j][0]
        $i += 1
      Next
      For $j = 0 To UBound($crimson) - 1
        $aColortable[$i] = $crimson[$j][0]
        $i += 1
      Next
      For $j = 0 To UBound($grey) - 1
        $aColortable[$i] = $grey[$j][0]
        $i += 1
      Next
    EndFunc
    
    Func SortByHSL2(ByRef $aColortable) ;by Mars
      Local $aColortable2[UBound($aColortable)][9]
      Local $a, $i, $hsl_
      For $i = 0 To UBound($aColortable) - 1
        $a = _RGB2LAB($aColortable[$i])
        $hsl_ = RGB2HSL($aColortable[$i])
        $aColortable2[$i][0] = $aColortable[$i]
        $aColortable2[$i][1] = $a[0] ; LAB -> L
        $aColortable2[$i][2] = Sqrt($a[1]^2 + $a[2]^2) ; chroma
        $aColortable2[$i][3] = Abs($a[0] - 50) ; L umformen um "hell und dunkel" rauszufiltern
        $aColortable2[$i][4] = $hsl_[0] ; HSL -> H (könnte man via Farbwinkel aus LAB auch machen, hab ich ausprobiert, sah nicht so schön aus)
      Next
      Local $10 = Int(UBound($aColortable)/10)
      _ArraySort($aColortable2, 0, 0, 0, 2) ; chroma -> ziemlich "unbunte" farben herausfiltern (10%)
      _ArraySort($aColortable2, 1, 1 * $10 + 1, 0 * $10, 3) ; abs(L-50) -> sehr helle und sehr dunkle Farben herausfiltern
      _ArraySort($aColortable2, 0, 1 * $10 + 1, 5 * $10, 2) ; chroma -> von den hellen und dunklen Farben die unbuntesten raussuchen (nochmal 10%)
      _ArraySort($aColortable2, 0, 0 * $10 + 0, 2 * $10, 1) ; Die packt man links an das erste 5tel als eine Art "Pseudograustufenliste" (darin sind 20% aller Farben)
      _ArraySort($aColortable2, 0, 2 * $10 + 1, 0 * $10, 1) ; L -> sortiere nach Helligkeit
      _ArraySort($aColortable2, 0, 2 * $10 + 1, 6 * $10, 4) ; H -> Sortiere nach Hue (1x für niedrige Helligkeit)
      _ArraySort($aColortable2, 1, 6 * $10 + 1, 0 * $10, 4) ; H -> Sortiere nach Hue (1x für hohe Helligkeit)
      For $i = 0 To UBound($aColortable2) - 1
        $aColortable[$i] = $aColortable2[$i][0]
      Next
      Dim $aColortable2[0]
    EndFunc
    
    Func RGBtoColorGroup($iColor)
      Local $HSL = RGB2HSL($iColor), $H, $r
      If $HSL[0] = 0 And $HSL[1] = 0 Then
        $H = -1
      Else
        $H = $HSL[0]
      EndIf
      Switch Round($H, 0)
        Case 0 To 14, 345 To 359
          Return "red"
        Case 15 To 44
          Return "orange"
        Case 45 To 74
          Return "yellow"
        Case 75 To 104
          Return "lime"
        Case 105 To 134
          Return "green"
        Case 135 To 164
          Return "turqoise"
        Case 165 To 194
          Return "cyan"
        Case 195 To 224
          Return "cobalt"
        Case 225 To 254
          Return "blue"
        Case 255 To 284
          Return "violet"
        Case 285 To 314
          Return "magenta"
        Case 315 To 344
          Return "crimson"
        Case -1
          Return "grey"
      EndSwitch
    EndFunc
    
    Func Distance($c1, $c2)
      Local $r1 = BitShift(BitAND($c1, 0xFF0000), 16), $g1 = BitShift(BitAND($c1, 0xFF00), 8), $b1 = BitAND($c1, 0xFF)
      Local $r2 = BitShift(BitAND($c2, 0xFF0000), 16), $g2 = BitShift(BitAND($c2, 0xFF00), 8), $b2 = BitAND($c2, 0xFF)
      Local $dr = $r2 - $r1, $dg = $g2 - $g1, $db =  $b2 - $b1
      Return SetExtended($dr + $dg + $db < 0, Sqrt($dr * $dr + $dg * $dg + $db * $db))
    EndFunc
    
    Func RGB2HSL($iColor) ;http://www.easyrgb.com/en/math.php
      Local $var_r = BitAND(BitShift($iColor, 16), 255) / 255, $var_g = BitAND(BitShift($iColor, 8), 255) / 255, $var_b = BitAND($iColor, 255) / 255
      Local $H, $S, $L, $var_Min, $var_Max, $del_Max, $del_Max2, $del_R, $del_G, $del_B
    
      $var_Min = Min3($var_r, $var_g, $var_b)
      $var_Max = Max3($var_r, $var_g, $var_b)
      $del_Max = $var_Max - $var_Min
      $L = ($var_Max + $var_Min) / 2
      If $del_Max = 0 Then
        $H = 0
        $S = 0
      Else
        $S = $L < 0.5 ? $del_Max / ($var_Max + $var_Min) : $del_Max / (2 - $var_Max - $var_Min)
        $del_Max2 = $del_Max / 2
        $del_R = ((($var_Max - $var_R) / 6) + $del_Max2) / $del_Max
        $del_G = ((($var_Max - $var_G) / 6) + $del_Max2) / $del_Max
        $del_B = ((($var_Max - $var_B) / 6) + $del_Max2) / $del_Max
        If ($var_R = $var_Max) Then
          $H = $del_B - $del_G
        Elseif $var_G = $var_Max Then
          $H = 0.333333333333333 + $del_R - $del_B
        Elseif $var_B = $var_Max Then
          $H = 0.666666666666667 + $del_G - $del_R
        EndIf
        If $H < 0 Then $H += 1
        If $H > 1 Then $H -= 1
      EndIf
      Local $aHSL[3] = [$H * 360, $S, $L]
      Return $aHSL
    EndFunc
    
    Func RGB2HSV($iColor) ;http://www.easyrgb.com/en/math.php
      Local $var_r = BitAND(BitShift($iColor, 16), 255) / 255, $var_g = BitAND(BitShift($iColor, 8), 255) / 255, $var_b = BitAND($iColor, 255) / 255
      Local $H, $S, $V, $var_Min, $var_Max, $del_Max, $del_Max2, $del_R, $del_G, $del_B
    
      $var_Min = Min3($var_r, $var_g, $var_b)
      $var_Max = Max3($var_r, $var_g, $var_b)
      $del_Max = $var_Max - $var_Min
      $V = $var_Max
      If $del_Max = 0 Then
        $H = 0
        $S = 0
      Else
        $S = $del_Max / $var_Max
        $del_Max2 = $del_Max / 2
        $del_R = ((($var_Max - $var_R) / 6) + $del_Max2) / $del_Max
        $del_G = ((($var_Max - $var_G) / 6) + $del_Max2) / $del_Max
        $del_B = ((($var_Max - $var_B) / 6) + $del_Max2) / $del_Max
        If $var_R = $var_Max Then
          $H = $del_B - $del_G
        ElseIf $var_G = $var_Max Then
          $H = 0.333333333333333 + $del_R - $del_B
        ElseIf $var_B = $var_Max Then
          $H = 0.666666666666667 + $del_G - $del_R
        EndIf
        If $H < 0 Then $H += 1
        If $H > 1 Then $H -= 1
      EndIf
      Local $aHSV[3] = [$H * 360, $S, $V]
      Return $aHSV
    EndFunc
    
    Func RGA2CMYK($iColor)
      Local $r = BitAND(BitShift($iColor, 16), 255), $g = BitAND(BitShift($iColor, 8), 255), $b = BitAND($iColor, 255)
      Local $C = 1 - ($r / 255), $M = 1 - ($G / 255), $Y = 1 - ($B / 255), $K = 1
      If ($C < $K) Then $K = $C
      If ($M < $K) Then $K = $M
      If ($Y < $K) Then $K = $Y
      If ($K = 1) Then ;Black only
        $C = 0
        $M = 0
        $Y = 0
      Else
        $C = ($C - $K) / (1 - $K)
        $M = ($M - $K) / (1 - $K)
        $Y = ($Y - $K) / (1 - $K)
      EndIf
      Local $aCMYK[] = [$C, $M, $Y, $K]
      Return $aCMYK
    EndFunc
    
    Func SortByBrightColor(ByRef $List) ; by fee
      Local Const _
          $High = UBound($List)
      Local $Sort[$High][$High]
      For $a = 0 To $High - 1
        $Redd = BitAnd(BitShift($List[$a], 16), 0xFF)
        $Gren = BitAnd(BitShift($List[$a],  8), 0xFF)
        $Blue = BitAnd(         $List[$a],      0xFF)
        $Mini = Min3($Redd, $Gren, $Blue)
        $Maxi = Max3($Redd, $Gren, $Blue)
        $Dist = $Maxi - $Mini
        $Luma = Round(($Redd * 0.299) + ($Gren * 0.587) + ($Blue * 0.114))
        $Sort[$Luma][$Dist] = $List[$a]
      Next
      $c = 0
      For $a = 0 To $High - 1
        For $b = 0 To $High - 1
          If $Sort[$a][$b] = '' Then ContinueLoop
          $List[$c] = $Sort[$a][$b]
          $c += 1
        Next
      Next
    EndFunc   ;==>SortByBrightColor
    
    Func Min($a, $b)
      Return ($a < $b) ? $a : $b
    EndFunc
    
    Func Max($a, $b)
      Return ($a > $b) ? $a : $b
    EndFunc
    
    Func Min3($a, $b, $c)
      Return Min(Min($a, $b), $C)
    EndFunc
    
    Func Max3($a, $b, $c)
      Return Max(Max($a, $b), $C)
    EndFunc
    
    ; #FUNCTION# =============================================================================
    ; Name.............:    _ArraySort_MultiColumn
    ; Description ...:      sorts an array at given colums (multi colum sort)
    ; Syntax...........:    _ArraySort_MultiColumn(ByRef $aSort, ByRef $aIndices)
    ; Parameters ...:        $aSort - array to sort
    ;                        $aIndices - array with colum indices which should be sorted in specified order - zero based
    ;                        $oDir/$iDir - sort direction - if set to 1, sort descending else ascending. $oDir is for the 1st row,
    ;                                                      $iDir for the remaining rows
    ;                        $iStart - where to start to sort - 0 = 0 based array, 1 = 1 based array
    ; Author .........:        UEZ
    ; Version ........:        v0.80 build 2019-01-26 Beta
    ; =========================================================================================
    Func _ArraySort_MultiColumn(ByRef $aSort, ByRef $aIndices, $oDir = 0, $iDir = 0, $iStart = 0)
      If Not IsArray($aIndices) Or Not IsArray($aSort) Then Return SetError(1, 0, 0) ;checks if $aIndices is an array
      If UBound($aSort, 2) = 0 Then Return SetError(4, 0, 0) ;array is 1D only
      If UBound($aIndices) > UBound($aSort, 2) Then Return SetError(2, 0, 0) ;check if $aIndices array is greater the $aSort array
      Local $1st, $2nd, $x, $j, $k, $l = 0
      For $x = 0 To UBound($aIndices) - 1 ;check if array content makes sense
        If Not IsInt($aIndices[$x]) Then Return SetError(3, 0, 0) ;array content is not numeric
      Next
      $iStart = Int($iStart) < 0 ? 0 : Int($iStart) > 1 ? 1 : Int($iStart)
      If UBound($aIndices) = 1 Then Return _ArraySort($aSort, $oDir, $iStart, 0, $aIndices[0]) ;check if only one index is given
      _ArraySort($aSort, $oDir, $iStart, 0, $aIndices[0])
      Do
        $1st = $aIndices[$l]
        $2nd = $aIndices[$l + 1]
        $j = 0
        $k = 1
        While $k < UBound($aSort)
          If $aSort[$j][$1st] <> $aSort[$k][$1st] Then
            If $k - $j > 1 Then
              _ArraySort($aSort, $iDir, $j, $k - 1, $2nd)
              $j = $k
            Else
              $j = $k
            EndIf
          EndIf
          $k += 1
        WEnd
        If $k - $j > 1 Then _ArraySort($aSort, $iDir, $j, $k, $2nd)
        $l += 1
      Until $l = UBound($aIndices) - 1
      Return 1
    EndFunc   ;==>_ArraySort_MultiColumn
    
    ; #FUNCTION# ====================================================================================================================
    ; Name...........: _ArrayMultiColSort
    ; Description ...: Sort 2D arrays on several columns
    ; Syntax.........: _ArrayMultiColSort(ByRef $aArray, $aSortData[, $iStart = 0[, $iEnd = 0]])
    ; Parameters ....: $aArray    - The 2D array to be sorted
    ;                  $aSortData - 2D array holding details of the sort format
    ;                               Format: [Column to be sorted, Sort order]
    ;                                   Sort order can be either numeric (0/1 = ascending/descending) or a ordered string of items
    ;                                   Any elements not matched in string are left unsorted after all sorted elements
    ;                  $iStart    - Element of array at which sort starts (default = 0)
    ;                  $iEnd      - Element of array at which sort endd (default = 0 - converted to end of array)
    ; Requirement(s).: v3.3.8.1 or higher
    ; Return values .: Success: No error
    ;                  Failure: @error set as follows
    ;                            @error = 1 with @extended set as follows (all refer to $sIn_Date):
    ;                                1 = Array to be sorted not 2D
    ;                                2 = Sort data array not 2D
    ;                                3 = More data rows in $aSortData than columns in $aArray
    ;                                4 = Start beyond end of array
    ;                                5 = Start beyond End
    ;                            @error = 2 with @extended set as follows:
    ;                                1 = Invalid string parameter in $aSortData
    ;                                2 = Invalid sort direction parameter in $aSortData
    ;                                3 = Invalid column index in $aSortData
    ; Author ........: Melba23
    ; Remarks .......: Columns can be sorted in any order
    ; Example .......; Yes
    ; ===============================================================================================================================
    Func _ArrayMultiColSort(ByRef $aArray, $aSortData, $iStart = 0, $iEnd = 0)
    
      ; Errorchecking
      ; 2D array to be sorted
      If UBound($aArray, 2) = 0 Then
        Return SetError(1, 1, "")
      EndIf
      ; 2D sort data
      If UBound($aSortData, 2) <> 2 Then
        Return SetError(1, 2, "")
      EndIf
      If UBound($aSortData) > UBound($aArray) Then
        Return SetError(1, 3)
      EndIf
      For $i = 0 To UBound($aSortData) - 1
        If $aSortData[$i][0] < 0 Or $aSortData[$i][0] > UBound($aArray, 2) -1 Then
          Return SetError(2, 3, "")
        EndIf
      Next
      ; Start element
      If $iStart < 0 Then
        $iStart = 0
      EndIf
      If $iStart >= UBound($aArray) - 1 Then
        Return SetError(1, 4, "")
      EndIf
      ; End element
      If $iEnd <= 0 Or $iEnd >= UBound($aArray) - 1 Then
        $iEnd = UBound($aArray) - 1
      EndIf
      ; Sanity check
      If $iEnd <= $iStart Then
        Return SetError(1, 5, "")
      EndIf
    
      Local $iCurrCol, $iChunk_Start, $iMatchCol
    
      ; Sort first column
      __AMCS_SortChunk($aArray, $aSortData, 0, $aSortData[0][0], $iStart, $iEnd)
      If @error Then
        Return SetError(2, @extended, "")
      EndIf
      ; Now sort within other columns
      For $iSortData_Row = 1 To UBound($aSortData) - 1
        ; Determine column to sort
        $iCurrCol = $aSortData[$iSortData_Row][0]
        ; Create arrays to hold data from previous columns
        Local $aBaseValue[$iSortData_Row]
        ; Set base values
        For $i = 0 To $iSortData_Row - 1
          $aBaseValue[$i] = $aArray[$iStart][$aSortData[$i][0]]
        Next
        ; Set start of this chunk
        $iChunk_Start = $iStart
        ; Now work down through array
        For $iRow = $iStart + 1 To $iEnd
          ; Match each column
          For $k = 0 To $iSortData_Row - 1
            $iMatchCol = $aSortData[$k][0]
            ; See if value in each has changed
            If $aArray[$iRow][$iMatchCol] <> $aBaseValue[$k] Then
              ; If so and row has advanced
              If $iChunk_Start < $iRow - 1 Then
                ; Sort this chunk
                __AMCS_SortChunk($aArray, $aSortData, $iSortData_Row, $iCurrCol, $iChunk_Start, $iRow - 1)
                If @error Then
                  Return SetError(2, @extended, "")
                EndIf
              EndIf
              ; Set new base value
              $aBaseValue[$k] = $aArray[$iRow][$iMatchCol]
              ; Set new chunk start
              $iChunk_Start = $iRow
            EndIf
          Next
        Next
        ; Sort final section
        If $iChunk_Start < $iRow - 1 Then
          __AMCS_SortChunk($aArray, $aSortData, $iSortData_Row, $iCurrCol, $iChunk_Start, $iRow - 1)
          If @error Then
            Return SetError(2, @extended, "")
          EndIf
        EndIf
      Next
    
    EndFunc   ;==>_ArrayMultiColSort
    
    ; #INTERNAL_USE_ONLY# ===========================================================================================================
    ; Name...........: __AMCS_SortChunk
    ; Description ...: Sorts array section
    ; Author ........: Melba23
    ; Remarks .......:
    ; ===============================================================================================================================
    Func __AMCS_SortChunk(ByRef $aArray, $aSortData, $iRow, $iColumn, $iChunkStart, $iChunkEnd)
    
      Local $aSortOrder
    
      ; Set default sort direction
      Local $iSortDirn = 1
      ; Need to prefix elements?
      If IsString($aSortData[$iRow][1]) Then
        ; Split elements
        $aSortOrder = StringSplit($aSortData[$iRow][1], ",")
        If @error Then
          Return SetError(1, 1, "")
        EndIf
        ; Add prefix to each element
        For $i = $iChunkStart To $iChunkEnd
          For $j = 1 To $aSortOrder[0]
            If $aArray[$i][$iColumn] = $aSortOrder[$j] Then
              $aArray[$i][$iColumn] = StringFormat("%02i-", $j) & $aArray[$i][$iColumn]
              ExitLoop
            EndIf
          Next
          ; Deal with anything that does not match
          If $j > $aSortOrder[0] Then
            $aArray[$i][$iColumn] = StringFormat("%02i-", $j) & $aArray[$i][$iColumn]
          EndIf
        Next
      Else
        Switch $aSortData[$iRow][1]
          Case 0, 1
            ; Set required sort direction if no list
            If $aSortData[$iRow][1] Then
              $iSortDirn = -1
            Else
              $iSortDirn = 1
            EndIf
          Case Else
            Return SetError(1, 2, "")
        EndSwitch
      EndIf
    
      ; Sort the chunk
      Local $iSubMax = UBound($aArray, 2) - 1
      __ArrayQuickSort2D($aArray, $iSortDirn, $iChunkStart, $iChunkEnd, $iColumn, $iSubMax)
    
      ; Remove any prefixes
      If IsString($aSortData[$iRow][1]) Then
        For $i = $iChunkStart To $iChunkEnd
          $aArray[$i][$iColumn] = StringTrimLeft($aArray[$i][$iColumn], 3)
        Next
      EndIf
    
    EndFunc   ;==>__AMCS_SortChunk
    Alles anzeigen

    Gruß, fee

  • _ArrayDisplay() kann keine Null-Keywords verarbeiten

    • fee
    • 6. Februar 2023 um 21:24

    Alina

    Es geht um das Keyword Null, nicht um den banalen Wert 0. Da drückte ich mich missverständlich aus und sorgte damit wohl nicht nur bei dir für Verwirrung.

    Bitte verzeiht mir diesen Benennungsfehler, den ich nun überall berichtigt habe.

  • _ArrayDisplay() kann keine Null-Keywords verarbeiten

    • fee
    • 6. Februar 2023 um 20:50

    Erst mal vielen Dank euch allen für eure schnellen Antworten.

    Peter S. Taler

    Klar, dass deine Beispiele funktionieren, denn sooo unerfahren bin ich in AutoIt im Gegensatz zu meinem Benutzertitel hier ja nun auch wieder nicht, sonst hätte ich die Fehlerquelle nicht gefunden, nicht wahr? ;)

    AspirinJunkie

    In diesem Forum ist noch die 3.3.16.0 verlinkt, weshalb ich meinen Gedanken an ein Update wieder verwarf.

    Der Fehler ist zwar behoben, aber meiner Meinung nach mit der Holzhammer-Methode, indem jeder Wert "einfach" in einen String umgewandelt wird. Außerdem wird das Schlüsselwort Null im ListView einfach als leeres Feld dargestellt statt in seiner Textform, wie es bei den Schlüsselworten Default, False und True der Fall ist.

    Jedenfalls kann ich jetzt wieder endlos weiterarbeiten statt endlos aufs Skriptende zu warten … ^^

    Gruß, fee

    Edit: Obendrein würde bei der Ausgabe von Null in Textform die Umwandlung in einen String für die DllCalls hinfällig werden, denke ich und sich auch noch von Feldern mit "leeren Strings" unterscheiden, was vor allem bei einer Sortierung nicht schlecht wäre.

  • _ArrayDisplay() kann keine Null-Keywords verarbeiten

    • fee
    • 4. Februar 2023 um 16:55

    Ich! ^^ – Für ein Beispiel zu einer eigenen UDF.

    Ist aber egal, Fehler bleibt Fehler, nicht?

    Gruß, fee


    Edit: Außerdem hab ich einen undokumentierten Wert einer WinAPI-Funktion entdeckt.

  • _ArrayDisplay() kann keine Null-Keywords verarbeiten

    • fee
    • 4. Februar 2023 um 14:59

    Guten Tag, liebe Leute.

    Ich habe hier ein Windows 7 Professional 64 Bit und AutoIt 3.3.16.0 mit SciTE installiert.

    Gestern machte ich die Entdeckung, dass _ArrayDisplay() nicht mit Null-Keywords im übergebenen Array umgehen kann und in eine Endlos-Schleife gerät.

    Hier ein Beispiel:

    AutoIt
    #Include <Array.au3>
    
    Dim $Array = [Null, False, True]
    _ArrayDisplay($Array)

    Auch zweidimensionale Arrays sind davon betroffen und die Platzierung des Null-Keywords ist egal.

    Meine Suche ergab, dass der Fehler in der Datei <ArrayDisplayInternals.au3> liegt, welche von <Array.au3> eingebunden wird. Dort wird von der Funktion __ArrayDisplay_Share() über weitere Funktionen die Funktion __ArrayDisplay_SortArrayStruct() aufgerufen. Darin kommt eine Do…Until-Schleife vor, welche bei Null-Keywords mit natürlicher Sortierung endlos läuft, weil in diesem Fall die DllCall()s den in der MSDN undokumentierten Wert -2 zurückgeben, der nicht abgefangen wird. Bei numerischer Sortierung liefern die Number()-Funktionen einfach 0, was zu keiner Endlos-Schleife führen sollte.

    Dabei dient der erstmalige Aufruf von __ArrayDisplay_SortArrayStruct() über vorgeschaltete Funktionen eigentlich nur der Ermittlung der Sortierdauer einer Spalte.

    Man könnte nach der If-Abfrage, also nach Zeile 801 eine Begrenzung mit If $r < -1 Or $r > 1 Then $r = 0 einfügen oder im nachfolgenden Switch-Teil aus Case 0 ein Case 0, -2 oder Case Else machen. Beide Varianten führen zu einem erfolgreichen Abbruch der Schleife bei Null-Keywords.

    Schön wäre es allerdings noch, wenn auch wie bei den Bool-Keywords False und True das Wort Null im ListView der _ArrayDisplay()-GUI erscheinen würde, wenn dieses Schlüsselwort auftritt. Wo das bewerkstelligt werden kann, habe jedoch nicht herausgefunden.

    Gruß, fee

  • Standardbenutzerkonto und AutoIt

    • fee
    • 9. November 2022 um 01:16

    Micha_he :

    Vielen Dank für deine Anleitung. Endlich bin ich mal dazu gekommen, zumindest die genannten Werte in der Registry zu überprüfen.

    Zu 1: Bei mir steht unter Progid der Wert Applications\AutoIt3.exe statt AutoIt3Script – falsch.

    Zu 2: Unter (Standard) steht AutoIt3Script – richtig. Als PerceivedType ist dort noch text definiert.

    Zu 3: Dort ist unter (Standard) der Wert AutoIt3Script angegeben und ebenfalls ein PerceivedType mit text.

    Zu 4.1: Die "Progid" AutoIt3.exe ist bei nur unter HKEY_CURRENT_USER\Software\Classes\Applications vorhanden, worunter es auch ein …\AutoIt3.exe\shell\open\command gibt, jedoch nirgendwo ein DefaultIcon – falsch. Für die (Standard)-Einträge in shell und open ist nur (Wert nicht festgelegt) zu finden.

    Zu 4.2: Dort ist der Schlüssel AutoIt3Script notiert mit allen Unterschlüsseln und Werten, wie es sich gehört.

    Weil aber in der Zwischenzeit auch andere Programme nach der Installation ihr Dateityp-Symbol nicht setzen oder sich nicht im Explorer-Kontextmenü eintragen konnten, gebe ich diesen Schwachsinn mit der Benutzerkontensteuerung auf, mache mein eingeschränktes Benutzerkonto zum Administrator und lösche das derzeitige Administratorkonto. "Sicherheitsgewinn" ade, aber dafür Funktionalität und weniger Ärger bzw. Zeit vertan, obwohl mir das Aufgeben nicht schmeckt.

    Trotzdem danke ich euch allen für eure Mühe und Hilfe.

    Gruß, fee

  • Standardbenutzerkonto und AutoIt

    • fee
    • 10. Oktober 2022 um 20:11

    gmmg : Ach so, okay. Deshalb heißt der Ordner für Benutzerdaten wohl auch "Roaming". Aber mit Server-Geschichten habe ich nichts am Hut, außer Internet natürlich.

  • StringReplace nur auf jede 2. Doppelziffe anwenden

    • fee
    • 10. Oktober 2022 um 20:10

    Alina : Grob gesagt schaut sein Skript, ob eine RNS-Datei im angegebenen Ordner erstellt oder geändert wurde und stellt über ein Dummy-Steuerelement die Dateigröße für Debugzwecke zur Ausgabe in die SciTE-Konsole bereit. Vorbereitet sind auch schon jene Aktionen, wenn du noch etwas beim Umbenennen oder einer Dateitypzuweisung erledigten lassen möchtest. Ansonsten hat er nur noch die Umwandlungsfunktion und beim Beenden des Skriptes das Deregistrieren der Überwachungsfunktion eingebaut.

    Eigentlich nichts Wildes und relativ einfach, wenn man es irgendwann mal verstanden hat. Bei welchem Teil blickst du noch nicht durch?

  • StringReplace nur auf jede 2. Doppelziffe anwenden

    • fee
    • 10. Oktober 2022 um 01:03

    Bitnugger :

    Zitat von Bitnugger

    den alten Namen bekommst du mit "Item1", den neuen mit "Item2".

    Okay, das wusste ich nicht.

    Zitat von Bitnugger

    Wir benötigen ja nicht nur den Namen des Pfades, sondern vor allem auch den Inhalt der Datei... den es aber evtl. noch nicht gibt, nachdem die Datei erstellt wurde ($SHCNE_CREATE) - z.B. mit FileOpen("filename.rns", $FO_OVERWRITE) - hier greift dann $SHCNE_UPDATEITEM, nachdem die Daten geschrieben wurden!

    Ups, das hatte ich nicht bedacht.

    Zitat von Bitnugger

    jedoch kein $SHCNE_ASSOCCHANGED.

    Das habe ich mit reingenommen, weil in der Beschreibung steht:

    Zitat von M$ Learn

    This event should also be sent for registered protocols.

    Muss ich dann wohl missverstanden haben. Ein Dateityp ist ja kein Protokoll, oder?

    Zitat von Bitnugger

    Schau mal hier, wie KaFu das gelöst hat.

    Uff, den *_Lock und *_Unlock-Teil hätte ich vielleicht noch hinbekommen können, aber allerspätestens bei _WinAPI_ShellChangeNotifyRegisterEx wäre für mich Schluss gewesen.

    Zitat von Bitnugger

    Ansonsten... sehr schön umgesetzt. :rock:

    Danke dir. :) Deine neue Version ebenso!

    Alina :

    Zitat von Alina

    Das Anzeigen das eine neue Datei im Ordner ist erfolgt bei mir nicht. Die GUI baut auf, aber sie füllt sich nicht, sobald eine weitere Datei in den Ordner kommt.

    Klar, weil Bitnugger kein Edit-Element wie ich in die GUI eingebaut hat und Meldungen zum Debuggen in der SciTE-Konsole ausgeben lässt, sofern das Skript von SciTE aus gestartet wurde.

  • StringReplace nur auf jede 2. Doppelziffe anwenden

    • fee
    • 9. Oktober 2022 um 01:37

    Alina : Gern geschehen! :)

    Bitnugger : Die Ordnerüberwachung wäre vermutlich toll, aber

    1. fehlt ein #include <GUIConstantsEx.au3> (nicht schlimm) und
    2. bekomme ich unter Win7 Pro x64 nur ein Event: 0x00040000 nach Hinzufügen einer RNS-Datei im Ordner.

    Leider verstehe ich (noch) nicht, warum.

    Edit:

    Bitnugger : So funktioniert es jetzt bei mir auf Win7 Pro x64, wenn ich eine RNS-Datei im zu überwachenden Ordner erstelle:

    AutoIt
    #include <APIShellExConstants.au3>
    #include <EditConstants.au3>
    #include <GUIConstantsEx.au3>
    #include <MsgBoxConstants.au3>
    #include <WinAPIShellEx.au3>
    #include <WinAPISysWin.au3>
    
    Opt('TrayAutoPause', 0)
    
    Global Const $g_sPath = @ScriptDir ; Zu überwachende Verzeichnisse (String oder Array)
    Global $g_idEdit, $g_iID
    
    OnAutoItExitRegister('_OnAutoItExit')
    
    Exit _Main()
    
    
    Func _Main()
      Local $hWnd = GUICreate('FolderMonitoring', 300, 400)
      $g_idEdit = GUICtrlCreateEdit('', 10, 10, 280, 380, BitOR($ES_MULTILINE, $ES_READONLY))
      GUISetState()
      WinSetOnTop($hWnd, '', 1)
      Local $iMsg = _WinAPI_RegisterWindowMessage('SHELLCHANGENOTIFY')
      GUIRegisterMsg($iMsg, '_WM_SHELLCHANGENOTIFY')
      $g_iID = _WinAPI_ShellChangeNotifyRegister($hWnd, $iMsg, BitOR($SHCNE_ASSOCCHANGED, _
                                                 $SHCNE_CREATE), BitOR($SHCNRF_INTERRUPTLEVEL, _
                                                 $SHCNRF_SHELLLEVEL), $g_sPath, 0)
      If @error Then
        MsgBox(BitOR($MB_OK, $MB_ICONERROR, $MB_SYSTEMMODAL), 'Fehler', _
               'Das Fenster wurde nicht registriert!')
        Return 1
      EndIf
      Do
      Until GUIGetMsg() = $GUI_EVENT_CLOSE
      Return 0
    EndFunc   ;==>_Main
    
    Func _WM_SHELLCHANGENOTIFY($hWnd, $iMsg, $wParam, $lParam)
      #forceref $hWnd, $iMsg
      Local $sPath = _WinAPI_ShellGetPathFromIDList(DllStructGetData( _
                     DllStructCreate('dword Item1;dword Item2', $wParam), 'Item1'))
      If $sPath Then
        If StringRight($sPath, 4) = '.rns' Then
          ControlSend($hWnd, '', $g_idEdit, '^{End}')
          GUICtrlSetData($g_idEdit, _
                         'Neue *.rns gefunden!' & @CRLF & _
                         'Event: 0x' & Hex($lParam) & @CRLF & _
                         'Pfad: ' & $sPath & @CRLF & @CRLF, 1)
        EndIf
      Else
        ControlSend($hWnd, '', $g_idEdit, '^{End}')
        GUICtrlSetData($g_idEdit, 'Event: 0x' & Hex($lParam) & @CRLF & @CRLF, 1)
      EndIf
    EndFunc   ;==>_WM_SHELLCHANGENOTIFY
    
    Func _OnAutoItExit()
      If $g_iID Then _WinAPI_ShellChangeNotifyDeregister($g_iID)
    EndFunc   ;==>_OnAutoItExit
    Alles anzeigen

    Eine RNS-Datei in einen andernen Dateityp umbenennen würde erkannt werden, umgekehrt jedoch nicht. $SHCNE_ALLEVENTS kann somit vom Erkennungsumfang her auf BitOR($SHCNE_ASSOCCHANGED, $SHCNE_CREATE) reduziert werden. Die rekursive Erkennung habe ich auch entfernt, um Leistung einzusparen. $SHCNE_UPDATEITEM tritt laut Beschreibung nur bei Veränderung des Inhaltes eines Elementes auf, hier also nicht nötig. $SHCNE_CREATE habe ich aus der Funktion _WM_SHELLCHANGENOTIFY() entfernt.

    Die Beschreibung zu SHChangeNotifyRegister empfiehlt statt BitOR($SHCNRF_INTERRUPTLEVEL, $SHCNRF_SHELLLEVEL) den Wert $SHCNRF_NEWDELIVERY in der Funktion _WinAPI_ShellChangeNotifyRegister():

    Zitat von M$ Learn

    Messages received use shared memory. Call SHChangeNotification_Lock to access the actual data. Call SHChangeNotification_Unlock to release the memory when done.

    Note: We recommend this flag because it provides a more robust delivery method. All clients should specify this flag.

    Den ersten Zitatsatz weiß ich leider nicht vollständig umzusetzen. Macht aber nix, für mich funktioniert es auch so.

  • StringReplace nur auf jede 2. Doppelziffe anwenden

    • fee
    • 8. Oktober 2022 um 22:35
    Zitat von Alina

    fee wandelt die 100 in 00 um und auch umgekehrt ! Das ist ja auch richtig. Bei den anderen Lösungen wird auch die 100 in 00 umgewandelt, aber umgekehrt kommt dann nicht wieder 100 raus.

    Am Anfang schriebst du, dass die Eingabezeichenfolge nur zweistellige Zahlen enthält. Finde ich zwar schön, dass mein Vorschlag deine erweiterte Aufgabe richtig löst, was aber nicht von mir beabsichtigt und vor allem nicht ganz deine Aufgabenstellung war. ;)

    Naja, besser so als anders herum. :)

    Bei der Ordnerüberwachung kann ich dir allerdings nicht helfen, das habe ich noch nie gebraucht/gemacht.

    Edit: Den Mod()-Teil in meinem Vorschlag würde ich allerdings durch den Vorschlag von Bitnugger in Beitrag #10 ersetzen, also der For-Schleife ein Step 2 verpassen und danach die letzte Doppelziffer an ungerader Position (sofern vorhanden) verarbeiten. Spart Laufzeit, denn Modulo ist leistungshungrig.

  • StringReplace nur auf jede 2. Doppelziffe anwenden

    • fee
    • 8. Oktober 2022 um 17:05

    Bitnugger : Die verbleibende Doppelziffer nach der Schleife anzuhängen hatte ich mir ein kleines bisschen aufwändiger vorgestellt. Aber so ist es bestimmt schneller als dieses Mod-Gedöns und auch einfach zu verstehen. Sehr schöne Lösung!

  • StringReplace nur auf jede 2. Doppelziffe anwenden

    • fee
    • 8. Oktober 2022 um 13:37

    Bitnugger : Und wie erledigst du dann die Umwandlung des Arrays in einen String ohne zweite Schleife, vor allem wenn die Anzahl der Doppelziffern ungerade ist? Deinen Vorschlag hatte ich nämlich auch erst so geschrieben.

  • StringReplace nur auf jede 2. Doppelziffe anwenden

    • fee
    • 8. Oktober 2022 um 09:36

    Hallo Alina ,

    hier mein Vorschlag mit einem Array, erstellt aus dem Code von @Musashi , der eine sehr gute Vorlage lieferte:

    AutoIt
    Local _
        $Source = '32 94 97 64 83 14 82 64 72', _
        $Array, $Target
    
    ConsoleWrite('Vorher = ' & $Source & @CRLF) ; *** nur zur Anzeige
    
    $Source = StringRegExpReplace($Source, ' +', ' ') ; Nur jeweils ein Trennzeichen sicherstellen
    $Array  = StringSplit($Source, ' ') ; String aufteilen und Array erstellen
    
    For $i = 1 To $Array[0]
      If Mod($i, 2) = 0 Then _ ; Jeder zweite Eintrag
          $Array[$i] = StringFormat('%02s', String(100 - Number($Array[$i])))
      $Target &= $Array[$i] & ' ' ; String wieder zusammenbauen
    Next
    
    $Target = StringTrimRight($Target, 1) ; Letztes Leerzeichen entfernen
    $Array  = '' ; Array freigeben
    
    ConsoleWrite('Danach = ' & $Target & @CRLF) ; *** nur zur Anzeige
    Alles anzeigen

    Dieser Code könnte jedoch langsamer, aber vielleicht leichter verständlich sein.

    Gruß, fee

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™