Recent

Author Topic: Can somebody explain the "Invalid Property Path" error?  (Read 9445 times)

DtC17

  • New Member
  • *
  • Posts: 13
Can somebody explain the "Invalid Property Path" error?
« on: July 07, 2013, 11:50:45 pm »
Hi guys, I've got a question I can't really figure out, though I kind of "circumvented" it for now (as in: it's not urgent and most certainly not a bugreport in Lazarus -- this is definitely a brainfart of mine)

Here's what I did:

type TBigMemo = class
       ....lots....
           FEDFont : TFont
           procedure SetEdFont(op : TFont);
       Published
           EditorFont : TFont read FEDFont write SetEdFont;
       end;

and:

TBigMemo.SetEdFont(op : TFont);
begin
  if op<>NIL then begin
    FEdFont.Assign(op);
    if not(csDesigning in ComponentState) then ...do some more actions...
  end;
end;

of course there's also an overridden constructor

TBigMemo.Create(theOwner: TWinControl);
begin
  FEdFont:=TFont.Create;
end;


And here's what it does (or does not) do:

The problem is not that my component does not work; properties even get saved to the LFM file (I checked). The only problem is, that Lazarus can't LOAD the EditorFont properties! Upon loading, it throws a dialog box with "Error reading BigMemo1.EditorFont.Color: Invalid Property Path"

Google came up blank, so in the meantime I declared several properties "EditorFontName", "EditorFontSize" and "EditorFontColour" as a workaround-- but I have no idea what it means or what could be done to prevent this. Also, I tracked the Keyword "Font" back and noticed a construction such as "stored IsFontStored" in the property definition. I have no idea what that means either... Poked around a lot with that, doesn't seem to do anything at all...??

To admit the truth, I'm having several other problems with "properties" -- for instance a TBigCheckbox that has to perform additional actions when the .Top property is modified, so I overrode it's property "Top". Result: I can still place the component using Lazarus' form designer, but it's Top property is always zero! I can however read the coordinates off the screen and enter them manually in the object inspector.

Seems my understanding of property storage is very, very wonky. Anybody care to elaborate?

taazz

  • Hero Member
  • *****
  • Posts: 5368
Re: Can somebody explain the "Invalid Property Path" error?
« Reply #1 on: July 08, 2013, 12:17:28 am »
The IsStored is a method of the object that the property belongs which is called by the streaming mechanism to determine if the property has anything worth while to save for example if you have never changed a default value then it is not worth wile to save that value to the stream at all. The isStored function can be seen as the mechanism to answer if a component property has all its subproperties to default and as a consequence it is not save until the user changes something.

Your setFont procedure has a small overlook add a check if the font passed on is the same font you already have eg
Code: [Select]
  if (op<>NIL) and (op<>FEdFont) then begin
    FEdFont.Assign(op);
    if not(csDesigning in ComponentState) then ...do some more actions...
  end;
IT doesn't make sense to copy data from your self does it?
I have no idea what the  "Invalid Property Path" means does it try to find a property named path for some odd reason or it tries to to find form1.panel2.MubigMemo.EditFont.Color and fails to find it? I'm guessing its the later but I can't be sure I need to see it for my self, never had such problems so far.

As for the TOP property I am guessing that you have inherited your checkbox from TCheckbox which it already has a published Top property and by redeclaring you are effectively hiding from the rest of world, well kinda not exactly hide it if you type cast your component back to a TcustomControl where I think the top property is first introduced and try to access it the class type information will know nothing about your new property since it can't be declared as virtual or dynamic to create a VMT override for it the designer there for will only see the old property not the new one. If you want to avoid that you better find an ancestor that does not have the top property published or find an other way to check when the component is moved eg overriding the setbounds method which the one that is called every time the size of position of a component on the form is changed.

Good judgement is the result of experience … Experience is the result of bad judgement.

OS : Windows 7 64 bit
Laz: Lazarus 1.4.4 FPC 2.6.4 i386-win32-win32/win64

DtC17

  • New Member
  • *
  • Posts: 13
Re: Can somebody explain the "Invalid Property Path" error?
« Reply #2 on: July 08, 2013, 01:32:11 am »
Well, never mind the Top-- I do most of my designing at runtime anyway. It was just another minor nuisance that goes to show how little I know about properties. The TBigCheckBox is one of my older designs and is in need of an overhaul. (FYI, the TBigXXX suite of components are transparent components designed for touch screens-- I am constantly adding new ones and learning new tricks along the way)

As far as the TFont goes, according to the LFM file it is looking for "EditorFont.Color" and it cannot access that. (no, there is no property Path-- it is definitely the TFont that's causing troubles here)

I believe I also know WHY it can't access .Color; if it were, for example, a TLabel, I would have to call said Label.SetSubComponent(TRUE) in my constructor to tell Lazarus to store subcomponent properties-- but TFont has no such feature. Ergo, I could probably assign a complete TFont structure at once to BigMemo.EditorFont (which is what I do at runtime) but I cannot access a property of a property since there is no "setter" for that.

Well at least, that's what I believe is going on here.

taazz

  • Hero Member
  • *****
  • Posts: 5368
Re: Can somebody explain the "Invalid Property Path" error?
« Reply #3 on: July 08, 2013, 04:25:48 am »
You are confusing TComponent with Tpersistent. Those two are handled differently for example a TComponent is created dynamically from the forms resource file a TPersistent is expected to be created by the component that saved it before the read takes place and is the streaming mechanism expects to find a valid instance in memory while reading. TFont as a direct child of TPersistent doesn't need the setsubcomponent call, which I have no idea what is its usage.

Code: [Select]
object Form1: TForm1
  Left = 273
  Height = 329
  Top = 242
  Width = 663
  Caption = 'Form1'
  ClientHeight = 329
  ClientWidth = 663
  LCLVersion = '1.0.10.0'
  object Panel1: TPanel
    Left = 0
    Height = 295
    Top = 34
    Width = 237
    Align = alLeft
    Caption = 'Panel1'
    ClientHeight = 295
    ClientWidth = 237
    Font.Color = clHighlight
    Font.Height = -51
    Font.Name = 'Arial Black'
    ParentFont = False
    TabOrder = 0
    object PaintBox1: TPaintBox
      Left = 1
.........

As you can see the same applies for the panel1.font.color that doesn't mean that the streammer doesn't search for the font property while loading. in any case if the font.color is out of order eg not inside the
object MyBigMemo1:TBigMemo
...
  EditFont.Color := clRed
.....
end
then it is save wrongly or some one edited the lfm and didn't close/open all the tags or the streaming was done wrong for some weird reason that I can't think of at the moment.
Good judgement is the result of experience … Experience is the result of bad judgement.

OS : Windows 7 64 bit
Laz: Lazarus 1.4.4 FPC 2.6.4 i386-win32-win32/win64

DtC17

  • New Member
  • *
  • Posts: 13
Re: Can somebody explain the "Invalid Property Path" error?
« Reply #4 on: November 05, 2013, 02:46:19 pm »
Allright guys, sorry to bother again but..... still the same errors: invalid property path. I still can't make heads or tails of the whole thing since nobody seems to know anything about it (or to the contrary, everybody knows and it's considered trivial) -- either way, here's an additional question:

- a "custom composite" EditBox, including a label, a button and a TEdit, works and streams as expected.

- a "composite TForm", very similar in design, does *not*. I cannot seem to hide the custom components (added as usual during the constructor) from the object inspector, whereas my custom editbox indeed behaves as one single component; and what's worse, they are streamed as separate components upon saving (?!??) -- leading to "duplicate <component>" errors, "invalid property path" and the like.

I have tried adding a property with getters and setters; a read-only property; then no property at all; I even moved these composite components to the private section; tried SetSubcomponent true and false; even tried a few "if csDesigning in componentstate then..." but to no avail: it insists on saving the properties of my PRIVATE components and throws all kinds of errors upon loading these properties. I can understand the failure to load them, but I cannot understand why (a) they are nontheless visible in object inspector (b) saved in the LFM file. [and no, TPersistent is not applicable, unless FPC conjures up multiple inheritance]

It would appear TForms behave different than regular components; could somebody at least confirm me this?

At the moment, I see no other option than designing a custom streamer for this component but I completely and utterly fail to understand why I need to.

Help? Any explanation? Confirmation? Help.

howardpc

  • Hero Member
  • *****
  • Posts: 4144
Re: Can somebody explain the "Invalid Property Path" error?
« Reply #5 on: November 05, 2013, 05:48:13 pm »
A TForm is a unique class in several respects. For instance every GUI app must have at least one instance of the TForm class (which becomes the app's Main form). Closing that form terminates the app. No other component behaves like that.
Also the Lazarus form Designer produces and maintains an .lfm file for every form created with resources (resourceless forms are a different topic altogether). That .lfm is designed to hold the resources for a single form. You can't AFAIK have two forms somehow residing in a single .lfm. If you try to do that by creating a "composite form" you will get nothing but headaches, because the .lfm system is not designed to support multiple forms within a single resource file.
I think the functionality you are looking for is already provided in TFrame. You can embed a frame containing any number of child components in a form, and you can embed several frames in a single form (obviously your form would have to be big enough for this).

 

TinyPortal © 2005-2018