قائمة التشغيل لمشغل الموسيقى في دلفي قائمة / من عناصر البيانات متعددة
سؤال
وأود أن يكون التشغيل لبلدي مشغل الموسيقى في دلفي / باسكال.
واعتقدت أنه سيكون أفضل حل لديك TStringList مع مسار ملف MP3 و- بالإضافة إلى ذلك - وهو TListBox مع أسماء أغنية. يجب أن يكون سلاسل متطابقة في كلا القائمتين في نفس الموقف. إذا كان الأمر كذلك يختار المستخدم البند 5 في TListBox يمكنني فقط أن تأخذ الطريق في موقف 5 في TStringList.
وهذا يعمل بشكل جيد.
ولكن الآن انا بحاجة الى قائمة التشغيل مع عمودين: "الفنان" و "عنوان الأغنية". يجب أن تكون قادرة على فرز قائمة التشغيل عن طريق الفنان (تصاعدي وتنازلي) فضلا عن عنوان الأغنية (تصاعدي وتنازلي) - حسب الترتيب الأبجدي، وبطبيعة الحال
وكيف يمكن أن أفعل هذا؟ وجود كائنين من TStringList - فرز واحد للفنان وفرزها واحدا تلو عنوان الأغنية
المحلول
ولقد فعلت عدد قليل من هذه "القوائم" مع مرور الوقت، وفي النهاية وجدتها دائما جعل الطبقات بدلا سهلا، ولكن تخزين وخصوصا قراءة القوائم من القرص أثبت "تحدي" على أقل تقدير.
لقد كان التحدي في الحالات كانوا مستخدمين التعامل مع الواقع القوائم مع المحررين الخارجي، مما يجعل قراءة القوائم عرضة للخطأ.
لشكل قائمة التشغيل المقبولة عالميا (M3U) إلقاء نظرة على HTTP: // schworak. كوم / البرمجة / موسيقى / playlist_m3u.asp .
ومكون VCL مع المصدر الذي يقرأ صيغ متعددة متاح في يسمى "v.0.5.1 التشغيل" توري ل. http://www.torry.net/quicksearchd. بى؟ سلسلة = التشغيل + v.0.5.1 وعنوان = نعم
نصائح أخرى
وأود أن تفعل فئة TSong التي تحتوي على ما لا يقل عن الفنان وعنوان الخصائص، وTSongList توفير 1 أو أكثر من أساليب نوع (يمكن أن تكون عامة) باستخدام هذا النوع السليم الميدان (ق.
بالتأكيد ليس الحفاظ على 2 StringLists منفصلة أن لديك لإدارة، والحفاظ على وفاق وتعديل وزاري عندما يكون الترتيب ...
واحد سيلة رخيصة لتنفيذ كيندا ذلك، يمكن أن يكون لديك في الذاكرة مجموعة البيانات مع سجل يحتوي على الفنان ومسار عرض في الشبكة التي يمكنك الفرز على أعمدة مختلفة.
سوف الصف الحالي تعطي كلا المعلومات مباشرة.
وحل واحد بسيط هو تنفيذ لائحة أغنية / معلومات الأغنية ك TCollection.
وباستخدام المجموعات يمكنك ترك VCL التعامل مع التحميل وإنقاذ إلى القرص.
وعلى سبيل المثال:
تجدر الإشارة هذه ليست كاملة وظيفيا، سأترك هذا متروك لكم، ومنذ أن كتبت هذا من أعلى رأسي أنني قد يكون شيئا عابث. أنها ليست سوى مثال للحصول على انك بدأته.
{...}
interface
Type
TSongCollectionItem = class(TCollectionItem)
public
constructor create(Owner:TCollection); override;
procedure assign(source : TPersistent); override;
published
property FileName : String read fFileName Write fFileName;
property Artist : string read fArtist write fArtist;
property Title : string read fTitle write fTitle;
{...}
property Album : string read fAlbum write fAlbum;
end;
TSongCollection = class(TOwnedCollection)
private
function GetItem(Index: Integer): TSongCollectionItem;
procedure SetItem(Index: Integer; Value: TSongCollectionItem);
public
constructor Create(AOwner: TPersistent);
function Add: TSongCollectionItem;
property Songs[Index: Integer]: TSongCollectionItem read GetItem write SetItem; default;
end;
procedure SaveSongList(Songs : TSongCollection; FileName:string; Binary:boolean);
procedure LoadSongList(Songs : TSongCollection; FileName:string; Binary:boolean);
{...}
implementation
{...}
type
TSongComponent = class(TComponent)
published
property SongList : TSongCollection read fsonglist write SetSongList;
end;
procedure SaveSongList(Songs : TSongCollection; FileName:string; Binary:boolean);
var
wFile : TFileStream;
wConvert : TMemoryStream;
wSongList : TSongComponent;
begin
RegisterClass(TSongComponent);
Try
wConvert := TMemoryStream.Create;
wFile := TFileStream.Create(filename, fmcreate);
wSongList := TSongComponent.create(nil);
try
wSongList.SongList.Assign(Songs);
if not Binary then
begin
wConvert.WriteComponent(wSongList);
wConvert.Position := 0;
ObjectBinaryToText(wConvert, wFile);
end
else
wFile.WriteComponent(wSongList);
finally
wConvert.Free;
wFile.Free;
wSongList.free;
end;
finally
Unregisterclass(TSongComponent);
end;
end;
procedure LoadSongList(Songs : TSongCollection; FileName:string; Binary:boolean);
var
wFile : TFileStream;
wConvert : TMemoryStream;
wSongList : TSongComponent;
begin
RegisterClass(TSongComponent);
Try
wConvert := TMemoryStream.Create;
wFile := TFileStream.Create(filename, fmOpenRead);
try
if not Binary then
begin
ObjectTextToBinary(wFile, wConvert);
wConvert.Position := 0;
wSongList := TSongComponent(wConvert.ReadComponent(Nil));
end
else
wSongList := TSongComponent(wFile.ReadComponent(Nil));
if assigned(Songs) and assigned(wSongList) then
Songs.Assign(wSongList.Songs);
if assigned(wSongList) then
wSongList.free;
finally
wConvert.Free;
wFile.Free;
end;
finally
Unregisterclass(TSongComponent);
end;
end;
إذا كنت لا ترغب في بناء بنية الكائن العمومي، يمكنك استخدام لل Allways هيكل TlistView في وضع التقرير. لديك هناك قائمة، مع البنود الفرعية. يمكنك فرز بواسطة عمود، وحفظ لCSV أو أي شكل. يمكنك بسهولة إضافة الرموز الخ ....
وكان لديك أحداث المناسبة لالزناد.