PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Festplatten nach Dateien durchsuchen und ausgeben?


Hui!
2003-01-19, 16:25:11
Hallo zusammen,

ich versuche gerade ein kleines Programm in C++, als IDE wird BCB eingesetzt.

Ich möchte eine Festplatte die man in einer DriveComboBox ausgewählt wurde nach MP3 Dateien durchsuchen und in einem Memo ausgeben lassen.

Ich hab versucht irgendwie mit FindFirst() FindNext() weiterzukommen, das ist mir aber einfach noch zu hoch(bin noch nicht solange dabei).
Was für Möglichkeiten habe ich da? Am besten so primitiv wie möglich.

Xmas
2003-01-19, 16:53:16
Ich würde sowas vorschlagen (scheint zu funktionieren)


void SucheMP3s( const AnsiString Path )
{
TSearchRec SRec;
if( 0 == FindFirst( Path + "\\*.mp3", faAnyFile, SRec ) )
{
do
{
// hier den Namen in das Memofeld
Form1->Memo1->Lines->Add( Path + "\\" + SRec.Name );
}
while( 0 == FindNext( SRec ) );
FindClose( SRec );
}

if( 0 == FindFirst( Path + "\\*", faDirectory, SRec ) )
{
do
{
if( (SRec.Name != ".") && (SRec.Name != "..") ) SucheMP3s( Path + "\\" + SRec.Name );
}
while( 0 == FindNext( SRec ) );
FindClose( SRec );
}
}

Unregistered
2003-01-19, 17:11:32
He danke :)

Eine kleine Frage noch:
Wie ruf ich das auf :stareup:

Xmas
2003-01-19, 17:17:21
Originally posted by Unregistered
He danke :)

Eine kleine Frage noch:
Wie ruf ich das auf :stareup:
Hab noch ne kleine Änderung reingebracht, das scheint jetzt zu funktionieren, auch wenns recht langsam ist (bei meiner Platte zumindest ;) )

Aufrufen tust du das mit z.B.
SucheMP3s( "C:" );
also mit dem Anfangspfad ohne \

"Form1->Memo1" musst du natürlich entsprechend deinem Formular ändern.

Hui!
2003-01-19, 17:46:27
An ner 20GB Partition hat er ganz schön zu knabbern ;D
Ich werd mir deinen Code erst mal mit der BCB Hilfe etwas genauer ansehen, vielleicht bekomm ich dann diese FindFirst Sache endlich in meinen Kopf.

Ich werd dir bestimmt später noch mal auf den Wecker gehen wenn es daran geht irgendwas mit diesen Dateien Anzufangen(z.B. an MediaPlayer Komponente weiterzugeben) oder das ganze in einem StringGridArray mit Dauer, Größe etc auszugeben.

Aber erst mal vielen Dank für deine Hilfe :)

Hui!
2003-01-20, 11:22:15
So, mit meinen bescheidenen Mitteln hab ich mal versucht die DriveComboBox da irgendwie in den Path reinzuwursten.
Mit Drive gibt die Box ja den Laufwerksbuchstaben aus, genau das was ich ja brauche, nur ohne den ":".
Also hab ich mir was ganz tolles Ausgedacht um das da hinten dran zu bekommen:


void SucheMP3s( const AnsiString Path )
{

AnsiString Punkt;
Punkt=":";

TSearchRec SRec;
if( 0 == FindFirst( Path + Punkt + "\\*.mp3", faAnyFile, SRec ) )
{
do
{
Form1->Memo1->Lines->Add(SRec.Name );
}
while( 0 == FindNext( SRec ) );
FindClose( SRec );
}

if( 0 == FindFirst( Path + Punkt + "\\*", faDirectory, SRec ) )
{
do
{
if( (SRec.Name != ".") && (SRec.Name != "..") ) SucheMP3s( Path + Punkt + "\\" + SRec.Name );
}
while( 0 == FindNext( SRec ) );
FindClose( SRec );
}

}
//---------------------------------------------------------------------------

void __fastcall TForm1::Button1Click(TObject *Sender)
{
SucheMP3s(DriveComboBox1->Drive);
}
//---------------------------------------------------------------------------

Überraschenderweise funktioniert das sogar (fast) :D
Nur durchsucht er jetzt nicht mehr die Unterverzeichnisse :...(

Was ist zu tun? Und wie mach ich das "etwas" eleganter mit der Box?

Danke

Xmas
2003-01-20, 14:34:50
Das kann ja auch nicht funktionieren. Die Funktion ruft sich selbst rekursiv auf, der Doppelpunkt darf also nur beim ersten Aufruf hinzugefügt werden. So wie du es machst wird er an jeden Verzeichnisnamen angehängt.

Also nimm das mit dem Punkt wieder raus und rufe die Funktion so auf:

SucheMP3s( AnsiString( &(DriveComboBox1->Drive), 1 ) + ":" );

Hui!
2003-03-06, 15:49:15
So, hab endlich mal wieder Zeit gefunden hier ein bisschen weiterzumachen, folgendes hab ich mir überlegt:
Dank Xmas Hilfe hab ich ja jetzt meine MP3s von der Festplatte, jetzt muss ich nur noch was mit ihnen Anfangen können, d.h. in eine andere Liste schieben oder Abspielen in einer Media Player Componente.
Ich brauch also einen Container für den Pfad der Datei, der beim Anklicken der Entsprechenden Zeile im Memo weitergegeben wird.
Was verwendet man für so was? Ein StringArray? Der Pfad ist ja ein String.
Oder denk ich da völlig in die falsche Richtung?

Xmas
2003-03-07, 12:49:32
Um MP3s auswählen zu können, verwendest du besser eine Listbox statt ein Memofeld.

Aber was meinst du mit Container? Möchtest du Mehrfachauswahl oder eine Playlist haben?

Hui!
2003-03-07, 13:09:56
Habs gemerkt und bin schon auf ListBox umgestiegen :)

Mit Container meine ich das ich ja irgendwo die Pfade der MP3 Dateien für meinen Player haben muss, oder?
Also müsste ich sie ja irgendwo hinlegen, hab ich mir zumindest so gedacht.
Da der Pfad ein String ist hab ich an ein StringArray gedacht, wenn die Suchfunktion die Namen in die ListBox schreibt würde ich sie den Pfad gleichzeitig in das Array schreiben lassen. Die Einträge haben dann jeweils die gleiche Nummer und ich könnte sie immer zusammen rumrücken, in eine andere List oder Player.

Wobei ich mir aber sicherlich vorstellen könnte das es viel einfachere und bessere Methoden gibt, nur kenn ich keine ?-)

x-dragon
2003-03-08, 20:10:38
Kannst du unter C++ auch eigene Objekte erstellen? Also ich kenn mich nur mit Delphi aus, aber da ist es am einfachsten zu handhaben wenn man ein Objekt erstellt in dem alle wichtigen Infos zu der MP3-Datei gespeichert sind. Bei der Listbox könnte man dann die Dateien z.B. mit "ListBox.AddObject(obj)" eintragen und später dann direkt alle benötigen Infos aus der markierten Zeile rausholen.

Wenn du das mit einem Array umsetzen willst, müsstest du ja entweder die max. Dateienanzahl begrenzen oder ein dynamisches Array einrichten.

Hui!
2003-03-09, 18:02:42
Originally posted by X-Dragon
Kannst du unter C++ auch eigene Objekte erstellen? Also ich kenn mich nur mit Delphi aus, aber da ist es am einfachsten zu handhaben wenn man ein Objekt erstellt in dem alle wichtigen Infos zu der MP3-Datei gespeichert sind. Bei der Listbox könnte man dann die Dateien z.B. mit "ListBox.AddObject(obj)" eintragen und später dann direkt alle benötigen Infos aus der markierten Zeile rausholen.

Wenn du das mit einem Array umsetzen willst, müsstest du ja entweder die max. Dateienanzahl begrenzen oder ein dynamisches Array einrichten.
Das hört sich interessant an, evt. werd ich mich an Objekte wagen wenn ich die Sache hier einigermaßen überstanden hab.

Die Sache mit dem Array läuft soweit, mit der Größeneinschränkung eben(was mir erstmal egal ist), ein kleines Problem hab ich aber noch:
Ich möchte Einträge aus meiner ListBox herauslöschen, das heißt einmal aus der ListBox(einfach mit delete, kein Thema) und aus dem Array das parallel dazu läuft.
Mit dem Array hab ich zu kämpfen, in meinem Büchlein steht dazu folgendes:

Das Element an der Position i kann man dadurch löschen, indem man a[i]
durch a[Satzzahl–1] überschreibt und Satzzahl um 1 reduziert.

Mir will aber nicht reingehen was für einen Sinn das haben soll, zumindest geht es bei mir nicht:

Array2[ListBox1->ItemIndex] = Array2[Laufzahl2-1];
Laufzahl2--;

ItemIndex beschreibt den in der ListBox zum löschen angewählten String.
Was ist daran falsch? Kann mir das jemand auf die schnelle besser erklären?

Demirug
2003-03-09, 19:17:21
Hui!,

Das mit dem


a[i] = a[Satzzahl-1]
Satzzahl--;

i = Index des zu löschenden Eintrags;


Ist die Variante einen Eintrag aus einem unsortierten Array zu löschen. Du hast aber ein Sortiertes Array.

Dort macht man das wie folgt:



for (int j = i ; j < Satzzahl-2 ; j++)
a[j] = a[j+1];

Satzzahl--;



Die Variante das man die Detaildaten direkt an die Listbox anhängt ist normalerweise die schnellere.

Unregistered
2003-03-09, 23:33:48
Hallo Demirug,

danke für die Antwort, ich scheine aber irgendwo einen Fehler zu haben:


int i = ListBox1->ItemIndex ;


for (int j = i ; j < Laufzahl2-2 ; j++)
Array2[j] = Array2[j+1];

Laufzahl2--;


Wenn ich 4 Werte in mein Array werfe passiert folgendes(0-4 = Plätze im Array, a-d = Werte, jeweils den ersten Eintrag(0) weggelöscht):

0 a | b c c c
1 b | c c c c
2 c | c c c c
3 d | d d d d


Könnte sein das evt. die Laufzahl2 den falschen Wert hat?

Demirug
2003-03-10, 07:32:28
Originally posted by Unregistered
Hallo Demirug,

danke für die Antwort, ich scheine aber irgendwo einen Fehler zu haben:


int i = ListBox1->ItemIndex ;


for (int j = i ; j < Laufzahl2-2 ; j++)
Array2[j] = Array2[j+1];

Laufzahl2--;


Wenn ich 4 Werte in mein Array werfe passiert folgendes(0-4 = Plätze im Array, a-d = Werte, jeweils den ersten Eintrag(0) weggelöscht):


Könnte sein das evt. die Laufzahl2 den falschen Wert hat?

Ja es sieht so aus. Laufzahl2 muss immer der Anzahl der Elemente im Array entsprechen. Schon mal mit dem Debugger geschaut was abläuft?

Hui!
2003-03-10, 22:11:01
Die Laufzahl scheint korrekt sein, bei 4 Werten im Array zeigt sie 4 an, jedes mal wenn einer rausgelöscht wird sinkt sie brav um 1.
Das einzige Problem scheint das die Werte nicht richtig aus dem Array verschwinden ???

Ich bin verwirrt, woran könnte das liegen?

Xmas
2003-03-10, 22:53:42
int i = ListBox1->ItemIndex ;


for (int j = i ; j <= Laufzahl2-2 ; j++)
Array2[j] = Array2[j+1];

Laufzahl2--;

Hui!
2003-03-10, 23:02:38
Danke, geht aber immer noch nicht richtig, irgendwann beginnen die Werte sich zu verdrehen :...(

Hui!
2003-03-10, 23:06:28
Oh, sry mein Fehler, es geht.
Hab nur vergessen die Löschung bei einem ItemIndex von -1(also nix in der Box angewählt) nicht zuzulassen.
Danke :)