• Version 1.3 ist fertig.

    Neu in v1.3
    - Alle Dateien und Verzeichnisse mit "S"-Attribut werden nun ignoriert.

    Neu in v1.2
    - Funktion zum löschen leerer Verzeichnisse. Das ist ganz praktisch, wenn man Dateien löscht und dabei dann ein leeres Verzeichnis überbleibt. Es werden dabei aber nur wirklich leere Verzeichnisse gelöscht (DirGetSize = 0).
    - Einige Optimierungen am Programmcode.

    Neu in v1.1
    - Es gibt nun einen zweiten Button, zum laden der Liste. Dabei wird getestet, ob die Datei (so wie sie in der Liste steht) auch tatsächlich noch existiert. Wenn nicht, dann wird der Eintrag in rot dargestellt.
    - Systemsounds beim beenden der Funktionen, damit man auch eine akustische Rückmeldung hat, wenn die Funktion fertig ist. Ein Danke an funkey für "_PlayDefaultSystemSound". :thumbup:
    - Anzeige, wie viele Einträge markiert sind.
    - beim kopieren/verschieben von Dateien wird jetzt nicht mehr eine evtl. vorhandene Datei überschrieben, sondern die neue wird umbenannt (durch einen Zähler (1) erweitert).
    - Man kann nun alle Dateien aus der Liste anhand der ID3-Tags in eine Verzeichnisstruktur einsortieren lassen (kopieren oder verschieben). Sollten dabei doppelte Dateinamen vorkommen, wird wieder umbenannt.
    - Vorher kann man noch aussuchen, ob man nur für den Interpreten ein Unterverzeichnis haben will oder ob man für Interpret und Album je ein Unterverzeichnis wünscht.
    - Beim verschieben von Dateien wird der Pfad-Eintrag in der Liste automatisch angepasst. Man muss die Liste dann nur abspeichern.

    Eigenschaften:
    - Alle Festplatten oder einzelne Ordner nach MP3-Dateien durchsuchen und Liste erstellen lassen.
    - Liste laden und speichern.
    - Innerhalb der Liste nach einem anzugebenen Begriff suchen lassen. Suchergebnisse werden in eigener Liste dargestellt.
    - Markierte Dateien kopieren, verschieben oder löschen lassen
    - Doppelklick auf einen Eintrag startet den Standard-MP3-Player

    Screenshot:
    autoit.de/wcf/attachment/10952/

    Skript, Exe und Icons befinden sich im ZIP-Archiv (Anhang).

    How To

    Spoiler anzeigen

    1: Download :D
    2: Starten der .exe oder via Editor(Empfohlen wird die .exe)

    Nach dem Ihr das prog gestartet habt,MÜSST ihr alls erstes den Button "Alle Festplatten nach MP3s durchsuchen" oder "Verzeichnis nach MP3s durchsuchen" Drücken.
    Ansonsten könnt ihr Garnichts anfangen mit dem Programm.
    Nach dem das Programm Fertig mit der Suche ist, habt Ihr die Wahl ob Ihr die Gefundenen Files in einer Datenbank Speichern wollt
    (Dabei werden nicht die Files sondern die Angaben gespeichert. z.b. Interpret / Album & Pfad)
    Ihr müsst nicht gleich nach der Suche eine Datenbank anlegen (ist aber Vorteilhafter)
    Nach dem Speichern habt Ihr unten Rechts eine "GroupBox" mit dem Namen "Verzeichnisstruktur anhand der ID3-Tags erstellen:" da könnt Ihr auswählen ob das Programm die Gespeichertnen Einträge nach der ordnerstruktur
    ..\Interpret\Deteiname
    z.b.
    F:\Musik\Autoit_Sound{Interpret}\Play1.mp3{Dateiname}

    ODER

    ..\Interpret\Album\Dateiname
    z.b.
    F:\Musik\Autoit_Sound{Interpret}\mp3_Search{Album}\Play1.mp3{Dateiname}

    Kopiert ODER Verschiebt (Dafür habt Ihr dan auch wider 2 Buttons die mit einem ToolTip Versehen sind(Wie alle Buttons))

    So,dass wahr die GRUND funktion des Programmes

    Nun die Features

    Play_Sound:
    Ihr könnt auf einen GEFUNDENEN Eintrag Doppelklicken und der Entsprechende Song wird mit dem "Standart" MediaPlayer Abgespielt.

    Datenbank / ListView Suche
    Sobald Ihr Einträge in der ListView habt, könnt Ihr nach einem Song suchen, dabei spielt es keine rolle ob "Interpret"/"Album" oder nur der "Dateiname" angegeben wird.
    Auserdem habt Ihr noch die Möglichkeit das ganze einzugrentzen, wen Ihr den Punkt "Gross-/Kleinschreibung beachten" aktiviert.

    ListView abspeichern
    Ihr habt die Möglichkeit mehrer Datenbanken zu Erstellen. Aus dem einfachen Grund, das Programm kann nicht mehr alls 40´000 dateien einfassen (Liegt soweit ich weiss an Autoit)

    ListView Einträge Löschen
    Ihr könnt Einzelne Einträge oder gar den Kompletten LisView Löschen. Das hat den Vorteil, dass wen man noch Spiele Installiert hat (Online oder Offline) werden die vom Programm auch gefunden
    (Sofern mann "Alle Festplatten nach MP3s durchsuchen" wählt) Ihr könnt diese Einträge dan Makrieren und mit dem "Markierte Einträge aus der ListView entfernen" löschen. Ihr könnt diese aber auch KOMPLETT von der Festplatte Löschen, mit dem Button "Markierte Dateien von der Festplatte Löschen".

    So,das wahren die Features. Es hat noch 2-3 kleine Features die sich von Selbst Erklären :D

    Mit Freude
    Oscar & Skilkor

  • Und was willst du den mit der Editbox und was ist dein Problem damit? :)

  • Naja, statt das ers beim arraydisplay auspuckt,in die editbox haut.

    [autoit]

    _ArrayDisplay($aReturn, 'Alle Dateien mit der Erweiterung ".mp3"')

    [/autoit]

    2 Mal editiert, zuletzt von Skilkor (25. Juli 2010 um 17:13)

  • Meinst du etwa so?

    Spoiler anzeigen
    [autoit]

    #include <ButtonConstants.au3>
    #include <EditConstants.au3>
    #include <GUIConstantsEx.au3>
    #include <ProgressConstants.au3>
    #include <StaticConstants.au3>
    #include <WindowsConstants.au3>
    #include <Array.au3> ; nur für die Beispiele erforderlich

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

    $Form = GUICreate("mp3 Searcher", 626, 443, 526, 278)
    $Label = GUICtrlCreateLabel("mp3 Searcher", 8, 8, 70, 17)
    $Label1 = GUICtrlCreateLabel("Der mp3 Sucher durchsucht alle vorhandenen Festplatten"& @CRLF &"nach mp3 Dateien." , 312, 88, 277, 257)
    $Group = GUICtrlCreateGroup("", 8, 64, 609, 369)
    $Edit = GUICtrlCreateEdit("", 24, 88, 273, 329)
    GUICtrlSetData(-1, "")
    $Button = GUICtrlCreateButton("Suche", 432, 400, 75, 25, $WS_GROUP)
    $Button1 = GUICtrlCreateButton("Beenden", 528, 400, 75, 25, $WS_GROUP)
    ;~ $Progress = GUICtrlCreateProgress(312, 360, 286, 17)
    GUICtrlCreateGroup("", -99, -99, 1, 1)
    GUISetState(@SW_SHOW)

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

    While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
    Case $GUI_EVENT_CLOSE
    Exit

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

    Case $Button
    _Search()
    Case $Button1
    Exit
    EndSwitch
    WEnd
    Func _Search()
    If @AutoItVersion < '3.3.0.0' Then Exit MsgBox(16, 'Fehler', 'Funktioniert erst ab AutoIt-Version 3.3.0.0')

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

    $timer = TimerInit()
    $aReturn = _RecursiveFileListToArray('C:\Users\Public\Music', '\.mp3\z', 1) ; Alle Dateien mit der Erweiterung ".mp3" (auf F:)
    ConsoleWrite(Round(TimerDiff($timer)/1000, 3) & ' sek.' & @CRLF)
    $sReturn = _ArrayToString($aReturn,@CRLF,1)
    GuictrlsetData($Edit,$sReturn)

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

    ;===============================================================================
    ; Function Name: _RecursiveFileListToArray($sPath, $sPattern, $iFlag = 0, $iFormat = 1, $sDelim = @CRLF)
    ; Description:: gibt Verzeichnisse und/oder Dateien (rekursiv) zurück, die
    ; einem RegExp-Pattern entsprechen
    ; Parameter(s): $sPath = Startverzeichnis
    ; $sPattern = ein beliebiges RexExp-Pattern für die Auswahl
    ; $iFlag = Auswahl
    ; 0 = Dateien & Verzeichnisse
    ; 1 = nur Dateien
    ; 2 = nur Verzeichnisse
    ; $iFormat = Rückgabeformat
    ; 0 = String
    ; 1 = Array mit [0] = Anzahl
    ; 2 = Nullbasiertes Array
    ; $sDelim = Trennzeichen für die String-Rückgabe
    ; Requirement(s): AutoIt 3.3.0.0
    ; Return Value(s): Array/String mit den gefundenen Dateien/Verzeichnissen
    ; Author(s): Oscar (http://www.autoit.de)
    ; Anregungen von: bernd670 (http://www.autoit.de)
    ;===============================================================================
    EndFunc
    Func _RecursiveFileListToArray($sPath, $sPattern, $iFlag = 1, $iFormat = 1, $sDelim = @CRLF)
    Local $hSearch, $sFile, $sReturn = ''
    If StringRight($sPath, 1) <> '\' Then $sPath &= '\'
    $hSearch = FileFindFirstFile($sPath & '*.*')
    If @error Or $hSearch = -1 Then Return SetError(1, 0, $sReturn)
    While True
    $sFile = FileFindNextFile($hSearch)
    If @error Then ExitLoop
    If StringInStr(FileGetAttrib($sPath & $sFile), 'D') Then
    If StringRegExp($sPath & $sFile, $sPattern) And ($iFlag = 1 Or $iFlag = 2) Then $sReturn &= $sPath & $sFile & '\' & $sDelim
    $sReturn &= _RecursiveFileListToArray($sPath & $sFile & '\', $sPattern, $iFlag, 0)
    ContinueLoop
    EndIf
    If StringRegExp($sFile, $sPattern) And ($iFlag = 0 Or $iFlag = 1) Then $sReturn &= $sPath & $sFile & $sDelim
    WEnd
    FileClose($hSearch)
    If $iFormat Then Return StringSplit(StringTrimRight($sReturn, StringLen($sDelim)), $sDelim, $iFormat)
    Return $sReturn
    EndFunc
    ;~ ====================================================================

    [/autoit]
  • Siht gut aus (bin leider grade nicht zuhause)
    Das ich da nicht draufgekommen bin, vors array ne variable zu setzen u diese dan zu verwenden :s
    Anfänger fehler :(
    Auf jeden vielen dank, hab grad was dazu gelehrnt betrevvend array in edit widergeben :)

    • Offizieller Beitrag

    Naja, Möglichkeiten gibt es viele, die Daten weiter zu verwenden. Ich verwende gerne ListViews, da könnte man die ID3-Tags auslesen und dann in jeweils eine Spalte einfügen (zusätzlich zum Dateipfad).
    Entscheidend ist aber, was willst Du damit erreichen, also: Was soll am Ende dabei rauskommen?
    Einfach eine Auflistung aller MP3s ist ja ganz schön, aber was soll man damit anfangen? Nicht falsch verstehen, ich will Dein Projekt nicht runtermachen, nur voranbringen. :)

    Wenn Du noch nicht viel mit Arrays anfangen kannst, dann wäre es vielleicht angebracht, dieses Projekt erstmal aufzuschieben und sich mit Grundlagen (Arrays) zu befassen.
    Oder anders ausgedrückt: Bevor Du anfängst zu rennen, lerne erst das gehen. ;)

  • Naja, Möglichkeiten gibt es viele, die Daten weiter zu verwenden. Ich verwende gerne ListViews, da könnte man die ID3-Tags auslesen und dann in jeweils eine Spalte einfügen (zusätzlich zum Dateipfad).
    Entscheidend ist aber, was willst Du damit erreichen, also: Was soll am Ende dabei rauskommen?
    Einfach eine Auflistung aller MP3s ist ja ganz schön, aber was soll man damit anfangen? Nicht falsch verstehen, ich will Dein Projekt nicht runtermachen, nur voranbringen. :)

    Wenn Du noch nicht viel mit Arrays anfangen kannst, dann wäre es vielleicht angebracht, dieses Projekt erstmal aufzuschieben und sich mit Grundlagen (Arrays) zu befassen.
    Oder anders ausgedrückt: Bevor Du anfängst zu rennen, lerne erst das gehen. ;)


    Moin Oscar
    Die Geschichte:

    Spoiler anzeigen

    allso, man sammelt im laufe der jahre immer mehr Musik an,ordnet dise und verbringt dabei Stunden am rechner, nur damit, das man am Ende so gut wie jeden Song beim richtigen Interpreten - Album und Titel NR hast,Ordner über ordner Häufen sich da an. Ihrgend wan lehrnst du neue Leute kennen, unterhälst dich mit diesen über sonnstiges,bis das thema Musik kommt. Der hat mehr alls ich, und was er hat, das höhr ich auch. Ergo, er schiebt dir mal son paar GB rüber in einem ordner, 50 interpreten,zich Alben und das alles ungeordnet. Dan Sizt du wider da,Stunde um Stunde und Ordnest dein Sound.
    Eines tages denkst du dir einfach "WTF, gibts dafür kein programm???"
    Ich gebe zu, der WMP is ja gut und Recht, gibste Pfad an, und er Aktualisiert dir die biblio... aber da hast du dan wider ein problem, dersucht nach I"nterpret / Album / Titel nr..."
    Jetz kanns sein das mehrere songs keine Angaben bezüglich " Interpreten / Album / Titel nr" haben. was macht der WMP?
    Kategorie U
    unter
    "Unbekannter Blablubb"
    und dan gehts Suchen los.

    Darum benutz ich keine biblio... sondern halte auf meiner HD die Musikordnung,und zihe dan die Songs in die Widergabe Liste.
    So haste kein grosses suchen.

    Deswegen kamm ich auf die Idee ein Prog zu Schreiben, welches den rechner nach mp3 dateien durchsucht, diese in eine ini sampt Pfad schreibt und man dan diese nach "Interpreten oder Album" an den gewünschten ort Verschiebt.

    Dafür wird benötigt.
    Suchsystem
    und ein
    Copier vorgang
    (Einfache auflistung)


    und dabei geh ich Schritt für Schritt vorran. GUI - Suchsystem einbauen - wen möglich beim Copieren eine neue GUI (*"via Wizzard - oder neues Script"*)

    da gibts aber noch ein kleines problem was ich festgestellt habe, und zwar. wen man Musik und "Games / offline & online" vorhanden hat, werden diese Songs der games mit einbezogen....
    das will man ja nicht, weill die verschiebt es dan ja auch..ergo, kein sound beim gamen oO -.-
    Da kommt dan die ID3 UDF ins Spiel, das auslessen der mp3 datei,da die meisten game Sounds kein interpret oder Album haben.
    Spich
    If interpret or Album then......
    da aber wider ein prob, was ist mit der Musik die (Wie oben genannt beim WMP) auch keine angaben hat?
    da bin ich vorrest an meinem grenz wert :(

    So, die ganze geschichte mit hintergund :D

    was das mit dem "Array" angeht. muss ich dir recht geben.
    Muss aber dazu Sagen,
    Learning by Doing
    Ich Lehrne dinge am besten wen ichs selber tuhe. und wen ich an meine grentzen stosse (Wie beim edit, was mir übrigens echt peinlich ist :()
    frage ich Euch (Nach der sufu versteht sich)

    Mfg Skilkor

    *Edit*
    So, ich hab mich wider n bissl dran gesezt.

    Momentaner Stand

    Script Sucht alle .mp3 Dateien (momentan noch auf einer HD) gibt sie in der "Editbox" wider und Schreibt via FileWrite eine .ini Datei.
    Da ja die IniWrite beschränkt auf 64 kb ist, und bei meiner sammlung der gefundenen files (rund 16´000) komm ich mit FileWrite auf eine .ini grösse von 1´374KB.
    Mit IniWrite hab ich Sehr schnell den max Zeichensatz erreicht, da ja noch die Pfad angabe mitgeschrieben wird :D

    2 Mal editiert, zuletzt von Skilkor (27. Juli 2010 um 15:45)

    • Offizieller Beitrag

    Da hast Du Dir ja einiges vorgenommen. Wobei ich zweifle, ob man das einfach so "by doing" lernen kann, aber ich lasse mich da gern eines Besseren belehren.

    Ein Edit-Control-Element halte ich für so ein Projekt aber für falsch oder sagen wir: suboptimal. Ich würde Dir lieber zu einem Listview raten. Falls Dir da auch die Grundlagen fehlen, kannst Du Dir vielleicht mal mein Listview-Datenbank-Beispiel anschauen:

    Spoiler anzeigen
    [autoit]


    #include <ButtonConstants.au3>
    #include <GUIConstantsEx.au3>
    #include <GuiListView.au3>
    #include <ListViewConstants.au3>
    #include <WindowsConstants.au3>

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

    Global $sHeader = "Artikelnummer|Art|Nummer|Baureihe|Name" ; Die Überschriften für das Listview und für das "Neuer Eintrag"-Fenster
    Global $sDBFile = @ScriptDir & "\datenbank.txt" ; Pfad und Name der Datenbank-Datei
    Global $iEdit = -1 ; Wert auf -1 setzen, weil _GUICtrlListView_GetSelectionMark() einen Nullbasierten Wert liefert

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

    #Region Hauptfenster
    Global $hGui = GUICreate("Listview-Datenbank-Beispiel", 600, 480) ; Hauptfenster erstellen
    Global $hListView = GUICtrlCreateListView($sHeader, 0, 0, 600, 420, $LVS_SHOWSELALWAYS) ; Listview erstellen

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

    Global $hLVHandle = GUICtrlGetHandle($hListView) ; das Handle vom Listview wird für die UDF-Listview-Funktionen benötigt
    _GUICtrlListView_SetColumn($hLVHandle, 0, "Artikelnummer", 120, 1) ; 1. Spalte = 120 Px breit, rechts ausgerichtet
    _GUICtrlListView_SetColumn($hLVHandle, 1, "Art", 60, 0) ; 2. Spalte = 60 Px breit, links ausgerichtet
    _GUICtrlListView_SetColumn($hLVHandle, 2, "Nummer", 90, 0) ; 3. Spalte = 90 Px breit, links ausgerichtet
    _GUICtrlListView_SetColumn($hLVHandle, 3, "Baureihe", 100, 0) ; 4. Spalte = 100 Px breit, links ausgerichtet
    _GUICtrlListView_SetColumn($hLVHandle, 4, "Name", 120, 0) ; 5. Spalte = 120 Px breit, links ausgerichtet

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

    Global $hNew = GUICtrlCreateButton("Neuer Eintrag", 5, 430, 80, 35, $BS_DEFPUSHBUTTON) ; Dieser Button ist der Default-Push-Button (wenn der User [Enter] drückt)
    Global $hEdit = GUICtrlCreateButton("Markierten Eintrag bearbeiten", 95, 430, 110, 35, $BS_MULTILINE) ; $BS_Multiline für mehrzeiligen Button
    Global $hLoad = GUICtrlCreateButton("Laden", 230, 430, 70, 35)
    Global $hSave = GUICtrlCreateButton("Speichern", 310, 430, 70, 35)
    Global $hDel = GUICtrlCreateButton("Markierte Einträge löschen", 400, 430, 90, 35, $BS_MULTILINE)
    Global $hDelAll = GUICtrlCreateButton("Alle Einträge löschen", 500, 430, 90, 35, $BS_MULTILINE)

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

    Global $hCM = GUICtrlCreateContextMenu($hListView) ; ein Kontextmenü für das Listview erstellen
    Global $hCMNew = GUICtrlCreateMenuItem("Neuer Eintrag", $hCM) ; der 1. Kontextmenüeintrag
    Global $hCMEdit = GUICtrlCreateMenuItem("Eintrag bearbeiten", $hCM) ; der 2. Kontextmenüeintrag
    Global $hCMDel = GUICtrlCreateMenuItem("Markierte Einträge löschen", $hCM) ; der 3. Kontextmenüeintrag
    #EndRegion Hauptfenster

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

    #Region Fenster für neuen Eintrag
    Global $hGuiNew = GUICreate("Neuer Eintrag", 632, 140, -1, -1, $WS_SYSMENU) ; das Fenster "Neuer Eintrag" erstellen
    Global $aHeader = StringSplit($sHeader, '|') ; Überschriften-Array
    Global $aNew[$aHeader[0]] ; Array für die Input-IDs
    For $i = 1 To $aHeader[0]
    GUICtrlCreateLabel($aHeader[$i], 4 + ($i - 1) * 125, 15, 110, 20) ; Überschriften-Label erstellen
    GUICtrlSetFont(-1, 8, 400, 0, 'Verdana') ; Schriftgröße und -art der Überschriften festlegen
    $aNew[$i - 1] = GUICtrlCreateInput("", 2 + ($i - 1) * 125, 30, 120, 20, Default, $WS_EX_STATICEDGE) ; Eingabefelder erstellen
    GUICtrlSetFont(-1, 10, 600, 0, 'Verdana') ; Schriftgröße und -art der Eingabefelder festlegen
    Next
    Global $hCreate = GUICtrlCreateButton("Eintrag speichern", 254, 65, 120, 25, $BS_DEFPUSHBUTTON) ; Button zum speichern
    #EndRegion Fenster für neuen Eintrag

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

    _GUICtrlListView_RegisterSortCallBack($hLVHandle) ; damit man das Listview (mit Klick auf die Spaltenüberschrift) sortieren kann

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

    GUISetState(@SW_SHOW, $hGui) ; Hauptfenster sichtbar machen

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

    If FileExists($sDBFile) Then Load() ; wenn Datenbank-Datei existiert, dann Datenbank laden

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

    While 1
    $nMsg = GUIGetMsg(1) ; Message-Event holen (1) = erweiterter Modus
    Switch $nMsg[0] ; anhand der Control-ID das entsprechende Case aufrufen
    Case $hListView ; User hat auf eine Spaltenüberschrift geklickt
    _GUICtrlListView_SortItems($hLVHandle, GUICtrlGetState($hListView)) ; Einträge entsprechend sortieren
    Case $hNew, $hCMNew ; User hat auf "Neuer Eintrag" geklickt
    WinSetTitle($hGuiNew, "", "Neuer Eintrag") ; den Titel des Fenster anpassen
    GUISetState(@SW_SHOW, $hGuiNew) ; das Fenster "Neuer Eintrag" anzeigen
    GUISetState(@SW_DISABLE, $hGui) ; das Hauptfenster deaktivieren
    Case $hEdit, $hCMEdit ; User hat auf "Eintrag bearbeiten" geklickt
    WinSetTitle($hGuiNew, "", "Eintrag bearbeiten") ; den Titel des Fenster anpassen
    GUISetState(@SW_SHOW, $hGuiNew) ; das Fenster "Neuer Eintrag" anzeigen
    GUISetState(@SW_DISABLE, $hGui) ; das Hauptfenster deaktivieren
    Edit()
    Case $hLoad ; User hat auf "Laden" geklickt
    Load()
    Case $hSave ; User hat auf "Laden" geklickt
    Save()
    Case $hDel, $hCMDel ; User hat auf "Markierte Einträge löschen" geklickt
    If MsgBox(256 + 32 + 4, "Einträge löschen", "Wollen sie die markierten Einträge wirklich löschen?") = 6 Then _GUICtrlListView_DeleteItemsSelected($hLVHandle)
    Case $hDelAll ; User hat auf "Alle Einträge löschen" geklickt
    If MsgBox(256 + 32 + 4, "Einträge löschen", "Wollen sie wirklich alle Einträge löschen?") = 6 Then _GUICtrlListView_DeleteAllItems($hLVHandle)
    Case $hCreate ; User hat auf "Eintrag speichern" im Fenster "Neuer Eintrag" geklickt
    NewItem()
    Case $GUI_EVENT_CLOSE ; User hat auf das Schließen-Symbol geklickt (bzw. die ESC-Taste gedrückt)
    Switch $nMsg[1] ; erweiterte Abfrage für welches Fenster
    Case $hGui ; User will das Hauptfenster schließen
    If MsgBox(32 + 4, "Beenden", "Wollen sie das Programm wirklich beenden?") = 6 Then End() ; wenn ja, dann End-Funktion aufrufen
    Case $hGuiNew ; User will das "Neuer Eintrag"-Fenster schließen
    $iEdit = -1
    For $i = 0 To UBound($aNew) - 1
    GUICtrlSetData($aNew[$i], "") ; Alle Eingabefelder leeren
    Next
    GUISetState(@SW_HIDE, $hGuiNew) ; "Neuer Eintrag"-Fenster verstecken
    GUISetState(@SW_ENABLE, $hGui) ; Hauptfenster wieder aktivieren
    WinActivate($hGui) ; und in den Vordergrund holen
    EndSwitch
    EndSwitch
    WEnd

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

    Func End()
    ;~ Save() ; wenn der vordere Kommentar entfernt wird, dann werden vor dem beenden noch die Daten gespeichert
    _GUICtrlListView_UnRegisterSortCallBack($hLVHandle) ; Sortierroutine wieder de-registrieren
    Exit ; Programm beenden
    EndFunc

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

    Func NewItem() ; Funktion zum auslesen der Eingabefelder (Neuer Eintrag bzw. Eintrag bearbeiten)
    Local $sItem = ""
    For $i = 0 To UBound($aNew) - 1 ; Schleife, um alle Eingabefelder durchzugehen
    If $iEdit > -1 Then ; wenn $iEdit > -1 (Eintrag bearbeiten), dann...
    _GUICtrlListView_SetItemText($hLVHandle, $iEdit, GUICtrlRead($aNew[$i]), $i) ; den Eintrag aus dem Eingabefeld ins Listview schreiben
    Else ; sonst $iEdit = -1 (neuer Eintrag)
    $sItem &= GUICtrlRead($aNew[$i]) & "|" ; den Eintrag aus dem Eingabefeld erstmal in einer Variablen ($sItem) speichern
    EndIf
    GUICtrlSetData($aNew[$i], "") ; das entsprechende Eingabefeld leeren
    Next
    If $iEdit > -1 Then ; wenn $iEdit > -1 (Eintrag bearbeiten), dann...
    $iEdit = -1
    GUISetState(@SW_HIDE, $hGuiNew) ; "Neuer Eintrag"-Fenster verstecken
    GUISetState(@SW_ENABLE, $hGui) ; Hauptfenster wieder aktivieren
    Sleep(300)
    WinActivate($hGui) ; und in den Vordergrund holen
    Else ; sonst $iEdit = -1 (neuer Eintrag)
    GUICtrlSetState($aNew[0], $GUI_FOCUS) ; den Focus wieder auf das erste Eingabefeld setzen, für weitere Eingaben
    GUICtrlCreateListViewItem(StringTrimRight($sItem, 1), $hListView) ; mit den Werten aus $sItem einen neuen Listview-Eintrag hinzufügen
    EndIf
    EndFunc ;==>NewItem

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

    Func Edit() ; Funktion zum bearbeiten eines Listview-Eintrags im "Eintrag bearbeiten"-Fenster
    $iEdit = _GUICtrlListView_GetSelectionMark($hLVHandle) ; auslesen, welcher Listview-Eintrag markiert (bei mehreren, den obersten) ist
    If $iEdit > -1 Then
    Local $aItem = _GUICtrlListView_GetItemTextArray($hLVHandle, $iEdit) ; die Einträge aus dem Listview in ein Array holen
    For $i = 1 To $aItem[0]
    GUICtrlSetData($aNew[$i - 1], $aItem[$i]) ; und in die entsprechenden Eingabefelder schreiben
    Next
    EndIf
    EndFunc ;==>Edit

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

    Func Load() ; Datenbank-Datei laden
    Local $hFile, $sContent, $aNewItems
    $hFile = FileOpen($sDBFile, 0) ; Datei zum lesen öffnen
    If $hFile <> -1 Then ; wenn das öffnen erfolgreich war, dann...
    $sContent = FileRead($hFile) ; Datei komplett einlesen
    FileClose($hFile) ; Datei schließen
    $sContent = StringTrimRight($sContent, 2) ; das letzte @CRLF entfernen
    $aNewItems = StringSplit($sContent, @CRLF, 1) ; Den Dateiinhalt am Zeilenende splitten
    If Not IsArray($aNewItems) Then Return ; Wenn $aNewItems kein Array ist, dann Funktion verlassen
    _GUICtrlListView_BeginUpdate($hLVHandle) ; Listview sperren
    For $i = 1 To $aNewItems[0] ; Alle Einträge des Arrays durchgehen
    GUICtrlCreateListViewItem($aNewItems[$i], $hListView) ; mit den eingelesenen Daten einen neuen Listview-Eintrag erstellen
    Next
    _GUICtrlListView_EndUpdate($hLVHandle) ; Listview wieder freigeben
    EndIf
    EndFunc ;==>Load

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

    Func Save() ; Datenbank-Datei speichern
    Local $sItem, $hFile, $iCount
    $iCount = _GUICtrlListView_GetItemCount($hLVHandle) - 1 ; Anzahl der Listview-Einträge holen
    If $iCount = -1 Then Return ; Wenn das Listview keine Einträge enthält, dann Funktion verlassen
    $hFile = FileOpen($sDBFile, 2) ; Datei zum speichern (überschreiben) öffnen
    If $hFile <> -1 Then ; wenn das öffnen erfolgreich war, dann...
    For $i = 0 To $iCount ; Schleife, um alle Listview-Einträge durchzugehen
    $sItem = _GUICtrlListView_GetItemTextString($hLVHandle, $i) ; die Werte aus dem Listview-Eintrag holen
    FileWriteLine($hFile, $sItem) ; und in die Datei schreiben
    Next
    FileClose($hFile) ; Datei schließen
    EndIf
    EndFunc ;==>Save

    [/autoit]


    Ein Listview bietet halt einfach eine bessere Übersicht (Spalten-Zeilenorientiert) und man kann nach einzelnen Spalten sortieren lassen.

  • Zitat

    Da hast Du Dir ja einiges vorgenommen. Wobei ich zweifle, ob man das einfach so "by doing" lernen kann, aber ich lasse mich da gern eines Besseren belehren.

    HeHe, Ich geb dir recht, wenig ist es nicht.
    Aber du must bedenken,der mensch ist vielseitig, oder soll ich eher Sagen, das menschliche gehirn ist Vielseitig bei der informations Aufnahme und Widergabe :D
    (Wens nicht so währe...währen wir noch Neandertaler/Urmenschen xD)


    Zitat

    Ein Edit-Control-Element halte ich für so ein Projekt aber für falsch oder sagen wir: suboptimal. Ich würde Dir lieber zu einem Listview raten. Falls Dir da auch die Grundlagen fehlen, kannst Du Dir vielleicht mal mein Listview-Datenbank-Beispiel anschauen:

    *Hust* *-BEISPIEL* *Reusper*

    wen Ich den Code mal so überfliege,siht das nach ner 7tage arbeit aus xD
    und ein Bsp keines wegs xD.

    Wen ich das Script daber richtig Verstanden habe, ist es ein "Editor" wo man Informationen bezüglich verschiederner teile reinspeichert, und diese dan nach bestimmter kriterie sortiert.
    Stimmt das so etwa im Goben??

    Ich hätte da dan nochn paar fragen ^^ die kannst du mir sicher beantworten :D
    Also. was währe deiner meinung nach besser (Jetz nur die GUI Betreffend)
    Fürs GUI ein Wizzard zu machen? Da es ja eine SuchGUI und eine CopyGUI haben soll (Die SuchGUI hab ich)
    Oder der SuchGUI via #Include auf die copyGUI verweissen? Was ein 2t Script erfordert.

    ach und, wie ich bei deiner Suchfunktion angeben kann das er alle Fixen HD durchsuchen soll. wie bei
    DriveGetDrive

    Spoiler anzeigen
    [autoit]

    $var = DriveGetDrive( "fixed" )
    If NOT @error Then
    MsgBox(4096,"", "Es wurden " & $var[0] & " Laufwerke gefunden")
    For $i = 1 to $var[0]
    MsgBox(4096,"Laufwerk " & $i, $var[$i])
    Next
    EndIf

    [/autoit]


    da ja deine Suchfunktion bei mir keine mehrern HD einträge Aktzeptiert

    Spoiler anzeigen
    [autoit]

    $aReturn = _RecursiveFileListToArray('F:', '\.mp3', 1) ; Alle Dateien mit der Erweiterung ".mp3" (auf F:)

    [/autoit]


    zu

    Spoiler anzeigen
    [autoit]

    $aReturn = _RecursiveFileListToArray('C:|E:|F:|G:', '\.mp3', 1) ; Alle Dateien mit der Erweiterung ".mp3" (auf F:)

    [/autoit]


    =0sek Such Ergebniss xD
    kann es sein das ich bei dieser art Suche, jede HD Einzeln Ansprechen muss?
    z.b.

    Spoiler anzeigen
    [autoit]

    $aReturn = _RecursiveFileListToArray('C:', '\.mp3', 1)
    $aReturn = _RecursiveFileListToArray('E:', '\.mp3', 1)
    $aReturn = _RecursiveFileListToArray('F:', '\.mp3', 1)
    $aReturn = _RecursiveFileListToArray('G:', '\.mp3', 1)

    [/autoit]


    mit den angaben uns so?

    das such script in probe

    Spoiler anzeigen
    [autoit]

    #include <ButtonConstants.au3>
    #include <EditConstants.au3>
    #include <GUIConstantsEx.au3>
    #include <ProgressConstants.au3>
    #include <StaticConstants.au3>
    #include <WindowsConstants.au3>
    #include <Array.au3>

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

    $Form = GUICreate("mp3 Searcher", 626, 443, 526, 278)
    $Label = GUICtrlCreateLabel("mp3 Searcher", 8, 8, 70, 17)
    $Label1 = GUICtrlCreateLabel("Der mp3 Sucher durchsucht alle vorhandenen Festplatten"& @CRLF &"nach mp3 Dateien." , 312, 88, 277, 257)
    $Group = GUICtrlCreateGroup("", 8, 64, 609, 369)
    $Edit = GUICtrlCreateEdit("", 24, 88, 273, 329)
    GUICtrlSetData(-1, "")
    $Button = GUICtrlCreateButton("Suche", 328, 400, 75, 25, $WS_GROUP)
    $Button1 = GUICtrlCreateButton("Beenden", 428, 400, 75, 25, $WS_GROUP)
    $Button2 = GUICtrlCreateButton("Weiter", 528, 400, 75, 25, $WS_GROUP)
    ;~ $Progress = GUICtrlCreateProgress(312, 360, 286, 17)
    GUICtrlCreateGroup("", -99, -99, 1, 1)
    GUISetState(@SW_SHOW)

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

    While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
    Case $GUI_EVENT_CLOSE
    Exit

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

    Case $Button
    _Search()
    Case $Button1
    Exit
    Case $Button2
    EndSwitch
    WEnd
    Func _Search()
    If @AutoItVersion < '3.3.0.0' Then Exit MsgBox(16, 'Fehler', 'Funktioniert erst ab AutoIt-Version 3.3.0.0')

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

    $timer = TimerInit()
    $aReturn = _RecursiveFileListToArray('C:', '\.mp3', 1) ; Alle Dateien mit der Erweiterung ".mp3" (auf F:)
    ConsoleWrite(Round(TimerDiff($timer)/1000, 3) & ' sek.' & @CRLF)
    $sReturn = _ArrayToString($aReturn,@CRLF,1)
    GuictrlsetData($Edit,$sReturn)
    ;~ Erstellen einer .ini Datei,mit den gefundenen Ergebnissen
    If FileExists("Ergebniss.ini") Then
    FileDelete("Ergebniss.ini")
    EndIf
    $file = FileOpen("Ergebniss.ini", 1)
    If $file = -1 Then
    MsgBox(0, "Fehler", "Die Datei konnte nicht geöffnet werden.")
    Exit
    EndIf
    FileWrite($file, $sReturn)
    FileClose($file)
    ;===============================================================================
    ; Function Name: _RecursiveFileListToArray($sPath, $sPattern, $iFlag = 0, $iFormat = 1, $sDelim = @CRLF)
    ; Description::gibt Verzeichnisse und/oder Dateien (rekursiv) zurück, die
    ; einem RegExp-Pattern entsprechen
    ; Parameter(s):$sPath = Startverzeichnis
    ; $sPattern = ein beliebiges RexExp-Pattern für die Auswahl
    ; $iFlag = Auswahl
    ; 0 = Dateien & Verzeichnisse
    ; 1 = nur Dateien
    ; 2 = nur Verzeichnisse
    ; $iFormat = Rückgabeformat
    ; 0 = String
    ; 1 = Array mit [0] = Anzahl
    ; 2 = Nullbasiertes Array
    ; $sDelim = Trennzeichen für die String-Rückgabe
    ; Requirement(s): AutoIt 3.3.0.0
    ; Return Value(s): Array/String mit den gefundenen Dateien/Verzeichnissen
    ; Author(s): Oscar (http://www.autoit.de)
    ; Anregungen von: bernd670 (http://www.autoit.de)
    ;===============================================================================
    EndFunc
    Func _RecursiveFileListToArray($sPath, $sPattern, $iFlag = 1, $iFormat = 1, $sDelim = @CRLF)
    Local $hSearch, $sFile, $sReturn = ''
    If StringRight($sPath, 1) <> '\' Then $sPath &= '\'
    $hSearch = FileFindFirstFile($sPath & '*.*')
    If @error Or $hSearch = -1 Then Return SetError(1, 0, $sReturn)
    While True
    $sFile = FileFindNextFile($hSearch)
    If @error Then ExitLoop
    If StringInStr(FileGetAttrib($sPath & $sFile), 'D') Then
    If StringRegExp($sPath & $sFile, $sPattern) And ($iFlag = 1 Or $iFlag = 2) Then $sReturn &= $sPath & $sFile & '\' & $sDelim
    $sReturn &= _RecursiveFileListToArray($sPath & $sFile & '\', $sPattern, $iFlag, 0)
    ContinueLoop
    EndIf
    If StringRegExp($sFile, $sPattern) And ($iFlag = 0 Or $iFlag = 1) Then $sReturn &= $sPath & $sFile & $sDelim
    WEnd
    FileClose($hSearch)
    If $iFormat Then Return StringSplit(StringTrimRight($sReturn, StringLen($sDelim)), $sDelim, $iFormat)
    Return $sReturn
    EndFunc
    ;~ ====================================================================

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

    Mfg Skilkor

    4 Mal editiert, zuletzt von Skilkor (26. Juli 2010 um 17:20)

    • Offizieller Beitrag

    Es hatte mich mal interessiert, wie "schnell" AutoIt dabei ist und deshalb habe ich mal meine Skripte (Listview-Datenbank, _RecursiveFileListToArray und _ReadID3Tag) zusammengefasst und mit ein paar Statusmeldungen versehen (damit der User sieht, was passiert). Es wird jetzt ein Listview mit den ID3-Tags von allen MP3s von allen installierten Festplatten erstellt.
    Nach dem erstellen, kann man das ganze Listview abspeichern, sodass man es beim nächsten Start des Programms wieder laden kann (ohne es neu erstellen zu müssen).

    Hier das Skript:

    Spoiler anzeigen
    [autoit]


    #include <ButtonConstants.au3>
    #include <GUIConstantsEx.au3>
    #include <GuiListView.au3>
    #include <GuiStatusBar.au3>
    #include <ListViewConstants.au3>

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

    Global $sHeader = "Title|Artist|Album|Year|Length|MPEG-Version|Bitrate|Sample-Freq.|Path" ; Die Überschriften für das Listview
    Global $sDBFile = @ScriptDir & "\MP3_Collection.txt" ; Pfad und Name der Datenbank-Datei

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

    #Region Hauptfenster
    Global $hGui = GUICreate("MP3-Search", 800, 500) ; Hauptfenster erstellen
    Global $hListView = GUICtrlCreateListView($sHeader, 0, 0, 800, 420, $LVS_SHOWSELALWAYS) ; Listview erstellen

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

    Global $hLVHandle = GUICtrlGetHandle($hListView) ; das Handle vom Listview wird für die UDF-Listview-Funktionen benötigt
    _GUICtrlListView_SetColumn($hLVHandle, 0, "Title", 180, 0)
    _GUICtrlListView_SetColumn($hLVHandle, 1, "Artist", 180, 0)
    _GUICtrlListView_SetColumn($hLVHandle, 2, "Length", 60, 0)
    _GUICtrlListView_SetColumn($hLVHandle, 3, "Album", 120, 0)
    _GUICtrlListView_SetColumn($hLVHandle, 4, "Year", 60, 0)
    _GUICtrlListView_SetColumn($hLVHandle, 5, "MPEG-Version", 100, 0)
    _GUICtrlListView_SetColumn($hLVHandle, 6, "Bitrate", 100, 0)
    _GUICtrlListView_SetColumn($hLVHandle, 7, "Sample-Freq.", 90, 0)
    _GUICtrlListView_SetColumn($hLVHandle, 8, "Path", 800, 0)

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

    Global $hSearch = GUICtrlCreateButton("Alle Festplatten durchsuchen", 10, 430, 160, 35, $BS_MULTILINE)
    Global $hLoad = GUICtrlCreateButton("Laden", 230, 430, 70, 35)
    Global $hSave = GUICtrlCreateButton("Speichern", 310, 430, 70, 35)
    Global $hDelAll = GUICtrlCreateButton("Alle Einträge löschen", 500, 430, 90, 35, $BS_MULTILINE)

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

    Global $aParts[3] = [160, 220, -1], $aText[3] =["Fertig.", "0", ""]
    Global $hStatus = _GUICtrlStatusBar_Create($hGui, $aParts, $aText)
    #EndRegion Hauptfenster

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

    ;~ _GUICtrlListView_RegisterSortCallBack($hLVHandle) ; damit man das Listview (mit Klick auf die Spaltenüberschrift) sortieren kann

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

    GUISetState(@SW_SHOW, $hGui) ; Hauptfenster sichtbar machen

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

    Global $fStop = False, $iCount = 0
    HotKeySet("{ESC}", "_Stop")

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

    While 1
    Switch GUIGetMsg() ; anhand der Control-ID das entsprechende Case aufrufen
    Case $hSearch
    _GUICtrlListView_DeleteAllItems($hLVHandle) ; Alle Listview-Einträge löschen
    $iCount = 0 ; Zähler auf Null setzen
    $aDrives = DriveGetDrive("FIXED") ; Alle Festplatten-Buchstaben holen
    If Not @error Then
    For $i = 1 To $aDrives[0] ; Alle Festplatten durchgehen
    $aDrives[$i] = StringUpper($aDrives[$i]) & "\"
    _GUICtrlStatusBar_SetText($hStatus, 'Durchsuche Festplatte "' & $aDrives[$i] & '"', 0)
    _GUICtrlStatusBar_SetText($hStatus, "Bitte warten...", 2)
    $aNewMP3 = _RecursiveFileListToArray($aDrives[$i], '\.mp3', 1) ; Alle MP3s auf der Festplatte auslesen
    If Not @error Then
    _GUICtrlStatusBar_SetText($hStatus, "Lese ID3-Tags...", 0)
    _GUICtrlListView_SetItemCount($hListView, $iCount + $aNewMP3[0])
    For $j = 1 To $aNewMP3[0] ; die gefundenen MP3s durchgehen
    _GUICtrlStatusBar_SetText($hStatus, $iCount, 1)
    $aID3Tags = _ReadID3Tag($aNewMP3[$j]) ; die ID3-Tags auslesen
    If Not @error Then
    _GUICtrlStatusBar_SetText($hStatus, $aNewMP3[$j], 2)
    $sNewItem = $aID3Tags[0][1] & "|" & $aID3Tags[1][1] & "|" & $aID3Tags[4][1] & "|" & $aID3Tags[2][1] & "|" & $aID3Tags[3][1]
    $sNewItem &= "|" & $aID3Tags[8][1] & "|" & $aID3Tags[9][1] & "|" & $aID3Tags[10][1] & "|" & $aNewMP3[$j]
    GUICtrlCreateListViewItem($sNewItem, $hListView)
    $iCount += 1
    EndIf
    If $fStop Then ExitLoop 2 ; Wenn [ESC] gedrückt wurde, die Schleifen verlassen
    Next
    EndIf
    Next
    EndIf
    _GUICtrlStatusBar_SetText($hStatus, "", 2)
    If $fStop Then
    $fStop = False
    _GUICtrlStatusBar_SetText($hStatus, "Abgebrochen!", 0)
    Else
    _GUICtrlStatusBar_SetText($hStatus, "Fertig.", 0)
    EndIf
    ;~ Case $hListView ; User hat auf eine Spaltenüberschrift geklickt
    ;~ _GUICtrlListView_SortItems($hLVHandle, GUICtrlGetState($hListView)) ; Einträge entsprechend sortieren
    Case $hLoad ; User hat auf "Laden" geklickt
    _GUICtrlStatusBar_SetText($hStatus, "Lade Daten...", 0)
    Load()
    _GUICtrlStatusBar_SetText($hStatus, "Fertig.", 0)
    Case $hSave ; User hat auf "Speichern" geklickt
    _GUICtrlStatusBar_SetText($hStatus, "Speichere Daten...", 0)
    Save()
    _GUICtrlStatusBar_SetText($hStatus, "Fertig.", 0)
    _GUICtrlStatusBar_SetText($hStatus, "", 2)
    Case $hDelAll ; User hat auf "Alle Einträge löschen" geklickt
    If MsgBox(256 + 32 + 4, "Einträge löschen", "Wollen sie wirklich alle Einträge löschen?") = 6 Then
    _GUICtrlListView_DeleteAllItems($hLVHandle)
    $iCount = 0
    EndIf
    Case $GUI_EVENT_CLOSE ; User hat auf das Schließen-Symbol geklickt (bzw. die ESC-Taste gedrückt)
    End()
    ;~ If MsgBox(32 + 4, "Beenden", "Wollen sie das Programm wirklich beenden?") = 6 Then End() ; wenn ja, dann End-Funktion aufrufen
    EndSwitch
    WEnd

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

    Func _Stop()
    $fStop = True
    EndFunc

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

    Func End()
    ;~ Save() ; wenn der vordere Kommentar entfernt wird, dann werden vor dem beenden noch die Daten gespeichert
    _GUICtrlListView_UnRegisterSortCallBack($hLVHandle) ; Sortierroutine wieder de-registrieren
    Exit ; Programm beenden
    EndFunc

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

    Func Load() ; Datenbank-Datei laden
    Local $hFile, $sContent, $aNewItems
    $hFile = FileOpen($sDBFile, 0) ; Datei zum lesen öffnen
    If $hFile <> -1 Then ; wenn das öffnen erfolgreich war, dann...
    $sContent = FileRead($hFile) ; Datei komplett einlesen
    FileClose($hFile) ; Datei schließen
    $sContent = StringTrimRight($sContent, 2) ; das letzte @CRLF entfernen
    $aNewItems = StringSplit($sContent, @CRLF, 1) ; Den Dateiinhalt am Zeilenende splitten
    If Not IsArray($aNewItems) Then Return ; Wenn $aNewItems kein Array ist, dann Funktion verlassen
    _GUICtrlListView_SetItemCount($hListView, $aNewItems[0])
    _GUICtrlListView_BeginUpdate($hLVHandle) ; Listview sperren
    For $i = 1 To $aNewItems[0] ; Alle Einträge des Arrays durchgehen
    $iCount += 1
    _GUICtrlStatusBar_SetText($hStatus, $iCount, 1)
    GUICtrlCreateListViewItem($aNewItems[$i], $hListView) ; mit den eingelesenen Daten einen neuen Listview-Eintrag erstellen
    Next
    _GUICtrlListView_EndUpdate($hLVHandle) ; Listview wieder freigeben
    EndIf
    EndFunc ;==>Load

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

    Func Save() ; Datenbank-Datei speichern
    Local $sContent, $hFile, $iCount
    $iCount = _GUICtrlListView_GetItemCount($hLVHandle); Anzahl der Listview-Einträge holen
    If $iCount = 0 Then Return ; Wenn das Listview keine Einträge enthält, dann Funktion verlassen
    For $i = 0 To $iCount - 1 ; Schleife, um alle Listview-Einträge durchzugehen
    $sContent &= _GUICtrlListView_GetItemTextString($hLVHandle, $i) & @CRLF
    _GUICtrlStatusBar_SetText($hStatus, $i + 1, 2)
    Next
    $hFile = FileOpen($sDBFile, 2) ; Datei zum speichern (überschreiben) öffnen
    If $hFile <> -1 Then ; wenn das öffnen erfolgreich war, dann...
    FileWrite($hFile, $sContent)
    FileClose($hFile) ; Datei schließen
    EndIf
    EndFunc ;==>Save

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

    ;===============================================================================
    ; Function Name: _RecursiveFileListToArray($sPath[, $sPattern][, $iFlag][, $iFormat][, $iRecursion][, $sDelim])
    ; Description:: gibt Verzeichnisse (rekursiv) und/oder Dateien zurück, die einem RegExp-Pattern entsprechen
    ; Parameter(s): $sPath = Startverzeichnis
    ; $sPattern = ein beliebiges RexExp-Pattern für die Auswahl
    ; $iFlag = Auswahl
    ; 0 = Dateien & Verzeichnisse
    ; 1 = nur Dateien
    ; 2 = nur Verzeichnisse
    ; $iFormat = Rückgabeformat
    ; 0 = String
    ; 1 = Array mit [0] = Anzahl
    ; 2 = Nullbasiertes Array
    ; $iRecursion = Verzeichnisse rekursiv durchsuchen
    ; 0 = Nein
    ; 1 = Ja
    ; $sDelim = Trennzeichen für die String-Rückgabe
    ; Requirement(s): AutoIt 3.3.0.0
    ; Return Value(s): Array/String mit den gefundenen Dateien/Verzeichnissen
    ; Author(s): Oscar (http://www.autoit.de)
    ; Anregungen von: bernd670 (http://www.autoit.de)
    ;===============================================================================
    Func _RecursiveFileListToArray($sPath, $sPattern = '', $iFlag = 0, $iFormat = 1, $iRecursion = 1, $sDelim = @CRLF)
    Local $hSearch, $sFile, $sReturn = ''
    If StringRight($sPath, 1) <> '\' Then $sPath &= '\'
    $hSearch = FileFindFirstFile($sPath & '*.*')
    If @error Or $hSearch = -1 Then Return SetError(1, 0, $sReturn)
    While True
    $sFile = FileFindNextFile($hSearch)
    If @error Then ExitLoop
    If @extended Then
    If StringRegExp($sPath & $sFile, $sPattern) And ($iFlag = 0 Or $iFlag = 2) Then $sReturn &= $sPath & $sFile & '\' & $sDelim
    If $iRecursion Then $sReturn &= _RecursiveFileListToArray($sPath & $sFile & '\', $sPattern, $iFlag, 0)
    ContinueLoop
    EndIf
    If StringRegExp($sFile, $sPattern) And ($iFlag = 0 Or $iFlag = 1) Then $sReturn &= $sPath & $sFile & $sDelim
    WEnd
    FileClose($hSearch)
    If $iFormat And $sReturn = '' Then Return StringSplit($sReturn, '', $iFormat)
    If $iFormat Then Return StringSplit(StringTrimRight($sReturn, StringLen($sDelim)), $sDelim, $iFormat)
    Return $sReturn
    EndFunc

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

    ;===============================================================================
    ; Function Name: _ReadID3Tag($sPath)
    ; Description:: gibt ein Array mit den Daten aus den ID3-Tags zurück
    ; unterstützt werden die ID3-Tag-Versionen 1.0, 1.1, 2.3 und 2.4
    ; bei v2.4 müssen sich die ID3-Tags am Anfang der Datei befinden
    ; Parameter(s): $sPath = Pfad zu einer MP3-Datei
    ; Requirement(s): min. AutoIt v3.3.0.0
    ; Return Value(s): bei Erfolg: Array mit den ID3-Tagdaten (@error = 0)
    ; im Fehlerfall bekommt @error:
    ; 1 = Datei existiert nicht
    ; 2 = Datei konnte nicht zum lesen geöffnet werden
    ; 3 = falsche ID3 v2 Version
    ; 4 = Datei ist keine MP3-Datei
    ; Author(s): Oscar (http://www.autoit.de)
    ;===============================================================================
    Func _ReadID3Tag($sPath)
    If Not FileExists($sPath) Then Return SetError(1, 0, 0)
    Local $hFile, $sData, $sID3Header, $iID3HeaderSize = 0, $iOffset, $iSize, $tmp
    Local $aID3v2Tags[8] = ['TIT2', 'TPE1', 'TALB', 'TYER', 'TLEN', 'TRCK', 'TCON', 'TENC']
    Local $aID3[11][2] = [ _
    ['Title', ''],['Artist', ''],['Album', ''],['Year', ''], _
    ['Length', '0'],['Track', ''],['Genre', ''],['Encoder', ''], _
    ['MPEG-Version', ''],['Bitrate', '-'],['Sample-Freq.', '']]
    Local $aMP3Version[4] = ['MPEG2.5', 'Reserved', 'MPEG2', 'MPEG1']
    Local $aMP3Layer[4] = ['Reserved', 'Layer III', 'Layer II', 'Layer I']
    Local $aMP3Bitrate[5][16] = [ _
    [000, 032, 064, 096, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448, 000], _
    [000, 032, 048, 056, 064, 080, 096, 112, 128, 160, 192, 224, 256, 320, 384, 000], _
    [000, 032, 040, 048, 056, 064, 080, 096, 112, 128, 160, 192, 224, 256, 320, 000], _
    [000, 032, 048, 056, 064, 080, 096, 112, 128, 144, 160, 176, 192, 224, 256, 000], _
    [000, 008, 016, 024, 032, 040, 048, 056, 064, 080, 096, 112, 128, 144, 160, 000]]
    Local $aSampleFreq[3][4] = [[44100, 48000, 32000, 0],[22050, 24000, 16000, 0],[11025, 12000, 8000, 0]]
    Local $sMP3FrameHeader, $iMP3Version, $sMP3Version, $sMP3Layer, $iMP3Bitrate, $iMP3SampleFreq
    Local $iVBRFrames = -1, $iVBRFilesize, $iVBRFlags
    $hFile = FileOpen($sPath, 16)
    If $hFile = -1 Then Return SetError(2, 0, 0)
    $sData = Binary(FileRead($hFile, 4))
    If BinaryMid($sData, 1, 3) = '0x494433' Then ; ID3 v2.x Kennung gefunden
    If (BinaryMid($sData, 4, 1) = '0x03') Or (BinaryMid($sData, 4, 1) = '0x04') Then ; nur v2.3 und 2.4
    FileRead($hFile, 2) ; 2 Bytes überspringen
    For $i = 0 To 3 ; berechne ID3-Headergröße (4 Bytes, jedoch nur jeweils die unteren 7 Bit)
    $iID3HeaderSize = BitShift($iID3HeaderSize, -7) + BitAND(Binary(FileRead($hFile, 1)), 0x7F)
    Next
    If $iID3HeaderSize > 0 Then
    $sID3Header = Binary(FileRead($hFile, $iID3HeaderSize)) ; lese gesamten ID3-Header
    For $i = 0 To 7
    $iOffset = StringInStr(BinaryToString($sID3Header), $aID3v2Tags[$i]) ; Offset zu dem ID3-Tag
    If $iOffset > 0 Then
    $iSize = Hex(BinaryMid($sID3Header, $iOffset + 4, 4)) ; Größe des ID3-Frames
    $tmp = BinaryMid($sID3Header, $iOffset + 11, Dec($iSize) - 1)
    If BinaryMid($tmp, 1, 2) = '0xFFFE' Then
    For $x = 3 To BinaryLen($tmp) Step 2
    $aID3[$i][1] &= BinaryToString(BinaryMid($tmp, $x, 2), 2)
    Next
    Else
    For $x = 1 To BinaryLen($tmp)
    $aID3[$i][1] &= BinaryToString(BinaryMid($tmp, $x, 1))
    Next
    EndIf
    $aID3[$i][1] = StringReplace($aID3[$i][1], Chr(0), '')
    EndIf
    Next
    EndIf
    Do
    $sData = String(FileRead($hFile, 1))
    If @error Then ExitLoop
    If BitAND($sData, 0xff) = 0xff Then
    FileSetPos($hFile, -1, 1)
    $sData = String(FileRead($hFile, 4))
    EndIf
    Until BitAND($sData, 0xFFE00000) = 0xFFE00000
    Else
    FileClose($hFile)
    Return SetError(3, 0, 0)
    EndIf
    Else ; ID3 v1.x
    $iOffset = FileGetPos($hFile)
    FileSetPos($hFile, -128, 2)
    $sID3Header = BinaryToString(FileRead($hFile, 3))
    If $sID3Header = 'TAG' Then
    $aID3[0][1] = StringReplace(BinaryToString(FileRead($hFile, 30)), Chr(0), '')
    $aID3[1][1] = StringReplace(BinaryToString(FileRead($hFile, 30)), Chr(0), '')
    $aID3[2][1] = StringReplace(BinaryToString(FileRead($hFile, 30)), Chr(0), '')
    $aID3[3][1] = StringReplace(BinaryToString(FileRead($hFile, 4)), Chr(0), '')
    EndIf
    FileSetPos($hFile, $iOffset, 0)
    EndIf
    $sMP3FrameHeader = String($sData)
    If BitAND($sMP3FrameHeader, 0xFFE00000) <> 0xFFE00000 Then
    FileClose($hFile)
    Return SetError(4, 0, 0) ; keine MP3-Datei, dann Return
    EndIf
    $iMP3Version = BitShift(BitXOR($sMP3FrameHeader, 0xFFE00000), 19) ; welche MP3-Version
    $sMP3Version = $aMP3Version[$iMP3Version] ; in Textform
    $sMP3Layer = $aMP3Layer[BitShift(BitAND($sMP3FrameHeader, 0x60000), 17)] ; welcher Layer
    $aID3[8][1] = $sMP3Version & ' / ' & $sMP3Layer ; ins Ausgabe-Array
    $iMP3Bitrate = BitShift(BitAND($sMP3FrameHeader, 0xF000), 12) ; Bitraten-Index auslesen
    Switch $sMP3Version ; je nach MPEG-Version Bitrate aus der Tabelle holen
    Case 'MPEG1'
    $aID3[9][1] = $aMP3Bitrate[$iMP3Version - ($iMP3Version > 1)][$iMP3Bitrate]
    Case 'MPEG2', 'MPEG2.5'
    If $sMP3Layer = 'Layer I' Then
    $aID3[9][1] = $aMP3Bitrate[3][$iMP3Bitrate]
    Else
    $aID3[9][1] = $aMP3Bitrate[4][$iMP3Bitrate]
    EndIf
    EndSwitch
    $iMP3SampleFreq = BitShift(BitAND($sMP3FrameHeader, 0xC00), 10) ; Sample-Frequenz-Index auslesen
    $aID3[10][1] = $aSampleFreq[2 - ($iMP3Version - ($iMP3Version > 1))][$iMP3SampleFreq] ; und Wert aus der Tabelle holen
    Do ; evtl. Leerbytes überspringen
    $tmp = FileRead($hFile, 1)
    If @error Then ExitLoop
    Until $tmp <> 0x00 Or @error
    If $tmp = 0x58 And BinaryToString(FileRead($hFile, 3)) = 'ing' Then ; MP3 mit VBR (Xing-Header gefunden)?
    $iVBRFlags = '0x' & Hex(FileRead($hFile, 4)) ; VBR-Flags auslesen
    If BitAND($iVBRFlags, 0x3) Then ; wenn die Einträge vorhanden sind, dann...
    $iVBRFrames = Dec(Hex(FileRead($hFile, 4))) ; Anzahl der VBR-Frames auslesen
    $iVBRFilesize = Dec(Hex(FileRead($hFile, 4))) ; Dateigröße auslesen
    $aID3[4][1] = $iVBRFrames * 1152 / $aID3[10][1] * 1000 ; VBR Laufzeit
    $aID3[9][1] = 'VBR ~' & Int($iVBRFilesize * 8 / ($aID3[4][1] / 1000) / 1000) ; VBR durchschnittliche Bitrate
    EndIf
    Else
    If $aID3[4][1] = 0 Then $aID3[4][1] = (FileGetSize($sPath) * 8) / ($aID3[9][1] * 1000) * 1000 ; alternative CBR Laufzeit
    $aID3[9][1] = 'CBR ' & $aID3[9][1]
    EndIf
    $aID3[4][1] = _MyTicksToTime($aID3[4][1]) ; Laufzeit (Ticks to hour:min:sec)
    $aID3[9][1] &= ' kBit/s'
    $aID3[10][1] &= ' Hz'
    FileClose($hFile)
    Return SetError(0, 0, $aID3)
    EndFunc ;==>_ReadID3Tag

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

    Func _MyTicksToTime($iTicks)
    Local $iHour, $iMins, $iSecs
    $iHour = Int($iTicks / 3600000)
    $iTicks -= $iHour * 3600000
    $iMins = Int($iTicks / 60000)
    $iTicks -= $iMins * 60000
    $iSecs = Int($iTicks / 1000)
    Return StringFormat('%02i:%02i:%02i', $iHour, $iMins, $iSecs)
    EndFunc ;==>_MyTicksToTime

    [/autoit]

    Naja, habe ich Dir schon eine Menge Arbeit abgenommen, aber wie gesagt, es war eigentlich nur das zusammensetzen von meinen bereits vorhandenen Skripten. :)

  • *Krank* Das was dich so interessiert hat, kann jetz schon mehr alls das was ich mir eigentlich vorgestellt habe xD
    Was ich aber festgestellt habe ist, dass teils programme die geöffnet sind (vor dem ausführen der mp3 progs) ein wenig Schwierigkeiten haben,Damit meine ich das sie dan bei erneuten öffnen zimlich lange haben.
    Wobei ich aber glaube, das Liegt daran das die SuFu der progs derart durch die verzeichnisse Schnellt das die HD bei einem ausführen eines anderen progs mühe hat :D weill, soballd er vom C:\ weg ist, ist das nicht mehr der fall :D

    Aber ich muss zugeben, und kann es nur in diesen worten fassen *Heilige Schei**e"
    Sooo, Klein und schon so OHO :D

    Ich bedanke mich auf jeden herzlich *-*
    und es nimmt mich wunder wielange du gecodet hast? (auch wen es nur eine zusammenführung von codes ist, die du schon hattest :D)

    Mfg Skilkor

    *Edit*
    Das durchsuchen hat gesammthaft etwa 15min gedauert bei einem Filefound von über 20´000 xD

    Meine Vorstellung:

    Spoiler anzeigen

    Was ich mich jetz Frage und wen ich dein Code so ansehe. ist es meiner meinung nach am besten via #Include das Sortier / Verschiebe Script einzu bauen. oder seh ich das falls?
    *So zu sagen, in Ehren und Danken an Oscar mit dem Such und auslese code ^^ und das andere is von mir xD haha ^^ Nein, es ist mir wichtig das die Autoren der codes im Script enthalten sind ^^
    da ich noch ein neuling bin, kann das bei mir nochn bissl warten ^^

    Was das Sortier / Verschiebe Script angeht, da hab ich 2 Dinge:
    1: Ich hab Keinerlei ansätze wie genau ich die Sortieren will
    -Vorgestellt hab ich mir,dass man Sie nach Artist oder Gengre Sortiert (Vorerst,man kann ja immernoch optionen hinzufügen :D)
    Dabei Frag ich mich, wie ich das am besten anstellen soll.
    Eine idee hab ich zumindest schon, via ordner create der dan die Entsprechende (Artis / Genre) ausliest und am angegebenen Pfad via (Sihe 2:)

    2: für das verschieben hab ich mir FileCopy vorgestellt, dabei bin ich mir noch nicht ganz sicher,
    -ob das NUR für den Ordner ist - Die Deteien oder Beides. Ich werd mir das Erst genauer anscheuen ^^ sonnst bringts ja nichts :D
    -Ok, Gefunden, je nach Flag einzelne Dateien, oder den Ordner mit den Dateien


    *Last Edit*
    Die Ellen Lange Geschichte in einen Spoiler gepackt, erleichter das Scrollen

    5 Mal editiert, zuletzt von Skilkor (27. Juli 2010 um 16:10)

    • Offizieller Beitrag

    Also zu der Sortierfunktion: Du brauchst vieeeeel Geduld, wenn Du >20000 Einträge im Listview hast! Das war der Grund, warum ich das im obigen Skript auskommentiert habe.
    Und wenn man schon so lange braucht, um die Liste zu sortieren, ist das eigentlich schon der Todesstoss für das Projekt. Es sei denn, jemand kennt eine Möglichkeit (C-Routine oder so) wie man ein Listview mit so vielen Einträgen wirklich schnell sortieren kann...

    Kopieren/verschieben der Dateien (inkl. erstellen evtl. Verzeichnisse) ist eher die einfache Aufgabe.

  • Zitat

    Also zu der Sortierfunktion: Du brauchst vieeeeel Geduld, wenn Du >20000 Einträge im Listview hast! Das war der Grund, warum ich das im obigen Skript auskommentiert habe.
    Und wenn man schon so lange braucht, um die Liste zu sortieren, ist das eigentlich schon der Todesstoss für das Projekt. Es sei denn, jemand kennt eine Möglichkeit (C-Routine oder so) wie man ein Listview mit so vielen Einträgen wirklich schnell sortieren kann...

    Kopieren/verschieben der Dateien (inkl. erstellen evtl. Verzeichnisse) ist eher die einfache Aufgabe.

    Ich habe mich gestern mal Intensiv mit der such nach möglichkeiten der sortierung beschäftigt und NICHTS gefunden was eben diese kriterien (Du hast sie oben gennant) funktionieren würde.
    Also,muss ich dir da mal zustimmen.
    Wobei ich mich jetz gerade frage. ob man dies nicht vll mit CMD machen könnte..... ich weiss nurnoch ob cmd ein .txt oder .ini auslessen kann und die darin enthalteten infors verwenden kann.(Is nur son Gedanke...kann sein das ich da vll voll aufm Holzweg bin xD, belehrt mich ^^)

    und was das Copy / Switch angeht.... das ist dan wie du sagts, das eiiiinfacheeere xD

    Ich werde aufjedenfall weiter suchen... und evt mal ein Direktes thema machen,wen das as hilfen sollte :D

    Mfg Skilkor

    *Edit*
    Hey Oscar
    Ich habe dein Search bisschen gändert. nichts grosses. nur die Fenstergrösse ein wenig.
    und noch Eingefügt das man ein Markierten Eintrag löschen kann. aus dem einfachen grund, da das Prog auch teils Windows Sounds und vorallem Gamesounds mit einbeziht.
    Dan kann man nähmlich die einträge wo man weiss (Man muss nur den PFad ansehen) Löschen :D aus dem Grund wollt ich auch den Pfad ^^ hehe
    naja alles automatisch kann man dan wohl doch nicht machen. auser man erstellt ein prog welches intellignt ist und erkennt was kein "gamesound und Windows Sound" ist. was aba ihrwie ne sisifuss arbeit werden könnte. d.h...lass ich das ^^

    wen du die source sehen willst, sag bescheid. ist nur was kleines hinzugefügt,wobei ich denke, du weisst was ich gemacht hab (<3 Copy / paste xD) haha

    ich muss ma guggen ob ich das auch per tastendruck hinbekommen, so Quasi
    So, auch das per tastendruck (del) funktioniert jetz. einfach eine Seperate func gemacht :D
    *Edit2*
    haha, nach dem aussortieren was nicht meine Musik is, sind es nurnoch etwa 10875 Files... da sind wohl doch n paar Doppelt xD
    naja Die grundlage funktioniert schonmal ^^

    Ich bin dir aufjedenfall Dankbar Oscar :D

    Auserdem hab ich bei deinem code noch volgendes gefunden:

    [autoit]

    ;~ _GUICtrlListView_RegisterSortCallBack($hLVHandle) ; damit man das Listview (mit Klick auf die Spaltenüberschrift) sortieren kann

    [/autoit]


    Zeile 35...
    Das dient doch zum Sortieren der Inhalte in der ListView oder nicht?
    wen man die listViwe sortieren kann, ist doch die halbe Arbeit der Sortieren getan? dan Kann man die SO abspeichen und dan hast du die Sortiert in der "Datenbank" oder seh ich das vollöig falsch???
    Mfg Skilkor

    3 Mal editiert, zuletzt von Skilkor (28. Juli 2010 um 19:03)

    • Offizieller Beitrag

    Also, die Sortierfunktion mit Hilfe von _GUICtrlListView_RegisterSortCallBack ausführen zu lassen dauert ewig: bei 42000 Einträgen = ca. 8 Minuten (!).
    Jetzt habe ich das Skript dahingehend umgeschrieben, dass die Einträge auch in einem 2D-Array vorhanden sind. Dieses lasse ich dann per _ArraySort sortieren, lösche die Listview-Einträge und erstelle sie neu. Das verringert die Sortierung auf etwa 20-30 Sekunden (!). Das ist immer noch relativ lange, aber das kann man noch akzeptieren, IMHO.

    Außerdem habe ich mal alle langwierigen Aktionen mit Rückmeldungen versehen, sodass man nicht den Eindruck hat, das Programm wäre abgestürzt. Das einlesen der Festplatten kann man mit [ESC] abbrechen.

    Skript:

    Spoiler anzeigen
    [autoit]


    #include <Array.au3>
    #include <ButtonConstants.au3>
    #include <GUIConstantsEx.au3>
    #include <GuiListView.au3>
    #include <GuiStatusBar.au3>
    #include <ListViewConstants.au3>

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

    Global $sHeader = 'Title|Artist|Album|Year|Length|MPEG-Version|Bitrate|Sample-Freq.|Path' ; Die Überschriften für das Listview
    Global $sDBFile = @ScriptDir & '\MP3_Collection.txt' ; Pfad und Name der Datenbank-Datei

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

    #region Hauptfenster
    Global $iWidth = @DesktopWidth - 100
    Global $hGui = GUICreate('MP3-Search', $iWidth, 500) ; Hauptfenster erstellen
    GUISetBkColor(0xAAAAAA)
    Global $hListView = GUICtrlCreateListView($sHeader, 5, 5, $iWidth - 10, 420, $LVS_SHOWSELALWAYS) ; Listview erstellen
    Global $aListview[1][9]
    Global $hLVHandle = GUICtrlGetHandle($hListView) ; das Handle vom Listview wird für die UDF-Listview-Funktionen benötigt
    _GUICtrlListView_SetColumn($hLVHandle, 0, 'Title', 180, 0)
    _GUICtrlListView_SetColumn($hLVHandle, 1, 'Artist', 180, 0)
    _GUICtrlListView_SetColumn($hLVHandle, 2, 'Length', 60, 0)
    _GUICtrlListView_SetColumn($hLVHandle, 3, 'Album', 120, 0)
    _GUICtrlListView_SetColumn($hLVHandle, 4, 'Year', 60, 0)
    _GUICtrlListView_SetColumn($hLVHandle, 5, 'MPEG-Version', 100, 0)
    _GUICtrlListView_SetColumn($hLVHandle, 6, 'Bitrate', 100, 0)
    _GUICtrlListView_SetColumn($hLVHandle, 7, 'Sample-Freq.', 90, 0)
    _GUICtrlListView_SetColumn($hLVHandle, 8, 'Path', 800, 0)

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

    Global $hSearch = GUICtrlCreateButton('Alle Festplatten durchsuchen', 10, 430, 160, 35, $BS_MULTILINE)
    Global $hLoad = GUICtrlCreateButton('Laden', 230, 430, 70, 35)
    Global $hSave = GUICtrlCreateButton('Speichern', 310, 430, 70, 35)
    Global $hDel = GUICtrlCreateButton("Markierte Einträge löschen", 400, 430, 90, 35, $BS_MULTILINE)
    Global $hDelAll = GUICtrlCreateButton('Alle Einträge löschen', 500, 430, 90, 35, $BS_MULTILINE)

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

    Global $aParts[3] = [180, 240, -1], $aText[3] = ['Fertig.', '0', '']
    Global $hStatus = _GUICtrlStatusBar_Create($hGui, $aParts, $aText)
    #endregion Hauptfenster

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

    GUISetState(@SW_SHOW, $hGui) ; Hauptfenster sichtbar machen

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

    Global $fStop = False, $iLVCount = 0
    HotKeySet('{ESC}', '_Stop')

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

    While 1
    Switch GUIGetMsg() ; anhand der Control-ID das entsprechende Case aufrufen
    Case $hSearch
    _GUICtrlListView_DeleteAllItems($hLVHandle) ; Alle Listview-Einträge löschen
    $iLVCount = 0 ; Zähler auf Null setzen
    $aDrives = DriveGetDrive('FIXED') ; Alle Festplatten-Buchstaben holen
    ;~ Dim $aDrives[2] = [1, 'c:']
    If Not @error Then
    GUISetCursor(15, 1, $hGui)
    For $i = 1 To $aDrives[0] ; Alle Festplatten durchgehen
    $aDrives[$i] = StringUpper($aDrives[$i]) & '\'
    _GUICtrlStatusBar_SetText($hStatus, 'Durchsuche Festplatte "' & $aDrives[$i] & '"', 0)
    _GUICtrlStatusBar_SetText($hStatus, 'Bitte warten...', 2)
    $aNewMP3 = _RecursiveFileListToArray($aDrives[$i], '\.mp3', 1) ; Alle MP3s auf der Festplatte auslesen
    If Not @error Then
    _GUICtrlListView_SetItemCount($hListView, $iLVCount + $aNewMP3[0])
    ConsoleWrite('$iLVCount = ' & $iLVCount & @CR & '$aNewMP3[0] = ' & $aNewMP3[0] & @CR)
    ReDim $aListview[$iLVCount + $aNewMP3[0] + 1][9]
    _GUICtrlStatusBar_SetText($hStatus, 'Lese ID3-Tags... (' & UBound($aListview) & ')', 0)
    For $j = 1 To $aNewMP3[0] ; die gefundenen MP3s durchgehen
    _GUICtrlStatusBar_SetText($hStatus, $iLVCount, 1)
    $aID3Tags = _ReadID3Tag($aNewMP3[$j]) ; die ID3-Tags auslesen
    If Not @error Then
    For $k = 0 To 10
    $aID3Tags[$k][1] = StringReplace($aID3Tags[$k][1], '|', '') ; evtl. vorhandene "|" entfernen
    Next
    _GUICtrlStatusBar_SetText($hStatus, $aNewMP3[$j], 2)
    $sNewItem = $aID3Tags[0][1] & '|' & $aID3Tags[1][1] & '|' & $aID3Tags[4][1] & '|' & $aID3Tags[2][1] & '|' & $aID3Tags[3][1]
    $sNewItem &= '|' & $aID3Tags[8][1] & '|' & $aID3Tags[9][1] & '|' & $aID3Tags[10][1] & '|' & $aNewMP3[$j]
    $aItem = StringSplit($sNewItem, '|')
    For $k = 1 To $aItem[0]
    $aListview[$iLVCount][$k - 1] = $aItem[$k]
    Next
    GUICtrlCreateListViewItem($sNewItem, $hListView)
    $iLVCount += 1
    EndIf
    If $fStop Then ExitLoop 2 ; Wenn [ESC] gedrückt wurde, die Schleifen verlassen
    Next
    ReDim $aListview[$iLVCount][9]
    EndIf
    Next
    GUISetCursor(2, 1, $hGui)
    EndIf
    _GUICtrlStatusBar_SetText($hStatus, $iLVCount, 1)
    _GUICtrlStatusBar_SetText($hStatus, '', 2)
    If $fStop Then
    $fStop = False
    _GUICtrlStatusBar_SetText($hStatus, 'Abgebrochen!', 0)
    Else
    _GUICtrlStatusBar_SetText($hStatus, 'Fertig.', 0)
    EndIf
    Case $hListView ; User hat auf eine Spaltenüberschrift geklickt
    If $iLVCount > 0 Then
    GUISetCursor(15, 1, $hGui)
    _GUICtrlStatusBar_SetText($hStatus, 'Sortiere Daten...', 0)
    $iSort = GUICtrlGetState($hListView)
    $iTimer = TimerInit()
    ConsoleWrite('Start Sort col: ' & $iSort & @CR)
    _ArraySort($aListview, 0, 0, 0, $iSort)
    ConsoleWrite('Sort: ' & Int(TimerDiff($iTimer)) & ' ms' & @CR)
    _GUICtrlListView_DeleteAllItems($hLVHandle)
    ConsoleWrite('Delete all: ' & Int(TimerDiff($iTimer)) & ' ms' & @CR)
    _GUICtrlListView_BeginUpdate($hLVHandle) ; Listview sperren
    _GUICtrlListView_AddArray($hLVHandle, $aListview)
    _GUICtrlListView_EndUpdate($hLVHandle) ; Listview wieder freigeben
    ConsoleWrite('Create new: ' & Int(TimerDiff($iTimer)) & ' ms' & @CR)
    ConsoleWrite('End.' & @CR)
    _GUICtrlStatusBar_SetText($hStatus, 'Fertig.', 0)
    GUISetCursor(2, 1, $hGui)
    EndIf
    Case $hLoad ; User hat auf 'Laden' geklickt
    GUISetCursor(15, 1, $hGui)
    _GUICtrlStatusBar_SetText($hStatus, 'Lade Daten...', 0)
    Load()
    _GUICtrlStatusBar_SetText($hStatus, 'Fertig.', 0)
    GUISetCursor(2, 1, $hGui)
    Case $hSave ; User hat auf 'Speichern' geklickt
    GUISetCursor(15, 1, $hGui)
    _GUICtrlStatusBar_SetText($hStatus, 'Speichere Daten...', 0)
    Save()
    _GUICtrlStatusBar_SetText($hStatus, 'Fertig.', 0)
    _GUICtrlStatusBar_SetText($hStatus, '', 2)
    GUISetCursor(2, 1, $hGui)
    Case $hDel
    $aSelectedItems = _GUICtrlListView_GetSelectedIndices($hLVHandle, True)
    If $aSelectedItems[0] > 0 Then
    GUISetCursor(15, 1, $hGui)
    For $i = $aSelectedItems[0] To 1 Step - 1
    _ArrayDelete($aListview, $aSelectedItems[$i])
    Next
    _GUICtrlListView_DeleteItemsSelected($hLVHandle)
    $iLVCount -= $aSelectedItems[0]
    _GUICtrlStatusBar_SetText($hStatus, $iLVCount, 1)
    GUISetCursor(2, 1, $hGui)
    EndIf
    Case $hDelAll ; User hat auf 'Alle Einträge löschen' geklickt
    If MsgBox(256 + 32 + 4, 'Einträge löschen', 'Wollen sie wirklich alle Einträge löschen?') = 6 Then
    _GUICtrlListView_DeleteAllItems($hLVHandle)
    ReDim $aListview[1][9]
    $iLVCount = 0
    _GUICtrlStatusBar_SetText($hStatus, $iLVCount, 1)
    EndIf
    Case $GUI_EVENT_CLOSE ; User hat auf das Schließen-Symbol geklickt (bzw. die ESC-Taste gedrückt)
    If MsgBox(32 + 4, 'Beenden', 'Wollen sie das Programm wirklich beenden?') = 6 Then End() ; wenn ja, dann End-Funktion aufrufen
    EndSwitch
    WEnd

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

    Func _Stop()
    $fStop = True
    EndFunc ;==>_Stop

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

    Func End()
    ;~ Save() ; wenn der vordere Kommentar entfernt wird, dann werden vor dem beenden noch die Daten gespeichert
    Exit ; Programm beenden
    EndFunc ;==>End

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

    Func Load() ; Datenbank-Datei laden
    Local $hFile, $sContent, $aNewItems, $iTimer, $iCount, $aItem
    $hFile = FileOpen($sDBFile, 0) ; Datei zum lesen öffnen
    If $hFile <> -1 Then ; wenn das öffnen erfolgreich war, dann...
    $sContent = FileRead($hFile) ; Datei komplett einlesen
    FileClose($hFile) ; Datei schließen
    $sContent = StringTrimRight($sContent, 2) ; das letzte @CRLF entfernen
    $aNewItems = StringSplit($sContent, @CRLF, 1) ; Den Dateiinhalt am Zeilenende splitten
    If Not IsArray($aNewItems) Then Return ; Wenn $aNewItems kein Array ist, dann Funktion verlassen
    _GUICtrlListView_DeleteAllItems($hLVHandle)
    _GUICtrlListView_SetItemCount($hLVHandle, $aNewItems[0])
    Global $aListview[$aNewItems[0]][9]
    _GUICtrlStatusBar_SetText($hStatus, 'Lade Daten... (' & $aNewItems[0] & ')', 0)
    _GUICtrlListView_BeginUpdate($hLVHandle) ; Listview sperren
    $iTimer = TimerInit()
    For $i = 1 To $aNewItems[0] ; Alle Einträge des Arrays durchgehen
    $iCount += 1
    If TimerDiff($iTimer) > 100 Then
    $iTimer = TimerInit()
    _GUICtrlStatusBar_SetText($hStatus, $iCount, 1)
    EndIf
    $aItem = StringSplit($aNewItems[$i], '|')
    For $j = 1 To $aItem[0]
    $aListview[$i - 1][$j - 1] = $aItem[$j]
    Next
    GUICtrlCreateListViewItem($aNewItems[$i], $hListView) ; mit den eingelesenen Daten einen neuen Listview-Eintrag erstellen
    Next
    _GUICtrlStatusBar_SetText($hStatus, $iCount, 1)
    _GUICtrlListView_EndUpdate($hLVHandle) ; Listview wieder freigeben
    $iLVCount = UBound($aListview)
    EndIf
    EndFunc ;==>Load

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

    Func Save() ; Datenbank-Datei speichern
    Local $sContent, $hFile, $iCount, $iTimer
    $iCount = _GUICtrlListView_GetItemCount($hLVHandle); Anzahl der Listview-Einträge holen
    If $iCount = 0 Then Return ; Wenn das Listview keine Einträge enthält, dann Funktion verlassen
    $iTimer = TimerInit()
    For $i = 0 To $iCount - 1 ; Schleife, um alle Listview-Einträge durchzugehen
    $sContent &= _GUICtrlListView_GetItemTextString($hLVHandle, $i) & @CRLF
    If TimerDiff($iTimer) > 100 Then
    $iTimer = TimerInit()
    _GUICtrlStatusBar_SetText($hStatus, $i + 1, 2)
    EndIf
    Next
    $hFile = FileOpen($sDBFile, 2) ; Datei zum speichern (überschreiben) öffnen
    If $hFile <> -1 Then ; wenn das öffnen erfolgreich war, dann...
    FileWrite($hFile, $sContent)
    FileClose($hFile) ; Datei schließen
    EndIf
    EndFunc ;==>Save

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

    ;===============================================================================
    ; Function Name: _RecursiveFileListToArray($sPath[, $sPattern][, $iFlag][, $iFormat][, $iRecursion][, $sDelim])
    ; Description:: gibt Verzeichnisse (rekursiv) und/oder Dateien zurück, die einem RegExp-Pattern entsprechen
    ; Parameter(s): $sPath = Startverzeichnis
    ; $sPattern = ein beliebiges RexExp-Pattern für die Auswahl
    ; $iFlag = Auswahl
    ; 0 = Dateien & Verzeichnisse
    ; 1 = nur Dateien
    ; 2 = nur Verzeichnisse
    ; $iFormat = Rückgabeformat
    ; 0 = String
    ; 1 = Array mit [0] = Anzahl
    ; 2 = Nullbasiertes Array
    ; $iRecursion = Verzeichnisse rekursiv durchsuchen
    ; 0 = Nein
    ; 1 = Ja
    ; $sDelim = Trennzeichen für die String-Rückgabe
    ; Requirement(s): AutoIt 3.3.0.0
    ; Return Value(s): Array/String mit den gefundenen Dateien/Verzeichnissen
    ; Author(s): Oscar (http://www.autoit.de)
    ; Anregungen von: bernd670 (http://www.autoit.de)
    ;===============================================================================
    Func _RecursiveFileListToArray($sPath, $sPattern = '', $iFlag = 0, $iFormat = 1, $iRecursion = 1, $sDelim = @CRLF)
    Local $hSearch, $sFile, $sReturn = ''
    If StringRight($sPath, 1) <> '\' Then $sPath &= '\'
    $hSearch = FileFindFirstFile($sPath & '*.*')
    If @error Or $hSearch = -1 Then Return SetError(1, 0, $sReturn)
    While Not $fStop
    $sFile = FileFindNextFile($hSearch)
    If @error Then ExitLoop
    If @extended Then
    If StringRegExp($sPath & $sFile, $sPattern) And ($iFlag = 0 Or $iFlag = 2) Then $sReturn &= $sPath & $sFile & '\' & $sDelim
    If $iRecursion Then $sReturn &= _RecursiveFileListToArray($sPath & $sFile & '\', $sPattern, $iFlag, 0)
    ContinueLoop
    EndIf
    If StringRegExp($sFile, $sPattern) And ($iFlag = 0 Or $iFlag = 1) Then $sReturn &= $sPath & $sFile & $sDelim
    WEnd
    FileClose($hSearch)
    If $iFormat And $sReturn = '' Then Return StringSplit($sReturn, '', $iFormat)
    If $iFormat Then Return StringSplit(StringTrimRight($sReturn, StringLen($sDelim)), $sDelim, $iFormat)
    Return $sReturn
    EndFunc ;==>_RecursiveFileListToArray

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

    ;===============================================================================
    ; Function Name: _ReadID3Tag($sPath)
    ; Description:: gibt ein Array mit den Daten aus den ID3-Tags zurück
    ; unterstützt werden die ID3-Tag-Versionen 1.0, 1.1, 2.3 und 2.4
    ; bei v2.4 müssen sich die ID3-Tags am Anfang der Datei befinden
    ; Parameter(s): $sPath = Pfad zu einer MP3-Datei
    ; Requirement(s): min. AutoIt v3.3.0.0
    ; Return Value(s): bei Erfolg: Array mit den ID3-Tagdaten (@error = 0)
    ; im Fehlerfall bekommt @error:
    ; 1 = Datei existiert nicht
    ; 2 = Datei konnte nicht zum lesen geöffnet werden
    ; 3 = falsche ID3 v2 Version
    ; 4 = Datei ist keine MP3-Datei
    ; Author(s): Oscar (http://www.autoit.de)
    ;===============================================================================
    Func _ReadID3Tag($sPath)
    If Not FileExists($sPath) Then Return SetError(1, 0, 0)
    Local $hFile, $sData, $sID3Header, $iID3HeaderSize = 0, $iOffset, $iSize, $tmp
    Local $aID3v2Tags[8] = ['TIT2', 'TPE1', 'TALB', 'TYER', 'TLEN', 'TRCK', 'TCON', 'TENC']
    Local $aID3[11][2] = [ _
    ['Title', ''],['Artist', ''],['Album', ''],['Year', ''], _
    ['Length', '0'],['Track', ''],['Genre', ''],['Encoder', ''], _
    ['MPEG-Version', ''],['Bitrate', '-'],['Sample-Freq.', '']]
    Local $aMP3Version[4] = ['MPEG2.5', 'Reserved', 'MPEG2', 'MPEG1']
    Local $aMP3Layer[4] = ['Reserved', 'Layer III', 'Layer II', 'Layer I']
    Local $aMP3Bitrate[5][16] = [ _
    [000, 032, 064, 096, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448, 000], _
    [000, 032, 048, 056, 064, 080, 096, 112, 128, 160, 192, 224, 256, 320, 384, 000], _
    [000, 032, 040, 048, 056, 064, 080, 096, 112, 128, 160, 192, 224, 256, 320, 000], _
    [000, 032, 048, 056, 064, 080, 096, 112, 128, 144, 160, 176, 192, 224, 256, 000], _
    [000, 008, 016, 024, 032, 040, 048, 056, 064, 080, 096, 112, 128, 144, 160, 000]]
    Local $aSampleFreq[3][4] = [[44100, 48000, 32000, 0],[22050, 24000, 16000, 0],[11025, 12000, 8000, 0]]
    Local $sMP3FrameHeader, $iMP3Version, $sMP3Version, $sMP3Layer, $iMP3Bitrate, $iMP3SampleFreq
    Local $iVBRFrames = -1, $iVBRFilesize, $iVBRFlags
    $hFile = FileOpen($sPath, 16)
    If $hFile = -1 Then Return SetError(2, 0, 0)
    $sData = Binary(FileRead($hFile, 4))
    If BinaryMid($sData, 1, 3) = '0x494433' Then ; ID3 v2.x Kennung gefunden
    If (BinaryMid($sData, 4, 1) = '0x03') Or (BinaryMid($sData, 4, 1) = '0x04') Then ; nur v2.3 und 2.4
    FileRead($hFile, 2) ; 2 Bytes überspringen
    For $i = 0 To 3 ; berechne ID3-Headergröße (4 Bytes, jedoch nur jeweils die unteren 7 Bit)
    $iID3HeaderSize = BitShift($iID3HeaderSize, -7) + BitAND(Binary(FileRead($hFile, 1)), 0x7F)
    Next
    If $iID3HeaderSize > 0 Then
    $sID3Header = Binary(FileRead($hFile, $iID3HeaderSize)) ; lese gesamten ID3-Header
    For $i = 0 To 7
    $iOffset = StringInStr(BinaryToString($sID3Header), $aID3v2Tags[$i]) ; Offset zu dem ID3-Tag
    If $iOffset > 0 Then
    $iSize = Hex(BinaryMid($sID3Header, $iOffset + 4, 4)) ; Größe des ID3-Frames
    $tmp = BinaryMid($sID3Header, $iOffset + 11, Dec($iSize) - 1)
    If BinaryMid($tmp, 1, 2) = '0xFFFE' Then
    For $x = 3 To BinaryLen($tmp) Step 2
    $aID3[$i][1] &= BinaryToString(BinaryMid($tmp, $x, 2), 2)
    Next
    Else
    For $x = 1 To BinaryLen($tmp)
    $aID3[$i][1] &= BinaryToString(BinaryMid($tmp, $x, 1))
    Next
    EndIf
    $aID3[$i][1] = StringReplace($aID3[$i][1], Chr(0), '')
    EndIf
    Next
    EndIf
    Do
    $sData = String(FileRead($hFile, 1))
    If @error Then ExitLoop
    If BitAND($sData, 0xff) = 0xff Then
    FileSetPos($hFile, -1, 1)
    $sData = String(FileRead($hFile, 4))
    EndIf
    Until BitAND($sData, 0xFFE00000) = 0xFFE00000
    Else
    FileClose($hFile)
    Return SetError(3, 0, 0)
    EndIf
    Else ; ID3 v1.x
    $iOffset = FileGetPos($hFile)
    FileSetPos($hFile, -128, 2)
    $sID3Header = BinaryToString(FileRead($hFile, 3))
    If $sID3Header = 'TAG' Then
    $aID3[0][1] = StringReplace(BinaryToString(FileRead($hFile, 30)), Chr(0), '')
    $aID3[1][1] = StringReplace(BinaryToString(FileRead($hFile, 30)), Chr(0), '')
    $aID3[2][1] = StringReplace(BinaryToString(FileRead($hFile, 30)), Chr(0), '')
    $aID3[3][1] = StringReplace(BinaryToString(FileRead($hFile, 4)), Chr(0), '')
    EndIf
    FileSetPos($hFile, $iOffset, 0)
    EndIf
    $sMP3FrameHeader = String($sData)
    If BitAND($sMP3FrameHeader, 0xFFE00000) <> 0xFFE00000 Then
    FileClose($hFile)
    Return SetError(4, 0, 0) ; keine MP3-Datei, dann Return
    EndIf
    $iMP3Version = BitShift(BitXOR($sMP3FrameHeader, 0xFFE00000), 19) ; welche MP3-Version
    $sMP3Version = $aMP3Version[$iMP3Version] ; in Textform
    $sMP3Layer = $aMP3Layer[BitShift(BitAND($sMP3FrameHeader, 0x60000), 17)] ; welcher Layer
    $aID3[8][1] = $sMP3Version & ' / ' & $sMP3Layer ; ins Ausgabe-Array
    $iMP3Bitrate = BitShift(BitAND($sMP3FrameHeader, 0xF000), 12) ; Bitraten-Index auslesen
    Switch $sMP3Version ; je nach MPEG-Version Bitrate aus der Tabelle holen
    Case 'MPEG1'
    $aID3[9][1] = $aMP3Bitrate[$iMP3Version - ($iMP3Version > 1)][$iMP3Bitrate]
    Case 'MPEG2', 'MPEG2.5'
    If $sMP3Layer = 'Layer I' Then
    $aID3[9][1] = $aMP3Bitrate[3][$iMP3Bitrate]
    Else
    $aID3[9][1] = $aMP3Bitrate[4][$iMP3Bitrate]
    EndIf
    EndSwitch
    $iMP3SampleFreq = BitShift(BitAND($sMP3FrameHeader, 0xC00), 10) ; Sample-Frequenz-Index auslesen
    $aID3[10][1] = $aSampleFreq[2 - ($iMP3Version - ($iMP3Version > 1))][$iMP3SampleFreq] ; und Wert aus der Tabelle holen
    Do ; evtl. Leerbytes überspringen
    $tmp = FileRead($hFile, 1)
    If @error Then ExitLoop
    Until $tmp <> 0x00 Or @error
    If $tmp = 0x58 And BinaryToString(FileRead($hFile, 3)) = 'ing' Then ; MP3 mit VBR (Xing-Header gefunden)?
    $iVBRFlags = '0x' & Hex(FileRead($hFile, 4)) ; VBR-Flags auslesen
    If BitAND($iVBRFlags, 0x3) Then ; wenn die Einträge vorhanden sind, dann...
    $iVBRFrames = Dec(Hex(FileRead($hFile, 4))) ; Anzahl der VBR-Frames auslesen
    $iVBRFilesize = Dec(Hex(FileRead($hFile, 4))) ; Dateigröße auslesen
    $aID3[4][1] = $iVBRFrames * 1152 / $aID3[10][1] * 1000 ; VBR Laufzeit
    $aID3[9][1] = 'VBR ~' & Int($iVBRFilesize * 8 / ($aID3[4][1] / 1000) / 1000) ; VBR durchschnittliche Bitrate
    EndIf
    Else
    If $aID3[4][1] = 0 Then $aID3[4][1] = (FileGetSize($sPath) * 8) / ($aID3[9][1] * 1000) * 1000 ; alternative CBR Laufzeit
    $aID3[9][1] = 'CBR ' & $aID3[9][1]
    EndIf
    $aID3[4][1] = _MyTicksToTime($aID3[4][1]) ; Laufzeit (Ticks to hour:min:sec)
    $aID3[9][1] &= ' kBit/s'
    $aID3[10][1] &= ' Hz'
    FileClose($hFile)
    Return SetError(0, 0, $aID3)
    EndFunc ;==>_ReadID3Tag

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

    Func _MyTicksToTime($iTicks)
    Local $iHour, $iMins, $iSecs
    $iHour = Int($iTicks / 3600000)
    $iTicks -= $iHour * 3600000
    $iMins = Int($iTicks / 60000)
    $iTicks -= $iMins * 60000
    $iSecs = Int($iTicks / 1000)
    Return StringFormat('%02i:%02i:%02i', $iHour, $iMins, $iSecs)
    EndFunc ;==>_MyTicksToTime

    [/autoit]
  • Du bist ja mir Eifer und fleiss daran ^^ Hats dich Gepackt wie :D Freut mich wirklich Sehr :D:D

    Ich habe das Fenster n bissl angepasst

    Spoiler anzeigen

    bei

    [autoit]

    Global $iWidth = @DesktopWidth - 100

    [/autoit]


    Hab ich

    [autoit]

    Global $iWidth = @DesktopWidth - 500

    [/autoit]


    So bekomm ichs auf beide Bildschierme (Habn 22" Main und n 17"Second) ^^

    Auserdem hab ich das Löschen der Markierung per Tastendruck noch eingefügt

    [autoit]

    HotKeySet("{DEL}", "_hDelObj")

    [/autoit]


    Unterhalb von

    [autoit]

    Global $fStop = False, $iLVCount = 0
    HotKeySet('{ESC}', '_Stop')

    [/autoit]


    und dir func dazu halt

    [autoit]

    Func _hDelObj()
    _GUICtrlListView_DeleteItemsSelected($hLVHandle)
    $iCount = 0
    EndFunc

    [/autoit]


    Und die Buttons bissl zusammen Gerückt
    Von

    [autoit]

    Global $hSearch = GUICtrlCreateButton('Alle Festplatten durchsuchen', 10, 430, 160, 35, $BS_MULTILINE)
    Global $hLoad = GUICtrlCreateButton('Laden', 230, 430, 70, 35)
    Global $hSave = GUICtrlCreateButton('Speichern', 310, 430, 70, 35)
    Global $hDel = GUICtrlCreateButton("Markierte Einträge löschen", 400, 430, 90, 35, $BS_MULTILINE)
    Global $hDelAll = GUICtrlCreateButton('Alle Einträge löschen', 500, 430, 90, 35, $BS_MULTILINE)

    [/autoit]


    zu

    [autoit]

    Global $hSearch = GUICtrlCreateButton('Alle Festplatten durchsuchen', 10, 430, 160, 35, $BS_MULTILINE)
    Global $hLoad = GUICtrlCreateButton('Laden', 180, 430, 70, 35)
    Global $hSave = GUICtrlCreateButton('Speichern', 260, 430, 70, 35)
    Global $hDel = GUICtrlCreateButton("Markierte Einträge löschen", 340, 430, 90, 35, $BS_MULTILINE)
    Global $hDelAll = GUICtrlCreateButton('Alle Einträge löschen', 440, 430, 90, 35, $BS_MULTILINE)

    [/autoit]

    Das ganze sieht dan So aus

    Spoiler anzeigen
    [autoit]

    #include <Array.au3>
    #include <ButtonConstants.au3>
    #include <GUIConstantsEx.au3>
    #include <GuiListView.au3>
    #include <GuiStatusBar.au3>
    #include <ListViewConstants.au3>

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

    Global $sHeader = 'Title|Artist|Album|Year|Length|MPEG-Version|Bitrate|Sample-Freq.|Path' ; Die Überschriften für das Listview
    Global $sDBFile = @ScriptDir & '\MP3_Collection.txt' ; Pfad und Name der Datenbank-Datei

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

    #region Hauptfenster
    Global $iWidth = @DesktopWidth - 500
    Global $hGui = GUICreate('MP3-Search', $iWidth, 500) ; Hauptfenster erstellen
    GUISetBkColor(0xAAAAAA)
    Global $hListView = GUICtrlCreateListView($sHeader, 5, 5, $iWidth - 10, 420, $LVS_SHOWSELALWAYS) ; Listview erstellen
    Global $aListview[1][9]
    Global $hLVHandle = GUICtrlGetHandle($hListView) ; das Handle vom Listview wird für die UDF-Listview-Funktionen benötigt
    _GUICtrlListView_SetColumn($hLVHandle, 0, "Title", 180, 0)
    _GUICtrlListView_SetColumn($hLVHandle, 1, "Artist", 180, 0)
    _GUICtrlListView_SetColumn($hLVHandle, 2, "Length", 60, 0)
    _GUICtrlListView_SetColumn($hLVHandle, 3, "Album", 120, 0)
    _GUICtrlListView_SetColumn($hLVHandle, 4, "Year", 60, 0)
    _GUICtrlListView_SetColumn($hLVHandle, 5, "MPEG-Version", 100, 0)
    _GUICtrlListView_SetColumn($hLVHandle, 6, "Bitrate", 100, 0)
    _GUICtrlListView_SetColumn($hLVHandle, 7, "Sample-Freq.", 90, 0)
    _GUICtrlListView_SetColumn($hLVHandle, 8, "Path", 500, 0)

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

    Global $hSearch = GUICtrlCreateButton('Alle Festplatten durchsuchen', 10, 430, 160, 35, $BS_MULTILINE)
    Global $hLoad = GUICtrlCreateButton('Laden', 180, 430, 70, 35)
    Global $hSave = GUICtrlCreateButton('Speichern', 260, 430, 70, 35)
    Global $hDel = GUICtrlCreateButton("Markierte Einträge löschen", 340, 430, 90, 35, $BS_MULTILINE)
    Global $hDelAll = GUICtrlCreateButton('Alle Einträge löschen', 440, 430, 90, 35, $BS_MULTILINE)

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

    Global $aParts[3] = [180, 240, -1], $aText[3] = ['Fertig.', '0', '']
    Global $hStatus = _GUICtrlStatusBar_Create($hGui, $aParts, $aText)
    #endregion Hauptfenster

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

    GUISetState(@SW_SHOW, $hGui) ; Hauptfenster sichtbar machen

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

    Global $fStop = False, $iLVCount = 0
    HotKeySet('{ESC}', '_Stop')

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

    HotKeySet("{DEL}", "_hDelObj")

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

    While 1
    Switch GUIGetMsg() ; anhand der Control-ID das entsprechende Case aufrufen
    Case $hSearch
    _GUICtrlListView_DeleteAllItems($hLVHandle) ; Alle Listview-Einträge löschen
    $iLVCount = 0 ; Zähler auf Null setzen
    $aDrives = DriveGetDrive('FIXED') ; Alle Festplatten-Buchstaben holen
    ;~ Dim $aDrives[2] = [1, 'c:']
    If Not @error Then
    GUISetCursor(15, 1, $hGui)
    For $i = 1 To $aDrives[0] ; Alle Festplatten durchgehen
    $aDrives[$i] = StringUpper($aDrives[$i]) & '\'
    _GUICtrlStatusBar_SetText($hStatus, 'Durchsuche Festplatte "' & $aDrives[$i] & '"', 0)
    _GUICtrlStatusBar_SetText($hStatus, 'Bitte warten...', 2)
    $aNewMP3 = _RecursiveFileListToArray($aDrives[$i], '\.mp3', 1) ; Alle MP3s auf der Festplatte auslesen
    If Not @error Then
    _GUICtrlListView_SetItemCount($hListView, $iLVCount + $aNewMP3[0])
    ConsoleWrite('$iLVCount = ' & $iLVCount & @CR & '$aNewMP3[0] = ' & $aNewMP3[0] & @CR)
    ReDim $aListview[$iLVCount + $aNewMP3[0] + 1][9]
    _GUICtrlStatusBar_SetText($hStatus, 'Lese ID3-Tags... (' & UBound($aListview) & ')', 0)
    For $j = 1 To $aNewMP3[0] ; die gefundenen MP3s durchgehen
    _GUICtrlStatusBar_SetText($hStatus, $iLVCount, 1)
    $aID3Tags = _ReadID3Tag($aNewMP3[$j]) ; die ID3-Tags auslesen
    If Not @error Then
    For $k = 0 To 10
    $aID3Tags[$k][1] = StringReplace($aID3Tags[$k][1], '|', '') ; evtl. vorhandene "|" entfernen
    Next
    _GUICtrlStatusBar_SetText($hStatus, $aNewMP3[$j], 2)
    $sNewItem = $aID3Tags[0][1] & '|' & $aID3Tags[1][1] & '|' & $aID3Tags[4][1] & '|' & $aID3Tags[2][1] & '|' & $aID3Tags[3][1]
    $sNewItem &= '|' & $aID3Tags[8][1] & '|' & $aID3Tags[9][1] & '|' & $aID3Tags[10][1] & '|' & $aNewMP3[$j]
    $aItem = StringSplit($sNewItem, '|')
    For $k = 1 To $aItem[0]
    $aListview[$iLVCount][$k - 1] = $aItem[$k]
    Next
    GUICtrlCreateListViewItem($sNewItem, $hListView)
    $iLVCount += 1
    EndIf
    If $fStop Then ExitLoop 2 ; Wenn [ESC] gedrückt wurde, die Schleifen verlassen
    Next
    ReDim $aListview[$iLVCount][9]
    EndIf
    Next
    GUISetCursor(2, 1, $hGui)
    EndIf
    _GUICtrlStatusBar_SetText($hStatus, $iLVCount, 1)
    _GUICtrlStatusBar_SetText($hStatus, '', 2)
    If $fStop Then
    $fStop = False
    _GUICtrlStatusBar_SetText($hStatus, 'Abgebrochen!', 0)
    Else
    _GUICtrlStatusBar_SetText($hStatus, 'Fertig.', 0)
    EndIf
    Case $hListView ; User hat auf eine Spaltenüberschrift geklickt
    If $iLVCount > 0 Then
    GUISetCursor(15, 1, $hGui)
    _GUICtrlStatusBar_SetText($hStatus, 'Sortiere Daten...', 0)
    $iSort = GUICtrlGetState($hListView)
    $iTimer = TimerInit()
    ConsoleWrite('Start Sort col: ' & $iSort & @CR)
    _ArraySort($aListview, 0, 0, 0, $iSort)
    ConsoleWrite('Sort: ' & Int(TimerDiff($iTimer)) & ' ms' & @CR)
    _GUICtrlListView_DeleteAllItems($hLVHandle)
    ConsoleWrite('Delete all: ' & Int(TimerDiff($iTimer)) & ' ms' & @CR)
    _GUICtrlListView_BeginUpdate($hLVHandle) ; Listview sperren
    _GUICtrlListView_AddArray($hLVHandle, $aListview)
    _GUICtrlListView_EndUpdate($hLVHandle) ; Listview wieder freigeben
    ConsoleWrite('Create new: ' & Int(TimerDiff($iTimer)) & ' ms' & @CR)
    ConsoleWrite('End.' & @CR)
    _GUICtrlStatusBar_SetText($hStatus, 'Fertig.', 0)
    GUISetCursor(2, 1, $hGui)
    EndIf
    Case $hLoad ; User hat auf 'Laden' geklickt
    GUISetCursor(15, 1, $hGui)
    _GUICtrlStatusBar_SetText($hStatus, 'Lade Daten...', 0)
    Load()
    _GUICtrlStatusBar_SetText($hStatus, 'Fertig.', 0)
    GUISetCursor(2, 1, $hGui)
    Case $hSave ; User hat auf 'Speichern' geklickt
    GUISetCursor(15, 1, $hGui)
    _GUICtrlStatusBar_SetText($hStatus, 'Speichere Daten...', 0)
    Save()
    _GUICtrlStatusBar_SetText($hStatus, 'Fertig.', 0)
    _GUICtrlStatusBar_SetText($hStatus, '', 2)
    GUISetCursor(2, 1, $hGui)
    Case $hDel
    $aSelectedItems = _GUICtrlListView_GetSelectedIndices($hLVHandle, True)
    If $aSelectedItems[0] > 0 Then
    GUISetCursor(15, 1, $hGui)
    For $i = $aSelectedItems[0] To 1 Step - 1
    _ArrayDelete($aListview, $aSelectedItems[$i])
    Next
    _GUICtrlListView_DeleteItemsSelected($hLVHandle)
    $iLVCount -= $aSelectedItems[0]
    _GUICtrlStatusBar_SetText($hStatus, $iLVCount, 1)
    GUISetCursor(2, 1, $hGui)
    EndIf
    Case $hDelAll ; User hat auf 'Alle Einträge löschen' geklickt
    If MsgBox(256 + 32 + 4, 'Einträge löschen', 'Wollen sie wirklich alle Einträge löschen?') = 6 Then
    _GUICtrlListView_DeleteAllItems($hLVHandle)
    ReDim $aListview[1][9]
    $iLVCount = 0
    _GUICtrlStatusBar_SetText($hStatus, $iLVCount, 1)
    EndIf
    Case $GUI_EVENT_CLOSE ; User hat auf das Schließen-Symbol geklickt (bzw. die ESC-Taste gedrückt)
    If MsgBox(32 + 4, 'Beenden', 'Wollen sie das Programm wirklich beenden?') = 6 Then End() ; wenn ja, dann End-Funktion aufrufen
    EndSwitch
    WEnd

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

    Func _hDelObj()
    _GUICtrlListView_DeleteItemsSelected($hLVHandle)
    $iCount = 0
    EndFunc

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

    Func _Stop()
    $fStop = True
    EndFunc ;==>_Stop

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

    Func End()
    ;~ Save() ; wenn der vordere Kommentar entfernt wird, dann werden vor dem beenden noch die Daten gespeichert
    Exit ; Programm beenden
    EndFunc ;==>End

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

    Func Load() ; Datenbank-Datei laden
    Local $hFile, $sContent, $aNewItems, $iTimer, $iCount, $aItem
    $hFile = FileOpen($sDBFile, 0) ; Datei zum lesen öffnen
    If $hFile <> -1 Then ; wenn das öffnen erfolgreich war, dann...
    $sContent = FileRead($hFile) ; Datei komplett einlesen
    FileClose($hFile) ; Datei schließen
    $sContent = StringTrimRight($sContent, 2) ; das letzte @CRLF entfernen
    $aNewItems = StringSplit($sContent, @CRLF, 1) ; Den Dateiinhalt am Zeilenende splitten
    If Not IsArray($aNewItems) Then Return ; Wenn $aNewItems kein Array ist, dann Funktion verlassen
    _GUICtrlListView_DeleteAllItems($hLVHandle)
    _GUICtrlListView_SetItemCount($hLVHandle, $aNewItems[0])
    Global $aListview[$aNewItems[0]][9]
    _GUICtrlStatusBar_SetText($hStatus, 'Lade Daten... (' & $aNewItems[0] & ')', 0)
    _GUICtrlListView_BeginUpdate($hLVHandle) ; Listview sperren
    $iTimer = TimerInit()
    For $i = 1 To $aNewItems[0] ; Alle Einträge des Arrays durchgehen
    $iCount += 1
    If TimerDiff($iTimer) > 100 Then
    $iTimer = TimerInit()
    _GUICtrlStatusBar_SetText($hStatus, $iCount, 1)
    EndIf
    $aItem = StringSplit($aNewItems[$i], '|')
    For $j = 1 To $aItem[0]
    $aListview[$i - 1][$j - 1] = $aItem[$j]
    Next
    GUICtrlCreateListViewItem($aNewItems[$i], $hListView) ; mit den eingelesenen Daten einen neuen Listview-Eintrag erstellen
    Next
    _GUICtrlStatusBar_SetText($hStatus, $iCount, 1)
    _GUICtrlListView_EndUpdate($hLVHandle) ; Listview wieder freigeben
    $iLVCount = UBound($aListview)
    EndIf
    EndFunc ;==>Load

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

    Func Save() ; Datenbank-Datei speichern
    Local $sContent, $hFile, $iCount, $iTimer
    $iCount = _GUICtrlListView_GetItemCount($hLVHandle); Anzahl der Listview-Einträge holen
    If $iCount = 0 Then Return ; Wenn das Listview keine Einträge enthält, dann Funktion verlassen
    $iTimer = TimerInit()
    For $i = 0 To $iCount - 1 ; Schleife, um alle Listview-Einträge durchzugehen
    $sContent &= _GUICtrlListView_GetItemTextString($hLVHandle, $i) & @CRLF
    If TimerDiff($iTimer) > 100 Then
    $iTimer = TimerInit()
    _GUICtrlStatusBar_SetText($hStatus, $i + 1, 2)
    EndIf
    Next
    $hFile = FileOpen($sDBFile, 2) ; Datei zum speichern (überschreiben) öffnen
    If $hFile <> -1 Then ; wenn das öffnen erfolgreich war, dann...
    FileWrite($hFile, $sContent)
    FileClose($hFile) ; Datei schließen
    EndIf
    EndFunc ;==>Save

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

    ;===============================================================================
    ; Function Name: _RecursiveFileListToArray($sPath[, $sPattern][, $iFlag][, $iFormat][, $iRecursion][, $sDelim])
    ; Description:: gibt Verzeichnisse (rekursiv) und/oder Dateien zurück, die einem RegExp-Pattern entsprechen
    ; Parameter(s): $sPath = Startverzeichnis
    ; $sPattern = ein beliebiges RexExp-Pattern für die Auswahl
    ; $iFlag = Auswahl
    ; 0 = Dateien & Verzeichnisse
    ; 1 = nur Dateien
    ; 2 = nur Verzeichnisse
    ; $iFormat = Rückgabeformat
    ; 0 = String
    ; 1 = Array mit [0] = Anzahl
    ; 2 = Nullbasiertes Array
    ; $iRecursion = Verzeichnisse rekursiv durchsuchen
    ; 0 = Nein
    ; 1 = Ja
    ; $sDelim = Trennzeichen für die String-Rückgabe
    ; Requirement(s): AutoIt 3.3.0.0
    ; Return Value(s): Array/String mit den gefundenen Dateien/Verzeichnissen
    ; Author(s): Oscar (http://www.autoit.de)
    ; Anregungen von: bernd670 (http://www.autoit.de)
    ;===============================================================================
    Func _RecursiveFileListToArray($sPath, $sPattern = '', $iFlag = 0, $iFormat = 1, $iRecursion = 1, $sDelim = @CRLF)
    Local $hSearch, $sFile, $sReturn = ''
    If StringRight($sPath, 1) <> '\' Then $sPath &= '\'
    $hSearch = FileFindFirstFile($sPath & '*.*')
    If @error Or $hSearch = -1 Then Return SetError(1, 0, $sReturn)
    While Not $fStop
    $sFile = FileFindNextFile($hSearch)
    If @error Then ExitLoop
    If @extended Then
    If StringRegExp($sPath & $sFile, $sPattern) And ($iFlag = 0 Or $iFlag = 2) Then $sReturn &= $sPath & $sFile & '\' & $sDelim
    If $iRecursion Then $sReturn &= _RecursiveFileListToArray($sPath & $sFile & '\', $sPattern, $iFlag, 0)
    ContinueLoop
    EndIf
    If StringRegExp($sFile, $sPattern) And ($iFlag = 0 Or $iFlag = 1) Then $sReturn &= $sPath & $sFile & $sDelim
    WEnd
    FileClose($hSearch)
    If $iFormat And $sReturn = '' Then Return StringSplit($sReturn, '', $iFormat)
    If $iFormat Then Return StringSplit(StringTrimRight($sReturn, StringLen($sDelim)), $sDelim, $iFormat)
    Return $sReturn
    EndFunc ;==>_RecursiveFileListToArray

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

    ;===============================================================================
    ; Function Name: _ReadID3Tag($sPath)
    ; Description:: gibt ein Array mit den Daten aus den ID3-Tags zurück
    ; unterstützt werden die ID3-Tag-Versionen 1.0, 1.1, 2.3 und 2.4
    ; bei v2.4 müssen sich die ID3-Tags am Anfang der Datei befinden
    ; Parameter(s): $sPath = Pfad zu einer MP3-Datei
    ; Requirement(s): min. AutoIt v3.3.0.0
    ; Return Value(s): bei Erfolg: Array mit den ID3-Tagdaten (@error = 0)
    ; im Fehlerfall bekommt @error:
    ; 1 = Datei existiert nicht
    ; 2 = Datei konnte nicht zum lesen geöffnet werden
    ; 3 = falsche ID3 v2 Version
    ; 4 = Datei ist keine MP3-Datei
    ; Author(s): Oscar (http://www.autoit.de)
    ;===============================================================================
    Func _ReadID3Tag($sPath)
    If Not FileExists($sPath) Then Return SetError(1, 0, 0)
    Local $hFile, $sData, $sID3Header, $iID3HeaderSize = 0, $iOffset, $iSize, $tmp
    Local $aID3v2Tags[8] = ['TIT2', 'TPE1', 'TALB', 'TYER', 'TLEN', 'TRCK', 'TCON', 'TENC']
    Local $aID3[11][2] = [ _
    ['Title', ''],['Artist', ''],['Album', ''],['Year', ''], _
    ['Length', '0'],['Track', ''],['Genre', ''],['Encoder', ''], _
    ['MPEG-Version', ''],['Bitrate', '-'],['Sample-Freq.', '']]
    Local $aMP3Version[4] = ['MPEG2.5', 'Reserved', 'MPEG2', 'MPEG1']
    Local $aMP3Layer[4] = ['Reserved', 'Layer III', 'Layer II', 'Layer I']
    Local $aMP3Bitrate[5][16] = [ _
    [000, 032, 064, 096, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448, 000], _
    [000, 032, 048, 056, 064, 080, 096, 112, 128, 160, 192, 224, 256, 320, 384, 000], _
    [000, 032, 040, 048, 056, 064, 080, 096, 112, 128, 160, 192, 224, 256, 320, 000], _
    [000, 032, 048, 056, 064, 080, 096, 112, 128, 144, 160, 176, 192, 224, 256, 000], _
    [000, 008, 016, 024, 032, 040, 048, 056, 064, 080, 096, 112, 128, 144, 160, 000]]
    Local $aSampleFreq[3][4] = [[44100, 48000, 32000, 0],[22050, 24000, 16000, 0],[11025, 12000, 8000, 0]]
    Local $sMP3FrameHeader, $iMP3Version, $sMP3Version, $sMP3Layer, $iMP3Bitrate, $iMP3SampleFreq
    Local $iVBRFrames = -1, $iVBRFilesize, $iVBRFlags
    $hFile = FileOpen($sPath, 16)
    If $hFile = -1 Then Return SetError(2, 0, 0)
    $sData = Binary(FileRead($hFile, 4))
    If BinaryMid($sData, 1, 3) = '0x494433' Then ; ID3 v2.x Kennung gefunden
    If (BinaryMid($sData, 4, 1) = '0x03') Or (BinaryMid($sData, 4, 1) = '0x04') Then ; nur v2.3 und 2.4
    FileRead($hFile, 2) ; 2 Bytes überspringen
    For $i = 0 To 3 ; berechne ID3-Headergröße (4 Bytes, jedoch nur jeweils die unteren 7 Bit)
    $iID3HeaderSize = BitShift($iID3HeaderSize, -7) + BitAND(Binary(FileRead($hFile, 1)), 0x7F)
    Next
    If $iID3HeaderSize > 0 Then
    $sID3Header = Binary(FileRead($hFile, $iID3HeaderSize)) ; lese gesamten ID3-Header
    For $i = 0 To 7
    $iOffset = StringInStr(BinaryToString($sID3Header), $aID3v2Tags[$i]) ; Offset zu dem ID3-Tag
    If $iOffset > 0 Then
    $iSize = Hex(BinaryMid($sID3Header, $iOffset + 4, 4)) ; Größe des ID3-Frames
    $tmp = BinaryMid($sID3Header, $iOffset + 11, Dec($iSize) - 1)
    If BinaryMid($tmp, 1, 2) = '0xFFFE' Then
    For $x = 3 To BinaryLen($tmp) Step 2
    $aID3[$i][1] &= BinaryToString(BinaryMid($tmp, $x, 2), 2)
    Next
    Else
    For $x = 1 To BinaryLen($tmp)
    $aID3[$i][1] &= BinaryToString(BinaryMid($tmp, $x, 1))
    Next
    EndIf
    $aID3[$i][1] = StringReplace($aID3[$i][1], Chr(0), '')
    EndIf
    Next
    EndIf
    Do
    $sData = String(FileRead($hFile, 1))
    If @error Then ExitLoop
    If BitAND($sData, 0xff) = 0xff Then
    FileSetPos($hFile, -1, 1)
    $sData = String(FileRead($hFile, 4))
    EndIf
    Until BitAND($sData, 0xFFE00000) = 0xFFE00000
    Else
    FileClose($hFile)
    Return SetError(3, 0, 0)
    EndIf
    Else ; ID3 v1.x
    $iOffset = FileGetPos($hFile)
    FileSetPos($hFile, -128, 2)
    $sID3Header = BinaryToString(FileRead($hFile, 3))
    If $sID3Header = 'TAG' Then
    $aID3[0][1] = StringReplace(BinaryToString(FileRead($hFile, 30)), Chr(0), '')
    $aID3[1][1] = StringReplace(BinaryToString(FileRead($hFile, 30)), Chr(0), '')
    $aID3[2][1] = StringReplace(BinaryToString(FileRead($hFile, 30)), Chr(0), '')
    $aID3[3][1] = StringReplace(BinaryToString(FileRead($hFile, 4)), Chr(0), '')
    EndIf
    FileSetPos($hFile, $iOffset, 0)
    EndIf
    $sMP3FrameHeader = String($sData)
    If BitAND($sMP3FrameHeader, 0xFFE00000) <> 0xFFE00000 Then
    FileClose($hFile)
    Return SetError(4, 0, 0) ; keine MP3-Datei, dann Return
    EndIf
    $iMP3Version = BitShift(BitXOR($sMP3FrameHeader, 0xFFE00000), 19) ; welche MP3-Version
    $sMP3Version = $aMP3Version[$iMP3Version] ; in Textform
    $sMP3Layer = $aMP3Layer[BitShift(BitAND($sMP3FrameHeader, 0x60000), 17)] ; welcher Layer
    $aID3[8][1] = $sMP3Version & ' / ' & $sMP3Layer ; ins Ausgabe-Array
    $iMP3Bitrate = BitShift(BitAND($sMP3FrameHeader, 0xF000), 12) ; Bitraten-Index auslesen
    Switch $sMP3Version ; je nach MPEG-Version Bitrate aus der Tabelle holen
    Case 'MPEG1'
    $aID3[9][1] = $aMP3Bitrate[$iMP3Version - ($iMP3Version > 1)][$iMP3Bitrate]
    Case 'MPEG2', 'MPEG2.5'
    If $sMP3Layer = 'Layer I' Then
    $aID3[9][1] = $aMP3Bitrate[3][$iMP3Bitrate]
    Else
    $aID3[9][1] = $aMP3Bitrate[4][$iMP3Bitrate]
    EndIf
    EndSwitch
    $iMP3SampleFreq = BitShift(BitAND($sMP3FrameHeader, 0xC00), 10) ; Sample-Frequenz-Index auslesen
    $aID3[10][1] = $aSampleFreq[2 - ($iMP3Version - ($iMP3Version > 1))][$iMP3SampleFreq] ; und Wert aus der Tabelle holen
    Do ; evtl. Leerbytes überspringen
    $tmp = FileRead($hFile, 1)
    If @error Then ExitLoop
    Until $tmp <> 0x00 Or @error
    If $tmp = 0x58 And BinaryToString(FileRead($hFile, 3)) = 'ing' Then ; MP3 mit VBR (Xing-Header gefunden)?
    $iVBRFlags = '0x' & Hex(FileRead($hFile, 4)) ; VBR-Flags auslesen
    If BitAND($iVBRFlags, 0x3) Then ; wenn die Einträge vorhanden sind, dann...
    $iVBRFrames = Dec(Hex(FileRead($hFile, 4))) ; Anzahl der VBR-Frames auslesen
    $iVBRFilesize = Dec(Hex(FileRead($hFile, 4))) ; Dateigröße auslesen
    $aID3[4][1] = $iVBRFrames * 1152 / $aID3[10][1] * 1000 ; VBR Laufzeit
    $aID3[9][1] = 'VBR ~' & Int($iVBRFilesize * 8 / ($aID3[4][1] / 1000) / 1000) ; VBR durchschnittliche Bitrate
    EndIf
    Else
    If $aID3[4][1] = 0 Then $aID3[4][1] = (FileGetSize($sPath) * 8) / ($aID3[9][1] * 1000) * 1000 ; alternative CBR Laufzeit
    $aID3[9][1] = 'CBR ' & $aID3[9][1]
    EndIf
    $aID3[4][1] = _MyTicksToTime($aID3[4][1]) ; Laufzeit (Ticks to hour:min:sec)
    $aID3[9][1] &= ' kBit/s'
    $aID3[10][1] &= ' Hz'
    FileClose($hFile)
    Return SetError(0, 0, $aID3)
    EndFunc ;==>_ReadID3Tag

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

    Func _MyTicksToTime($iTicks)
    Local $iHour, $iMins, $iSecs
    $iHour = Int($iTicks / 3600000)
    $iTicks -= $iHour * 3600000
    $iMins = Int($iTicks / 60000)
    $iTicks -= $iMins * 60000
    $iSecs = Int($iTicks / 1000)
    Return StringFormat('%02i:%02i:%02i', $iHour, $iMins, $iSecs)
    EndFunc ;==>_MyTicksToTime

    [/autoit]

    Mein Feedback.
    Alls ich zum erstenmal sortieren lies, Nach "Artist" bin ich bissl erschrocken. das ganze war für 2-3sec nur Weiss, hättest du das ganze ned Komentiert :thumbup: ,währ ich echt davon ausgegangen das dass Script hengen geblieben währ xD
    was ich noch festgestallt habe, beim erneutehn such nach mp3´s hat er argh lange gehabt, hastu was am Search geändert? Wennich dan Liegt es wohl daran das ich noch 2 progs offen hatte die die C:\ HD etwas beanspuchen ^^

    Gesammt Eindruck:
    Ich bleibe immernoch dabei das das was du so "Testen" wolltest und was dich "Wunder genommen" hat, immernoch 100% mehr kann, als ichs mir eig vorgestellt habe oO xD :D


    Ich werde einmal das Obere Thread ändern und das Script dort einfügen :D

    Mfg Skilkor,der dir zu GROSSEM Dank verpflichtet ist ^^Sei gepriesen, o Heiliger Oscar :D

    Einmal editiert, zuletzt von Skilkor (29. Juli 2010 um 01:27)

    • Offizieller Beitrag

    Das mit dem Fenster anpassen habe ich jetzt mal auf ReSizing gesetzt. Das Fenster kann also in der Größe verändert werden (wird abgespeichert).

    Die Buttons waren eigentlich noch nicht vollzählig. ;)
    Da habe ich jetzt noch [Verzeichnis durchsuchen] hinzugefügt und dann etwas zusammengerückt.

    Das mit der DEL-Taste kannst Du so nicht machen. Es sieht zwar erstmal richtig aus, aber dabei wird das 2D-Array nicht angepasst und beim nächsten sortieren sind die Einträge wieder da. Ich hab's mal kommentiert (so ist es einfacher).

    Beim sortieren wird jetzt unten in der Statusleiste angezeigt, was das Programm gerade macht (mit Zeitstempel wie lange es dafür gebraucht hat).

    Skript:

    Spoiler anzeigen
    [autoit]


    #include <Array.au3>
    #include <ButtonConstants.au3>
    #include <ColorConstants.au3>
    #include <Date.au3>
    #include <GUIConstantsEx.au3>
    #include <GuiListView.au3>
    #include <GuiStatusBar.au3>
    #include <ListViewConstants.au3>
    #include <WindowsConstants.au3>

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

    Global $sHeader = 'Title|Artist|Album|Year|Length|MPEG-Version|Bitrate|Sample-Freq.|Path' ; Die Überschriften für das Listview
    Global $sDBFile = @ScriptDir & '\MP3-Search.txt' ; Pfad und Name der Datenbank-Datei
    Global $sInifile = @ScriptDir & '\MP3-Search.ini' ; Inidatei
    Global $aListview[1][9]

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

    Global $iWidth = IniRead($sInifile, 'Config', 'Width', 770)
    Global $iHeight = IniRead($sInifile, 'Config', 'Height', 406)
    Global $iLeft = IniRead($sInifile, 'Config', 'Left', @DesktopWidth / 2 - 385)
    Global $iTop = IniRead($sInifile, 'Config', 'Top', @DesktopHeight / 2 - 203)

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

    #region Hauptfenster
    Global $sStyle = BitOR($GUI_SS_DEFAULT_GUI, $WS_MAXIMIZEBOX, $WS_SIZEBOX)
    Global $hGui = GUICreate('MP3-Search', 770, 406, $iLeft, $iTop, $sStyle) ; Hauptfenster erstellen
    GUISetBkColor(0xAAAAAA)

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

    Global $hListView = GUICtrlCreateListView($sHeader, 5, 5, 760, 330, $LVS_SHOWSELALWAYS) ; Listview erstellen
    GUICtrlSetResizing(-1, 2 + 4 + 32 + 64)
    Global $hLVHandle = GUICtrlGetHandle($hListView) ; das Handle vom Listview wird für die UDF-Listview-Funktionen benötigt
    _GUICtrlListView_SetColumn($hLVHandle, 0, 'Title', 180, 0)
    _GUICtrlListView_SetColumn($hLVHandle, 1, 'Artist', 180, 0)
    _GUICtrlListView_SetColumn($hLVHandle, 2, 'Length', 60, 0)
    _GUICtrlListView_SetColumn($hLVHandle, 3, 'Album', 120, 0)
    _GUICtrlListView_SetColumn($hLVHandle, 4, 'Year', 60, 0)
    _GUICtrlListView_SetColumn($hLVHandle, 5, 'MPEG-Version', 100, 0)
    _GUICtrlListView_SetColumn($hLVHandle, 6, 'Bitrate', 100, 0)
    _GUICtrlListView_SetColumn($hLVHandle, 7, 'Sample-Freq.', 90, 0)
    _GUICtrlListView_SetColumn($hLVHandle, 8, 'Path', 800, 0)

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

    Global $hSearch = GUICtrlCreateButton('Alle Festplatten durchsuchen', 10, 340, 120, 35, $BS_MULTILINE)
    GUICtrlSetResizing(-1, 512 + 64)
    Global $hSearchPath = GUICtrlCreateButton('Verzeichnis durchsuchen', 140, 340, 100, 35, $BS_MULTILINE)
    GUICtrlSetResizing(-1, 512 + 64)
    Global $hLoad = GUICtrlCreateButton('Laden', 250, 340, 70, 35)
    GUICtrlSetResizing(-1, 512 + 64)
    Global $hSave = GUICtrlCreateButton('Speichern', 330, 340, 70, 35)
    GUICtrlSetResizing(-1, 512 + 64)
    Global $hDel = GUICtrlCreateButton("Markierte Einträge löschen", 410, 340, 90, 35, $BS_MULTILINE)
    GUICtrlSetResizing(-1, 512 + 64)
    Global $hDelAll = GUICtrlCreateButton('Alle Einträge löschen', 510, 340, 90, 35, $BS_MULTILINE)
    GUICtrlSetResizing(-1, 512 + 64)

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

    Global $aParts[3] = [300, 360, -1], $aText[3] = ['Fertig.', '0', '']
    Global $hStatus = _GUICtrlStatusBar_Create($hGui, $aParts, $aText)
    #endregion Hauptfenster

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

    GUISetState(@SW_SHOW, $hGui) ; Hauptfenster sichtbar machen

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

    Global $fStop = False, $iLVCount = 0
    HotKeySet('{ESC}', '_Stop')

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

    Dim $aAccelKeys[1][2] = [['{DEL}', $hDel]] ; beim drücken der [Delete]-Taste wird "Case $hDel" ausgeführt
    GUISetAccelerators($aAccelKeys, $hGui)

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

    GUIRegisterMsg($WM_SIZE, '_WM_SIZE')
    GUIRegisterMsg($WM_MOVE, '_WM_MOVE')
    GUIRegisterMsg($WM_GETMINMAXINFO, '_WM_GETMINMAXINFO')

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

    WinMove($hGui, '', $iLeft, $iTop, $iWidth, $iHeight)

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

    While 1
    Switch GUIGetMsg() ; anhand der Control-ID das entsprechende Case aufrufen
    Case $hSearch
    _GUICtrlListView_DeleteAllItems($hLVHandle) ; Alle Listview-Einträge löschen
    $iLVCount = 0 ; Zähler auf Null setzen
    $aDrives = DriveGetDrive('FIXED') ; Alle Festplatten-Buchstaben holen
    If Not @error Then
    GUISetCursor(15, 1, $hGui)
    For $i = 1 To $aDrives[0] ; Alle Festplatten durchgehen
    _GUICtrlStatusBar_SetText($hStatus, 'Durchsuche Festplatte "' & StringUpper($aDrives[$i]) & '"', 0)
    _DriveSearch(StringUpper($aDrives[$i]))
    Next
    GUISetCursor(2, 1, $hGui)
    EndIf
    _GUICtrlStatusBar_SetText($hStatus, $iLVCount, 1)
    _GUICtrlStatusBar_SetText($hStatus, '', 2)
    If $fStop Then
    $fStop = False
    _GUICtrlStatusBar_SetText($hStatus, 'Abgebrochen!', 0)
    Else
    _GUICtrlStatusBar_SetText($hStatus, 'Fertig.', 0)
    EndIf
    Case $hSearchPath
    $sPath = FileSelectFolder('Verzeichnis auswählen!', '', 2, '', $hGui)
    If FileExists($sPath) Then
    _GUICtrlListView_DeleteAllItems($hLVHandle) ; Alle Listview-Einträge löschen
    $iLVCount = 0 ; Zähler auf Null setzen
    GUISetCursor(15, 1, $hGui)
    _GUICtrlStatusBar_SetText($hStatus, 'Durchsuche Verzeichnis "' & $sPath & '"', 0)
    _DriveSearch($sPath)
    GUISetCursor(2, 1, $hGui)
    _GUICtrlStatusBar_SetText($hStatus, $iLVCount, 1)
    _GUICtrlStatusBar_SetText($hStatus, '', 2)
    If $fStop Then
    $fStop = False
    _GUICtrlStatusBar_SetText($hStatus, 'Abgebrochen!', 0)
    Else
    _GUICtrlStatusBar_SetText($hStatus, 'Fertig.', 0)
    EndIf
    EndIf
    Case $hListView ; User hat auf eine Spaltenüberschrift geklickt
    If $iLVCount > 0 Then
    GUISetCursor(15, 1, $hGui)
    _GUICtrlStatusBar_SetBkColor($hStatus, $CLR_MONEYGREEN)
    _GUICtrlStatusBar_SetText($hStatus, 'Sortiere Daten! Bitte warten...', 0)
    $iSort = GUICtrlGetState($hListView)
    $iTimer = TimerInit()
    _GUICtrlStatusBar_SetText($hStatus, '[' & _TicksToTimeFormat(TimerDiff($iTimer), '%mm:%ss.%ms') & '] Sortiere nach Spalte: ' & $iSort, 2)
    _ArraySort($aListview, 0, 0, 0, $iSort)
    _GUICtrlStatusBar_SetText($hStatus, '[' & _TicksToTimeFormat(TimerDiff($iTimer), '%mm:%ss.%ms') & '] Lösche alle Einträge', 2)
    _GUICtrlListView_DeleteAllItems($hLVHandle)
    _GUICtrlStatusBar_SetText($hStatus, '[' & _TicksToTimeFormat(TimerDiff($iTimer), '%mm:%ss.%ms') & '] Einträge neu erstellen', 2)
    _GUICtrlListView_BeginUpdate($hLVHandle) ; Listview sperren
    _GUICtrlListView_AddArray($hLVHandle, $aListview)
    _GUICtrlListView_EndUpdate($hLVHandle) ; Listview wieder freigeben
    _GUICtrlStatusBar_SetText($hStatus, '[' & _TicksToTimeFormat(TimerDiff($iTimer), '%mm:%ss.%ms') & '] Sortiert.', 2)
    _GUICtrlStatusBar_SetText($hStatus, 'Fertig.', 0)
    _GUICtrlStatusBar_SetBkColor($hStatus, $CLR_DEFAULT)
    GUISetCursor(2, 1, $hGui)
    EndIf
    Case $hLoad ; User hat auf 'Laden' geklickt
    GUISetCursor(15, 1, $hGui)
    _GUICtrlStatusBar_SetText($hStatus, 'Lade Daten...', 0)
    Load()
    _GUICtrlStatusBar_SetText($hStatus, 'Fertig.', 0)
    GUISetCursor(2, 1, $hGui)
    Case $hSave ; User hat auf 'Speichern' geklickt
    GUISetCursor(15, 1, $hGui)
    _GUICtrlStatusBar_SetText($hStatus, 'Speichere Daten...', 0)
    Save()
    _GUICtrlStatusBar_SetText($hStatus, 'Fertig.', 0)
    _GUICtrlStatusBar_SetText($hStatus, '', 2)
    GUISetCursor(2, 1, $hGui)
    Case $hDel
    $aSelectedItems = _GUICtrlListView_GetSelectedIndices($hLVHandle, True)
    If $aSelectedItems[0] > 0 Then
    GUISetCursor(15, 1, $hGui)
    For $i = $aSelectedItems[0] To 1 Step -1
    _ArrayDelete($aListview, $aSelectedItems[$i])
    Next
    _GUICtrlListView_DeleteItemsSelected($hLVHandle)
    $iLVCount -= $aSelectedItems[0]
    _GUICtrlStatusBar_SetText($hStatus, $iLVCount, 1)
    GUISetCursor(2, 1, $hGui)
    EndIf
    Case $hDelAll ; User hat auf 'Alle Einträge löschen' geklickt
    If MsgBox(256 + 32 + 4, 'Einträge löschen', 'Wollen sie wirklich alle Einträge löschen?') = 6 Then
    _GUICtrlListView_DeleteAllItems($hLVHandle)
    ReDim $aListview[1][9]
    $iLVCount = 0
    _GUICtrlStatusBar_SetText($hStatus, $iLVCount, 1)
    EndIf
    Case $GUI_EVENT_CLOSE ; User hat auf das Schließen-Symbol geklickt (bzw. die ESC-Taste gedrückt)
    If MsgBox(32 + 4, 'Beenden', 'Wollen sie das Programm wirklich beenden?') = 6 Then _End() ; wenn ja, dann End-Funktion aufrufen
    EndSwitch
    WEnd

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

    Func _Stop()
    $fStop = True
    EndFunc ;==>_Stop

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

    Func _End()
    ;~ Save() ; wenn der vordere Kommentar entfernt wird, dann werden vor dem beenden noch die Daten gespeichert
    Exit ; Programm beenden
    EndFunc ;==>End

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

    Func _DriveSearch($sPath)
    Local $aNewMP3, $aID3Tags, $sNewItem, $aItem
    If StringRight($sPath, 1) <> '\' Then $sPath &= '\'
    _GUICtrlStatusBar_SetText($hStatus, 'Bitte warten...', 2)
    $aNewMP3 = _RecursiveFileListToArray($sPath, '\.mp3', 1) ; Alle MP3s auf der Festplatte auslesen
    If Not @error And $aNewMP3[0] > 0 Then
    _GUICtrlListView_SetItemCount($hListView, $iLVCount + $aNewMP3[0])
    ReDim $aListview[$iLVCount + $aNewMP3[0] + 1][9]
    _GUICtrlStatusBar_SetText($hStatus, 'Lese ID3-Tags... (' & $aNewMP3[0] & ')', 0)
    For $j = 1 To $aNewMP3[0] ; die gefundenen MP3s durchgehen
    _GUICtrlStatusBar_SetText($hStatus, $iLVCount, 1)
    $aID3Tags = _ReadID3Tag($aNewMP3[$j]) ; die ID3-Tags auslesen
    If Not @error Then
    For $k = 0 To 10
    $aID3Tags[$k][1] = StringReplace($aID3Tags[$k][1], '|', '') ; evtl. vorhandene "|" entfernen
    Next
    _GUICtrlStatusBar_SetText($hStatus, $aNewMP3[$j], 2)
    $sNewItem = $aID3Tags[0][1] & '|' & $aID3Tags[1][1] & '|' & $aID3Tags[4][1] & '|' & $aID3Tags[2][1] & '|' & $aID3Tags[3][1]
    $sNewItem &= '|' & $aID3Tags[8][1] & '|' & $aID3Tags[9][1] & '|' & $aID3Tags[10][1] & '|' & $aNewMP3[$j]
    $aItem = StringSplit($sNewItem, '|')
    For $k = 1 To $aItem[0]
    $aListview[$iLVCount][$k - 1] = $aItem[$k]
    Next
    GUICtrlCreateListViewItem($sNewItem, $hListView)
    $iLVCount += 1
    EndIf
    If $fStop Then ExitLoop
    Next
    ReDim $aListview[$iLVCount][9]
    EndIf
    EndFunc ;==>_DriveSearch

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

    Func _WM_SIZE($hWnd, $msg, $wParam, $lParam)
    Local $aGuiPos = WinGetPos($hGui)
    If Not BitAND(WinGetState($hGui), 16) Then
    IniWrite($sInifile, 'Config', 'Width', $aGuiPos[2])
    IniWrite($sInifile, 'Config', 'Height', $aGuiPos[3])
    EndIf
    _GUICtrlStatusBar_Resize($hStatus)
    Return $GUI_RUNDEFMSG
    EndFunc ;==>WM_SIZE

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

    Func _WM_MOVE($hWnd, $msg, $wParam, $lParam)
    Local $aGuiPos = WinGetPos($hGui)
    If Not BitAND(WinGetState($hGui), 16) Then
    IniWrite($sInifile, 'Config', 'Left', $aGuiPos[0])
    IniWrite($sInifile, 'Config', 'Top', $aGuiPos[1])
    EndIf
    Return $GUI_RUNDEFMSG
    EndFunc

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

    Func _WM_GETMINMAXINFO($hWnd, $msg, $wParam, $lParam)
    If $hWnd = $hGui Then
    Local $minmaxinfo = DllStructCreate("int;int;int;int;int;int;int;int;int;int", $lParam)
    DllStructSetData($minmaxinfo, 7, 786) ; min X
    DllStructSetData($minmaxinfo, 8, 444) ; min Y
    ;~ DllStructSetData($minmaxinfo, 9, 800) ; max X
    ;~ DllStructSetData($minmaxinfo, 10, 800) ; max Y
    EndIf
    EndFunc

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

    Func Load() ; Datenbank-Datei laden
    Local $hFile, $sContent, $aNewItems, $iTimer, $iCount, $aItem
    $hFile = FileOpen($sDBFile, 0) ; Datei zum lesen öffnen
    If $hFile <> -1 Then ; wenn das öffnen erfolgreich war, dann...
    $sContent = FileRead($hFile) ; Datei komplett einlesen
    FileClose($hFile) ; Datei schließen
    $sContent = StringTrimRight($sContent, 2) ; das letzte @CRLF entfernen
    $aNewItems = StringSplit($sContent, @CRLF, 1) ; Den Dateiinhalt am Zeilenende splitten
    If Not IsArray($aNewItems) Then Return ; Wenn $aNewItems kein Array ist, dann Funktion verlassen
    _GUICtrlListView_DeleteAllItems($hLVHandle)
    _GUICtrlListView_SetItemCount($hLVHandle, $aNewItems[0])
    Global $aListview[$aNewItems[0]][9]
    _GUICtrlStatusBar_SetText($hStatus, 'Lade Daten... (' & $aNewItems[0] & ')', 0)
    _GUICtrlListView_BeginUpdate($hLVHandle) ; Listview sperren
    $iTimer = TimerInit()
    For $i = 1 To $aNewItems[0] ; Alle Einträge des Arrays durchgehen
    $iCount += 1
    If TimerDiff($iTimer) > 100 Then
    $iTimer = TimerInit()
    _GUICtrlStatusBar_SetText($hStatus, $iCount, 1)
    EndIf
    $aItem = StringSplit($aNewItems[$i], '|')
    For $j = 1 To $aItem[0]
    $aListview[$i - 1][$j - 1] = $aItem[$j]
    Next
    GUICtrlCreateListViewItem($aNewItems[$i], $hListView) ; mit den eingelesenen Daten einen neuen Listview-Eintrag erstellen
    Next
    _GUICtrlStatusBar_SetText($hStatus, $iCount, 1)
    _GUICtrlListView_EndUpdate($hLVHandle) ; Listview wieder freigeben
    $iLVCount = UBound($aListview)
    EndIf
    EndFunc ;==>Load

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

    Func Save() ; Datenbank-Datei speichern
    Local $sContent, $hFile, $iCount, $iTimer
    $iCount = _GUICtrlListView_GetItemCount($hLVHandle); Anzahl der Listview-Einträge holen
    If $iCount = 0 Then Return ; Wenn das Listview keine Einträge enthält, dann Funktion verlassen
    $iTimer = TimerInit()
    For $i = 0 To $iCount - 1 ; Schleife, um alle Listview-Einträge durchzugehen
    $sContent &= _GUICtrlListView_GetItemTextString($hLVHandle, $i) & @CRLF
    If TimerDiff($iTimer) > 100 Then
    $iTimer = TimerInit()
    _GUICtrlStatusBar_SetText($hStatus, $i + 1, 2)
    EndIf
    Next
    $hFile = FileOpen($sDBFile, 2) ; Datei zum speichern (überschreiben) öffnen
    If $hFile <> -1 Then ; wenn das öffnen erfolgreich war, dann...
    FileWrite($hFile, $sContent)
    FileClose($hFile) ; Datei schließen
    EndIf
    EndFunc ;==>Save

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

    ;===============================================================================
    ; Function Name: _RecursiveFileListToArray($sPath[, $sPattern][, $iFlag][, $iFormat][, $iRecursion][, $sDelim])
    ; Description:: gibt Verzeichnisse (rekursiv) und/oder Dateien zurück, die einem RegExp-Pattern entsprechen
    ; Parameter(s): $sPath = Startverzeichnis
    ; $sPattern = ein beliebiges RexExp-Pattern für die Auswahl
    ; $iFlag = Auswahl
    ; 0 = Dateien & Verzeichnisse
    ; 1 = nur Dateien
    ; 2 = nur Verzeichnisse
    ; $iFormat = Rückgabeformat
    ; 0 = String
    ; 1 = Array mit [0] = Anzahl
    ; 2 = Nullbasiertes Array
    ; $iRecursion = Verzeichnisse rekursiv durchsuchen
    ; 0 = Nein
    ; 1 = Ja
    ; $sDelim = Trennzeichen für die String-Rückgabe
    ; Requirement(s): AutoIt 3.3.0.0
    ; Return Value(s): Array/String mit den gefundenen Dateien/Verzeichnissen
    ; Author(s): Oscar (http://www.autoit.de)
    ; Anregungen von: bernd670 (http://www.autoit.de)
    ;===============================================================================
    Func _RecursiveFileListToArray($sPath, $sPattern = '', $iFlag = 0, $iFormat = 1, $iRecursion = 1, $sDelim = @CRLF)
    Local $hSearch, $sFile, $sReturn = ''
    If StringRight($sPath, 1) <> '\' Then $sPath &= '\'
    $hSearch = FileFindFirstFile($sPath & '*.*')
    If @error Or $hSearch = -1 Then Return SetError(1, 0, $sReturn)
    While Not $fStop
    $sFile = FileFindNextFile($hSearch)
    If @error Then ExitLoop
    If @extended Then
    If StringRegExp($sPath & $sFile, $sPattern) And ($iFlag = 0 Or $iFlag = 2) Then $sReturn &= $sPath & $sFile & '\' & $sDelim
    If $iRecursion Then $sReturn &= _RecursiveFileListToArray($sPath & $sFile & '\', $sPattern, $iFlag, 0)
    ContinueLoop
    EndIf
    If StringRegExp($sFile, $sPattern) And ($iFlag = 0 Or $iFlag = 1) Then $sReturn &= $sPath & $sFile & $sDelim
    WEnd
    FileClose($hSearch)
    If $iFormat And $sReturn = '' Then Return StringSplit($sReturn, '', $iFormat)
    If $iFormat Then Return StringSplit(StringTrimRight($sReturn, StringLen($sDelim)), $sDelim, $iFormat)
    Return $sReturn
    EndFunc ;==>_RecursiveFileListToArray

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

    ;===============================================================================
    ; Function Name: _ReadID3Tag($sPath)
    ; Description:: gibt ein Array mit den Daten aus den ID3-Tags zurück
    ; unterstützt werden die ID3-Tag-Versionen 1.0, 1.1, 2.3 und 2.4
    ; bei v2.4 müssen sich die ID3-Tags am Anfang der Datei befinden
    ; Parameter(s): $sPath = Pfad zu einer MP3-Datei
    ; Requirement(s): min. AutoIt v3.3.0.0
    ; Return Value(s): bei Erfolg: Array mit den ID3-Tagdaten (@error = 0)
    ; im Fehlerfall bekommt @error:
    ; 1 = Datei existiert nicht
    ; 2 = Datei konnte nicht zum lesen geöffnet werden
    ; 3 = falsche ID3 v2 Version
    ; 4 = Datei ist keine MP3-Datei
    ; Author(s): Oscar (http://www.autoit.de)
    ;===============================================================================
    Func _ReadID3Tag($sPath)
    If Not FileExists($sPath) Then Return SetError(1, 0, 0)
    Local $hFile, $sData, $sID3Header, $iID3HeaderSize = 0, $iOffset, $iSize, $tmp
    Local $aID3v2Tags[8] = ['TIT2', 'TPE1', 'TALB', 'TYER', 'TLEN', 'TRCK', 'TCON', 'TENC']
    Local $aID3[11][2] = [ _
    ['Title', ''],['Artist', ''],['Album', ''],['Year', ''], _
    ['Length', '0'],['Track', ''],['Genre', ''],['Encoder', ''], _
    ['MPEG-Version', ''],['Bitrate', '-'],['Sample-Freq.', '']]
    Local $aMP3Version[4] = ['MPEG2.5', 'Reserved', 'MPEG2', 'MPEG1']
    Local $aMP3Layer[4] = ['Reserved', 'Layer III', 'Layer II', 'Layer I']
    Local $aMP3Bitrate[5][16] = [ _
    [000, 032, 064, 096, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448, 000], _
    [000, 032, 048, 056, 064, 080, 096, 112, 128, 160, 192, 224, 256, 320, 384, 000], _
    [000, 032, 040, 048, 056, 064, 080, 096, 112, 128, 160, 192, 224, 256, 320, 000], _
    [000, 032, 048, 056, 064, 080, 096, 112, 128, 144, 160, 176, 192, 224, 256, 000], _
    [000, 008, 016, 024, 032, 040, 048, 056, 064, 080, 096, 112, 128, 144, 160, 000]]
    Local $aSampleFreq[3][4] = [[44100, 48000, 32000, 0],[22050, 24000, 16000, 0],[11025, 12000, 8000, 0]]
    Local $sMP3FrameHeader, $iMP3Version, $sMP3Version, $sMP3Layer, $iMP3Bitrate, $iMP3SampleFreq
    Local $iVBRFrames = -1, $iVBRFilesize, $iVBRFlags
    $hFile = FileOpen($sPath, 16)
    If $hFile = -1 Then Return SetError(2, 0, 0)
    $sData = Binary(FileRead($hFile, 4))
    If BinaryMid($sData, 1, 3) = '0x494433' Then ; ID3 v2.x Kennung gefunden
    If (BinaryMid($sData, 4, 1) = '0x03') Or (BinaryMid($sData, 4, 1) = '0x04') Then ; nur v2.3 und 2.4
    FileRead($hFile, 2) ; 2 Bytes überspringen
    For $i = 0 To 3 ; berechne ID3-Headergröße (4 Bytes, jedoch nur jeweils die unteren 7 Bit)
    $iID3HeaderSize = BitShift($iID3HeaderSize, -7) + BitAND(Binary(FileRead($hFile, 1)), 0x7F)
    Next
    If $iID3HeaderSize > 0 Then
    $sID3Header = Binary(FileRead($hFile, $iID3HeaderSize)) ; lese gesamten ID3-Header
    For $i = 0 To 7
    $iOffset = StringInStr(BinaryToString($sID3Header), $aID3v2Tags[$i]) ; Offset zu dem ID3-Tag
    If $iOffset > 0 Then
    $iSize = Hex(BinaryMid($sID3Header, $iOffset + 4, 4)) ; Größe des ID3-Frames
    $tmp = BinaryMid($sID3Header, $iOffset + 11, Dec($iSize) - 1)
    If BinaryMid($tmp, 1, 2) = '0xFFFE' Then
    For $x = 3 To BinaryLen($tmp) Step 2
    $aID3[$i][1] &= BinaryToString(BinaryMid($tmp, $x, 2), 2)
    Next
    Else
    For $x = 1 To BinaryLen($tmp)
    $aID3[$i][1] &= BinaryToString(BinaryMid($tmp, $x, 1))
    Next
    EndIf
    $aID3[$i][1] = StringReplace($aID3[$i][1], Chr(0), '')
    EndIf
    Next
    EndIf
    Do
    $sData = String(FileRead($hFile, 1))
    If @error Then ExitLoop
    If BitAND($sData, 0xff) = 0xff Then
    FileSetPos($hFile, -1, 1)
    $sData = String(FileRead($hFile, 4))
    EndIf
    Until BitAND($sData, 0xFFE00000) = 0xFFE00000
    Else
    FileClose($hFile)
    Return SetError(3, 0, 0)
    EndIf
    Else ; ID3 v1.x
    $iOffset = FileGetPos($hFile)
    FileSetPos($hFile, -128, 2)
    $sID3Header = BinaryToString(FileRead($hFile, 3))
    If $sID3Header = 'TAG' Then
    $aID3[0][1] = StringReplace(BinaryToString(FileRead($hFile, 30)), Chr(0), '')
    $aID3[1][1] = StringReplace(BinaryToString(FileRead($hFile, 30)), Chr(0), '')
    $aID3[2][1] = StringReplace(BinaryToString(FileRead($hFile, 30)), Chr(0), '')
    $aID3[3][1] = StringReplace(BinaryToString(FileRead($hFile, 4)), Chr(0), '')
    EndIf
    FileSetPos($hFile, $iOffset, 0)
    EndIf
    $sMP3FrameHeader = String($sData)
    If BitAND($sMP3FrameHeader, 0xFFE00000) <> 0xFFE00000 Then
    FileClose($hFile)
    Return SetError(4, 0, 0) ; keine MP3-Datei, dann Return
    EndIf
    $iMP3Version = BitShift(BitXOR($sMP3FrameHeader, 0xFFE00000), 19) ; welche MP3-Version
    $sMP3Version = $aMP3Version[$iMP3Version] ; in Textform
    $sMP3Layer = $aMP3Layer[BitShift(BitAND($sMP3FrameHeader, 0x60000), 17)] ; welcher Layer
    $aID3[8][1] = $sMP3Version & ' / ' & $sMP3Layer ; ins Ausgabe-Array
    $iMP3Bitrate = BitShift(BitAND($sMP3FrameHeader, 0xF000), 12) ; Bitraten-Index auslesen
    Switch $sMP3Version ; je nach MPEG-Version Bitrate aus der Tabelle holen
    Case 'MPEG1'
    $aID3[9][1] = $aMP3Bitrate[$iMP3Version - ($iMP3Version > 1)][$iMP3Bitrate]
    Case 'MPEG2', 'MPEG2.5'
    If $sMP3Layer = 'Layer I' Then
    $aID3[9][1] = $aMP3Bitrate[3][$iMP3Bitrate]
    Else
    $aID3[9][1] = $aMP3Bitrate[4][$iMP3Bitrate]
    EndIf
    EndSwitch
    $iMP3SampleFreq = BitShift(BitAND($sMP3FrameHeader, 0xC00), 10) ; Sample-Frequenz-Index auslesen
    $aID3[10][1] = $aSampleFreq[2 - ($iMP3Version - ($iMP3Version > 1))][$iMP3SampleFreq] ; und Wert aus der Tabelle holen
    Do ; evtl. Leerbytes überspringen
    $tmp = FileRead($hFile, 1)
    If @error Then ExitLoop
    Until $tmp <> 0x00 Or @error
    If $tmp = 0x58 And BinaryToString(FileRead($hFile, 3)) = 'ing' Then ; MP3 mit VBR (Xing-Header gefunden)?
    $iVBRFlags = '0x' & Hex(FileRead($hFile, 4)) ; VBR-Flags auslesen
    If BitAND($iVBRFlags, 0x3) Then ; wenn die Einträge vorhanden sind, dann...
    $iVBRFrames = Dec(Hex(FileRead($hFile, 4))) ; Anzahl der VBR-Frames auslesen
    $iVBRFilesize = Dec(Hex(FileRead($hFile, 4))) ; Dateigröße auslesen
    $aID3[4][1] = $iVBRFrames * 1152 / $aID3[10][1] * 1000 ; VBR Laufzeit
    $aID3[9][1] = 'VBR ~' & Int($iVBRFilesize * 8 / ($aID3[4][1] / 1000) / 1000) ; VBR durchschnittliche Bitrate
    EndIf
    Else
    If $aID3[4][1] = 0 Then $aID3[4][1] = (FileGetSize($sPath) * 8) / ($aID3[9][1] * 1000) * 1000 ; alternative CBR Laufzeit
    $aID3[9][1] = 'CBR ' & $aID3[9][1]
    EndIf
    $aID3[4][1] = _TicksToTimeFormat($aID3[4][1]) ; Laufzeit (Ticks to hour:min:sec)
    $aID3[9][1] &= ' kBit/s'
    $aID3[10][1] &= ' Hz'
    FileClose($hFile)
    Return SetError(0, 0, $aID3)
    EndFunc ;==>_ReadID3Tag

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

    ;===============================================================================
    ; Function Name: _TicksToTimeFormat($iTicks, $sFormat = '%hh:%mm:%ss')
    ; Description:: Diese Funktion wandelt Millisekunden in ein anzugebenes Zeitformat um
    ; Parameter(s): $iTicks = Zeit in Millisekunden
    ; $sFormat:
    ; %hh für Stunden
    ; %mm für Minuten
    ; %ss für Sekunden
    ; %ms für Millisekunden
    ; sonstige Zeichen, die dazwischen stehen, werden übernommen
    ; Requirement(s): -
    ; Return Value(s): Zeit im ausgewählten Format (String)
    ; Author(s): Oscar (http://www.autoit.de)
    ;===============================================================================
    Func _TicksToTimeFormat($iTicks, $sFormat = '%hh:%mm:%ss')
    Local $aTime[4] = [0, 0, 0, 0], $sOut, $aTimeFormat[4] = ['hh', 'mm', 'ss', 'ms'], $aFormat
    $aTime[2] = Int($iTicks / 1000)
    $aTime[3] = $iTicks - $aTime[2] * 1000
    $aTime[0] = Int($aTime[2] / 3600)
    $aTime[2] = Mod($aTime[2], 3600)
    $aTime[1] = Int($aTime[2] / 60)
    $aTime[2] = Mod($aTime[2], 60)
    $aFormat = StringRegExp($sFormat, '%([^%]+)', 3)
    If Not IsArray($aFormat) Then Return SetError(1, 0, $iTicks)
    For $i = 0 To UBound($aFormat) - 1
    For $j = 0 To UBound($aTimeFormat) - 1
    If StringLeft($aFormat[$i], 2) = $aTimeFormat[$j] Then $sOut &= StringFormat('%02i', $aTime[$j]) & StringMid($aFormat[$i], 3)
    Next
    Next
    Return $sOut
    EndFunc ;==>_TicksToTimeFormat

    [/autoit]
  • Moin

    Uff, dass mit dem 2D-Array wusst ich nicht :S wen ichs gewusst hätt,hett ichs gelassen ^^

    Mein Performance Feedback
    bei meinem system
    CPU - Intel Dualcore E6750 (20% Overclock)
    4GB Ram
    Graka - ATI XFX 4870 (15%Overclocked)
    braucht das Prog
    1-12% CPU (Schwankend)
    13,6MB Ram zu Beginn
    16-21% CPU beim Tag auslesen
    am ende des Programmes
    (Nach dem er 3 HD´s und rund 20´000 Files gefunden hat)
    Braucht das Prog um die 83,15MBRAM

    Geschwindikeit ohne Speichern
    9-10min bei 20´000

    Speichern
    28Sec

    Laden
    4Sec

    Sortieren(Artist)
    20Sec

    Beim Löschen via Del taste von etwa 90 Eintägen
    braucht knap 1min

    • Offizieller Beitrag

    Mit "Geschwindikeit ohne Speichern" meinst Du vermutlich das einlesen/durchsuchen der Festplatten, oder?
    Wenn ja, das ist normal. Die Funktion muss ja alle Dateien auf den Festplatten durchgehen. Ganz witzig in diesem Zusammenhang ist, dass, wenn man die Funktion ein zweites Mal (gleich danach) aufruft, es dann wesentlich schneller geht (Verzeichnisse/Dateien befinden sich im Cache).

    Ressourcenverbrauch ist normal.

    Geschwindigkeit auch, bis auf das mit dem Löschen. Das könnte evtl. auch schneller gehen, wenn man alle Einträge löscht und neu erstellen lässt (analog zum sortieren). Muss ich mal testen...

  • Zitat

    Mit "Geschwindikeit ohne Speichern" meinst Du vermutlich das einlesen/durchsuchen der Festplatten, oder?


    100% :D

    Um die resourcen mach ich mir sowas von keine Sorgen ^^ bei keinem "Heutigen" Rechner.

    Ich würd mir dan Sorgen machen, wen einer kommt und Fragen würde

    Zitat

    Das prog, läuft laut Berichten auf WIN Xp - Vista & 7 einwahnfrei, sowohl 32 bit als auch 64 bit.... Wie sieht es aber mit win 98 aus?

    Ab dem Punkt, müsst ich Passen xD
    und *nur mal so am rande* Es gibt Heute noch Leute die win 98 verwenden oO kein witz

    Ja das mit dem löschen ging vorher Schneller ^^ Du musst es ja nict so machen das es GLEICHZEITIG den Markierten ListView Eintrag UND den Eintrag in der .ini Löscht.
    Das braucht dan wie jetz einen enormen Zeitaufwand ^^
    Mach es Lieber so wie vorhin, das es NUR den ListViwe eintrag Löscht, dann muss man halt nach dem Löschen Speichern? Das is doch kein ding, Ist bei Games genauso ^^ (Wen man kein autosave Patch verwendet xD)

    Feedback 1.1
    Ich habs jetz mal mit 9k Einträgen zum löschen versucht.......
    *Er löscht seid 15min*
    HA!?!?!?!
    Grade eben hat er das Löschen begonnen oO wiso erst jetz? kA :D Erklärungs Not ^^
    Der eigentliche löschvorgang dauert keine Minute.
    Aber wiso muss es Bevor es lösch nch was initzialisieren?? (Auch wens ned da Steht, ich kanns ned anders ausdrücken) :D

    Einmal editiert, zuletzt von Skilkor (29. Juli 2010 um 15:08)

    • Offizieller Beitrag

    Also Win98 wird von AutoIt nicht mehr unterstützt. ^^

    Ich musste beim Löschen ja auch die Einträge aus dem Array löschen (das dauerte so lange, wegen umsortieren/ReDim).
    Jetzt bin ich aber noch auf _GUICtrlListView_SimpleSort gestossen und habe das mal ausprobiert. Das dauert zwar etwas länger als mit 2D-Array und _ArraySort, aber der Vorteil ist: das 2D-Array kann wegfallen, was beim Löschen von Einträgen einen erheblichen Zeitvorteil bringt. Kurzum: Ich habe alles wieder umgestellt. :D

    Außerdem kann man jetzt beim Laden und Speichern die Datei auswählen, wohin gespeichert bzw. von wo geladen werden soll. Das hat den Vorteil, dass man sich mehrere Datenbanken anlegen kann. :)
    Beim speichern wird automatisch die Endung ".db3" (ausgedacht) angehängt. Laden kann man auch nur Dateien mit dieser Endung.

    Und man kann jetzt einen Doppelklick auf einen Listview-Eintrag machen. Das entsprechende MP3 wird dann mit dem Standard-MP3-Player abgespielt.

    Skript:

    Spoiler anzeigen
    [autoit]


    #include <Array.au3>
    #include <ButtonConstants.au3>
    #include <ColorConstants.au3>
    #include <Date.au3>
    #include <GUIConstantsEx.au3>
    #include <GuiListView.au3>
    #include <GuiStatusBar.au3>
    #include <ListViewConstants.au3>
    #include <WindowsConstants.au3>

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

    Global $sHeader = 'Title|Artist|Length|Album|Year|MPEG-Version|Bitrate|Sample-Freq.|Path' ; Die Überschriften für das Listview
    Global $sInifile = @ScriptDir & '\MP3-Search.ini' ; Inidatei

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

    Global $iWidth = IniRead($sInifile, 'Config', 'Width', 770)
    Global $iHeight = IniRead($sInifile, 'Config', 'Height', 406)
    Global $iLeft = IniRead($sInifile, 'Config', 'Left', @DesktopWidth / 2 - 385)
    Global $iTop = IniRead($sInifile, 'Config', 'Top', @DesktopHeight / 2 - 203)

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

    #region Hauptfenster
    Global $sStyle = BitOR($GUI_SS_DEFAULT_GUI, $WS_MAXIMIZEBOX, $WS_SIZEBOX)
    Global $hGui = GUICreate('MP3-Search', 770, 406, $iLeft, $iTop, $sStyle) ; Hauptfenster erstellen
    GUISetBkColor(0xAAAAAA)

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

    Global $hListView = GUICtrlCreateListView($sHeader, 5, 5, 760, 330, $LVS_SHOWSELALWAYS) ; Listview erstellen
    GUICtrlSetResizing(-1, 2 + 4 + 32 + 64)
    Global $hLVHandle = GUICtrlGetHandle($hListView) ; das Handle vom Listview wird für die UDF-Listview-Funktionen benötigt
    _GUICtrlListView_SetColumnWidth($hLVHandle, 0, 180)
    _GUICtrlListView_SetColumnWidth($hLVHandle, 1, 180)
    _GUICtrlListView_SetColumnWidth($hLVHandle, 2, 60)
    _GUICtrlListView_SetColumnWidth($hLVHandle, 3, 120)
    _GUICtrlListView_SetColumnWidth($hLVHandle, 4, 60)
    _GUICtrlListView_SetColumnWidth($hLVHandle, 5, 100)
    _GUICtrlListView_SetColumnWidth($hLVHandle, 6, 100)
    _GUICtrlListView_SetColumnWidth($hLVHandle, 7, 90)
    _GUICtrlListView_SetColumnWidth($hLVHandle, 8, 800)

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

    Global $hSearch = GUICtrlCreateButton('Alle Festplatten durchsuchen', 10, 340, 120, 35, $BS_MULTILINE)
    GUICtrlSetResizing(-1, 512 + 64)
    Global $hSearchPath = GUICtrlCreateButton('Verzeichnis durchsuchen', 140, 340, 100, 35, $BS_MULTILINE)
    GUICtrlSetResizing(-1, 512 + 64)
    Global $hLoad = GUICtrlCreateButton('Laden', 250, 340, 70, 35)
    GUICtrlSetResizing(-1, 512 + 64)
    Global $hSave = GUICtrlCreateButton('Speichern', 330, 340, 70, 35)
    GUICtrlSetResizing(-1, 512 + 64)
    Global $hDel = GUICtrlCreateButton("Markierte Einträge löschen", 410, 340, 90, 35, $BS_MULTILINE)
    GUICtrlSetResizing(-1, 512 + 64)
    Global $hDelAll = GUICtrlCreateButton('Alle Einträge löschen', 510, 340, 90, 35, $BS_MULTILINE)
    GUICtrlSetResizing(-1, 512 + 64)

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

    Global $aParts[3] = [300, 360, -1], $aText[3] = ['Fertig.', '0', '']
    Global $hStatus = _GUICtrlStatusBar_Create($hGui, $aParts, $aText)
    #endregion Hauptfenster

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

    GUISetState(@SW_SHOW, $hGui) ; Hauptfenster sichtbar machen

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

    Global $fStop = False, $iLVCount = 0
    HotKeySet('{ESC}', '_Stop')

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

    Dim $aAccelKeys[1][2] = [['{DEL}', $hDel]] ; beim drücken der [Delete]-Taste wird "Case $hDel" ausgeführt
    GUISetAccelerators($aAccelKeys, $hGui)

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

    GUIRegisterMsg($WM_SIZE, '_WM_SIZE')
    GUIRegisterMsg($WM_MOVE, '_WM_MOVE')
    GUIRegisterMsg($WM_GETMINMAXINFO, '_WM_GETMINMAXINFO')
    GUIRegisterMsg($WM_NOTIFY, '_WM_NOTIFY')

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

    WinMove($hGui, '', $iLeft, $iTop, $iWidth, $iHeight)

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

    While 1
    Switch GUIGetMsg() ; anhand der Control-ID das entsprechende Case aufrufen
    Case $hSearch
    _GUICtrlListView_DeleteAllItems($hLVHandle) ; Alle Listview-Einträge löschen
    _GUICtrlStatusBar_SetText($hStatus, 0, 1)
    $iLVCount = 0 ; Zähler auf Null setzen
    $aDrives = DriveGetDrive('FIXED') ; Alle Festplatten-Buchstaben holen
    If Not @error Then
    GUISetCursor(15, 1, $hGui)
    For $i = 1 To $aDrives[0] ; Alle Festplatten durchgehen
    _GUICtrlStatusBar_SetText($hStatus, 'Durchsuche Festplatte "' & StringUpper($aDrives[$i]) & '\"', 0)
    _DriveSearch(StringUpper($aDrives[$i]))
    Next
    GUISetCursor(2, 1, $hGui)
    EndIf
    _GUICtrlStatusBar_SetText($hStatus, _GUICtrlListView_GetItemCount($hLVHandle), 1)
    _GUICtrlStatusBar_SetText($hStatus, '', 2)
    If $fStop Then
    $fStop = False
    _GUICtrlStatusBar_SetText($hStatus, 'Abgebrochen!', 0)
    Else
    _GUICtrlStatusBar_SetText($hStatus, 'Fertig.', 0)
    EndIf
    Case $hSearchPath
    $sPath = FileSelectFolder('Verzeichnis auswählen!', '', 2, '', $hGui)
    If FileExists($sPath) Then
    _GUICtrlListView_DeleteAllItems($hLVHandle) ; Alle Listview-Einträge löschen
    $iLVCount = 0 ; Zähler auf Null setzen
    GUISetCursor(15, 1, $hGui)
    _GUICtrlStatusBar_SetText($hStatus, 'Durchsuche Verzeichnis "' & $sPath & '"', 0)
    _DriveSearch($sPath)
    GUISetCursor(2, 1, $hGui)
    _GUICtrlStatusBar_SetText($hStatus, _GUICtrlListView_GetItemCount($hLVHandle), 1)
    _GUICtrlStatusBar_SetText($hStatus, '', 2)
    If $fStop Then
    $fStop = False
    _GUICtrlStatusBar_SetText($hStatus, 'Abgebrochen!', 0)
    Else
    _GUICtrlStatusBar_SetText($hStatus, 'Fertig.', 0)
    EndIf
    EndIf
    Case $hListView ; User hat auf eine Spaltenüberschrift geklickt (sortieren)
    If _GUICtrlListView_GetItemCount($hLVHandle) > 0 Then
    Dim $aDescending[_GUICtrlListView_GetColumnCount($hLVHandle)]
    GUISetCursor(15, 1, $hGui)
    $iTimer = TimerInit()
    _GUICtrlStatusBar_SetText($hStatus, 'Sortiere Daten! Bitte warten...', 0)
    _GUICtrlListView_SimpleSort($hLVHandle, $aDescending, GUICtrlGetState($hListView))
    _GUICtrlStatusBar_SetText($hStatus, _TicksToTimeFormat(TimerDiff($iTimer), '%mm:%ss.%ms'), 2)
    _GUICtrlStatusBar_SetText($hStatus, 'Fertig.', 0)
    GUISetCursor(2, 1, $hGui)
    EndIf
    Case $hLoad ; User hat auf 'Laden' geklickt
    GUISetCursor(15, 1, $hGui)
    _GUICtrlStatusBar_SetText($hStatus, 'Lade Daten...', 0)
    Load()
    _GUICtrlStatusBar_SetText($hStatus, 'Fertig.', 0)
    GUISetCursor(2, 1, $hGui)
    Case $hSave ; User hat auf 'Speichern' geklickt
    GUISetCursor(15, 1, $hGui)
    _GUICtrlStatusBar_SetText($hStatus, 'Speichere Daten...', 0)
    Save()
    _GUICtrlStatusBar_SetText($hStatus, 'Fertig.', 0)
    _GUICtrlStatusBar_SetText($hStatus, '', 2)
    GUISetCursor(2, 1, $hGui)
    Case $hDel
    GUISetCursor(15, 1, $hGui)
    _GUICtrlListView_DeleteItemsSelected($hLVHandle)
    _GUICtrlStatusBar_SetText($hStatus, _GUICtrlListView_GetItemCount($hLVHandle), 1)
    GUISetCursor(2, 1, $hGui)
    Case $hDelAll ; User hat auf 'Alle Einträge löschen' geklickt
    If MsgBox(256 + 32 + 4, 'Einträge löschen', 'Wollen sie wirklich alle Einträge löschen?') = 6 Then
    _GUICtrlListView_DeleteAllItems($hLVHandle)
    _GUICtrlStatusBar_SetText($hStatus, 0, 1)
    EndIf
    Case $GUI_EVENT_CLOSE ; User hat auf das Schließen-Symbol geklickt
    If MsgBox(32 + 4, 'Beenden', 'Wollen sie das Programm wirklich beenden?') = 6 Then _End() ; wenn ja, dann End-Funktion aufrufen
    EndSwitch
    WEnd

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

    Func _Stop()
    $fStop = True
    EndFunc ;==>_Stop

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

    Func _End()
    ;~ Save() ; wenn der vordere Kommentar entfernt wird, dann werden vor dem beenden noch die Daten gespeichert
    Exit ; Programm beenden
    EndFunc ;==>End

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

    Func _DriveSearch($sPath)
    Local $aNewMP3, $aID3Tags, $sNewItem, $aItem
    If StringRight($sPath, 1) <> '\' Then $sPath &= '\'
    _GUICtrlStatusBar_SetText($hStatus, 'Bitte warten...', 2)
    $aNewMP3 = _RecursiveFileListToArray($sPath, '\.mp3', 1) ; Alle MP3s auf der Festplatte auslesen
    If Not @error And $aNewMP3[0] > 0 Then
    _GUICtrlListView_SetItemCount($hListView, _GUICtrlListView_GetItemCount($hLVHandle) + $aNewMP3[0])
    _GUICtrlStatusBar_SetText($hStatus, 'Lese ID3-Tags... (' & $aNewMP3[0] & ')', 0)
    For $j = 1 To $aNewMP3[0] ; die gefundenen MP3s durchgehen
    $aID3Tags = _ReadID3Tag($aNewMP3[$j]) ; die ID3-Tags auslesen
    If Not @error Then
    For $k = 0 To 10
    $aID3Tags[$k][1] = StringReplace($aID3Tags[$k][1], '|', '') ; evtl. vorhandene "|" entfernen
    Next
    _GUICtrlStatusBar_SetText($hStatus, _GUICtrlListView_GetItemCount($hLVHandle), 1)
    _GUICtrlStatusBar_SetText($hStatus, $aNewMP3[$j], 2)
    $sNewItem = $aID3Tags[0][1] & '|' & $aID3Tags[1][1] & '|' & $aID3Tags[4][1] & '|' & $aID3Tags[2][1] & '|' & $aID3Tags[3][1]
    $sNewItem &= '|' & $aID3Tags[8][1] & '|' & $aID3Tags[9][1] & '|' & $aID3Tags[10][1] & '|' & $aNewMP3[$j]
    GUICtrlCreateListViewItem($sNewItem, $hListView)
    EndIf
    If $fStop Then ExitLoop
    Next
    EndIf
    EndFunc ;==>_DriveSearch

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

    Func _WM_NOTIFY($hWnd, $msg, $wParam, $lParam)
    Local $hWndFrom, $iIDFrom, $iCode, $tNMHDR, $tInfo, $sExecutePath
    $tNMHDR = DllStructCreate($tagNMHDR, $lParam)
    $hWndFrom = HWnd(DllStructGetData($tNMHDR, 'hWndFrom'))
    $iIDFrom = DllStructGetData($tNMHDR, 'IDFrom')
    $iCode = DllStructGetData($tNMHDR, 'Code')
    Switch $hWndFrom
    Case $hLVHandle
    Switch $iCode
    Case $NM_DBLCLK
    $tInfo = DllStructCreate($tagNMITEMACTIVATE, $lParam)
    $sExecutePath = _GUICtrlListView_GetItemText($hLVHandle, DllStructGetData($tInfo, "SubItem"), 8)
    ShellExecute($sExecutePath)
    EndSwitch
    EndSwitch
    Return $GUI_RUNDEFMSG
    EndFunc

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

    Func _WM_SIZE($hWnd, $msg, $wParam, $lParam)
    Local $aGuiPos = WinGetPos($hGui)
    If Not BitAND(WinGetState($hGui), 16) Then
    IniWrite($sInifile, 'Config', 'Width', $aGuiPos[2])
    IniWrite($sInifile, 'Config', 'Height', $aGuiPos[3])
    EndIf
    _GUICtrlStatusBar_Resize($hStatus)
    Return $GUI_RUNDEFMSG
    EndFunc ;==>WM_SIZE

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

    Func _WM_MOVE($hWnd, $msg, $wParam, $lParam)
    Local $aGuiPos = WinGetPos($hGui)
    If Not BitAND(WinGetState($hGui), 16) Then
    IniWrite($sInifile, 'Config', 'Left', $aGuiPos[0])
    IniWrite($sInifile, 'Config', 'Top', $aGuiPos[1])
    EndIf
    Return $GUI_RUNDEFMSG
    EndFunc

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

    Func _WM_GETMINMAXINFO($hWnd, $msg, $wParam, $lParam)
    If $hWnd = $hGui Then
    Local $minmaxinfo = DllStructCreate("int;int;int;int;int;int;int;int;int;int", $lParam)
    DllStructSetData($minmaxinfo, 7, 786) ; min X
    DllStructSetData($minmaxinfo, 8, 444) ; min Y
    ;~ DllStructSetData($minmaxinfo, 9, 800) ; max X
    ;~ DllStructSetData($minmaxinfo, 10, 800) ; max Y
    EndIf
    EndFunc

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

    Func Load() ; Datenbank-Datei laden
    Local $sDBFile, $hFile, $sContent, $aNewItems, $iTimer, $iCount
    FileChangeDir(@ScriptDir)
    $sDBFile = FileOpenDialog('MP3-Datenbank-Datei auswählen', @ScriptDir, 'MP3-Datenbank (*.db3)', 3, '', $hGui)
    If Not FileExists($sDBFile) Then Return
    $hFile = FileOpen($sDBFile, 0) ; Datei zum lesen öffnen
    If $hFile = -1 Then Return; wenn das öffnen nicht erfolgreich war, dann Funktion verlassen
    $sContent = FileRead($hFile) ; Datei komplett einlesen
    FileClose($hFile) ; Datei schließen
    $sContent = StringTrimRight($sContent, 2) ; das letzte @CRLF entfernen
    $aNewItems = StringSplit($sContent, @CRLF, 1) ; Den Dateiinhalt am Zeilenende splitten
    If Not IsArray($aNewItems) Then Return ; Wenn $aNewItems kein Array ist, dann Funktion verlassen
    _GUICtrlListView_DeleteAllItems($hLVHandle)
    _GUICtrlListView_SetItemCount($hLVHandle, $aNewItems[0])
    _GUICtrlStatusBar_SetText($hStatus, 'Lade Daten... (' & $aNewItems[0] & ')', 0)
    _GUICtrlListView_BeginUpdate($hLVHandle) ; Listview sperren
    $iTimer = TimerInit()
    For $i = 1 To $aNewItems[0] ; Alle Einträge des Arrays durchgehen
    $iCount += 1
    If TimerDiff($iTimer) > 100 Then
    $iTimer = TimerInit()
    _GUICtrlStatusBar_SetText($hStatus, $iCount, 1)
    EndIf
    GUICtrlCreateListViewItem($aNewItems[$i], $hListView) ; mit den eingelesenen Daten einen neuen Listview-Eintrag erstellen
    Next
    _GUICtrlStatusBar_SetText($hStatus, $iCount, 1)
    _GUICtrlListView_EndUpdate($hLVHandle) ; Listview wieder freigeben
    EndFunc ;==>Load

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

    Func Save() ; Datenbank-Datei speichern
    Local $sDBFile, $hFile, $iCount, $iTimer
    $sDBFile = FileSaveDialog('MP3-Datenbank-Datei auswählen', '', 'MP3-Datenbank (*.db3)', 18, '', $hGui)
    If @error Then Return
    If StringRight($sDBFile, 4) <> '.db3' Then $sDBFile &= '.db3'
    $iCount = _GUICtrlListView_GetItemCount($hLVHandle); Anzahl der Listview-Einträge holen
    If $iCount = 0 Then Return ; Wenn das Listview keine Einträge enthält, dann Funktion verlassen
    $hFile = FileOpen($sDBFile, 2) ; Datei zum speichern (überschreiben) öffnen
    If $hFile = -1 Then Return; wenn das öffnen nicht erfolgreich war, dann Funktion verlassen
    $iTimer = TimerInit()
    For $i = 0 To $iCount - 1 ; Schleife, um alle Listview-Einträge durchzugehen
    FileWriteLine($hFile, _GUICtrlListView_GetItemTextString($hLVHandle, $i))
    If TimerDiff($iTimer) > 100 Then
    $iTimer = TimerInit()
    _GUICtrlStatusBar_SetText($hStatus, $i + 1, 2)
    EndIf
    Next
    FileClose($hFile) ; Datei schließen
    EndFunc ;==>Save

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

    ;===============================================================================
    ; Function Name: _RecursiveFileListToArray($sPath[, $sPattern][, $iFlag][, $iFormat][, $iRecursion][, $sDelim])
    ; Description:: gibt Verzeichnisse (rekursiv) und/oder Dateien zurück, die einem RegExp-Pattern entsprechen
    ; Parameter(s): $sPath = Startverzeichnis
    ; $sPattern = ein beliebiges RexExp-Pattern für die Auswahl
    ; $iFlag = Auswahl
    ; 0 = Dateien & Verzeichnisse
    ; 1 = nur Dateien
    ; 2 = nur Verzeichnisse
    ; $iFormat = Rückgabeformat
    ; 0 = String
    ; 1 = Array mit [0] = Anzahl
    ; 2 = Nullbasiertes Array
    ; $iRecursion = Verzeichnisse rekursiv durchsuchen
    ; 0 = Nein
    ; 1 = Ja
    ; $sDelim = Trennzeichen für die String-Rückgabe
    ; Requirement(s): AutoIt 3.3.0.0
    ; Return Value(s): Array/String mit den gefundenen Dateien/Verzeichnissen
    ; Author(s): Oscar (http://www.autoit.de)
    ; Anregungen von: bernd670 (http://www.autoit.de)
    ;===============================================================================
    Func _RecursiveFileListToArray($sPath, $sPattern = '', $iFlag = 0, $iFormat = 1, $iRecursion = 1, $sDelim = @CRLF)
    Local $hSearch, $sFile, $sReturn = ''
    If StringRight($sPath, 1) <> '\' Then $sPath &= '\'
    $hSearch = FileFindFirstFile($sPath & '*.*')
    If @error Or $hSearch = -1 Then Return SetError(1, 0, $sReturn)
    While Not $fStop
    $sFile = FileFindNextFile($hSearch)
    If @error Then ExitLoop
    If @extended Then
    If StringRegExp($sPath & $sFile, $sPattern) And ($iFlag = 0 Or $iFlag = 2) Then $sReturn &= $sPath & $sFile & '\' & $sDelim
    If $iRecursion Then $sReturn &= _RecursiveFileListToArray($sPath & $sFile & '\', $sPattern, $iFlag, 0)
    ContinueLoop
    EndIf
    If StringRegExp($sFile, $sPattern) And ($iFlag = 0 Or $iFlag = 1) Then $sReturn &= $sPath & $sFile & $sDelim
    WEnd
    FileClose($hSearch)
    If $iFormat And $sReturn = '' Then Return StringSplit($sReturn, '', $iFormat)
    If $iFormat Then Return StringSplit(StringTrimRight($sReturn, StringLen($sDelim)), $sDelim, $iFormat)
    Return $sReturn
    EndFunc ;==>_RecursiveFileListToArray

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

    ;===============================================================================
    ; Function Name: _ReadID3Tag($sPath)
    ; Description:: gibt ein Array mit den Daten aus den ID3-Tags zurück
    ; unterstützt werden die ID3-Tag-Versionen 1.0, 1.1, 2.3 und 2.4
    ; bei v2.4 müssen sich die ID3-Tags am Anfang der Datei befinden
    ; Parameter(s): $sPath = Pfad zu einer MP3-Datei
    ; Requirement(s): min. AutoIt v3.3.0.0
    ; Return Value(s): bei Erfolg: Array mit den ID3-Tagdaten (@error = 0)
    ; im Fehlerfall bekommt @error:
    ; 1 = Datei existiert nicht
    ; 2 = Datei konnte nicht zum lesen geöffnet werden
    ; 3 = falsche ID3 v2 Version
    ; 4 = Datei ist keine MP3-Datei
    ; Author(s): Oscar (http://www.autoit.de)
    ;===============================================================================
    Func _ReadID3Tag($sPath)
    If Not FileExists($sPath) Then Return SetError(1, 0, 0)
    Local $hFile, $sData, $sID3Header, $iID3HeaderSize = 0, $iOffset, $iSize, $tmp
    Local $aID3v2Tags[8] = ['TIT2', 'TPE1', 'TALB', 'TYER', 'TLEN', 'TRCK', 'TCON', 'TENC']
    Local $aID3[11][2] = [ _
    ['Title', ''],['Artist', ''],['Album', ''],['Year', ''], _
    ['Length', '0'],['Track', ''],['Genre', ''],['Encoder', ''], _
    ['MPEG-Version', ''],['Bitrate', '-'],['Sample-Freq.', '']]
    Local $aMP3Version[4] = ['MPEG2.5', 'Reserved', 'MPEG2', 'MPEG1']
    Local $aMP3Layer[4] = ['Reserved', 'Layer III', 'Layer II', 'Layer I']
    Local $aMP3Bitrate[5][16] = [ _
    [000, 032, 064, 096, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448, 000], _
    [000, 032, 048, 056, 064, 080, 096, 112, 128, 160, 192, 224, 256, 320, 384, 000], _
    [000, 032, 040, 048, 056, 064, 080, 096, 112, 128, 160, 192, 224, 256, 320, 000], _
    [000, 032, 048, 056, 064, 080, 096, 112, 128, 144, 160, 176, 192, 224, 256, 000], _
    [000, 008, 016, 024, 032, 040, 048, 056, 064, 080, 096, 112, 128, 144, 160, 000]]
    Local $aSampleFreq[3][4] = [[44100, 48000, 32000, 0],[22050, 24000, 16000, 0],[11025, 12000, 8000, 0]]
    Local $sMP3FrameHeader, $iMP3Version, $sMP3Version, $sMP3Layer, $iMP3Bitrate, $iMP3SampleFreq
    Local $iVBRFrames = -1, $iVBRFilesize, $iVBRFlags
    $hFile = FileOpen($sPath, 16)
    If $hFile = -1 Then Return SetError(2, 0, 0)
    $sData = Binary(FileRead($hFile, 4))
    If BinaryMid($sData, 1, 3) = '0x494433' Then ; ID3 v2.x Kennung gefunden
    If (BinaryMid($sData, 4, 1) = '0x03') Or (BinaryMid($sData, 4, 1) = '0x04') Then ; nur v2.3 und 2.4
    FileRead($hFile, 2) ; 2 Bytes überspringen
    For $i = 0 To 3 ; berechne ID3-Headergröße (4 Bytes, jedoch nur jeweils die unteren 7 Bit)
    $iID3HeaderSize = BitShift($iID3HeaderSize, -7) + BitAND(Binary(FileRead($hFile, 1)), 0x7F)
    Next
    If $iID3HeaderSize > 0 Then
    $sID3Header = Binary(FileRead($hFile, $iID3HeaderSize)) ; lese gesamten ID3-Header
    For $i = 0 To 7
    $iOffset = StringInStr(BinaryToString($sID3Header), $aID3v2Tags[$i]) ; Offset zu dem ID3-Tag
    If $iOffset > 0 Then
    $iSize = Hex(BinaryMid($sID3Header, $iOffset + 4, 4)) ; Größe des ID3-Frames
    $tmp = BinaryMid($sID3Header, $iOffset + 11, Dec($iSize) - 1)
    If BinaryMid($tmp, 1, 2) = '0xFFFE' Then
    For $x = 3 To BinaryLen($tmp) Step 2
    $aID3[$i][1] &= BinaryToString(BinaryMid($tmp, $x, 2), 2)
    Next
    Else
    For $x = 1 To BinaryLen($tmp)
    $aID3[$i][1] &= BinaryToString(BinaryMid($tmp, $x, 1))
    Next
    EndIf
    $aID3[$i][1] = StringReplace($aID3[$i][1], Chr(0), '')
    EndIf
    Next
    EndIf
    Do
    $sData = String(FileRead($hFile, 1))
    If @error Then ExitLoop
    If BitAND($sData, 0xff) = 0xff Then
    FileSetPos($hFile, -1, 1)
    $sData = String(FileRead($hFile, 4))
    EndIf
    Until BitAND($sData, 0xFFE00000) = 0xFFE00000
    Else
    FileClose($hFile)
    Return SetError(3, 0, 0)
    EndIf
    Else ; ID3 v1.x
    $iOffset = FileGetPos($hFile)
    FileSetPos($hFile, -128, 2)
    $sID3Header = BinaryToString(FileRead($hFile, 3))
    If $sID3Header = 'TAG' Then
    $aID3[0][1] = StringReplace(BinaryToString(FileRead($hFile, 30)), Chr(0), '')
    $aID3[1][1] = StringReplace(BinaryToString(FileRead($hFile, 30)), Chr(0), '')
    $aID3[2][1] = StringReplace(BinaryToString(FileRead($hFile, 30)), Chr(0), '')
    $aID3[3][1] = StringReplace(BinaryToString(FileRead($hFile, 4)), Chr(0), '')
    EndIf
    FileSetPos($hFile, $iOffset, 0)
    EndIf
    $sMP3FrameHeader = String($sData)
    If BitAND($sMP3FrameHeader, 0xFFE00000) <> 0xFFE00000 Then
    FileClose($hFile)
    Return SetError(4, 0, 0) ; keine MP3-Datei, dann Return
    EndIf
    $iMP3Version = BitShift(BitXOR($sMP3FrameHeader, 0xFFE00000), 19) ; welche MP3-Version
    $sMP3Version = $aMP3Version[$iMP3Version] ; in Textform
    $sMP3Layer = $aMP3Layer[BitShift(BitAND($sMP3FrameHeader, 0x60000), 17)] ; welcher Layer
    $aID3[8][1] = $sMP3Version & ' / ' & $sMP3Layer ; ins Ausgabe-Array
    $iMP3Bitrate = BitShift(BitAND($sMP3FrameHeader, 0xF000), 12) ; Bitraten-Index auslesen
    Switch $sMP3Version ; je nach MPEG-Version Bitrate aus der Tabelle holen
    Case 'MPEG1'
    $aID3[9][1] = $aMP3Bitrate[$iMP3Version - ($iMP3Version > 1)][$iMP3Bitrate]
    Case 'MPEG2', 'MPEG2.5'
    If $sMP3Layer = 'Layer I' Then
    $aID3[9][1] = $aMP3Bitrate[3][$iMP3Bitrate]
    Else
    $aID3[9][1] = $aMP3Bitrate[4][$iMP3Bitrate]
    EndIf
    EndSwitch
    $iMP3SampleFreq = BitShift(BitAND($sMP3FrameHeader, 0xC00), 10) ; Sample-Frequenz-Index auslesen
    $aID3[10][1] = $aSampleFreq[2 - ($iMP3Version - ($iMP3Version > 1))][$iMP3SampleFreq] ; und Wert aus der Tabelle holen
    Do ; evtl. Leerbytes überspringen
    $tmp = FileRead($hFile, 1)
    If @error Then ExitLoop
    Until $tmp <> 0x00 Or @error
    If $tmp = 0x58 And BinaryToString(FileRead($hFile, 3)) = 'ing' Then ; MP3 mit VBR (Xing-Header gefunden)?
    $iVBRFlags = '0x' & Hex(FileRead($hFile, 4)) ; VBR-Flags auslesen
    If BitAND($iVBRFlags, 0x3) Then ; wenn die Einträge vorhanden sind, dann...
    $iVBRFrames = Dec(Hex(FileRead($hFile, 4))) ; Anzahl der VBR-Frames auslesen
    $iVBRFilesize = Dec(Hex(FileRead($hFile, 4))) ; Dateigröße auslesen
    $aID3[4][1] = $iVBRFrames * 1152 / $aID3[10][1] * 1000 ; VBR Laufzeit
    $aID3[9][1] = 'VBR ~' & Int($iVBRFilesize * 8 / ($aID3[4][1] / 1000) / 1000) ; VBR durchschnittliche Bitrate
    EndIf
    Else
    If $aID3[4][1] = 0 Then $aID3[4][1] = (FileGetSize($sPath) * 8) / ($aID3[9][1] * 1000) * 1000 ; alternative CBR Laufzeit
    $aID3[9][1] = 'CBR ' & $aID3[9][1]
    EndIf
    $aID3[4][1] = _TicksToTimeFormat($aID3[4][1]) ; Laufzeit (Ticks to hour:min:sec)
    $aID3[9][1] &= ' kBit/s'
    $aID3[10][1] &= ' Hz'
    FileClose($hFile)
    Return SetError(0, 0, $aID3)
    EndFunc ;==>_ReadID3Tag

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

    ;===============================================================================
    ; Function Name: _TicksToTimeFormat($iTicks, $sFormat = '%hh:%mm:%ss')
    ; Description:: Diese Funktion wandelt Millisekunden in ein anzugebenes Zeitformat um
    ; Parameter(s): $iTicks = Zeit in Millisekunden
    ; $sFormat:
    ; %hh für Stunden
    ; %mm für Minuten
    ; %ss für Sekunden
    ; %ms für Millisekunden
    ; sonstige Zeichen, die dazwischen stehen, werden übernommen
    ; Requirement(s): -
    ; Return Value(s): Zeit im ausgewählten Format (String)
    ; Author(s): Oscar (http://www.autoit.de)
    ;===============================================================================
    Func _TicksToTimeFormat($iTicks, $sFormat = '%hh:%mm:%ss')
    Local $aTime[4] = [0, 0, 0, 0], $sOut, $aTimeFormat[4] = ['hh', 'mm', 'ss', 'ms'], $aFormat
    $aTime[2] = Int($iTicks / 1000)
    $aTime[3] = $iTicks - $aTime[2] * 1000
    $aTime[0] = Int($aTime[2] / 3600)
    $aTime[2] = Mod($aTime[2], 3600)
    $aTime[1] = Int($aTime[2] / 60)
    $aTime[2] = Mod($aTime[2], 60)
    $aFormat = StringRegExp($sFormat, '%([^%]+)', 3)
    If Not IsArray($aFormat) Then Return SetError(1, 0, $iTicks)
    For $i = 0 To UBound($aFormat) - 1
    For $j = 0 To UBound($aTimeFormat) - 1
    If StringLeft($aFormat[$i], 2) = $aTimeFormat[$j] Then $sOut &= StringFormat('%02i', $aTime[$j]) & StringMid($aFormat[$i], 3)
    Next
    Next
    Return $sOut
    EndFunc ;==>_TicksToTimeFormat

    [/autoit]

    Edit: Kleinen Bug behoben.