Link to home
Start Free TrialLog in
Avatar of fischermx
fischermxFlag for Mexico

asked on

How to assign a procedure to a TButton.OnClick event


I know that if I declare a method to a form, like:
    procedure ButtonCancelClick(Sender: TObject);

I can assign that to the button:
  btnCancel.OnClick := ButtonCancelClick;

But in this case, I don't have a form previously created.  I mean, I created a Form at run time, and I'm adding some buttons and I want to add some events to the clicks of the buttons.
So, without the procedure being in a form, I get the error:

Incompatible types: 'TNotifyEvent' and 'procedure, untyped pointer or untyped parameter'

Avatar of gazzzzzzer
gazzzzzzer
Flag of United Kingdom of Great Britain and Northern Ireland image

Make sure that the ButtonCancelClick procedure has the correct signature.

procedure TForm1.SomeOtherProcedure()
begin
    btnCancel.OnClick := ButtonCancelClick;
end;


procedure TForm1.ButtonCancelClick(Sender : TObject);
begin
  
end;

Open in new window

Avatar of fischermx

ASKER

gazzzzer:

I don't have "TForm1".

So I can't write it as :
procedure TForm1.ButtonCancelClick(Sender : TObject);

Mine is plain:
procedure ButtonCancelClick(Sender : TObject);
Perhaps this might help you...

Delphi: How to assign dynamically an event handler without overwriting the existing event handler?
http://stackoverflow.com/questions/4501623/delphi-how-to-assign-dynamically-an-event-handler-without-overwriting-the-existi
ASKER CERTIFIED SOLUTION
Avatar of Ephraim Wangoya
Ephraim Wangoya
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of jimyX
jimyX

I have created a demo for how to create form with button and assign an event for the button OnClick:
demo.zip
Here;
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    CheckBox1: TCheckBox;
    procedure Button1Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure CheckBox1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
showmessage('Button test');
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
[b]Button1.OnClick := Button1Click;
CheckBox1.OnClick := CheckBox1Click;[/b]
end;

procedure TForm1.CheckBox1Click(Sender: TObject);
begin
showmessage('CheckBox test');
end;

end.

Open in new window

you need to show your code for creating the form on the fly
to attach a event you need to create a procedure "of object"

you can attach an event use the form from which create the dynamic form:
 
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    procedure OnClickbtnTest1(Sender: TObject);
    procedure OnClickbtnTest2(Sender: TObject);

  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var frm: TForm;
  b: TButton;
begin
  frm := TForm.Create(Self);
  try
    frm.Caption := 'Test click';
    b := TButton.Create(frm);
    b.Parent := frm;
    b.Caption := 'Test1';
    b.Name := 'btnTest1';
    b.Left := 100;
    b.Top := 20;
    b.OnClick := OnClickbtnTest1;
    b := TButton.Create(frm);
    b.Parent := frm;
    b.Caption := 'Test2';
    b.Name := 'btnTest2';
    b.Left := 200;
    b.Top := 20;
    b.OnClick := OnClickbtnTest2;
    frm.ShowModal;
  finally
    frm.Free;
  end;
end;

procedure TForm1.OnClickbtnTest1(Sender: TObject);
begin
  ShowMessage(TButton(Sender).Name + ' Clicked in form with caption "' + TForm(TButton(Sender).Owner).Caption + '"');
end;

procedure TForm1.OnClickbtnTest2(Sender: TObject);
begin
  ShowMessage(TButton(Sender).Name + ' Clicked in form with caption "' + TForm(TButton(Sender).Owner).Caption + '"');
end;


end.

Open in new window

SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
if you are creating your own component
then override the Click method instead
(or the DoShow or the DoCreate or ...) (look for dynamic in the delphi source codes)
and then call the inherited (or first call inherited) depends on behaviour you want

This will leave the event empty for other people to use in the form designer

assume you want do something (like add a 'A' in the caption)

type
  TMyButton = class(TButton)
  public
    procedure Click; override;
  end;

procedure TMyButton.Click;
begin
  Self.Caption := 'A' + Self.Caption;
  inherited Click;
end;

I wasn't creating a custom button.

It was a creating a form on the fly with buttons on the fly with events on the fly.

The solution I used was from Ewangoya.



Thank you!