Danke UEZ , vielleicht kann ich sowas irgendwann mal in PureBasic brauchen, wenn ich das wiederum portiert bekomme, FreeBasic hab ich nämlich nicht.
Beiträge von fee
-
-
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.
-
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!
-
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):
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
-
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.
-
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.
-
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
Alles anzeigen;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
Gruß, fee
-
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.
-
Erst mal vielen Dank euch allen für eure schnellen Antworten.
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?
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.
-
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.
-
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:
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
-
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
-
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.
-
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?
-
den alten Namen bekommst du mit "Item1", den neuen mit "Item2".
Okay, das wusste ich nicht.
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.
jedoch kein $SHCNE_ASSOCCHANGED.
Das habe ich mit reingenommen, weil in der Beschreibung steht:
This event should also be sent for registered protocols.
Muss ich dann wohl missverstanden haben. Ein Dateityp ist ja kein Protokoll, oder?
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.
Ansonsten... sehr schön umgesetzt.
Danke dir.
Deine neue Version ebenso!
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.
-
Alina : Gern geschehen!
Bitnugger : Die Ordnerüberwachung wäre vermutlich toll, aber
- fehlt ein #include <GUIConstantsEx.au3> (nicht schlimm) und
- 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
Alles anzeigen#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
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():
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.
-
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.
-
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!
-
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.
-
Hallo Alina ,
hier mein Vorschlag mit einem Array, erstellt aus dem Code von Musashi , der eine sehr gute Vorlage lieferte:
AutoIt
Alles anzeigenLocal _ $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
Dieser Code könnte jedoch langsamer, aber vielleicht leichter verständlich sein.
Gruß, fee