Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / lazarus / 2016-10

Dynamic Form Components - SynEdit Help Please...

5 messages · 3 people ·

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Martin Collins

I apologise for emailing but need a little bit of help please.

Creating form components dynamically is a new area of pascal programming for me and I have become stuck. My application is supposed to be an editor that can open multiple files for editing. I have a page control and when opening a new file I add a page and place a synedit on the page on it's own, into which the file is loaded. The loading works fine - I create a stringlist, loadfromfile, then SetObjectProp(Component, PropInfo['Lines'], StringList). StringList.Free works without error.

However, when I try to save the file the following code works, insomuch the file is saved to disk, but the application crashes when trying to free the stringlist (HTMLFile.Free) with the error 'Project raised exception class 'External: SIGSEGV' At address 4201C3'. If I don't free the stringlist, the application does not crash but I'm left with a memory leak as indicated in my heap.trc file.

I have a feeling that HTMLFile is not actually a stringlist, I'm just forcing it to be one here - HTMLFile := TStringList(GetObjectProp(Comp, PropInfo, TStrings)); If that's the case, how can I get and/or save the text from the dynamically created synedit. This has been puzzling me for days now!!!!

Many thanks for your help.

Martin Collins

Using Lazarus 1.6, FPC 3.0.0, Linux x86_64 gtk2

####

procedure TMainForm.SaveSynEdit(ThisPage: Integer);
var
   HTMLFile: TStringList;
   Filename: String;
   Comp : TComponent;
   PropInfo: PPropInfo;
begin
   FileSaveDialog.Title:= 'Save File...';
   FileSaveDialog.DefaultExt := 'html'; //default extension
   FileSaveDialog.Filter := 'HTML source file|*.html';
   Filename:= FileList[ThisPage];
   FileSaveDialog.FileName:= Filename + '.html';
   If FileSaveDialog.Execute then
   begin
     HTMLFile:= TStringList.Create;
     Comp := PageControlEditor.ActivePage.Controls[0];
     If Comp is TWinControl then
     begin
       If IsPublishedProp(Comp, 'Lines') then
       begin
         PropInfo := GetPropInfo(Comp, 'Lines', [tkClass]);
         HTMLFile := TStringList(GetObjectProp(Comp, PropInfo, TStrings));
         Filename:= FileSaveDialog.FileName;
         HTMLFile.SaveToFile(Filename);
         HTMLFile.Free;
         FileList[ThisPage]:= Filename;
         PageControlEditor.ActivePage.Caption:= ExtractFileName(Filename);
         PageControlEditor.ActivePage.Font.Style:= [];
         PageControlEditor.ActivePage.Font.Color:= clDefault;
       end;
     end;
   end;
end;

Reply by email

Mattias Gaertner
to Martin Collins
[...]

You didn't wrote, why you need RTTI.
Simply access the TSynEdit:

procedure TMainForm.SaveSynEdit(ThisPage: Integer);
var
   HTMLFile: TStringList;
   Filename: String;
   Comp : TComponent;
   PropInfo: PPropInfo;
   aSynEdit: TSynEdit;
begin
   FileSaveDialog.Title:= 'Save File...';
   FileSaveDialog.DefaultExt := 'html'; //default extension
   FileSaveDialog.Filter := 'HTML source file|*.html';
   Filename:= FileList[ThisPage];
   FileSaveDialog.FileName:= Filename + '.html';
   If FileSaveDialog.Execute then
   begin
//     HTMLFile:= TStringList.Create;
     Comp := PageControlEditor.ActivePage.Controls[0];
     If Comp is TSynEdit then
     begin
       aSynEdit:=TSynEdit(Comp);
//       If IsPublishedProp(Comp, 'Lines') then
//       begin
//         PropInfo := GetPropInfo(Comp, 'Lines', [tkClass]);
//         HTMLFile := TStringList(GetObjectProp(Comp, PropInfo,
TStrings)); Filename:= FileSaveDialog.FileName;
         aSynEdit.Lines.SaveToFile(Filename);
//         HTMLFile.Free;
         FileList[ThisPage]:= Filename;
         PageControlEditor.ActivePage.Caption:=
ExtractFileName(Filename);
         PageControlEditor.ActivePage.Font.Style:= [];
         PageControlEditor.ActivePage.Font.Color:= clDefault;
//       end;
     end;
   end;
end;

Mattias

Reply by email

Martin Frb
to Martin Collins: I apologise for emailing but need a little bit of help please. Creating form components…

See mail from Mattias.

Martin Collins wrote
If IsPublishedProp(Comp, 'Lines') then begin PropInfo := GetPropInfo(Comp, 'Lines', [tkClass]);

SynEdit.Lines is TStrings, not TStringList.

HTMLFile := TStringList(GetObjectProp(Comp, PropInfo, TStrings));

If anything, you get a reference to the SynEdit.LInes object, but you do NOT create a new object here

HTMLFile.Free;

So this then is the same as

   SynEdit.Lines.Free;

And that you should not do.

Reply by email