Entwickler-Ecke

Delphi Language (Object-Pascal) / CLX - unbekannte Anzahl an Dateien öffnen


beastofchaos - Sa 14.05.11 12:58
Titel: unbekannte Anzahl an Dateien öffnen
Hallo Leute,
ich hab schon rumgescuht, aber konnte nicht finden, wie ich aus einem Ordner beliebig viele Dateien aufrufen kann, ohne ihren Namen zuwissen außerdem. Es funktioniert so, dass bei meinem Programm im Hintergrund Musik läuft, die ich in dem Ordner "Sounds/Background" habe. Ich arbeite nebenbei mit der Bass.dll...

In FormCreate hab ich diesen Befehl stehen: "FBackgroundStream := BASS_StreamCreateFile(false, PAnsiChar(AnsiString(path + 'Sounds/Crazy Town - Butterfly [Instrumental].mp3')), 0, 0, 0)".

Mit einem Timer überprüfe ich immer, ob die Musik noch läuft.

Grüße, Thomas


Regan - Sa 14.05.11 13:17

Du könntest mit FindFirst, FindNext und einer while-Schleife durch ein Verzeichnis iterieren und die Dateien auflisten.


Gerd Kayser - Sa 14.05.11 13:31

user profile iconbeastofchaos hat folgendes geschrieben Zum zitierten Posting springen:
wie ich aus einem Ordner beliebig viele Dateien aufrufen kann, ohne ihren Namen zuwissen

Beispiel:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
procedure TForm1.Button1Click(Sender: TObject);
var
  SearchRec : TSearchRec;
  Verz      : string;
begin
  Memo1.Clear;
  Verz := 'I:\Sound.Dat\';
  if FindFirst(Verz + '*.mp3', faAnyFile, SearchRec) = 0 then
  begin
    repeat
      Memo1.Lines.Add(SearchRec.Name);
    until
      FindNext(SearchRec) <> 0;
    SysUtils.FindClose(SearchRec);
  end;
end;


Zitat:
Ich arbeite nebenbei mit der Bass.dll...

Ich benutze mciSendstring der Multimedia-API (uses MMSystem). Jedem das Seine ...
Zitat:
Mit einem Timer überprüfe ich immer, ob die Musik noch läuft.

Man kann sich auch benachrichtigen lassen, wenn das Lied zu Ende ist. Aber das wäre ein neues Thema und gehört nicht in diesen Thread.


jaenicke - Sa 14.05.11 13:32

Du kannst die Dateinamen z.B. als konstantes Array einbinden.

Oder du erstellst eine Konfigurationsdatei, z.B. als XML-Datei. Dann kannst du daraus die Dateinamen auslesen. Das wäre vermutlich die sinnvollste Variante.

// EDIT:
user profile iconGerd Kayser hat folgendes geschrieben Zum zitierten Posting springen:
Zitat:
Ich arbeite nebenbei mit der Bass.dll...

Ich benutze mciSendstring der Multimedia-API (uses MMSystem). Jedem das Seine ...
Damit kannst aber auch extrem viel weniger machen...


beastofchaos - Sa 14.05.11 13:35

Ich mach mir dann ein dynamisches Array, das die Namen speichert. Dann spiele ich per random(Höhe des Arrays) ein zufälliges Lied ab und der Bedingung, dass es nicht das vorherige ist(bei mehr als 1 Lied). Danke für die Hilfe ;)

Grüße, Thomas


jaenicke - Sa 14.05.11 13:39

Eine TStringList ist doch gut dafür geeignet. Und in der Library hier gibt es auch eine Funktion, die dir diese füllt, das musst du gar nicht selber schreiben. ;-)
http://www.delphi-library.de/topic_nach+Dateien+suchen_1107.html


Gerd Kayser - Sa 14.05.11 13:43

user profile iconjaenicke hat folgendes geschrieben Zum zitierten Posting springen:
Damit kannst aber auch extrem viel weniger machen...

Zum Abspielen von Liedern und Videos sowie zur Abfrage von Infos reicht mciSendString vollkommen aus. Man kann auch mit Kanonen auf Spatzen schießen. ;-)


jaenicke - Sa 14.05.11 13:53

user profile iconGerd Kayser hat folgendes geschrieben Zum zitierten Posting springen:
Zum Abspielen von Liedern und Videos sowie zur Abfrage von Infos reicht mciSendString vollkommen aus. Man kann auch mit Kanonen auf Spatzen schießen. ;-)
Es fehlt aber z.B. die Lautstärkeregelung, außerdem werden nur wenige Dateitypen unterstützt. :zwinker:
Aber das ist hier ja auch nicht das Thema. :D


beastofchaos - Sa 14.05.11 16:37

Genau ;)

Übrigens ist da meiner Meinung ein kleiner Fehler in der von dir genannten Prozedur:


Delphi-Quelltext
1:
  Procedure FindFiles (aPath, aFindMask: String; aWithSub: Boolean; aResult: tStrings);                    


Müsste bei aResult nicht ein "var" davor, damit das dann auch auf die genannte Variable übvertragen werden kann?
Außerdme verhält sich eine StringList wie ein array, oder? ncoh nie damit gearbeitet, aber nicht unbedingt schwer. Gibt es da auch die Funktion high()? Also "high(Liste: TStrings): Integer"

Und danke für die Hilfe, Thomas


beastofchaos - Sa 14.05.11 17:17

So, ich habe mal meinen Quelltext entsprechend verändert. Jetzt gibts anscheinend iwo Probleme. Erst kommt eine Fehlermeldung und dann zeigt er mir die Zeile "Application.CreateForm(TEditorForm, EditorForm);" an...

Hier ein Bild, darüber seht ihr den entsprechenden Quelltext, wenn ihr Fragen zu dem habt( weil DA anscheinend der Fehler ist), fragt mich.

Grüße

edit: Insbesondere vermute ich den Fehler in der For-Schleife nach "FindFiles", in der die Länge des arrays FBackgroundStream (dynamisches vom Typ HSTREAM) um eins erhöht wird und die Musik geladen wird.
Hier mal auch n Testergebnis von mir dazu: Wenn man von der Zeile "SoundNames.Create" bis zum Ende("BASS_Channelplay....") als Kommentar markiert, funktioniert alles (ohne Sound halt). Wenn ich nur SoundNames.Create oder alles außer dieser Zeile als Kommentar markiere, kommt wieder die Meldung :/ Liegt wohl eher an meiner Unwissenheit mit TStrings. Suche Hilfe :P


jaenicke - Sa 14.05.11 17:18

user profile iconbeastofchaos hat folgendes geschrieben Zum zitierten Posting springen:
Müsste bei aResult nicht ein "var" davor, damit das dann auch auf die genannte Variable übvertragen werden kann?
Nein, das ist ein Objekt, wird also ohnehin als Referenz übergeben. Ein var wäre doppelt gemoppelt.

user profile iconbeastofchaos hat folgendes geschrieben Zum zitierten Posting springen:
Gibt es da auch die Funktion high()? Also "high(Liste: TStrings): Integer"
Nein, es ist ein Objekt.

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
private
  FMyList: TStringList;
...
// FormCreate
FMyList := TStringList.Create;
...
// Find
FindFiles(..., FMyList);
...
// Anzahl
FMyList.Count
...
// FormDestroy
FreeAndNil(FMyList);
// EDIT:
Schau dir einmal die Grundlagen bei der Arbeit mit Objekten an. Wie wird das erzeugt...?

Hatten wir nicht das Thema schon in einem deiner anderen Threads? :gruebel:


beastofchaos - Sa 14.05.11 17:34

Jep, hab auch schon den Befehl über "Delphi Basics" herausgefunden und ja, das haben wir ;)

Dachte gerade, dass "SoundNames.Create" falsch ist und habe es auf "SoundNames := TStrings.Create" abgeändert.
Jetzt kommt eine andere Fehlermeldung "EAbstractError" statt wie vorher(siehe Bild) "EAccessViolation". Wieso? :(

edit: Verstanden, liegt wohl daran, dass TStrings eine Basisklasse ist und man am eine untergeordnete nimmt(TStringList). Man ich muss das mal lernen xD


jaenicke - Sa 14.05.11 17:37

user profile iconbeastofchaos hat folgendes geschrieben Zum zitierten Posting springen:
Dachte gerade, dass "SoundNames.Create" falsch ist und habe es auf "SoundNames := TStrings.Create" abgeändert.
Jetzt kommt eine andere Fehlermeldung "EAbstractError" statt wie vorher(siehe Bild) "EAccessViolation". Wieso? :(
Vergleich einmal mit meinem Quelltext. ;-)

TStrings ist nur die Basisklasse für verschiedene Implementierungen einer Liste von Strings. Zum Beispiel für TStringList. Die Methoden sind dort aber noch nicht definiert, nur deklariert. Eben als abstrakte Methoden. Abstrakt im Sinne von "da gibts ne Methode mit diesen Parametern, aber man weiß noch nicht was der Code darin machen wird".

TStringList implementiert diese Methoden dann, damit du sie nutzen kannst. Deshalb musst du TStringList benutzen.


beastofchaos - Sa 14.05.11 17:46

Jep, hab ich auch schon inzwischen :) (siehe "Edit" von vorherigen Beitrag)

Nun hab ich mal getestet, wo es noch Probleme geben könnte(immer noch Fehlermeldung) - also lass ich mir mal einfach mit ShowMessage die Größe(Count) von meiner TStringList ausgeben... Sie ist 0, dabei liegen in dem Ordner zwei Lieder (mp3). Iwie will FindFiles die nciht finden, ist mein Schema vll falsch?


Delphi-Quelltext
1:
FindFiles(path + 'Sounds/Background''.mp3', False, SoundNames);                    


Grüße

edit: JA, ein * vor ".mp3" ... Sorry