Recent

Author Topic: [Solved] Is changing name supposed to make a control nil?  (Read 3104 times)

Joanna

  • Hero Member
  • *****
  • Posts: 759
[Solved] Is changing name supposed to make a control nil?
« on: June 09, 2023, 10:30:47 am »
I just discovered a strange behavior of a tcheckbox created at design time acting very differently than one created at runtime. I have not tested this for other controls..
When I put a checkbox on a frame at design time and change its name at runtime , it seems to become nil when referenced by its original name.

If I created a checkbox at runtime and rename it , it can still be referenced by its original name.

Is this intentiona to have different behavior for controls created at runtime ?

Using Lazarus version 2.0.12 On windows 7
« Last Edit: June 14, 2023, 02:36:00 am by Joanna »
✨ 🙋🏻‍♀️ More Pascal enthusiasts are needed on IRC .. https://libera.chat/guides/ IRC.LIBERA.CHAT  Ports [6667 plaintext ] or [6697 secure] channel #fpc  Please private Message me if you have any questions or need assistance. 💁🏻‍♀️

wp

  • Hero Member
  • *****
  • Posts: 11915
Re: Is changing name supposed to make a control nil?
« Reply #1 on: June 09, 2023, 11:00:07 am »
At first I thought you are mixing up the variable name and the property Checkbox.Name. But you are right: I set up a little demo verifying the issue. Click on the "Clear Checkbox1.Name" button, then on "Toggle Checkbox1.Checked", and finally on the checkbox itself - and you'll get an access violation.

Very strange. Looks like a bug. But Delphi has the same issue, so we're in good company...

VisualLab

  • Sr. Member
  • ****
  • Posts: 320
Re: Is changing name supposed to make a control nil?
« Reply #2 on: June 09, 2023, 11:37:02 am »
I confirm. I tested on both Lazarus and Delphi:

- Windows 8.1 64-bit,
- Lazarus 2.2.4
- Delphi 10.3

After returning from work, I will try to check Lazarus 2.2.6 and Delphi 11 on Windows 10 and Lazarus 2.2.6 on Linux Kubuntu 23 and Raspberry Pi (RaspberryOS Bullseye).

balazsszekely

  • Guest

Joanna

  • Hero Member
  • *****
  • Posts: 759
Re: Is changing name supposed to make a control nil?
« Reply #4 on: June 09, 2023, 12:14:03 pm »
Thanks for helping me test this  :)

I didn’t notice this behavior sooner because I usually create controls at runtime. When creating more than one of the same control at runtime it’s imperative to be able to give each one a unique name.

I suppose the only thing I can do to allow name changing is to create the checkbox at runtime.
✨ 🙋🏻‍♀️ More Pascal enthusiasts are needed on IRC .. https://libera.chat/guides/ IRC.LIBERA.CHAT  Ports [6667 plaintext ] or [6697 secure] channel #fpc  Please private Message me if you have any questions or need assistance. 💁🏻‍♀️

wp

  • Hero Member
  • *****
  • Posts: 11915
Re: Is changing name supposed to make a control nil?
« Reply #5 on: June 09, 2023, 12:59:15 pm »

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 9864
  • Debugger - SynEdit - and more
    • wiki
Re: Is changing name supposed to make a control nil?
« Reply #6 on: June 09, 2023, 02:10:49 pm »
https://www.marcocantu.com/papers/MyName.htm
Thanks for this reference. Still rather mysterious...

I haven't looked at the test code, but from the linked doc...

Its the internals of the lfm streaming (dfm for Delphi). And it is not limited to streaming.

Code: Pascal  [Select][+][-]
  1. type
  2. TMyForm = class(TForm)
  3.   MyCheckBoxFoo: TCheckBox

And in the LFM there is a checkbox with that name.

Now when the lfm is read, then a checkbox is created. And somehow it must be put into that exact field.

In the code of SetName (called on MyCheckBoxFoo) somewhere...
The code looks at the Form (Owner) by rtti, and finds a published field of the same name as the MyCheckBoxFoo.Name.
It will then assign itself to that field.

It will also know to which field it has previously been assigned (if any) and remove itself there.

----
So when you change the name, you change the form/owners published field to which a control is assigned.

wp

  • Hero Member
  • *****
  • Posts: 11915
Re: Is changing name supposed to make a control nil?
« Reply #7 on: June 09, 2023, 02:59:00 pm »
Its the internals of the lfm streaming (dfm for Delphi). And it is not limited to streaming.

Code: Pascal  [Select][+][-]
  1. type
  2. TMyForm = class(TForm)
  3.   MyCheckBoxFoo: TCheckBox

And in the LFM there is a checkbox with that name.

Now when the lfm is read, then a checkbox is created. And somehow it must be put into that exact field.

In the code of SetName (called on MyCheckBoxFoo) somewhere...
The code looks at the Form (Owner) by rtti, and finds a published field of the same name as the MyCheckBoxFoo.Name.
It will then assign itself to that field.

It will also know to which field it has previously been assigned (if any) and remove itself there.

----
So when you change the name, you change the form/owners published field to which a control is assigned.
It is clear that the Name is essential at designtime. But these issues occur at runtime, long after the form has been read from the lfm. It seems that the LCL needs the Name to identify a control also at runtime. But why then does it work if the control is created at runtime? See attached modified demo in which in the right groupbox another checkbox is created at runtime where this crash after the same operations does not occur. This demonstrates that the LCL must be able to resolve child-parent relationship without having the Name property.

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 9864
  • Debugger - SynEdit - and more
    • wiki
Re: Is changing name supposed to make a control nil?
« Reply #8 on: June 09, 2023, 03:56:21 pm »
private fields are not in the RTTI.

Procedure TComponent.SetReference(Enable: Boolean);

Will first go through all published fields, and if any of them matches the old name, then that becomes nil.
Then it will find the field for the new name and set it.

---
It can't do anything to non published fields.

Also the field must be part of the owner. If you create a control with different owner.....

Remy Lebeau

  • Hero Member
  • *****
  • Posts: 1314
    • Lebeau Software
Re: Is changing name supposed to make a control nil?
« Reply #9 on: June 09, 2023, 08:14:09 pm »
When I put a checkbox on a frame at design time and change its name at runtime , it seems to become nil when referenced by its original name.

This is working by design.  It behaves the same way in Lazarus as it does in Delphi.

At design-time, dropping a component onto the Designer will create a published field in the Owner and name that field the same as the component's Name.  If you then change the component's Name at design-time, the published field is renamed to match.

Then at runtime, when the DFM/LFM is streamed in, the component gets created in memory and its Name is assigned its design-time value, at which time the RTL updates the corresponding published field in the Owner to point at the component.

If you later change the component's Name at run-time, the original published field can't be renamed anymore (it is read-only in the Owner's RTTI), but it can and does get updated to nil.  If there is another published field available in the same Owner that already has the new name in the Owner's RTTI, it will be updated to point at the component.

If I created a checkbox at runtime and rename it , it can still be referenced by its original name.

That is only true if the field that points at the component is not declared as published, thus changing the component's Name will not update the field.

Is this intentiona to have different behavior for controls created at runtime ?

Yes.
« Last Edit: June 09, 2023, 08:18:41 pm by Remy Lebeau »
Remy Lebeau
Lebeau Software - Owner, Developer
Internet Direct (Indy) - Admin, Developer (Support forum)

Joanna

  • Hero Member
  • *****
  • Posts: 759
Re: Is changing name supposed to make a control nil?
« Reply #10 on: June 09, 2023, 11:18:07 pm »
Thanks for the explanation, I guess things that are created at design time shouldn’t have their names changed   8)
I didn’t understand how something visible on the frame could be nil.
 Maybe it would be better to not allow me to change name of a published control if doing so will do will cause it to become nil. A compile time warning would be nice. :)
✨ 🙋🏻‍♀️ More Pascal enthusiasts are needed on IRC .. https://libera.chat/guides/ IRC.LIBERA.CHAT  Ports [6667 plaintext ] or [6697 secure] channel #fpc  Please private Message me if you have any questions or need assistance. 💁🏻‍♀️

PascalDragon

  • Hero Member
  • *****
  • Posts: 5469
  • Compiler Developer
Re: Is changing name supposed to make a control nil?
« Reply #11 on: June 10, 2023, 01:26:28 pm »
Maybe it would be better to not allow me to change name of a published control if doing so will do will cause it to become nil. A compile time warning would be nice. :)

There can not be a compile time warning, because the compiler has no clue what the component system is doing, that's much too high level.

And introducing a runtime exception would introduce complexity for something that nearly no one is doing anyway while the assignment stuff and clearing is part of the standard behavior.

Joanna

  • Hero Member
  • *****
  • Posts: 759
Re: Is changing name supposed to make a control nil?
« Reply #12 on: June 10, 2023, 04:54:20 pm »
Quote
There can not be a compile time warning, because the compiler has no clue what the component system is doing, that's much too high level.
Regardless it does produce a rather unexpected behavior. I’m not sure what should be done about it. Isn’t there a way to make it more robust?
✨ 🙋🏻‍♀️ More Pascal enthusiasts are needed on IRC .. https://libera.chat/guides/ IRC.LIBERA.CHAT  Ports [6667 plaintext ] or [6697 secure] channel #fpc  Please private Message me if you have any questions or need assistance. 💁🏻‍♀️

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 9864
  • Debugger - SynEdit - and more
    • wiki
Re: Is changing name supposed to make a control nil?
« Reply #13 on: June 10, 2023, 06:24:56 pm »
Regardless it does produce a rather unexpected behavior.

While I would have been equally surprised, it is a point of view. The name is used by the streaming system. Using it for anything else...

Quote
I’m not sure what should be done about it. Isn’t there a way to make it more robust?

Well technically it is very robust. It does exactly what it should, and it does not offer any weak points to get around it...



There are 2 items here:

1) review the docs. Make sure they are sufficiently making it clear.
=> Anyone who wants to.

2) Your code, and how can you get it to work.
=>

Well, ideally you just don't change those names. But if that is not an option
Code: Pascal  [Select][+][-]
  1.   TForm1 = class(TForm)
  2.   {published} // created by designer
  3.     Button1: TButton;
  4.     //...
  5.   private // or protected or public
  6.     MyButton1: TButton;
  7.   protected
  8.     procedure Loaded; override;
  9.   //...
  10.   end;
  11.  
  12. ...
  13. procedure TForm1.Loaded;
  14. begin
  15.   MyButton1 := Button1;
  16. end;
  17.  

Don't use Button1. Always use MyButton1. And feel free to change the name of the Button.

Joanna

  • Hero Member
  • *****
  • Posts: 759
Re: Is changing name supposed to make a control nil?
« Reply #14 on: June 11, 2023, 01:19:12 am »
 That’s interesting, I never thought of pointing another variable to it .  Thanks for idea.

Unfortunately your idea will not work for me because when I reference controls by control index it gives me the original checkbox put on frame at design time instead of the alias..  :(

I guess creating at runtime is only way?

Another problem I’m having is I can’t seem to make the checkbox the first control on the frame at runtime, {another control was placed on frame at design time.} The setcontrolindex (checkbox,0) does not make it the first element in controls array. Am I doing something wrong? I guess the control index of the one placed at design time cannot be changed either?

It seems that everything has to be created at runtime to get consistent behavior
« Last Edit: June 11, 2023, 05:22:49 am by Joanna »
✨ 🙋🏻‍♀️ More Pascal enthusiasts are needed on IRC .. https://libera.chat/guides/ IRC.LIBERA.CHAT  Ports [6667 plaintext ] or [6697 secure] channel #fpc  Please private Message me if you have any questions or need assistance. 💁🏻‍♀️

 

TinyPortal © 2005-2018