Jump to content
Stano

Loading data from dfm

Recommended Posts

Custom component

    FCaptions: TStrings;
//  or FCaptionsAdded: TStringList;

I'm trying 

  • property as published. I am not entering this process
  • Writer and Reader
  • TStream

The entry is OK
I won't even get into the reading method. I have these errors:

  •   published - Error reading Nav.CaptionsAdded.Strings: invalid property path (???)
  •   other - Error creating form in MainForm.dfm: Error reading jstnav2.CaptionAdded: Access violation at address 4E352E4F in module 'JasotComponents.bpl'. Read of address 00000000

As a layman. I don't understand why this is happening at all.
 

Share this post


Link to post

Try creating a component with the bare minimum to reproduce your problem and a strict minimal application using it and demonstrating the issue. Then publish your code here.

Share this post


Link to post

I thought the problem was clear I can't read the data from dfm. That is all.

To be sure, I enclosed the entire passport. Interesting are:

    FCaptionsAdded: TStrings;
    procedure ReadCaptionAdded(Reader: TReader);
    procedure WriteCaptionAdded(Writer: TWriter);
 

procedure TjstVstDBNavigator.WriteCaptionAdded(Writer: TWriter);
begin
   Writer.WriteListBegin;

   try
     for var I := 0 to FCaptionsAdded.Count - 1 do
       Writer.WriteString(FCaptionsAdded[I]);
   finally
     Writer.WriteListEnd;
   end;
end;
procedure TjstVstDBNavigator.ReadCaptionAdded(Reader: TReader);
var
  Len: Integer;
begin
ShowMessage('ReadCaptionAdded');  // I won't get here
end;

 

jstVstDBNavigator.pas

MainForm.dfm

MainForm.pas

Share this post


Link to post

FCaptionsAdded is created in procedure NewStrings, which itself is calle in CreateWnd. The loading process happens way before the window is created, so there is no instance of FCaptionsAdded during loading.

 

Best is to create all instances of the fields inside the class in its Create routine and free them in Destroy.

Share this post


Link to post
On 3/26/2022 at 3:00 AM, Stano said:

 


procedure TjstVstDBNavigator.WriteCaptionAdded(Writer: TWriter);
begin
  ...
end;

procedure TjstVstDBNavigator.ReadCaptionAdded(Reader: TReader);
begin
  ...
end;

 

Uwe Raabe already nailed the root cause of your error - FCaptionsAdded is not instantiated early enough, so it is nil when the DFM system is trying to access it.  The real question is, why are you MANUALLY streaming FCaptionsAdded AT ALL?  TStringList is a TPersistent descendant that implements its own native DFM streaming logic.  So, it is enough to just declare a TStrings/TStringList property in your component and back it with a VALID TStringList instance at component creation, no manual streaming is necessary.

Edited by Remy Lebeau

Share this post


Link to post

I do not want to publish these properties. I have a ComponentEditor on them. Of course I can change that.
I tried it. Write OK, loading failed! And that's a big problem.

Share this post


Link to post

I suspect the root cause is one needs to override the virtual method with override then the inherited can be commented out or moved as needed. 

Share this post


Link to post

It is possible. I had a hidden error (out of range) that could have caused it. After removing it, I did not try published.

Thanks to Uwe, I solved the problem immediately with Loaded.

Share this post


Link to post

The error was in the file itself. I set him full access rights. Nothing.
I created a new one. Both writing and reading work. I can debug it.

Share this post


Link to post

The dfm file is obviously annoyed by the manual intervention in its contents.

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×