* * *

Author Topic: Assigning a static class methods to regular procedural variables  (Read 1274 times)

simone

  • Jr. Member
  • **
  • Posts: 94
The reference language guide states that static class methods can be assigned to regular procedural variabile.
(https://www.freepascal.org/docs-html/ref/refsu30.html)

Nevertheless the following code generate the error:

Incompatible types: got "<class method type of procedure(TObject) of object;Register>" expected "<procedure variable type of procedure(TObject) of object;Register>"

Why? Thanks in advance for explanations!

Code: Pascal  [Select]
  1. unit Unit1;
  2. {$mode objfpc}{$H+}
  3.  
  4. interface
  5.  
  6. uses
  7.   Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls;
  8.  
  9. type
  10.   TForm1 = class(TForm)
  11.     procedure FormCreate(Sender: TObject);
  12.   end;
  13.  
  14.   Handler=class
  15.     class procedure OnClick(Sender : TObject); static;
  16.   end;
  17.  
  18. var
  19.   Form1: TForm1;
  20.   Button1 : TButton;
  21.  
  22. implementation
  23.  
  24. {$R *.lfm}
  25.  
  26. class procedure Handler.OnClick(Sender: TObject);
  27. begin
  28.   ShowMessage('Ok');
  29. end;
  30.  
  31. procedure TForm1.FormCreate(Sender: TObject);
  32. begin
  33.   Button1:=TButton.Create(Self);
  34.   Button1.Parent:=Self;
  35.   Button1.Left:=100;
  36.   Button1.Top:=100;
  37.   Button1.OnClick:=@Handler.OnClick;  //<--- ERROR
  38. end;
  39.  
  40. end.

Blaazen

  • Hero Member
  • *****
  • Posts: 2510
  • POKE 54296,15
    • Eye-Candy Controls
Re: Assigning a static class methods to regular procedural variables
« Reply #1 on: January 06, 2018, 12:45:07 am »
Regular procedural variable probably means this:
Code: Pascal  [Select]
  1. TRegProcVar = procedure(Sender: TObject); //of object;
i.e. not method.
But it does not work too:
Code: Pascal  [Select]
  1. var aRPV: TRegProcVar;
  2. begin
  3.   aRPV:=@Handler.OnClick;
Lazarus 1.9.0 r57500 FPC 3.0.4 x86_64-linux-qt Chakra, Qt 4.8.7, Plasma 5.11.4
Lazarus 1.8.0 r56594 FPC 3.0.4 i386-win32-win32/win64 Wine 3.2

Try Eye-Candy Controls: https://sourceforge.net/projects/eccontrols/files/

engkin

  • Hero Member
  • *****
  • Posts: 1952
Re: Assigning a static class methods to regular procedural variables
« Reply #2 on: January 06, 2018, 01:03:14 am »
Regular procedure variable is just a simple pointer.
Method variable is a record of two pointers.
Static class methods can be assigned to the first type, but you seem you want to assign them to the second type. Here is how to do it:
Code: Pascal  [Select]
  1. procedure TForm1.FormCreate(Sender: TObject);
  2. var
  3.   e:TMethod;
  4. begin
  5.   Button1:=TButton.Create(Self);
  6.   Button1.Parent:=Self;
  7.   Button1.Left:=100;
  8.   Button1.Top:=100;
  9.   e.Data:=nil;
  10.   e.Code:=@Handler.OnClick;
  11.   Button1.OnClick:=TNotifyEvent(e);
  12.   //Button1.OnClick:=@Handler.OnClick;  //<--- ERROR
  13. end;

Blaazen

  • Hero Member
  • *****
  • Posts: 2510
  • POKE 54296,15
    • Eye-Candy Controls
Re: Assigning a static class methods to regular procedural variables
« Reply #3 on: January 06, 2018, 01:06:00 am »
Finally, this works, but requires delphi mode (and remove @):
Code: Pascal  [Select]
  1. {$mode delphi}{$H+}
  2. ...
  3. TRegProcVar = procedure(Sender: TObject);
  4. ...
  5. var aRPV: TRegProcVar;
  6. begin
  7.   aRPV:=Handler.OnClick;
Lazarus 1.9.0 r57500 FPC 3.0.4 x86_64-linux-qt Chakra, Qt 4.8.7, Plasma 5.11.4
Lazarus 1.8.0 r56594 FPC 3.0.4 i386-win32-win32/win64 Wine 3.2

Try Eye-Candy Controls: https://sourceforge.net/projects/eccontrols/files/

engkin

  • Hero Member
  • *****
  • Posts: 1952
Re: Assigning a static class methods to regular procedural variables
« Reply #4 on: January 06, 2018, 01:10:51 am »
Finally, this works, but requires delphi mode (and remove @):
Code: Pascal  [Select]
  1. {$mode delphi}{$H+}
  2. ...
  3. TRegProcVar = procedure(Sender: TObject);
  4. ...
  5. var aRPV: TRegProcVar;
  6. begin
  7.   aRPV:=Handler.OnClick;

or:
Code: Pascal  [Select]
  1.   aRPV: TRegProcVar;
  2. begin
  3.   aRPV:=TRegProcVar(@Handler.OnClick);
  4.   aRPV(nil);

simone

  • Jr. Member
  • **
  • Posts: 94
Re: Assigning a static class methods to regular procedural variables
« Reply #5 on: January 06, 2018, 12:03:11 pm »
It was my mistake: In the documentation I underestimated the adjective 'regular' refering to procedure.

I took into consideration class methods to logically group many event handlers of different controls created dynamically in a program with a complex GUI.

Proposed solutions are very interesting from the technical point of view, but in my context could make the code less readable. So I'm looking for others solutions. Thanks!

Jonas Maebe

  • Hero Member
  • *****
  • Posts: 561
Re: Assigning a static class methods to regular procedural variables
« Reply #6 on: January 06, 2018, 06:51:10 pm »
No, it was a compiler bug. It has been fixed in the current development version: https://bugs.freepascal.org/view.php?id=27414

simone

  • Jr. Member
  • **
  • Posts: 94
Re: Assigning a static class methods to regular procedural variables
« Reply #7 on: January 06, 2018, 07:51:49 pm »
Thanks Jonas. Although I'm not very familiar with Delphi, I noticed the same issue with 10.2 Starter Edition...
« Last Edit: January 07, 2018, 01:31:52 am by simone »

clauswk

  • Newbie
  • Posts: 1
Re: Assigning a static class methods to regular procedural variables
« Reply #8 on: March 20, 2018, 03:27:43 am »
Finally, this works, but requires delphi mode (and remove @):
Code: Pascal  [Select]
  1. {$mode delphi}{$H+}
  2. ...
  3. TRegProcVar = procedure(Sender: TObject);
  4. ...
  5. var aRPV: TRegProcVar;
  6. begin
  7.   aRPV:=Handler.OnClick;

Thank you, Blaazen. I have been looking for a solution to a similar problem for a couple of days now, and the delphi mode did it.

Claus

 

Recent

Get Lazarus at SourceForge.net. Fast, secure and Free Open Source software downloads Open Hub project report for Lazarus