Recent

Author Topic: Affect many buttons to class with events ?  (Read 4842 times)

jojo86

  • Jr. Member
  • **
  • Posts: 52
Affect many buttons to class with events ?
« on: January 29, 2019, 02:02:57 pm »
Hi,
I just want to know if it's possible to affect many buttons to a class.
For exemple, I would want to create a class module with many procedure like OnEnter, OnExit, OnClick...

Today If I want to do that, I can use a specific unit with my specifics procedures (OnEnter, click...) and I still have to add on all my buttons :
Code: Pascal  [Select][+][-]
  1. procedure TForm1.Button1Click(Sender: TObject);
  2. begin
  3.     MyUnit.ClickTheButton(Sender);
  4. end;      
  5.  
  6. procedure TForm1.Button1MouseUp(Sender: TObject; Button: TMouseButton;
  7.   Shift: TShiftState; X, Y: Integer);
  8. begin
  9.   MyUnit.MouseUp(Sender, Button, Shift, X, Y);
  10. end;  
  11.  

It's really long...
How can I do with a class module to say "Button1 = MySPecificClass" and MySpecificClass could store all registered buttons to activate events as necessary ??

I hope that you could understand my need.

Thanks,

balazsszekely

  • Guest
Re: Affect many buttons to class with events ?
« Reply #1 on: January 29, 2019, 02:24:50 pm »
I'm not sure if I understood you correctly, but if I did you need something like this:
Code: Pascal  [Select][+][-]
  1. procedure TfMain.FormCreate(Sender: TObject);
  2. begin
  3.   Button1.OnClick := @MyUnit.ClickTheButton;
  4.   Button1.OnMouseUp := @MyUnit.MouseUp;
  5.  
  6.   Button2.OnClick := @MyUnit.ClickTheButton;
  7.   Button2.OnMouseUp := @MyUnit.MouseUp;
  8. end;
« Last Edit: January 29, 2019, 02:35:52 pm by GetMem »

jojo86

  • Jr. Member
  • **
  • Posts: 52
Re: Affect many buttons to class with events ?
« Reply #2 on: January 29, 2019, 02:37:11 pm »
Thank you, but I don't want to specify for each events from each buttons... I just want to register my buttons to a class with procedures...

The result is the same but it's easier to use a class module...

I can do that with VBA with a class module and a collection... But I can't find the solution to do that in lazarus...

balazsszekely

  • Guest
Re: Affect many buttons to class with events ?
« Reply #3 on: January 29, 2019, 02:41:29 pm »
You have a though request  :). How about this:
Code: Pascal  [Select][+][-]
  1. procedure SetButtons(const AControl: TControl);
  2. var
  3.   I: Integer;
  4. begin
  5.   if (AControl = nil) then
  6.     Exit;
  7.   if AControl is TWinControl then
  8.   begin
  9.     if (TWinControl(AControl) is TButton) and ((TWinControl(AControl) as TButton).Tag = 0) then
  10.     begin
  11.      (TWinControl(AControl) as TButton).OnClick := @MyUnit.ClickTheButton;
  12.      (TWinControl(AControl) as TButton).OnMouseUp := @MyUnit.MouseUp;
  13.     end;
  14.     for I := 0 to TWinControl(AControl).ControlCount - 1 do
  15.       SetButtons(TWinControl(AControl).Controls[I]);
  16.   end;
  17. end;
  18.  

and you have to call it once for the form:
Code: Pascal  [Select][+][-]
  1. procedure TForm1.FormCreate(Sender: TObject);
  2. begin
  3.   {It will register the events for each buttons on the form with "Tag" property zero.
  4.   Since tag is zero by default, every button will be registered by default. If you wish to exclude a button,
  5.   just change its Tag to a custom value.}
  6.   SetButtons(Form1);
  7. end;
« Last Edit: January 29, 2019, 03:29:10 pm by GetMem »

jojo86

  • Jr. Member
  • **
  • Posts: 52
Re: Affect many buttons to class with events ?
« Reply #4 on: January 29, 2019, 04:14:55 pm »
Ok, that's a good proposal, but with your code, we have to loop on each components form...
And I can't store datas to a class module...
« Last Edit: January 29, 2019, 04:18:26 pm by jojo86 »

balazsszekely

  • Guest
Re: Affect many buttons to class with events ?
« Reply #5 on: January 29, 2019, 05:44:43 pm »
Quote
Ok, that's a good proposal, but with your code, we have to loop on each components form...
I'm afraid there is no other way. What's wrong with the loop?

Quote
And I can't store datas to a class module...
You have to create a class in MyUnit.

jojo86

  • Jr. Member
  • **
  • Posts: 52
Re: Affect many buttons to class with events ?
« Reply #6 on: January 29, 2019, 06:07:11 pm »
Quote
Ok, that's a good proposal, but with your code, we have to loop on each components form...
I'm afraid there is no other way. What's wrong with the loop?

Quote
And I can't store datas to a class module...
You have to create a class in MyUnit.

Yes sorry, you are right, but I have another problem with your method.
I've got an error :
Error: Incompatible types: got "<address of procedure(TObject);Register>" expected "<procedure variable type of procedure(TObject) of object;Register>"

I put this code in a specific unit :
Code: Pascal  [Select][+][-]
  1. Unit Functions;
  2. {$mode objfpc}{$H+}
  3.  
  4. interface
  5.  
  6. uses
  7.   Classes, SysUtils, IBDatabase, IBQuery, Forms, Filtrer, Buttons, Dialogs,
  8.   types, LCLIntf,
  9.   FileUtil, Controls, Graphics, StdCtrls, ExtCtrls, IniFiles, ShellApi, Windows, ComCtrls, Menus,
  10.   strutils, Printers, fpstypes, fpspreadsheet, fpsallformats, fpsexport, FGL; //, fpstypes,  fpsallformats, fpsexport;
  11.  
  12.  
  13. Procedure SetImgZoom(TrackBar: TTrackBar);
  14. Procedure TrackBarChange(Sender:TOBject);
  15.  
  16. type
  17.     TZoomCls = class
  18.     Form: TComponent;
  19.     TrackBar: TTrackBar;
  20.   end;                    
  21.    
  22. Var MyZoom: TZoomCls; //No list yet, just a test
  23.  
  24. procedure SetImgZoom(TrackBar: TTrackBar);
  25. begin
  26.   MyZoom:= TZoomCls.Create;
  27.   MyZoom.Form:=TrackBar.Owner;
  28.   MyZoom.TrackBar:= TrackBar;
  29.  
  30. [color=red][b]  TrackBar.OnChange := @TrackBarChange;[/b] //Error with this line[/color]
  31. end;
  32.  
  33. procedure TrackBarChange(Sender: TOBject);
  34. begin
  35. Showmessage('You Changed Me !!!');
  36. end;    
  37.  
  38.  

Thanks for helping me.

balazsszekely

  • Guest
Re: Affect many buttons to class with events ?
« Reply #7 on: January 29, 2019, 06:38:04 pm »
As I mentioned in my previous post,  procedure ClickTheButton and MouseUp must be part of a class, like this:
Code: Pascal  [Select][+][-]
  1. //your custom unit
  2. type
  3.   TMyClass = class
  4.   private
  5.     procedure ClickTheButton(Sender: TObject);
  6.     procedure MouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
  7.   public
  8.     constructor Create;
  9.     destructor Destroy; override;
  10.   end;
  11.  
  12. var
  13.   MyClass: TMyClass;
  14.  
  15. procedure TMyClass.ClickTheButton(Sender: TObject);
  16. begin
  17.  
  18. end;
  19.  
  20. procedure TMyClass.MouseUp(Sender: TObject; Button: TMouseButton;
  21.   Shift: TShiftState; X, Y: Integer);
  22. begin
  23.  
  24. end;
  25.  
  26. constructor TMyClass.Create;
  27. begin
  28.   //do some initialization if needed, create objects, etc...
  29. end;
  30.  
  31. destructor TMyClass.Destroy;
  32. begin
  33.   //free object here
  34.   inherited Destroy;
  35. end;
  36.  
  37. //form's unit
  38. procedure SetButtons(const AControl: TControl);
  39. var
  40.   I: Integer;
  41. begin
  42.   if (AControl = nil) then
  43.     Exit;
  44.   if AControl is TWinControl then
  45.   begin
  46.     if (TWinControl(AControl) is TButton) and ((TWinControl(AControl) as TButton).Tag = 0) then
  47.     begin
  48.      (TWinControl(AControl) as TButton).OnClick := @Myclass.ClickTheButton;
  49.      (TWinControl(AControl) as TButton).OnMouseUp := @MyClass.MouseUp;
  50.     end;
  51.     for I := 0 to TWinControl(AControl).ControlCount - 1 do
  52.       SetButtons(TWinControl(AControl).Controls[I]);
  53.   end;
  54. end;
  55.  
  56. procedure TForm1.FormCreate(Sender: TObject);
  57. begin
  58.   MyClass := TMyClass.Create;
  59.   SetButtons(Form1);
  60. end;
  61.  
  62. procedure TForm1.FormDestroy(Sender: TObject);
  63. begin
  64.   MyClass.Free;
  65. end;

jojo86

  • Jr. Member
  • **
  • Posts: 52
Re: Affect many buttons to class with events ?
« Reply #8 on: January 29, 2019, 06:49:49 pm »
Ohhhh!!!
Thank you.
I can’t test actually because I left my job, but I’ll try this tomorrow but I’m sure that’s going to work!!!

Thanks!!!!

jojo86

  • Jr. Member
  • **
  • Posts: 52
Re: Affect many buttons to class with events ?
« Reply #9 on: January 31, 2019, 10:09:56 am »
As I mentioned in my previous post,  procedure ClickTheButton and MouseUp must be part of a class, like this:
Code: Pascal  [Select][+][-]
  1. //your custom unit
  2. type
  3.   TMyClass = class
  4.   private
  5.     procedure ClickTheButton(Sender: TObject);
  6.     procedure MouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
  7.   public
  8.     constructor Create;
  9.     destructor Destroy; override;
  10.   end;
  11.  
  12. var
  13.   MyClass: TMyClass;
  14.  
  15. procedure TMyClass.ClickTheButton(Sender: TObject);
  16. begin
  17.  
  18. end;
  19.  
  20. procedure TMyClass.MouseUp(Sender: TObject; Button: TMouseButton;
  21.   Shift: TShiftState; X, Y: Integer);
  22. begin
  23.  
  24. end;
  25.  
  26. constructor TMyClass.Create;
  27. begin
  28.   //do some initialization if needed, create objects, etc...
  29. end;
  30.  
  31. destructor TMyClass.Destroy;
  32. begin
  33.   //free object here
  34.   inherited Destroy;
  35. end;
  36.  
  37. //form's unit
  38. procedure SetButtons(const AControl: TControl);
  39. var
  40.   I: Integer;
  41. begin
  42.   if (AControl = nil) then
  43.     Exit;
  44.   if AControl is TWinControl then
  45.   begin
  46.     if (TWinControl(AControl) is TButton) and ((TWinControl(AControl) as TButton).Tag = 0) then
  47.     begin
  48.      (TWinControl(AControl) as TButton).OnClick := @Myclass.ClickTheButton;
  49.      (TWinControl(AControl) as TButton).OnMouseUp := @MyClass.MouseUp;
  50.     end;
  51.     for I := 0 to TWinControl(AControl).ControlCount - 1 do
  52.       SetButtons(TWinControl(AControl).Controls[I]);
  53.   end;
  54. end;
  55.  
  56. procedure TForm1.FormCreate(Sender: TObject);
  57. begin
  58.   MyClass := TMyClass.Create;
  59.   SetButtons(Form1);
  60. end;
  61.  
  62. procedure TForm1.FormDestroy(Sender: TObject);
  63. begin
  64.   MyClass.Free;
  65. end;

Hi It’s working!
But how can I destroy all my custom class with variables?

I tried by adding « myclassvariable.free » inside my destructor code and I added MyClass.Destroy  but it doesn’t works...

Thank you,


balazsszekely

  • Guest
Re: Affect many buttons to class with events ?
« Reply #10 on: January 31, 2019, 10:31:54 am »
@jojo86
Quote
But how can I destroy all my custom class with variables?
I tried by adding « myclassvariable.free » inside my destructor code and I added MyClass.Destroy  but it doesn’t works...
Hmm.. I'm not sure what you mean. In the above example, every object belonging to TMyClass(usually created in the constructor), must be freed inside the same class(usually in the destructor). The insance of TMyClass must be created and freed outside the class. In the above example is created and freed in TForm. You should always call MyClass.Free not MyClass.Destroy.

jojo86

  • Jr. Member
  • **
  • Posts: 52
Re: Affect many buttons to class with events ?
« Reply #11 on: January 31, 2019, 10:53:55 am »
I tried to add a TSQLQuery variable in my class.
When I create my class, I link the TSQLQuery Class with another TSQLQuery wich is in a form.

But when  I call
Code: Pascal  [Select][+][-]
  1. MyClass.Free
I can't use my first TSQLQuery (on my form).

Code: Pascal  [Select][+][-]
  1. { TZoomCls }
  2. Type
  3.   TZoomCls = Class
  4.   Form: TComponent;
  5.   TrackBar: TTrackBar;
  6.   DtSource: TDataSource;
  7.   Query: TSQLQuery;
  8.   ChkBox: TCheckBox;
  9.   Img: TImage;
  10.   PContenantImg: TPanel;
  11.  
  12.   private
  13.          procedure TrackBarChange(Sender:TOBject);
  14.          procedure DtSourceChange(Sender: TObject; Field: TField);
  15.   public
  16.     constructor Create;
  17.     destructor Destroy; override;
  18. end;                      
  19.  
  20. var
  21. MyZoom: TZoomCls;    
  22.  
  23. procedure SetImgZoom(TrackBar: TTrackBar; ChkPlRep: TCheckBox;
  24.   DataSrc: TDataSource; Qry: TSQLQuery);
  25. begin
  26.   MyZoom:= TZoomCls.Create;
  27.   MyZoom.Form:=TrackBar.Owner;
  28.   MyZoom.TrackBar:= TrackBar;
  29.   MyZoom.DtSource:=DataSrc;
  30.   MyZoom.ChkBox:= ChkPlRep;
  31.   MyZoom.Query:=Qry;
  32.   MyZoom.Img:=(MyZoom.Form.FindComponent('Img1') as TImage);
  33.   MyZoom.PContenantImg:=(MyZoom.Form.FindComponent('PContenantImg') as TPanel);
  34.   TrackBar.OnChange := @MyZoom.TrackBarChange;
  35.   MyZoom.DtSource.OnDataChange:=@MyZoom.DtSourceChange;
  36.   MyZoom.TrackBarChange(TrackBar);
  37.   AfficherImage;
  38. end;
  39.  

When I call MyZoom.Free, I can't use the originale Qry wich is in another form...
It's as if MyZoom.Query was still linked to My real TSQLQuery...

 :o
« Last Edit: January 31, 2019, 10:56:09 am by jojo86 »

balazsszekely

  • Guest
Re: Affect many buttons to class with events ?
« Reply #12 on: January 31, 2019, 11:32:14 am »
TrackBar,  ChkPlRep,  DataSrc and Qry are parts of an external form?

jojo86

  • Jr. Member
  • **
  • Posts: 52
Re: Affect many buttons to class with events ?
« Reply #13 on: January 31, 2019, 02:06:37 pm »
TrackBar,  ChkPlRep,  DataSrc and Qry are parts of an external form?

Yes... I can’t explain why, but I’m sure that you’re going to tell me that’s the problem...
I hope that you have a solution?

Thank!

balazsszekely

  • Guest
Re: Affect many buttons to class with events ?
« Reply #14 on: January 31, 2019, 02:23:23 pm »
Quote
Yes... I can’t explain why, but I’m sure that you’re going to tell me that’s the problem...
It's not a problem, but makes no sense to pass all those components as parameter. Why don't you use them directly by adding the form's unit to the uses clause? Like this:
Code: Pascal  [Select][+][-]
  1. uses unit1;//forms unit
  2.  
  3. procedure SetImgZoom;
  4. begin
  5.   MyZoom:= TZoomCls.Create;
  6.   Form1.TrackBar.OnChange := @MyZoom.TrackBarChange;
  7.   Form1.DtSource.OnDataChange:=@MyZoom.DtSourceChange;
  8.   MyZoom.TrackBarChange(Form1.TrackBar);
  9.   AfficherImage;
  10. end;
  11.  
« Last Edit: January 31, 2019, 02:58:45 pm by GetMem »

 

TinyPortal © 2005-2018