I'm trying to implement TValueListEditor containing objects Here's the source code of the whole unit.
By pressing btnAdd, a new instance of TTempObj is created, which will be added together with a new row to vle (TValueListEditor), using vle.Strings.AddObject method. By pressing btnAdd several times, multiple rows are created.
And by clicking any row, the content in the RTTIMemo1 changes accordingly --- by OnSelection event --- procedure vleSelection.
If I close application here, it's fine. I do not have to free the objects myself, as
vle.Strings.OwnsObjects := True; within FormCreate. HeapTrac says there are no unallocated memory.
Problem is when I delete any row, by pressing brnDelete. If I delete one row and close the form, then it's fine. But if I select any row after deleting any one row, there occur SIGSEGV error.
That is, following code is not executed after deleting one row.
TIMemo1.Link.TIObject := vle.Strings.Objects[vle.Row-1] as TTempObj; (either in vleSelection procedure or btnDeleteClick procedure)
What would be possible reason? Is it not a good idea to use TValueListEditor.Strings.Object?
unit Unit1;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, Forms, Controls, Graphics, Dialogs, Grids, ComCtrls, ValEdit, StdCtrls, RTTICtrls;
type
TValueListEditor = class(ValEdit.TValueListEditor)
property Row; // Redefining Row property as published
end;
{ TTempObj }
TTempObj = class(TStringList) // Test object that will be added to Strings.
private
function getFL: string;
procedure setFL(AValue:string);
published
property FirstLine : string read getFL write setFL;
end;
{ TForm1 }
TForm1 = class(TForm)
btnAdd: TButton;
brnDelete: TButton;
Label1: TLabel;
TIEdit1: TTIEdit;
TIMemo1: TTIMemo;
vle: TValueListEditor;
procedure btnAddClick(Sender: TObject);
procedure brnDeleteClick(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure vleSelection(Sender: TObject; aCol, aRow: Integer);
end;
var
Form1: TForm1;
implementation
{$R *.lfm}
var
c: integer = 0;
{ TTempObj }
function TTempObj.getFL: string;
begin
if count >= 1
then Result := Strings[0]
else Result := 'No item';
end;
procedure TTempObj.setFL(AValue: string);
begin
if Count <= 0 then Append(AValue) else Strings[0] := AValue;
end;
{ TForm1 }
procedure TForm1.FormCreate(Sender: TObject);
begin
vle.Clear;
vle.Strings.OwnsObjects:= True;
end;
procedure TForm1.vleSelection(Sender: TObject; aCol, aRow: Integer
);
begin
TIMemo1.Link.TIObject := vle.Strings.Objects[vle.Row-1] as TTempObj;
end;
procedure TForm1.btnAddClick(Sender: TObject);
var
tobj : TTempObj;
ts: string;
begin
c += 1;
tobj := TTempObj.Create;
ts := Format('%d=VLE item %0:d', [c]);
tobj.FirstLine := 'Content in obj: ' + ts;
vle.Strings.AddObject(ts, tobj);
TIMemo1.Link.TIObject := vle.Strings.Objects[vle.Row-1] as TTempObj;
end;
procedure TForm1.brnDeleteClick(Sender: TObject);
begin
TIMemo1.Link.TIObject := nil;
vle.DeleteRow(vle.Row);
// TIMemo1.Link.TIObject := vle.Strings.Objects[vle.Row-1] as TTempObj;
// --> Error occurs here
end;
end.