Recent

Author Topic: When a component is created at runtime is not given a name how can it be found?  (Read 3652 times)

vfclists

  • Hero Member
  • *****
  • Posts: 1146
    • HowTos Considered Harmful?
When a component is created at runtime and was not given a name Is one automatically created for it?

I have created program that at runtime can list all the components fouond on a form so I can use the property editor to change the properties, but it seems they are not showing up on the list. Those on the lists have names like DBMemoX, PanelX etc, X being a number.

For instance I want to change a DBMemo, but after going through every memo on the list and changing a property none of them are changed, so I suspect the one created is not listed.

I've got to check the original code and get back to you.

Does Lazarus have  a way of naming components created at runtime?
Lazarus 3.0/FPC 3.2.2

KodeZwerg

  • Hero Member
  • *****
  • Posts: 2269
  • Fifty shades of code.
    • Delphi & FreePascal
Does Lazarus have  a way of naming components created at runtime?
Sure:
Code: Pascal  [Select][+][-]
  1. YourComponent := TYourComponent.Create(Self);
  2. try
  3.   YourComponent.Parent := Self;
  4.   YourComponent.Name := 'YourComponent';  // or via Format() to include numbering etc...
« Last Edit: Tomorrow at 31:76:97 xm by KodeZwerg »

BlueIcaro

  • Hero Member
  • *****
  • Posts: 803
    • Blog personal
Hello, I'm not sure what are you doing. But with my limited knowledge, this code works for me

Code: [Select]

procedure TForm1.FormCreate(Sender: TObject);
var
  P, P1: TPanel;
  B: TButton;
begin
  P := TPanel.Create(Self);
  P.Caption := 'RunTime';
  P.Parent := Self;

  P1 := TPanel.Create(Self);
  P1.Caption := 'RunTime1';
  P1.Parent := Self;
  P1.Left := 200;
  P1.Top := 0;


  B := TButton.Create(Self);
  B.Parent := Self;
  B.Left := 50;
  B.Top := 100;
  B.Caption := 'Test';
  B.OnClick:=@BClick;

end;

procedure TForm1.BClick(Sender: TObject);
var
  C: Integer;
begin
  C := Self.ComponentCount;
  ShowMessage('Componentes on Form1: '+IntToStr(C)); //Shows 3
end;
   

Also you can put a name, as KodeZwerg says.
@KodeZwerg you are faster than me, I could not finish my answer  ;)
/BlueIcaro
/BlueIcaro

KodeZwerg

  • Hero Member
  • *****
  • Posts: 2269
  • Fifty shades of code.
    • Delphi & FreePascal
For instance I want to change a DBMemo, but after going through every memo on the list and changing a property none of them are changed, so I suspect the one created is not listed.
I do suggest that you switch to a better generic way of how to dynamic create at runtime components and keep track about them.
When I do create, I most often create them in a list and to quick identify I give each a unique tag, with a unique tag you can write generic methods that just seperate the different tag handling.
« Last Edit: Tomorrow at 31:76:97 xm by KodeZwerg »

Thaddy

  • Hero Member
  • *****
  • Posts: 16151
  • Censorship about opinions does not belong here.
Code: Pascal  [Select][+][-]
  1. function CreateUniqueName(const BaseName: string; Owner: TComponent): string;
  2. var
  3.   Counter: Integer;
  4. begin
  5.   Counter := 1;
  6.   Writestr(Result,BaseName,Counter);
  7.   while Assigned(Owner.FindComponent(Result)) do
  8.   begin
  9.     Writestr(Result,BaseName,Counter);
  10.     Inc(Counter);
  11.   end;
  12. end;
But IIRC there is already such a function in the LCL? Except I could not find it, but Lazarus does something similar, of course.
Compiles, but not tested since Lazarus trunk will not compile at the moment.
« Last Edit: February 15, 2024, 12:13:16 pm by Thaddy »
If I smell bad code it usually is bad code and that includes my own code.

kjteng

  • Sr. Member
  • ****
  • Posts: 259
...
For instance I want to change a DBMemo, but after going through every memo on the list and changing a property none of them are changed, so I suspect the one created is not listed.
Does Lazarus have  a way of naming components created at runtime?
AFAIK, component name would not be automatically generated for component created at run time ( though you can assign a name to it). If the component was created with the  form as owner (i.e. TDBMemo.Create(Self) ) then it should be listed in Self.components. Though the component name is blank/empty, you may still refer to a component (owned by the form) by index and modify its properties accordingly, for example:
Code: Pascal  [Select][+][-]
  1. (components[x] as TDBMemo).Color := clYellow;

Quote
...so I can use the property editor to change the properties
No. You only use the property editor to edit the properties of a component at designtime. Since the component is created at runtime, you wont be able to access it at design time.
 

Thaddy

  • Hero Member
  • *****
  • Posts: 16151
  • Censorship about opinions does not belong here.
No. components created at runtime will not have a filled in name property, but you can do that with by my snippet or search the Laz designer part how Lazarus does it.
My code works like so:
Code: Pascal  [Select][+][-]
  1. program unique;
  2. {$mode objfpc}
  3. uses classes;
  4.  
  5. function CreateUniqueName(const BaseName: string; Owner: TComponent): string;
  6. var
  7.   Counter: Integer;
  8. begin
  9.   Counter := 1;
  10.   Writestr(Result,BaseName,Counter);
  11.   while Assigned(Owner.FindComponent(Result)) do
  12.   begin
  13.     Writestr(Result,BaseName,Counter);
  14.     Inc(Counter);
  15.   end;
  16. end;
  17.  
  18. var
  19.  Owner:Tcomponent;
  20.  Buttons: Array[0..3] of TComponent;
  21.  i:integer;
  22. begin
  23.  Owner := TComponent.Create(nil);
  24.  for i := 0 to 3 do
  25.  begin
  26.    Buttons[i] :=TComponent.Create(Owner);// of course in Lazarus GUI TButton.Create
  27.    Buttons[i].Name := CreateUniqueName('Button',Owner);
  28.    writeln(Buttons[i].Name);
  29.  end;
  30.  Owner.Free;
  31. end.
Tested on a 3.2.2 install.
I do not expect that the IDE generates the name much more complicated.
« Last Edit: February 15, 2024, 02:24:23 pm by Thaddy »
If I smell bad code it usually is bad code and that includes my own code.

vfclists

  • Hero Member
  • *****
  • Posts: 1146
    • HowTos Considered Harmful?
...
For instance I want to change a DBMemo, but after going through every memo on the list and changing a property none of them are changed, so I suspect the one created is not listed.
Does Lazarus have  a way of naming components created at runtime?
AFAIK, component name would not be automatically generated for component created at run time ( though you can assign a name to it). If the component was created with the  form as owner (i.e. TDBMemo.Create(Self) ) then it should be listed in Self.components. Though the component name is blank/empty, you may still refer to a component (owned by the form) by index and modify its properties accordingly, for example:
Code: Pascal  [Select][+][-]
  1. (components[x] as TDBMemo).Color := clYellow;

Quote
...so I can use the property editor to change the properties
No. You only use the property editor to edit the properties of a component at designtime. Since the component is created at runtime, you wont be able to access it at design time.

I am modifying them at runtime and the object inspector and component inspector can be created at runtime.
Lazarus 3.0/FPC 3.2.2

kjteng

  • Sr. Member
  • ****
  • Posts: 259
You mean you want to let the end user to change the properties in the object inspector created at runtime?

KodeZwerg

  • Hero Member
  • *****
  • Posts: 2269
  • Fifty shades of code.
    • Delphi & FreePascal
I am modifying them at runtime and the object inspector and component inspector can be created at runtime.
Please attach an example that show what you try to do and how.
« Last Edit: Tomorrow at 31:76:97 xm by KodeZwerg »

vfclists

  • Hero Member
  • *****
  • Posts: 1146
    • HowTos Considered Harmful?
You mean you want to let the end user to change the properties in the object inspector created at runtime?

Yes, but I am that end user. I don't intend for other users to do that themselves.

The object inspector and property editor are rather complicated so if I enable it for end users it will be a restricted custom interface.
Lazarus 3.0/FPC 3.2.2

vfclists

  • Hero Member
  • *****
  • Posts: 1146
    • HowTos Considered Harmful?
I am modifying them at runtime and the object inspector and component inspector can be created at runtime.
Please attach an example that show what you try to do and how.

An example comes with Lazarus - examples/objectinspector/oiexample.lpi
Lazarus 3.0/FPC 3.2.2

KodeZwerg

  • Hero Member
  • *****
  • Posts: 2269
  • Fifty shades of code.
    • Delphi & FreePascal
I am modifying them at runtime and the object inspector and component inspector can be created at runtime.
Please attach an example that show what you try to do and how.

An example comes with Lazarus - examples/objectinspector/oiexample.lpi
And there I see what you do and how you do?
« Last Edit: Tomorrow at 31:76:97 xm by KodeZwerg »

Joanna from IRC

  • Hero Member
  • *****
  • Posts: 1205
I never knew that the object inspector could be created at runtime and used inside of a program...
✨ 🙋🏻‍♀️ More Pascal enthusiasts are needed on IRC .. https://libera.chat/guides/ IRC.LIBERA.CHAT  Ports [6667 plaintext ] or [6697 secure] channel #fpc  #pascal Please private Message me if you have any questions or need assistance. 💁🏻‍♀️

Thaddy

  • Hero Member
  • *****
  • Posts: 16151
  • Censorship about opinions does not belong here.
Not necessarily THE object inspector - that can be re-used indeed - but A object inspector and that is as old as Delphi1, Many people have written libraries that allow form design at runtime and for various reasons. It is absolutely not uncommon. It is also not particularly difficult.
It only takes some knowledge about the component streaming mechanism and that is straightforward in both Delphi and FreePascal/Lazarus. Writing good property editors to go with it is slightly more difficult, though, depending on the property kind.
« Last Edit: February 24, 2024, 07:56:37 am by Thaddy »
If I smell bad code it usually is bad code and that includes my own code.

 

TinyPortal © 2005-2018