Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   StringList weiter reichen zur Eigentliche Klasse (https://www.delphipraxis.net/102542-stringlist-weiter-reichen-zur-eigentliche-klasse.html)

mimi 30. Okt 2007 17:43


StringList weiter reichen zur Eigentliche Klasse
 
Hallo,
ich möchte gerne wie im Titel schon beschrieben steht eine TStringList weiter reichen.

Am Anfang wird eine Variable aus der Haupt Klasse(TPlayListManger) mit einer ListBox1.Items
verbunden.

Jetzt Lade ich eine Datei und sie wird auch in der ListBox angezeigt.

Nun Möchte ich von einem Button Klick den Inhalt der Variable aus Klasse(TPlayListManger) anzeigen lassen.
Aber sie ist leer warum ?

Hier mal mein Soruce Code. Ich sehe einfach keinen Fehler. Oder verstehe ich das mit den Pointern falsch ?
Delphi-Quellcode:
TPlaylistenManger = class
    fOnAddPlayListe: TOnAddPlayliste;
    fOnGetPlayListeItem:TOnGetPlaylisteItem;
  private
    procedure InitPlaylist(const aFileName:String; var aPlayliste:TPlaylistBase);
  protected

  public
    _ext:string;
    FileName:String;
    PlayListItems:TStrings;
    OhneExt:Boolean;
    Playliste:TPlaylistBase;

    constructor Create;
    destructor Destroy;

....

procedure TPlaylistenManger.InitPlaylist(const aFileName: String;
  var aPlayliste: TPlaylistBase);
var
  ext:String;
begin
  ext:=UpperCase(ExtractFileExt(aFileName));
  if ext = '.M3U' then aPlayliste:=TPlayListM3U.Create;
//  if ext = 'PLS' then aPlayliste:=TPlayList.Create;
end;

// Hier lade ich eine M3U Datei
procedure TPlaylistenManger.LoadFromFile(const aFileName: String = '');
var
  i:integer;
begin
  InitPlaylist(ExtractFileName(aFileName),Playliste);

  Playliste.OhneExt:=OhneExt;
  Playliste.PlayListItems:=PlayListItems;
  Playliste.LoadFromFile(aFileName);

//  PlayListItems.Assign(Playliste.PlayListItems);

  _ext:=Playliste.ext;

end;    

procedure TPlayListM3U.LoadFromFile(const aFileName: String);
var
  tmp:TStrings;
  i,m:Integer;
  str:String;
  Item:TInfo;
begin
  tmp:=TStringList.Create;
  with tmp do begin
    LoadFromFile(aFileName); m:=0;
    if UpperCase(Strings[0]) = '#EXTM3U' then begin
      m:=1;
      ext:='#EXTM3U';
    end
    else
      ext:='';
   
    i:=m;
    while i <= Count-1 do begin
      str:=strings[i]; Item:=TInfo.Create;

      if (str <> '') and (str[1] = '#') then begin
        Item.Kometar:=str;
        Item.FileName:=strings[i+1];
        if OhneExt then
          PlayListItems.AddObject(SplitStr(ExtractFileName(Item.FileName),'.'),Item)
        else
          PlayListItems.AddObject(ExtractFileName(Item.FileName),Item);

        inc(i,2);
      end
      else begin
        if (str <> '') and (str[1] <> '#') then begin
          Item.Kometar:='';
          Item.FileName:=strings[i];
          if OhneExt then
            PlayListItems.AddObject(SplitStr(ExtractFileName(Item.FileName),'.'),Item)
          else
            PlayListItems.AddObject(ExtractFileName(Item.FileName),Item);

          inc(i);
        end;
      end;
    end; // for i:=0
  end; // tmp
  tmp.free;
end;
Ich hoffe da steigt einer von euch durch. Im Prinzip ist das ein ganz einfacher Weg. Aber irgendwo in diesen Methoden muss ein Fehler sein.

... Vielen Dank schonmal für eure Hilfe ....

Edit00: In dieser Version, werden alle Daten angezeigt. Nur wenn ich in einem Button von From1 jetzt die alle Items anzeigen möchte, steht in der StringList:
PlayListeManger.PlayListItems.Text
nix drin.
obwohl PlayListeManger Global Definiert ist.
Delphi-Quellcode:
procedure TForm1.FormCreate(Sender: TObject);
begin
  PlayListeManger:=TPlaylistenManger.Create;
  PlayListeManger.PlayListItems:=ListBox1.Items;
  PlayListeManger.LoadFromFile('/media/hda7/Daten/music/entspannung.m3u');
//  :=;

end;

Muetze1 30. Okt 2007 17:54

Re: StringList weiter reichen zur Eigentliche Klasse
 
Im LoadFromFile() übernimmst du die Instanz der TStrings-Instanz von einem anderen Control anstatt dir in deinem PLaylistmanager selber eine im Constructor anzulegen (im Destructor freizugeben) und über eine Property zu veröffentlichen. Dabei im Setter die Assign() Methode nutzen, um deine Instanz zu schützen.

mimi 30. Okt 2007 18:31

Re: StringList weiter reichen zur Eigentliche Klasse
 
ich kann die leider nicht so ganz folgen......

per Assign() habe ich das auch schon versucht....

Muetze1 30. Okt 2007 19:38

Re: StringList weiter reichen zur Eigentliche Klasse
 
Delphi-Quellcode:
type
  TPlaylistenManager = class
  private
    fPlayListItems: TStrings;

    procedure SetPlaylistItems(const AValue: TStrings);

  public
    constructor Create;
    destructor Destroy; override;  // <--- override vergessen!!!

    property PlaylistItems: TStrings read fPlaylistItems write SetPlaylistItems;
  end;

...

constructor TPlaylistenManager.Create;
begin
  inherited;

  fPlaylistItems := TStringList.Create;
end;

destructor TPlaylistenManager.Destroy;
begin
  fPlaylistItems.Free;
 
  inherited;
end;

procedure TPlaylistenManager.SetPlaylistItems(const AValue: TStrings);
begin
  fPlaylistItems.Assign(AValue);  // <<-- damit du dir nicht deine eigene Instanz von aussen überschreiben lässt!!
end;

mimi 30. Okt 2007 22:03

Re: StringList weiter reichen zur Eigentliche Klasse
 
VIELEN DANK für den code,
doch leider wird jetzt die Playliste nicht mehr in der ListBox Angezeigt.

Ich habe deinen Code genau so übernommen, wie du ihn vorgeschlagen hast.

Dafür kann ich jetzt von ausen auf PlayListItems
zugreifen. Ich wollte eigentlich die Listbox mit der Eigenschaft: PlayListItems verbinden. so das sie gleich bedeutet sind.

Muetze1 30. Okt 2007 22:12

Re: StringList weiter reichen zur Eigentliche Klasse
 
Warum weist du nicht nach dem Laden einfach deine Playlistitems wieder der Listbox.items zu? Damit aktualisierst du diese. Man sollte eh Oberfläche und Daten trennen und genau das haben wir dann entsprechend getan.

mimi 30. Okt 2007 22:30

Re: StringList weiter reichen zur Eigentliche Klasse
 
naja, ich wollte die Listbox1.items nur einmal zuweisen und nicht nach jeder Änderung.

Das müsste doch gehen oder nicht ?

Ich möchte das PlaylistItems von der PlaylistManger Classe nur auf Listbox1.Items zeigt.
und wenn ich intern auf PlaylistItem zugreife z.b. um ein Eintrag auszugeben, dann müsste ich doch eigentlich ListBox1.Items ansprechenden oder nicht ?

Wenn das nicht geht, müsste ich ein Event dazu packen, dann währe das aber mehr Aufwand .

Ich wollte die Verwendung so einfach wie nur möglich machen.

Muetze1 30. Okt 2007 23:28

Re: StringList weiter reichen zur Eigentliche Klasse
 
Nein, wenn du es wirklich so machen willst, dann war dein erster Code genau der richtige. Beachte dabei aber, dass du mit der Klasse nicht mehr auf die Instanz zugreifst, wenn die Listbox nicht mehr existiert etc.

mimi 30. Okt 2007 23:33

Re: StringList weiter reichen zur Eigentliche Klasse
 
Genau dieser Code geht ja nicht.
Im Prinzip möchte ich ein mischmasch von deinem code und meinem.

Ich möchte auf PlaylistItems von der Klasse TPlaylistManger zugreifen können und von der Listbox aus.

und das geht mit meinem Code leider nicht. und ich weiß nicht warum.

jedes mal wenn ich versuche nach dem Laden auf PlaylistItems zuzugreifen ist die liste leer. Was aber gar nicht sein dürfte, da sie ja mit der von der Listbox verbunden ist.

Muetze1 31. Okt 2007 01:11

Re: StringList weiter reichen zur Eigentliche Klasse
 
Zitat:

Zitat von mimi
jedes mal wenn ich versuche nach dem Laden auf PlaylistItems zuzugreifen ist die liste leer. Was aber gar nicht sein dürfte, da sie ja mit der von der Listbox verbunden ist.

Zuweisen tust du die Listbox.Items in der Klasse TPlaylistenManager. Laden tust du wiederrum in der Klasse TPlayListM3U. Deren Implementation und Zuweisungen bzw. wovon sie abgeleitet ist, wurde nicht geklärt...

Und korrigiere das schon vorhin von mir im Code angesprochene Override beim Destruktor!

mimi 31. Okt 2007 10:01

Re: StringList weiter reichen zur Eigentliche Klasse
 
das mit Override habe ich schon.
Du meinst es könnte damit was zu tun habe, da nirgend geklärt ist das es sich um eine TStringList handelt ?
sondern "nur" um eine TStrings ?

Aber auch als das klar war, hat es nicht geklappt.

Ich habe im Create ja schonmal gesagt, das es sich um eine TStringList handelt und alle Items manuel per addObject hinzugefügt, klappte aber auch nicht.

mimi 31. Okt 2007 10:40

Re: StringList weiter reichen zur Eigentliche Klasse
 
wenn ich das so habe:
Delphi-Quellcode:
procedure TPlaylistenManger.SetPlaylistItems(const AValue: TStrings);
begin
  //fPlaylistItems.Assign(AValue);
  fPlaylistItems:=TStringList(AValue);
end;

procedure TPlaylistenManger.LoadFromFile(const aFileName: String = '');
var
  i:integer;
begin
  InitPlaylist(ExtractFileName(aFileName),Playliste);

  Playliste.OhneExt:=OhneExt;
  Playliste.PlayListItems:=TStringlist(PlayListItems);
  Playliste.LoadFromFile(aFileName);
  writeln(PlayListItems.text);

//  PlayListItems.Assign(Playliste.PlayListItems);

  _ext:=Playliste.ext;

end;
sehe ich was in der Listbox und die Writeln Meldung wird ausgeben.
Das Problem jedoch sobald ich versuche von einer anderen Procedure aus auf PlayListItems.Text zuzugreifen, ist diese Leer. Aber genau das ist gerade für mein vorhaben wichtig. Das das nicht so ist.

Muetze1 31. Okt 2007 13:45

Re: StringList weiter reichen zur Eigentliche Klasse
 
Nein, TStrings reicht. Der Typecast ist unsinnig und braucht nicht getan werden im Constructor sowie im LoadFromFile().

Meine Frage zu dem Code: Was ist "Playliste" für ein Typ und was macht er mit PlayListItems?

mimi 31. Okt 2007 13:59

Re: StringList weiter reichen zur Eigentliche Klasse
 
Ich habe mir das so gedacht:
Ich verbinde die TStrings von der Playlistmanger klasse z.b. mit der Listbox.Items.

Jetzt lade ich eine Playliste - meiner wahl z.b. eine m3u(später sollen noch mehr folgen),
anhand der Datei Endung wird der Playlisten Typ in der Procedure InitPlaylist Ermittelt und gesetzt.

In der TPlayListM3U.LoadFromFile soll PlayListenItems(von typ TStrings) gefült werden.
dazu wird er von TPlaylistenManger.LoadFromFile gesetzt.

Playliste ist von typ TPlaylistBase das kann im Moment nur eine TPlayListM3U sein.

Alle Playlisten müssen von TPlaylistBase abgeleitet werden.

TPlaylistBase stellt im wesentlichen zwei Methoden zuverfügung: Laden und Speichern.

Ich kann mir den Fehler immer noch nicht Erklären. Gut den Typ Cast mache ich wieder weg.

Muetze1 31. Okt 2007 14:05

Re: StringList weiter reichen zur Eigentliche Klasse
 
So sehe ich auch erstmal keinen Fehler. Grundlegend: Kannst du den Code zippen (der reine Playlistenteil, also Manager + BasePlaylist + M3U Ableitung reicht ja) und hier mal anhängen? Ich würde dann mal reinschauen. Wir haben ja heute Feiertag...

mimi 31. Okt 2007 14:15

Re: StringList weiter reichen zur Eigentliche Klasse
 
Liste der Anhänge anzeigen (Anzahl: 1)
ja ! ist kein Problem, ist aber ein Lazarus Projekt.
Aber ich nutzte allgemeine Sachen.
du müsstest nur eine eigene Oberfläche Bauen

Vielen Dank für deine Hilfe. Ich hoffe du findest den Fehler.

Also dir ist klar, was ich möchte ? Aber im Prinzip müsste es doch so gehen oder nicht ?
(habe die Typcast noch nicht entfernt)

Muetze1 31. Okt 2007 14:58

Re: StringList weiter reichen zur Eigentliche Klasse
 
Liste der Anhänge anzeigen (Anzahl: 1)
Ok, es lag nur daran, dass du im Manager noch ein Assign() anstatt der Zuweisung drinne hattest.

Folgende Punkte:

1. Denk dran, dass du alle Instanzen von TInfo die du angelegt hast auch selber wieder freigeben musst. Die Listbox kümmert sich nicht darum!
2. Ich habe "Kommentar" mal verbessert - nur mal so nebenbei
3. Warum ist der Parameter Filename bei LoadFromFile() optional? Ich brauch die Methode Loadfromfile nicht aufrufen, wenn ich keinen Dateinamen habe. Beim speichern sehe ich dass ein: keine Angabe heisst: Speicher unter original geladenem Namen. Aber beim Laden? Ich habe das mal abgeändert.
4. Der Destruktor ist schon virtuell (muss er auch sein), somit zerschiesst du die gesamte Kette der Aufrufe mit der Deklaration eines virtuellen Destruktors in deiner Basisplaylistklasse. Ich habe es abgeändert.
5. Warum definierst und implementierst du Constructoren und Destructoren, wenn sie keinen Code beinhalten? Dies ist nicht nötig und macht den Code nur grösser und damit unleserlicher.
6. Ich habe ein paar Resourcen-Schutzblöcke eingefügt (try/finally), damit die temporären Instanzen auch im Falle eines Fehlers (Exception) wieder ordentlich freigegeben werden.
7. Alles was du direkt nach "class" deklarierst, ist public (oder sogar published). Damit ist es öffentlich einseh- und zugreifbar. (TPlaylistenManager)
8. Beim setzen einer neuen Instanz für die PlaylistenItems (also einer anderen Listbox o.ä.), muss diese Änderung mit durchgereicht werden, so dass die eigentliche Playlist auch die richtige Instanz hat. (siehe SetPlaylistItems())
9. Was macht InitPlaylist() wenn er die Endung nicht kennt? Die Variable wird nicht initialisiert und somit weisst du nicht, ob du eine gültige Instanz in fPlayliste hast nach dem Aufruf oder nicht.
10. TPlaylistenManager.SaveToFile() ruft InitPlaylist() auf, damit erstellst du eine neue Instanz und überschreibst die vorhandene Instanz in fPlayliste

Korrigierte Version im Anhang.

mimi 31. Okt 2007 15:30

Re: StringList weiter reichen zur Eigentliche Klasse
 
Zu 1: Danke ! Irgendwie dachte ich das würde TStrings auto. tuen bei der Freigabe.
Zu 2: Danke !
Zitat:

Warum ist der Parameter Filename bei LoadFromFile() optional? Ich brauch die Methode Loadfromfile nicht aufrufen
Wenn im Playlisten Manger der Parameter FileName schon mit einem namen belegt ist, kann dieser Auto. genommen werden bei LoadFromFile, wenn der nicht genommen werden soll, muss man im LoadFromFile einen Parameter eingeben

zu 4:
Wenn du das bei der PlaylistBase meinst, ja, weil er soll ja was machen, und es soll überschrieben werden können, wenn es nötig ist.

zu 5: Als Vorbereitung, es kann ja sein, das ich später dort Variablen Definieren möchte.
zu 6: Danke.
zu 7: Ich weiß, aber das ist auch published sein kann, ist mir neu.

Vielen Dank, für deine Mühe, ich glaube das ist das erste mal seit dem ich hier im Forum bin das jemand meinen Soruce-Code zu genau unter die Lupe nimmt.

Das ist ein Teil von http://www.delphipraxis.net/internal...t.php?t=119063,
ich werde dich auf jeden Fall erwähnen.

Zitat:

// FileName:=''; // alle member sind automatisch 0, 0.0, false bzw. ''
dazu gibt es hier einen schönen Thread:
http://www.lazarusforum.de/viewtopic.php?t=1022

also nach einen ersten test geht es immer noch nicht so wie ich es wollte.

Wenn ich von ausen auf writeln(PlayListeManger.PlayListItems.Text);
zugreife ist diese Eigenschaft leer. In der Listbox sehe ich aber Einträge.

mimi 31. Okt 2007 15:33

Re: StringList weiter reichen zur Eigentliche Klasse
 
PlayListeManger ist im TFrom1 Definiert

Muetze1 31. Okt 2007 16:16

Re: StringList weiter reichen zur Eigentliche Klasse
 
Zitat:

Zitat von mimi
Zu 1: Danke ! Irgendwie dachte ich das würde TStrings auto. tuen bei der Freigabe.

Ja, hatte ich vermutet. Dies ist aber nicht der Fall, da die TStrings nichtmal wissen, ob da wirklich eine Instanz hinterlegt ist oder der Programmierer nicht vllt. einfach nur einen Integer reinpackt.

Zitat:

Zitat von mimi
Wenn im Playlisten Manger der Parameter FileName schon mit einem namen belegt ist, kann dieser Auto. genommen werden bei LoadFromFile, wenn der nicht genommen werden soll, muss man im LoadFromFile einen Parameter eingeben

Ok, das widerspricht ja nicht meiner Anpassung, schliesslich kann der Manager schauen ob sein Aufruf mit '' war und entsprechend den internen Filename weiterreichen zu der Playlist Instanz.

Zitat:

Zitat von mimi
Wenn du das bei der PlaylistBase meinst, ja, weil er soll ja was machen, und es soll überschrieben werden können, wenn es nötig ist.

Kannst du doch. Wenn du sowas schreibst:
Delphi-Quellcode:
type
type
  TMyClass = class
  end;
ist dies das gleiche wie
Delphi-Quellcode:
type
  TMyClass = class(TObject)
  end;
Das erste ist nur eine Kurzform. Du leitest immer (sofern du nichts anderes angibst) von TObject ab. Somit erbst du automatisch den als virtuell deklarierten Destructor von TObject. Du hast somit schon einen als virtuell deklarierten Destruktor.

Wenn du nun in TPlaylistBase deinen Destruktor definierst und virtual; dahinter vermerkst, dann führst du einen neuen Destruktor ein mit dem gleichen Namen und verdeckst den von TObject. Dadurch wird aber jeder Destructor-Aufruf der bei dem TObject.Destroy ankommt nicht mehr an dich weiter geleitet. Free, FreeAndNil() etc. rufen immer den Destruktor vom Typ TObject auf und somit wird deiner niemals aufgerufen. Und damit in abgeleiteten Klassen trotzdem immernoch der Destruktor aufgerufen wird, muss dieser virtuell sein und in nachfolgenden Klassen überschrieben werden. Somit: Nimm das virtual weg!

Zitat:

Zitat von mimi
zu 7: Ich weiß, aber das ist auch published sein kann, ist mir neu.

Sie bei den Formularen: Füge eine Komponente ein. Sie wird direkt unter dem class eingefügt und ist aber von einer anderen Unit aus zugreifbar. Diese Elemente sind mindestens public, mMn aber sogar published (wegen dem Streaming zum wiederfinden der Komponenten beim Streaming).

Zitat:

Zitat von mimi
also nach einen ersten test geht es immer noch nicht so wie ich es wollte.

Ich habe ehrlich gesagt nur so über den Quellcode geschaut und geändert. Da das Assign() so offensichtlich war, habe ich nicht weiter geschaut.

Aber zu deinem Problem: Du rufst InitPlaylist() o.ä. im Manager auch vor dem Speichern auf. Dadurch legst du eine neue Instanz an. Rufst du vllt. das Speichern auf?

Ich schaue nochmal in mein Project und teste explizit.

Muetze1 31. Okt 2007 16:39

Re: StringList weiter reichen zur Eigentliche Klasse
 
Liste der Anhänge anzeigen (Anzahl: 1)
So, habe das ganze getestet und klappt alles einwandfrei. Ich habe das komplette (Delphi) Projekt angehangen. Die Konsolenanwendung sollte sich leicht zu Lazarus umsetzen lassen. Zur Not kann ich das sonst auch noch machen.

Ich habe B'n'D noch mal schnell aus den M3U extendend info Einträgen die Spielzeit mit ausgelesen und gebe diese mit aus. Die Ausgabe des Programmes ist doppelt. Einmal die Ausgabe von deiner Laderoutine und einmal die von der Main Procedure im Projectfile (diese ist dann mit Spieldauer).

Die M3U muss als Parameter mitgegeben werden.

mimi 31. Okt 2007 16:58

Re: StringList weiter reichen zur Eigentliche Klasse
 
Zitat:

Ok, das widerspricht ja nicht meiner Anpassung, schliesslich kann der Manager schauen ob sein Aufruf mit '' war und entsprechend den internen Filename weiterreichen zu der Playlist Instanz.
Naja, ich wollte schon eine gewisse Freiheit haben, wenn man die Methode benutzt.

Zitat:

Aber zu deinem Problem: Du rufst InitPlaylist() o.ä. im Manager auch vor dem Speichern auf. Dadurch legst du eine neue Instanz an. Rufst du vllt. das Speichern auf?
Ja, weil ich auch die Möglichkeit haben wollte eine m3u Datei in eine pls Datei umzuwandeln.
und das geht meiner meinung nach nur so.

Ich habe mir in deinem Beispiel Projekt die dpr angeschaut, aber so habe ich mir das eigentlich nicht vorgestellt:
Delphi-Quellcode:
 lList := TStringList.Create;

  try



    PLM := TPlaylistenManger.Create;

    try

      PLM.PlaylistItems := lList;



      PLM.LoadFromFile(ParamStr(1));



    finally

      PLM.Free;

    end;
warum gibst du hier PLM wieder frei ? Ich möchte ihn ja später noch verwenden.
Trotzdem, vielen Dank für deine Hilfe.

Wie könnte ich mein Problem noch beschreiben, damit du es verstehst ?

Also nochmal:
Ich erstelle in meine From1.pas eine Variable von Typ TPlaylistenManger und die heißt PlayListeManger.

Beim erstellen von From1 also im OnCreate Event. verknüpfe ich die TStrings von ListBox1.items mit
"PlayListeManger.PlaylistItems" das das sie gleich sind.

Beim Laden wieder hole ich das im Prinzip wieder:
Dort verknüpfe ich bei der Angebenden Playliste.
Wenn ich jetzt bei TPlayListM3U auf PlaylistItems zugreife müsste ich doch jetzt eigentlich die Listbox1.Items ansprechen, oder nicht ?

und genau hier kommt es zu einem Fehler. Aber ich weiß nicht wo.

Ich könnte es nur mit einem Event lösen. Aber das finde ich blöd.. weil das mehr Aufwand bedeuten würde.

Edit: Wenn ich jetzt intern von einer anderen Procedure aus auf "PlayListeManger.PlayListItems
zugreife ist diese einfach leer. Die Listbox ist aber gefüllt. Sollte die "Verbindung" aufgehoben wurden sein ?

mimi 31. Okt 2007 17:04

Re: StringList weiter reichen zur Eigentliche Klasse
 
Das Seltsamme ist, so wird die richtige anzahl ausgeben.
Delphi-Quellcode:
procedure TForm1.FormCreate(Sender: TObject);
begin
  PlayListeManger:=TPlaylistenManger.Create;
  PlayListeManger.PlayListItems:=ListBox1.Items;
  PlayListeManger.LoadFromFile('/media/hda7/Daten/music/entspannung.m3u');
  writeln(PlayListeManger.PlaylistItems.Count);
end;

// So aber nicht wird nur 0 Ausgeben.
procedure TForm1.SpeedButton5Click(Sender: TObject);
begin
  writeln(PlayListeManger.PlaylistItems.Count);
end;
Die Listbox ist aber gefüllt.

Muetze1 31. Okt 2007 17:45

Re: StringList weiter reichen zur Eigentliche Klasse
 
Zitat:

Zitat von mimi
Ja, weil ich auch die Möglichkeit haben wollte eine m3u Datei in eine pls Datei umzuwandeln.
und das geht meiner meinung nach nur so.

Aber damit überschreibst du dir die in fPlaylist vorhandene Instanz. Diese geht verloren (existiert immernoch, nur du kannst nirgendwo mehr drauf zugreifen). Die neue Instanz ist dann wieder komplett ohne Infos, Einstellungen, etc.

Und es geht noch anders. Du kannst dir, um in einem anderen Playlistenformat zu exportieren, dir einfach in der Playlisten-Basisklasse eine Methode bauen, welche die Titelinformationen aus einer anderen Playlisten-Basisklasse übernimmt. Somit sieht dein Export im Playlistenmanager so aus: (Pseudocode):

Code:
Export(AFileName, AType)
var
  lExportPlaylist: TBasePLaylist;
begin
  lExportPlaylist := CreatePlaylist(AType);
  try
    lExportPlaylist.ÜbernehmeTitel( fPlaylist );

    lExportPlaylist.SaveToFile( AFilename );
  finally
    lExportPlaylist.Free;
  end;
end;
Zitat:

Zitat von mimi
warum gibst du hier PLM wieder frei ? Ich möchte ihn ja später noch verwenden.

Das ist die Hauptprocedure des Programmes. Dort erstelle ich den PLM, nutze ihn (in dem ich die Playlist lade & ausgebe) und danach gebe ich ihn wieder frei, da am Ende dieser Procedure auch das Programm zu Ende ist. Dabei ist es doch völligst unerheblich wie du das implementieren möchtest. Du kannst doch genauso das anlegen des PLM im OnCreate machen, das Laden im OnClick und das freigeben im OnDestroy. Wo sollte dort der Unterschied liegen?

Zitat:

Zitat von mimi
Dort verknüpfe ich bei der Angebenden Playliste.

Der PLM hat dann schon die angebene Instanz von der Listbox. Warum reicht er diese nicht einfach nur weiter an die Playlistinstanz die er selber anlegt?

Zitat:

Zitat von mimi
Wenn ich jetzt bei TPlayListM3U auf PlaylistItems zugreife müsste ich doch jetzt eigentlich die Listbox1.Items ansprechen, oder nicht ?

Ja, so lange es immernoch die selbe/gleiche Instanz ist. Wenn du zwischendurch (also zwischen der ersten Zuweisung des TStrings Objektes und dem jetzigen Zugriff z.B. wieder InitPlaylist() aufrufst, dann ist es eine andere Instanz - und die hat dann nicht mehr die TStrings Instanz sondern nil. Da es eine komplett andere Instanz ist.

Zitat:

Zitat von mimi
und genau hier kommt es zu einem Fehler. Aber ich weiß nicht wo.

Debuggen! Der Debugger von Lazarus ist sehr gut nutzbar und hilfreich. Auch ein Breakpoint in der SetPlaylistItems des PLM etc würde vllt. zu mehr Erkenntnissen führen, weil dieser vllt. öfters und vllt. mit anderen Instanzen aufgerufen wird.

Zitat:

Zitat von mimi
Die Listbox ist aber gefüllt.

Dann hast du immernoch irgendwo ein unnötige TStringList.Create drin und/oder weist der TPLaylistM3U Instanz eine andere Instanz zu, als die, welcher der PDM in fPlaylistItems hat.

mimi 31. Okt 2007 18:36

Re: StringList weiter reichen zur Eigentliche Klasse
 
um umwandeln: Nein, dein code ist mir zu aufwendig.
da gebe ich lieber Playliste beim Speichern einfach wieder frei, wenn es belegt.

Ich habe den Code mehrfach geprüft und konnte keinen Fehler Feststellen.

Naja, evlt. finde ich den Fehler noch.

mimi 31. Okt 2007 18:47

Re: StringList weiter reichen zur Eigentliche Klasse
 
Wenn ich das was ich bei onCreate im From1 drin stehen habe, in einem Button Verschiebe und klicke dann geht das alles wie ich es mir Vorgestellt habe.

Aber wie kann das angehen ?

mimi 31. Okt 2007 18:52

Re: StringList weiter reichen zur Eigentliche Klasse
 
Wenn ich das so habe, wird das Memo gefüllt:
Delphi-Quellcode:
procedure TForm1.FormCreate(Sender: TObject);
begin
  PlayListeManger:=TPlaylistenManger.Create;
  PlayListeManger.PlayListItems:=ListBox1.Items;
end;
und nicht die Listbox. Ich denke das es sich hierbei um einen Lazarus BUG handeln muss.

Ich glaube ich sollte die Frage noch mal im Lazarus-Forum stellen.

Vielen Dank, für deine Mühevolle Hilfe.

Muetze1 31. Okt 2007 19:01

Re: StringList weiter reichen zur Eigentliche Klasse
 
1. Es gibt da oben rechts bei deinen Einträgen einen recht nützlichen "EDIT" Button.

2.
Zitat:

Zitat von mimi
um umwandeln: Nein, dein code ist mir zu aufwendig.

Was ist daran aufwendig? Vor allem ist es OOP!

3.
Zitat:

Zitat von mimi
Wenn ich das so habe, wird das Memo gefüllt und nicht die Listbox. Ich denke das es sich hierbei um einen Lazarus BUG handeln muss.

Es ist definitv kein BUG von Lazarus sondern recht eindeutig ein Bug von dir. Du weist irgendwo der Instanz die Items auf die Lines Eigenschaft des Memos selber zu. Lazarus denkt sich das nicht aus und es mehr ein fast unmöglicher Zufall, dass es die Lines Eigenschaft des Memos anstatt der Listbox ist. Und ich glaube nicht an Zufälle - und ich kann dir versichern, dass dies auch keiner ist.

mimi 1. Nov 2007 11:23

Re: StringList weiter reichen zur Eigentliche Klasse
 
Liste der Anhänge anzeigen (Anzahl: 1)
Zitat:

Du weist irgendwo der Instanz die Items auf die Lines Eigenschaft des Memos selber zu
Nein das tue ich mit 100%iger Sicherheit nirgends, warum auch ?

Da du dich anscheind mit Lazarus auskennst, habe ich mal das gesammte Projekt Angehangen

ich glaube ja auch das es mein Fehler ist, aber so langsam glaube ich das liegt gar nicht an mir. Nach dem was ich gestern gesehen habe. Ich verwende Memo1 nur einmal und das ist beim Klicken. auf die Listbox.

zu1: ist mir bekannt.....

edit:
Delphi-Quellcode:
procedure TForm1.FormCreate(Sender: TObject);
begin
  PlayListeManger:=TPlaylistenManger.Create;
  PlayListeManger.PlayListItems:=Memo1.Lines;
end;
Wenn ich das Memo1 direkt zuweise, hängt sich das Programm beim ausführen auf.
Ich vermute es liegt ein Pointer Problem vor, was direkt oder indirekt mit Lazarus zu tun hat.
Evlt. werde ich es mal unter Delphi testet, wie es sich dort verhält. Wenn es da klappt, dann ist es doch beweisen, das es ein Lazarus Problem ist oder ?

Muetze1 1. Nov 2007 11:53

Re: StringList weiter reichen zur Eigentliche Klasse
 
Zitat:

Zitat von mimi
Zitat:

Zitat von Muetze1
Du weist irgendwo der Instanz die Items auf die Lines Eigenschaft des Memos selber zu

Nein das tue ich mit 100%iger Sicherheit nirgends, warum auch ?

Aber genau in dem von dir geposteten Quellcode weist doch der PlaylistenManager-Eigenschaft Memo1.Lines (wie ich es sagte) zu, und genau diese Eigenschaft weist du doch den PlaylistItems der TBasePlaylist zu. Somit nutzt er das Memo1. Vollkommen logisch und wie ich behauptet hatte.

Delphi-Quellcode:
procedure TForm1.FormCreate(Sender: TObject);
begin
  PlayListeManger:=TPlaylistenManger.Create;
  PlayListeManger.PlayListItems:=Memo1.Lines;  // <<< Ich denke du willst ListBox.Items und nicht Memo1.Lines
                                                // genau davon habe ich geredet...
end;
Zitat:

Zitat von mimi
Wenn ich das Memo1 direkt zuweise, hängt sich das Programm beim ausführen auf.

Diese Zuweisung sollte der Compiler nichtmal akzeptieren ohne harten Typecast, da du schliesslich nicht kompatible Typen zuweisen willst. Und das es abstürzt ist mehr als logisch, schliesslich ist ein TStrings-Derivat was anderes als ein TMemo.

mimi 1. Nov 2007 11:58

Re: StringList weiter reichen zur Eigentliche Klasse
 
Zitat:

TForm1.FormCreate(Sender: TObject);
begin
PlayListeManger:=TPlaylistenManger.Create;
// AUCH WENN ICH HIER LISTBOX1.ITEMS schreibe wird Memo1.Lines gefüllt.
// Wenn ich memo1.lines schreibe hängt sich das Programm beim ausführen auf.
PlayListeManger.PlayListItems:=Memo1.Lines; // <<< Ich denke du willst ListBox.Items und nicht Memo1.Lines
// genau davon habe ich geredet...
end;


mimi hat folgendes geschrieben:
Das habe ich nur zum testen gemacht um zu sehen was passiert vorher stand da auch Listbox1.items

Zitat:

Diese Zuweisung sollte der Compiler nichtmal akzeptieren ohne harten Typecast
Ich meinte eigentlich die Lines Eigenschaft von Memo1, ich dachte das wüsstest du.....

Also unter Delphi wird die Listbox gefüllt

edit:
ich habe die frage jetzt doch unter
http://www.lazarusforum.de/viewtopic.php?p=14145#14145
gestellt.
mal sehen was "die" sagen werden. Ich bin mir sicher es handelt sich um ein Pointer Problem.

Muetze1 1. Nov 2007 12:13

Re: StringList weiter reichen zur Eigentliche Klasse
 
Leider habe ich hier im Forum gelernt, dass man nicht einfach Annahmen treffen kann bezüglich offensichtlicher Aussagen.

Und zu dem Pointer Problem: ich bin noch immer zu 99.9% davon überzeugt, dass es nicht an Lazarus sondern am Code liegt. Ich habe hier auf Arbeit kein Lazarus und werde es mir heute Abend zu Hause anschauen.

mimi 1. Nov 2007 12:16

Re: StringList weiter reichen zur Eigentliche Klasse
 
Danke !

Ich verstehe das nicht mehr, ich weiße nirgend Memo1.Lines zu einer anderen TSTringlist

lösche ich das Memo1 hängt sich das Programm auf.

Ist das nicht beweis genug ?

mimi 1. Nov 2007 12:23

Re: StringList weiter reichen zur Eigentliche Klasse
 
wenn ich:
Delphi-Quellcode:
procedure TForm1.SpeedButton1Click(Sender: TObject); // Öffnen
begin
  PlayListeManger.PlayListItems:=Listbox1.items;
  PlayListeManger.LoadFromFile('/media/hda7/Daten/music/entspannung.m3u');

end;
Geht es wie gewünscht. der Unterschied ist das ich
PlayListeManger.PlayListItems:=Listbox1.items;
nicht schon in OnCreate zuweise sondern erst wenn es gebraucht wird.

Muetze1 1. Nov 2007 19:55

Re: StringList weiter reichen zur Eigentliche Klasse
 
Das Problem liegt einfach nur daran, dass du die im PlaylistenManager hinterlegte Instanz der Items nicht beim InitPlaylist() - also anlegen der Instanz - deren Eigenschaft weiterreichst. Wenn du dies dort machst, brauchst du diese Zuweisung nicht mehr.

Grundlegend habe ich debuggt mit Lazarus und Lazarus hat ein Problem mit dem AddObject() mit dem Info. Anscheinend meint er, dass die TInfo Instanz nicht mehr existiert. Der Debugger ist leider keine Hilfe und in den Komponentenquelltext komme ich nicht reindebuggt. Grundlegend scheint es wirklich ein Lazarus Problem zu sein. Warum ist eine andere Frage.

Also: auch wenn ich es wirklich nicht geglaubt habe durch dieses abstruse Verhalten, so sind doch die 0.1% eingetreten und es ist ein Fehler von Lazarus (meines Erachtens). Somit: sorry, aber das konnte ich wirklich nicht glauben. Das ist wirklich zu abstrus. Aber ich nehme alles zurück und behaupte nun das Gegenteil. Sorry nochmal.

mimi 2. Nov 2007 12:44

Re: StringList weiter reichen zur Eigentliche Klasse
 
Na macht nix. Vielen Dank für deine Ausführliche Hilfe und Erklärungen.

Hast du evlt. eine Idee, wie ich den Fehler am besten umgehen kann ?

Oder ist meine Lösung evlt. schon die beste: einfach den Ort zu verschieben. Wo die zuweisung stad findet.
Ich frage mich gerade wann eigentlich diese OnCreate von From1 ausgelöst wird.
Sobald das Formular fertig erstellt ist oder ? also wenn alle Komponenten Installisiert wurden sind.

Evlt wird der BUG aber schon in der Nächsten Version behoben sein.

Welche FCL Version hast du ? es gibt da schon eine neuere evlt. tritt der Fehler dort nicht mehr auf.

Zitat:

also anlegen der Instanz - deren Eigenschaft weiterreichst. Wenn du dies dort machst, brauchst du diese Zuweisung nicht mehr.
Das Verstehe ich leider nicht so ganz, kannst du mir das noch einmal genauer Beschreiben ?


Alle Zeitangaben in WEZ +1. Es ist jetzt 17:08 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz