Recent

Author Topic: How to assign onclick event to dynamically created object ?  (Read 1749 times)

lazer

  • Full Member
  • ***
  • Posts: 215
How to assign onclick event to dynamically created object ?
« on: January 31, 2023, 12:08:03 pm »
Hi,

I have created a bunch of TstaticText objects dynamically and need to assign some event handlers to be the same as a design time control of the same type.

Code: Pascal  [Select][+][-]
  1.     result[i]:=TstaticText.create(nil);
  2.     result[i].onclick:=refTextClick.onclick;
  3.  

It fails to compile saying the number of arguments does not match.
Code: Pascal  [Select][+][-]
  1.  Error: Wrong number of parameters specified for call to "refTextClick"

Can someone explain what I should be doing?

TIA.

bytebites

  • Hero Member
  • *****
  • Posts: 640
Re: How to assign onclick event to dynamically created object ?
« Reply #1 on: January 31, 2023, 12:35:15 pm »
Code: Pascal  [Select][+][-]
  1.  result[i].onclick:=@refTextClick.onclick;


Zvoni

  • Hero Member
  • *****
  • Posts: 2327
Re: How to assign onclick event to dynamically created object ?
« Reply #3 on: January 31, 2023, 01:02:48 pm »
Code: Pascal  [Select][+][-]
  1.  result[i].onclick:=@refTextClick.onclick;
If not Mode Delphi!
One System to rule them all, One Code to find them,
One IDE to bring them all, and to the Framework bind them,
in the Land of Redmond, where the Windows lie
---------------------------------------------------------------------
Code is like a joke: If you have to explain it, it's bad

KodeZwerg

  • Hero Member
  • *****
  • Posts: 2066
  • Fifty shades of code.
    • Delphi & FreePascal
Re: How to assign onclick event to dynamically created object ?
« Reply #4 on: January 31, 2023, 01:10:13 pm »
Code: Pascal  [Select][+][-]
  1.  Error: Wrong number of parameters specified for call to "refTextClick"
If the current suggestions not work, I would suggest that...
Can someone explain what I should be doing?
...you explain by showing your "OnClick" event header/signature.
« Last Edit: Tomorrow at 31:76:97 xm by KodeZwerg »

lazer

  • Full Member
  • ***
  • Posts: 215
Re: How to assign onclick event to dynamically created object ?
« Reply #5 on: January 31, 2023, 02:12:01 pm »
Code: Pascal  [Select][+][-]
  1.     result[i].onclick:=@refTextClick.onclick;
  2.  
I wondered if that was it but it doesn't seems to help:
Quote
Error: Wrong number of parameters specified for call to "refTextClick"

Quote
...you explain by showing your "OnClick" event header/signature.

Code: Pascal  [Select][+][-]
  1.     procedure refTextClick(Sender: TObject);

How does that explain what syntax I need?  I'm trying to assign a event procedure to an event , not define a new one.

TRon

  • Hero Member
  • *****
  • Posts: 2514
Re: How to assign onclick event to dynamically created object ?
« Reply #6 on: January 31, 2023, 02:20:40 pm »
Code: Pascal  [Select][+][-]
  1.     procedure refTextClick(Sender: TObject);
How does that explain what syntax I need?  I'm trying to assign a event procedure to an event , not define a new one.
That is not an event and also not what you showed in your first post. see: https://wiki.freepascal.org/Form_Tutorial#Creating_a_new_form_dynamically

Thaddy

  • Hero Member
  • *****
  • Posts: 14373
  • Sensorship about opinions does not belong here.
Re: How to assign onclick event to dynamically created object ?
« Reply #7 on: January 31, 2023, 02:37:11 pm »
If refTextClick.OnClick is already an existing method from an existing instance (a procedure of object and assuming refTextClick is a TStaticText) the initial code should work. It is perfectly allowed to share a method between classes/components, but they should be there.
A method has a hidden self parameter. You can't simply assign a normal procedure to an event. That needs to be a method, a.k.a. procedure of object.
Object Pascal programmers should get rid of their "component fetish" especially with the non-visuals.

lazer

  • Full Member
  • ***
  • Posts: 215
Re: How to assign onclick event to dynamically created object ?
« Reply #8 on: January 31, 2023, 03:27:18 pm »
If refTextClick.OnClick is already an existing method from an existing instance (a procedure of object and assuming refTextClick is a TStaticText) the initial code should work. It is perfectly allowed to share a method between classes/components, but they should be there.

"Should" but doesn't.  As I reported it fails to compile.  The event handler for the refText object was created in the IDE.  I'm simply trying to assign it to a bunch of similar but dynamically created objects.

Quote
A method has a hidden self parameter. You can't simply assign a normal procedure to an event. That needs to be a method, a.k.a. procedure of object.

That is exactly what I'm doing. Maybe I did not post enough context with that declaration:
Code: Pascal  [Select][+][-]
  1.   TPuzzleForm = class(TForm)        
  2.     procedure refTextClick(Sender: TObject);
  3.   private
  4. .....

So I seem to be doing what you say should work but it gets rejected by the compiler. Maybe I'm still missing, or mis-explaining, something.

TRon

  • Hero Member
  • *****
  • Posts: 2514
Re: How to assign onclick event to dynamically created object ?
« Reply #9 on: January 31, 2023, 03:31:03 pm »
That is exactly what I'm doing. Maybe I did not post enough context with that declaration:
Code: Pascal  [Select][+][-]
  1.   TPuzzleForm = class(TForm)        
  2.     procedure refTextClick(Sender: TObject);
  3.   private
  4. .....

So I seem to be doing what you say should work but it gets rejected by the compiler. Maybe I'm still missing, or mis-explaining, something.
That is at least much better and yes that is how it is suppose to look.

What type (and in case an array what type of elements) is your result variable ? Otherwise post a complete small example that generates your issue.

alpine

  • Hero Member
  • *****
  • Posts: 1064
Re: How to assign onclick event to dynamically created object ?
« Reply #10 on: January 31, 2023, 03:38:53 pm »
*snip*
That is exactly what I'm doing. Maybe I did not post enough context with that declaration:
Code: Pascal  [Select][+][-]
  1.   TPuzzleForm = class(TForm)        
  2.     procedure refTextClick(Sender: TObject);
  3.   private
  4. .....

So I seem to be doing what you say should work but it gets rejected by the compiler. Maybe I'm still missing, or mis-explaining, something.

But the refTextClick is a "procedure of object". Why you're appending .onclick after it?

Edit:
When you have 2 components, say CompA and CompB, it is normal to assign:
Code: Pascal  [Select][+][-]
  1.   CompB.OnClick := CompA.OnClick;
Since both components have an OnClick property.
But when you want to assign a procedure, then you should write:
Code: Pascal  [Select][+][-]
  1.   CompB.OnClick := @refTextClick; // Depending on the mode you may not need the @
« Last Edit: January 31, 2023, 03:48:01 pm by alpine »
"I'm sorry Dave, I'm afraid I can't do that."
—HAL 9000

lazer

  • Full Member
  • ***
  • Posts: 215
Re: How to assign onclick event to dynamically created object ?
« Reply #11 on: January 31, 2023, 04:12:31 pm »
Thanks alpine. This works:

Code: Pascal  [Select][+][-]
  1. result[i].onclick:=refText.onclick;

since refText.onclick   is refTextClick  , I still don't see why it failed doing it that way.
« Last Edit: January 31, 2023, 04:45:06 pm by lazer »

KodeZwerg

  • Hero Member
  • *****
  • Posts: 2066
  • Fifty shades of code.
    • Delphi & FreePascal
Re: How to assign onclick event to dynamically created object ?
« Reply #12 on: January 31, 2023, 04:16:00 pm »
How does that explain what syntax I need?  I'm trying to assign a event procedure to an event , not define a new one.
Since you get an error, I asked, I am sorry that it made you sad that I asked.

Anyway, I show you an example, maybe you find your error by reading it.
Code: Pascal  [Select][+][-]
  1. unit Unit1;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.   Classes , SysUtils , Forms , Controls , Graphics , Dialogs , ExtCtrls ,
  9.   StdCtrls;
  10.  
  11. type
  12.  
  13.   { TForm1 }
  14.  
  15.   TForm1 = class(TForm)
  16.     btnremove: TButton;
  17.     btncreate: TButton;
  18.     Panel1: TPanel;
  19.     procedure btncreateClick(Sender: TObject);
  20.     procedure btnremoveClick(Sender: TObject);
  21.     procedure FormCreate(Sender: TObject);
  22.     procedure GenericOnClick(Sender: TObject);
  23.   strict private
  24.     FInc: Integer;
  25.   private
  26.  
  27.   public
  28.  
  29.   end;
  30.  
  31. var
  32.   Form1: TForm1;
  33.  
  34. implementation
  35.  
  36. {$R *.lfm}
  37.  
  38. { TForm1 }
  39.  
  40. procedure TForm1.GenericOnClick(Sender: TObject);
  41. begin
  42.   if Sender is TLabel then
  43.     begin
  44.       TLabel(Sender as TLabel).Caption := IntToStr(FInc);
  45.       Inc(Finc);
  46.     end;
  47. end;
  48.  
  49. procedure TForm1.btncreateClick(Sender: TObject);
  50. var
  51.   lbl: TLabel;
  52. begin
  53.   lbl := TLabel.Create(Self);
  54.   try
  55.     lbl.Parent := Panel1;
  56.     lbl.Align := alTop;
  57.     lbl.Caption := 'test';
  58.     lbl.Name := 'Label1';
  59.     lbl.OnClick := @GenericOnClick;
  60.   finally
  61.     lbl.Visible := True;
  62.   end;
  63.   btncreate.Enabled := False;
  64.   btnremove.Enabled := True;
  65. end;
  66.  
  67. procedure TForm1.btnremoveClick(Sender: TObject);
  68. var
  69.   lbl: TLabel;
  70. begin
  71.   lbl := nil;
  72.   if (FindComponent('Label1') <> nil) then
  73.     begin
  74.       lbl := TLabel(FindComponent('Label1'));
  75.       lbl.OnClick := nil;
  76.       lbl.Free;
  77.       lbl := nil;
  78.       btnremove.Enabled := False;
  79.       btncreate.Enabled := True;
  80.     end;
  81. end;
  82.  
  83. procedure TForm1.FormCreate(Sender: TObject);
  84. begin
  85.   FInc := 0;
  86. end;
  87.  
  88. end.
  89.  
« Last Edit: Tomorrow at 31:76:97 xm by KodeZwerg »

lazer

  • Full Member
  • ***
  • Posts: 215
Re: How to assign onclick event to dynamically created object ?
« Reply #13 on: January 31, 2023, 04:22:52 pm »
Quote
Since you get an error, I asked, I am sorry that it made you sad that I asked.
Where did I say I was "sad".

Your rather annoying way of refusing to answer the question and making it ten times harder to understand does not help. I'm sure you are playing some kind of "teacher" game but it does not work. Reconsider the "educational theory" you think you learnt somewhere.

KodeZwerg

  • Hero Member
  • *****
  • Posts: 2066
  • Fifty shades of code.
    • Delphi & FreePascal
Re: How to assign onclick event to dynamically created object ?
« Reply #14 on: January 31, 2023, 04:33:37 pm »
Code: Pascal  [Select][+][-]
  1. result[i].onclick:=refTextClick.onclick;
Hmm...
since refText.onclic   is refTextClick  , I still don't see why it failed doing it that way.
Double hmmm....

All in here told how to do but you refuse to use what they write.
Code: Pascal  [Select][+][-]
  1.   CompB.OnClick := @refTextClick; // Depending on the mode you may not need the @
Code: Pascal  [Select][+][-]
  1.     lbl.OnClick := @GenericOnClick;

You still dont see a difference to your way?...
Your rather annoying way of refusing to answer the question and making it ten times harder to understand does not help. I'm sure you are playing some kind of "teacher" game but it does not work. Reconsider the "educational theory" you think you learnt somewhere.
...good luck, I just tried to help and put even a full working example here.
« Last Edit: Tomorrow at 31:76:97 xm by KodeZwerg »

 

TinyPortal © 2005-2018