TStrings verbundene Objekte. geht nicht oder bin ich zu blöd

Für Fragen von Einsteigern und Programmieranfängern...
ghieber
Beiträge: 13
Registriert: Mo 9. Nov 2009, 21:39

TStrings verbundene Objekte. geht nicht oder bin ich zu blöd

Beitrag von ghieber »

Ich hänge in einer Sackgasse:

Code: Alles auswählen

 
// Formular mit ein paar buttons, 2 edits und einem Memo,
// dann
 
type
 TMyObject = class(TObject)
    a: integer;
    s: string;
  end;
 
var i: integer;
...
procedure TForm1.Button3Click(Sender: TObject);
var myob: TMyObject;
    ob2: TObject;
  j : integer;
begin
  myob:= TMyObject.Create;
  Myob.a:=StrToInt(edit1.Text);
  Myob.s:=edit2.Text;
  i := i+1;
  j := Memo1.Lines.AddObject('Line '+IntToStr(i), myob);
  ob2 :=  Memo1.Lines.Objects[j];
end;    
 
Eigentlich sollte hier ja bei jedem Durchlauf eine Instanz von TMyObject erzeugt und an die Liste angehängt werden. Der String wird angehängt, das Memo zeigt schön "Line 1, Line 2, ...." an.

ob2 sollte ja jetzt gleich myob sein, zeigt aber hartnäckig auf NIL.
mit typecast (ob2 deklariert als TMyObject, dann ob2 := Memo1.Lines.Objects[j] as TMyObject geht genausowenig.

Mach ich hier nen kapitalen Denkfehler, oder ist was anderes Faul???

Lazarus 1.0.8 unter Fedora19.

Vbxler
Beiträge: 129
Registriert: Sa 25. Mai 2013, 07:43
OS, Lazarus, FPC: Win7_x64 (FPC:4.7.1)
CPU-Target: 32Bit

Re: TStrings verbundene Objekte. geht nicht oder bin ich zu

Beitrag von Vbxler »

Ich würde bei der Speicherung von einzelnen Zeilen mit zusatzätzlichen Objekten eine Listbox verwenden.
Da funktioniert das so:

Code: Alles auswählen

unit Unit1;
{$mode objfpc}{$H+}
 
interface
uses
    Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls;
 
type
    { TForm1 }
    TForm1 = class(TForm)
        ListBox1: TListBox;
        procedure FormCreate(Sender: TObject);
        procedure ListBox1Click(Sender: TObject);
    private
        { private declarations }
    public
        { public declarations }
    end;
 
var
    Form1: TForm1;
 
type
//-----------------------------------------
//Klasse für die Zusatzinfo Info
//-----------------------------------------
  TZusatzInfo = class
    private
        m_Zusatz_01   : string;
        m_Zusatz_02   : string;
 
    public
        constructor Create(const Zu01 : string; const Zu02 : string) ;
        property Zusatz_01  : string read m_Zusatz_01;
        property Zusatz_02  : string read m_Zusatz_02;  
  end;
 
implementation
{$R *.lfm}
 
//-----------------------------------------
//constructor für die Zusatzinfo
//-----------------------------------------
constructor TZusatzInfo.Create(const Zu01 : string; const Zu02 : string) ;
begin
  m_Zusatz_01   := Zu01;
  m_Zusatz_02   := Zu02;
end;
 
{ TForm1 }
//eintragen der Daten
procedure TForm1.FormCreate(Sender: TObject);
var
    oZsatzInfo  : TZusatzInfo;
begin
    ListBox1.Items.AddObject('Das ist die Zeile_01 mit Zusatzinfo_01', TZusatzInfo.Create('Z01_A', 'Z01_B'));
    ListBox1.Items.AddObject('Das ist die Zeile_01 mit Zusatzinfo_02', TZusatzInfo.Create('Z02_A', 'Z02_B'));
end;
 
//ermitteln der Daten
procedure TForm1.ListBox1Click(Sender: TObject);
var
    oZsatzInfo  : TZusatzInfo;
begin
    oZsatzInfo := ListBox1.Items.Objects[ListBox1.ItemIndex] as TZusatzInfo;
    ShowMessage(oZsatzInfo.Zusatz_01 + '-' + oZsatzInfo.Zusatz_02) ;  
end;
 
end.
 
Vielleicht hilft Dir das.

Vbxler
Vbxler
-------------------------

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 6766
Registriert: So 7. Jan 2007, 10:20
OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
CPU-Target: 32Bit (64Bit)
Wohnort: Burgenland
Kontaktdaten:

Re: TStrings verbundene Objekte. geht nicht oder bin ich zu

Beitrag von af0815 »

Mit dem Debugger ansehen was du in j stehen hast. Einen Index oder eine Referenz. Außerdem würde ich das Rangechecking etc. Einschalten, dann bekommst du rasch eine Rückmeldung das du den Wertebereich verlassen hast.
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

Scotty
Beiträge: 768
Registriert: Mo 4. Mai 2009, 13:24
OS, Lazarus, FPC: Arch Linux, Lazarus 1.3 r44426M FPC 2.6.4
CPU-Target: x86_64-linux-qt/gtk2
Kontaktdaten:

Re: TStrings verbundene Objekte. geht nicht oder bin ich zu

Beitrag von Scotty »

Eigentlich sollte das so funktionieren. Vielleicht optimiert der Compiler die zweite Zuweisung weg - du machst ja nichts mit ob2.

wp_xyz
Beiträge: 5134
Registriert: Fr 8. Apr 2011, 09:01

Re: TStrings verbundene Objekte. geht nicht oder bin ich zu

Beitrag von wp_xyz »

Ich sehe das auch so wie scotty.

Warum ich zusätzlich in diesem Thread antworte, ist der Hinweis, dass du nicht vergessen darfst, die erzeugten Objekte wieder freizugeben, sonst bleibt dir ein Speicherleck.

ghieber
Beiträge: 13
Registriert: Mo 9. Nov 2009, 21:39

Re: TStrings verbundene Objekte. geht nicht oder bin ich zu

Beitrag von ghieber »

Zunächst mal danke für die raschen Antworten. Dazu einige Kommentare:

Listbox: auch die verwendet füe die "Items" ein Objekt der Klasse TStrings. Ich werd's aber probieren.

j ist ein index (in meinem Codeschnipsel verwende ich ja direkt den Rückgabewert von AddObject).

Was Wieder - Freigabe angeht, hast Du natürlich recht.

Das Problem tauchte bei der Entwicklung eines anderen Programmes auf. Einem Memo wird ein Text zugewiesen, in dem rumeditiert werden kann, bei Bedarf sollte aber Originalwert Zeilenweise wiederhergestellt werden können. Dazu wollte ich eine Kopie der originalzeile (und ein paar flags) in einem verbundenen Objekt zusammen mit jeder Zeile ablegen. Der Hier gezeigte Code stammt aus einer kleinen Testanwendung, die ich gestern abend noch geschrieben habe, um genau dieses Verhalten zu überprüfen, nachdem ich damit in meinem Projekt an die Wand gefahren bin.

Ich werd's jetzt mit einem TListBox probieren, und einer StringList (ohne visuelles Element).

Grüße, Georg

ghieber
Beiträge: 13
Registriert: Mo 9. Nov 2009, 21:39

Re: TStrings verbundene Objekte. geht nicht oder bin ich zu

Beitrag von ghieber »

So, ich bin ein stück weiter

- AddObject auf den Items einer TListBox --> geht, ..Items.Objects[j] entspricht dem Original
- AddObject auf MyList = TStringList --> geht, MyList.Objects[j] entspricht dem Original
- AddObject auf MyList = TStrings --> geht, MyList.Objects[j] entspricht dem Original

AddObjects auf den Lines eines TMemo --> geht nicht, ..Lines.MyList.Objects[j] ist immer NIL

Anscheinend liegt hier ein Bug in der Implementierung von TMemo vor.

Die Dokumentation von TStrings bezeichnet TStrings zwar als abstrakte Klasse, und einige Methoden (z.B. Clear) sind auch als "abstract" deklariert. Add und AddObject allerdings nicht, diese sind virtual, und offensichtlich in TStrings implementiert. Warum geht's dann in TMemo.Lines nicht mehr????


wp_xyz
Beiträge: 5134
Registriert: Fr 8. Apr 2011, 09:01

Re: TStrings verbundene Objekte. geht nicht oder bin ich zu

Beitrag von wp_xyz »

Kannst du das Object im zweiten Schritt explizit zuweisen?

Code: Alles auswählen

 
procedure TForm1.Button3Click(Sender: TObject);
var myob: TMyObject;
    ob2: TObject;
  j : integer;
begin
  myob:= TMyObject.Create;
  Myob.a:=StrToInt(edit1.Text);
  Myob.s:=edit2.Text;
  i := i+1;
  // hier statt "AddObject" zuerst "Add", dann Zuweisung des Objects direkt
  j := Memo1.Lines.Add('Line '+IntToStr(i));
  Memo1.Lines.Objects[j] := myob;
  ob2 :=  Memo1.Lines.Objects[j];
end;    
 

Scotty
Beiträge: 768
Registriert: Mo 4. Mai 2009, 13:24
OS, Lazarus, FPC: Arch Linux, Lazarus 1.3 r44426M FPC 2.6.4
CPU-Target: x86_64-linux-qt/gtk2
Kontaktdaten:

Re: TStrings verbundene Objekte. geht nicht oder bin ich zu

Beitrag von Scotty »

theo hat geschrieben:http://bugs.freepascal.org/view.php?id=9366
2007-08-01 23:49 :roll:

Benutzeravatar
theo
Beiträge: 10865
Registriert: Mo 11. Sep 2006, 19:01

Re: TStrings verbundene Objekte. geht nicht oder bin ich zu

Beitrag von theo »

Scotty hat geschrieben: 2007-08-01 23:49 :roll:
Und? Ein Feature-request, den niemand implementiert hat.
Delphi 7 macht das auch nicht.

Scotty
Beiträge: 768
Registriert: Mo 4. Mai 2009, 13:24
OS, Lazarus, FPC: Arch Linux, Lazarus 1.3 r44426M FPC 2.6.4
CPU-Target: x86_64-linux-qt/gtk2
Kontaktdaten:

Re: TStrings verbundene Objekte. geht nicht oder bin ich zu

Beitrag von Scotty »

Ein Bug der auf minor und dann auf feature request runter gestuft wurde. Matthias' Argumentation kann ich nachvollziehen. Aber wenn ein Problem in solch einem Fehler wie hier resultieren kann, dann bleibt der Bug ein Bug. Und die sollten nicht 6 Jahre alt werden...
Zuletzt geändert von Scotty am Mo 26. Aug 2013, 00:03, insgesamt 1-mal geändert.

Benutzeravatar
theo
Beiträge: 10865
Registriert: Mo 11. Sep 2006, 19:01

Re: TStrings verbundene Objekte. geht nicht oder bin ich zu

Beitrag von theo »

Scotty hat geschrieben:Ein Bug der auf minor und dann auf feature request runter gestuft wurde. Matthias' Argumentation kann ich nachvollziehen. Aber wenn Probleme in solche einem Fehler wie hier resultiert können, dann bleibt der Bug ein Bug. Und die sollten nicht 6 Jahre alt werden...
Das ist im Falle eines TMemo wohl nicht so einfach ohne Ressourcen zu verschwenden, wenn das Widgetset ein solches Feature nicht vorsieht.
Wie gesagt, Delphi 7 macht's auch nicht.

Christian
Beiträge: 6079
Registriert: Do 21. Sep 2006, 07:51
OS, Lazarus, FPC: iWinux (L 1.x.xy FPC 2.y.z)
CPU-Target: AVR,ARM,x86(-64)
Wohnort: Dessau
Kontaktdaten:

Re: TStrings verbundene Objekte. geht nicht oder bin ich zu

Beitrag von Christian »

Ich finds auch verabscheuenswürdig das du das jetzt 6 Jahre nicht implementiert hast Scotty.
W.m.k.A.h.e.m.F.h. -> http://www.gidf.de/

mschnell
Beiträge: 3444
Registriert: Mo 11. Sep 2006, 10:24
OS, Lazarus, FPC: svn (Window32, Linux x64, Linux ARM (QNAP) (cross+nativ)
CPU-Target: X32 / X64 / ARMv5
Wohnort: Krefeld

Re: TStrings verbundene Objekte. geht nicht oder bin ich zu

Beitrag von mschnell »

ghieber hat geschrieben:- AddObject auf MyList = TStrings --> geht, MyList.Objects[j] entspricht dem Original
Wenn ich mich recht erinnere ist ist TStrings abstrakt und speichert überhaupt nichts ?!?!?! Die Funktionen/Properties in TStrings sollten auf abstrakte Methoden fürhren und eine Exception auslösen, wenn sie benutzt wedren. (Man könnte js zum Beispiel eine Klasse ableitet, die auf einer Datei arbeitet. )
ghieber hat geschrieben:AddObjects auf den Lines eines TMemo --> geht nicht, ..Lines.MyList.Objects[j] ist immer NIL
Anscheinend liegt hier ein Bug in der Implementierung von TMemo vor.
Wieso Bug ? Höchstens eine unzureichende Doku.
TMemo ist eine Klasse die (zufällig) von TStrings abgeleitet ist. Was die einzelnen Properties machen, muss in der Doku von TMemo beschrieben werden und muss nicht unbedingt was mit dem Verhalten der Parent Klasse zu tun haben - auch wenn es sinnvoller Weise so sein sollte.

-Michael

Antworten