Lazarus

Programming => General => Topic started by: pcurtis on September 25, 2020, 02:27:54 pm

Title: [SOLVED] Component events
Post by: pcurtis on September 25, 2020, 02:27:54 pm
Hi All,

I am playing/trying to develop a component. All is going well except for one small problem.

The component is based on TCustomComponent and has three buttons.

I can handle the onclick events of the buttons and the onclick event of the new component.

My question is this - How can I make the button onclick events fire the main components onclick event? and how can I identify which button was clicked?

I have attached a small project, that can be run without installing anything, to show my current situation. A click on a button plays a beep, and a click on the control (colored gray) shows a message.

I suppose the result should be clicking a button should beep and show a message indication which button was pressed.

Thanks in advance.
Title: Re: Component events
Post by: Soner on September 25, 2020, 03:34:01 pm
You must make your own event for this buttons like this:
Code: Pascal  [Select][+][-]
  1. unit mybutton;
  2.  
  3. //...
  4. type
  5.   TClickedButton = (btnAdd, btnSave, btnCancel); //ADD THIS
  6.   TButtonClickEvent = procedure(Sender: TObject; AButton: TClickedButton) of object; //ADD THIS
  7.  
  8.   TMyButton = class(TCustomControl)
  9.   private
  10.     fOnButtonClick: TButtonClickEvent; //ADD THIS
  11.     procedure BtnClick(Sender: TObject);  // EDIT THIS FUNCTION
  12.     //..
  13.   published
  14.     property RecordCount : integer read GetRecordCount write SetRecordCount;
  15.     property OnButtonClick: TButtonClickEvent read fOnButtonClick write fOnButtonClick; // ADD THIS
  16.  
  17.   end;
  18.  
  19. implementation
  20.  
  21. procedure TMyButton.BtnClick(Sender : TObject);   //EDIT THIS FUNCTION
  22. begin
  23.   if not Assigned(fOnButtonClick) then exit;
  24.  
  25.   if Sender=fbtnADD then fOnButtonClick(Self, btnAdd)
  26.   else if Sender=fbtnSAVE then fOnButtonClick(Self, btnSave)
  27.   else if Sender=fbtnCANCEL then fOnButtonClick(Self, btnCancel);
  28. end;
  29.  
  30. //...
  31.  
  32.  

In mainunit you can use this like this:
Code: Pascal  [Select][+][-]
  1.   TForm1 = class(TForm)
  2.   //..
  3.   private
  4.     procedure OnButtonClick(Sender: TObject; AButton: TClickedButton); //ADD THIS
  5. //..
  6.  
  7. implementation
  8.  
  9. //..
  10.  
  11. procedure TForm1.FormCreate(Sender: TObject);
  12. begin
  13.   //..
  14.   MyDB.OnButtonClick:=@OnButtonClick;  //ADD THIS
  15. end;
  16.  
  17. procedure TForm1.OnButtonClick(Sender: TObject; AButton: TClickedButton); //ADD THIS
  18. begin
  19.   MessageDlg('Button Clicked: '+Ord(AButton).ToString, mtWarning, [mbOK],0);
  20. end;
  21.  

I upload modified project.
Title: Re: Component events
Post by: Soner on September 25, 2020, 03:38:49 pm
Don't forget, TMyButton.OnClick is for clicks on the TMyButton.
When you click outside of the three button you can still get the message "abc".

TMyButton.OnButtonClick ist for the click on the tree buttons inside of the TMyButton.
Title: Re: Component events
Post by: howardpc on September 25, 2020, 03:45:11 pm
Or you can do something like this (adding a few lines to your MyButton unit):
Code: Pascal  [Select][+][-]
  1. unit mybutton;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.   Classes, SysUtils, LResources, Forms, Controls, Graphics, Dialogs, Buttons;
  9.  
  10. type
  11.  
  12.   TMyButton = class(TCustomControl)
  13.   private
  14.     fbtnADD : TBitBtn;
  15.     fbtnSAVE : TBitBtn;
  16.     fbtnCANCEL : TBitBtn;
  17.     fRecordCount : integer;
  18.     function GetRecordCount : integer;
  19.     procedure SetRecordCount(Value : integer);
  20.     procedure BtnClick(Sender: TObject);
  21.     procedure DoParentClick;
  22.   public
  23.     constructor Create(AOwner : TComponent); override;
  24.   published
  25.     property RecordCount : integer read GetRecordCount write SetRecordCount;
  26.   end;
  27.  
  28. implementation
  29.  
  30. procedure TMyButton.BtnClick(Sender : TObject);
  31. var
  32.   btn: TBitBtn absolute Sender;
  33. begin
  34.   Beep;
  35.   if Sender is TBitBtn then
  36.     ShowMessageFmt('You pressed the %s button',[btn.Name]);
  37.   DoParentClick;
  38. end;
  39.  
  40. procedure TMyButton.DoParentClick;
  41. begin
  42.   if Assigned(OnClick) then
  43.     OnClick(Self);
  44. end;
  45.  
  46. constructor TMyButton.Create(AOwner : TComponent);
  47. var
  48.   btnHeight : integer = 64;
  49.   btnWidth : integer = 64;
  50.   btnMinWidth : integer = 284;
  51.   btnGap : integer = 8;
  52.  
  53. begin
  54.   inherited Create(AOwner);
  55.  
  56.   fbtnADD := TBitBtn.Create(self);
  57.   With fbtnADD do
  58.   begin
  59.     Name := 'Add';
  60.     AutoSize := false;
  61.     Width := btnWidth;
  62.     Height := btnHeight;
  63.     Left := 0;
  64.     Caption := 'ADD';
  65.     SetSubComponent(true);
  66.     ControlStyle := ControlStyle - [csNoDesignSelectable];
  67.     parent := self;
  68.     OnClick := @BtnClick;
  69.   end;
  70.  
  71.   fbtnSAVE := TBitBtn.Create(self);
  72.   With fbtnSAVE do
  73.   begin
  74.     Name := 'Save';
  75.     AutoSize := false;
  76.     Width := btnWidth;
  77.     Height := btnHeight;
  78.     Left := fbtnADD.Left + btnWidth + btnGap;
  79.     Caption := 'SAVE';
  80.     SetSubComponent(true);
  81.     ControlStyle := ControlStyle - [csNoDesignSelectable];
  82.     parent := self;
  83.     OnClick := @BtnClick;
  84.   end;
  85.  
  86.   fbtnCANCEL := TBitBtn.Create(self);
  87.   With fbtnCANCEL do
  88.   begin
  89.     Name := 'Cancel';
  90.     AutoSize := false;
  91.     Width := btnWidth;
  92.     Height := btnHeight;
  93.     //Left := fbtnSAVE.Left + btnWidth + btnGap;
  94.     Align := alRight;
  95.     Caption := 'CANCEL';
  96.     SetSubComponent(true);
  97.     ControlStyle := ControlStyle - [csNoDesignSelectable];
  98.     parent := self;
  99.     OnClick := @BtnClick;
  100.   end;
  101.  
  102.   Color := clGray;
  103.  
  104.   Constraints.MaxHeight := btnHeight;
  105.   Constraints.MinHeight := btnHeight;
  106.  
  107.   Constraints.MinWidth := btnMinWidth;
  108.   SetBounds(0, 0, btnMinWidth, btnHeight);
  109. end;
  110.  
  111. function TMyButton.GetRecordCount : integer;
  112. begin
  113.   result := fRecordCount;
  114. end;
  115.  
  116. procedure TMyButton.SetRecordCount(Value : integer);
  117. begin
  118.   If fRecordCount <> Value then
  119.     fRecordCount := Value;
  120. end;
  121.  
  122.  
  123. end.
Title: Re: Component events
Post by: pcurtis on September 25, 2020, 03:49:02 pm
Thanks all.
TinyPortal © 2005-2018