Recent

Author Topic: Is this TComponent method useless?  (Read 1242 times)

EganSolo

  • Sr. Member
  • ****
  • Posts: 290
Is this TComponent method useless?
« on: February 10, 2021, 11:01:03 am »
It may be me ... It's late and I'm a bit tired, but while attempting to add a Name property to a descendent of TGridColumnTitle (which is not a class that descends from TComponent), I looked around to see how the name property is handled in other components that have a name. I found out that the Name property is declared in TComponent and saw that the setter SetName calls this function below, which I've copied verbatim from the file compon.inc:
Code: Pascal  [Select][+][-]
  1. Procedure TComponent.SetReference(Enable: Boolean);
  2. var
  3.   Field: ^TComponent;
  4. begin
  5.   if Assigned(Owner) then
  6.   begin
  7.     Field := Owner.FieldAddress(Name);
  8.     if Assigned(Field) then
  9.       if Enable then
  10.         Field^ := Self
  11.       else
  12.         Field^ := nil;
  13.   end;
  14. end;
  15.  

Is it me or is this method useless? I mean, all it does is set the local variable Field to Nil or Self. Am I missing something? I did read the code for Owner.FieldAddress and looked for a side-effect that might explain why we've got the code as it is written here, but couldn't see anything obvious. Like I said, I'm trying to provide a descendant of TGridColumnTitle a name and I wanted to implement the appropriate checks, which is why I ended here.

Thoughts?

wp

  • Hero Member
  • *****
  • Posts: 11857
Re: Is this TComponent method useless?
« Reply #1 on: February 10, 2021, 11:31:20 am »
To begin with: I cannot answer your main question.

But I wonder why you want to give a property Name to TGridColumnTitle. The Name is a property mainly needed by the Object Inspector and the Lazarus IDE internally. Setting the Name manually a runtime often leads to crashes because the Name must be unique.

EganSolo

  • Sr. Member
  • ****
  • Posts: 290
Re: Is this TComponent method useless?
« Reply #2 on: February 10, 2021, 12:00:27 pm »
Hi wp,

You may have guessed that this is the follow-up to my attempt to use TColumns in the TStringGrid  :)

Basically, a String grid has almost all the properties I need to manage the set of CSV files as a database, but its Title (which is really the meta-data store of a TColumn, lacks a data type and a Name, which is why I'm adding both to my descendant class of TColumnGridTitle. Obviously, it's a bit awkward because the name of the column is in its title, but the column itself is not a component either, so storing it in the Title still make sense (given that caption is there).

Anyway, a long-winded way of answering why I'd like to add a name to each column in the grid.  :D

Bart

  • Hero Member
  • *****
  • Posts: 5275
    • Bart en Mariska's Webstek
Re: Is this TComponent method useless?
« Reply #3 on: February 10, 2021, 12:12:16 pm »
I still don't see why you need a name for a component/object at runtime.
You cannot address the object by it's name like Column['Foo'].SomeField := SomeValue.

I can imaging it would make some sort of sense for debugging purposes (which is why I did this for TabSheets in my editor, but you then, as wp said, make sure you never hav a duplicate name, since that would immediately lead to an exception being raised).

Bart

howardpc

  • Hero Member
  • *****
  • Posts: 4144
Re: Is this TComponent method useless?
« Reply #4 on: February 10, 2021, 12:33:45 pm »
Is it me or is this method useless? I mean, all it does is set the local variable Field to Nil or Self. Am I missing something? I did read the code for Owner.FieldAddress and looked for a side-effect that might explain why we've got the code as it is written here, but couldn't see anything obvious.
Your question is an interesting one.
TObject has no public Name property. That property is introduced by TComponent.
However, while TObject lacks a Name, browsing its code reveals that it does have a (somewhat hidden) database of "Fields", which may be empty or have one or more TFieldInfo entries. Each TFieldInfo has a Name field, and TObject can search for matching names among those entries.
TComponent's SetReference method enables you to insert a component (including its Name) into its Parent's FieldAddress, thus giving the Parent a reference to that child component that is independent of TComponent's own child-tracking mechanism.
The source code does not, of course, explain why this facility might be needed. But it is not a useless method, it definitely has an effect. Under what circumstances that effect is truly useful, I am not sure.
But no doubt the VCL designers who introduced it had their reasons.
« Last Edit: February 10, 2021, 12:37:10 pm by howardpc »

wp

  • Hero Member
  • *****
  • Posts: 11857
Re: Is this TComponent method useless?
« Reply #5 on: February 10, 2021, 12:33:55 pm »
Still not clear to me. Do you mean "Caption" when you say "Title"?

[...] manage the set of CSV files as a database [...]
Are you aware that there is also a TCSVDataset which allows you to handle CSV files with database technology? I somehow have the feeling that you are trying to re-invent the wheel.

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 9792
  • Debugger - SynEdit - and more
    • wiki
Re: Is this TComponent method useless?
« Reply #6 on: February 10, 2021, 03:03:18 pm »
Code: Pascal  [Select][+][-]
  1.       if Enable then
  2.         Field^ := Self
  3.       else
  4.         Field^ := nil;
  5.  

Is it me or is this method useless? I mean, all it does is set the local variable Field to Nil or Self. Am I missing something?

You are missing the "^".

Field is a pointer. It does not set Field to nil/self, but instead it sets whatever Field points to.

Remy Lebeau

  • Hero Member
  • *****
  • Posts: 1312
    • Lebeau Software
Re: Is this TComponent method useless?
« Reply #7 on: February 10, 2021, 05:52:49 pm »
Is it me or is this method useless?

It is not useless to TComponent itself, it is actually VERY important.  But outside of TComponent, it is useless and should not be used in your own code.

This code is part of the DFM streaming system.  It is used to link components created at design-time to the pointers that are declared for them in the owning TForm/TDataModule/TFrame at runtime.  For example, if you place a TButton component named Button1 on a TForm at design-time, a variable named Button1 is declared in the TForm class, eg:

Code: Pascal  [Select][+][-]
  1. type
  2.   TMyForm = class(TForm)
  3.     Button1: TButton; // <--
  4.     ...
  5.   end;
  6.  

When the DFM is streamed into the Form at runtime, and that TButton object is created, its Name property gets set to 'Button1', which then calls SetReference(True) to set TMyForm.Button1 to Self.  When that object is later renamed (and during its destruction, it is renamed to ''), setting its Name to a new value will call SetReference(False) to set TMyForm.Button1 to nil.

I mean, all it does is set the local variable Field to Nil or Self. Am I missing something?

Yes.  The code is not setting the local variable itself, it is setting the variable that is being pointing at.  Calling FieldAddress() returns a pointer to a data member, in this case a pointer variable, and then the code sets that pointed-at variable to nil or Self as needed.

For example, MyForm.FieldAddress('Button1') returns Field := @MyForm.Button1, and then Field^ := Self/nil is effectively doing MyForm.Button1 := Self/nil.

Like I said, I'm trying to provide a descendant of TGridColumnTitle a name and I wanted to implement the appropriate checks, which is why I ended here.

This kind of code does not belong in a user-defined Name property, unless you are manually tracking your own runtime pointers by name, which there are better ways to handle that (TDictionary, etc).
« Last Edit: February 10, 2021, 05:58:29 pm by Remy Lebeau »
Remy Lebeau
Lebeau Software - Owner, Developer
Internet Direct (Indy) - Admin, Developer (Support forum)

EganSolo

  • Sr. Member
  • ****
  • Posts: 290
Re: Is this TComponent method useless?
« Reply #8 on: February 11, 2021, 12:48:47 am »
To wp: think of name as any other published property. Since TGridColumnTitle is not a component, name is accessible like any other property at runtime.

Thank you, Remy for the detailed explanation, that was very helpful, and to Martin_fr, I should have refrained from posting at 3:15 AM. Now, I need to find me a good mud-hole to sit in for the next twenty-four hours.

Thanks, guys, for your answers and kind help. Much appreciated.

 

TinyPortal © 2005-2018