Creating control from code in Delphi

Creating control from code in Delphi

Question:
I want to create a button in code, put it on a form and attach a procedure to its click event. How can I get the click event linked to a predefined procedure name from code? I assume the IDE linking in the object browser is key to the answer, but I want to do this at run time, not in development.

Here is a sample of my code:

unit Unit1;interfaceuses  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,Dialogs,  StdCtrls;type  TForm1 = class(TForm)    Button1: TButton;    procedure Button1Click(Sender: TObject);    procedure Button2Click(Sender: TObject);  private    { Private declarations }  public    { Public declarations }  end;var  Form1: TForm1;implementation{$R *.DFM}procedure TForm1.Button1Click(Sender: TObject); var x : tbutton;beginx := tbutton.Create(form1);x.visible := true;x.top := 200;x.left := 25;x.width := 400;x.caption := ‘I am a brand new button’;x.name := ‘button2’;x.parent := form1;end;procedure tform1.Button2Click(Sender: TObject);begin  showmessage (‘cool’); end;unit Unit1;interfaceuses  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,Dialogs,  StdCtrls;type  TForm1 = class(TForm)    Button1: TButton;    procedure Button1Click(Sender: TObject);    procedure Button2Click(Sender: TObject);  private    { Private declarations }  public    { Public declarations }  end;var  Form1: TForm1;implementation{$R *.DFM}procedure TForm1.Button1Click(Sender: TObject); var x : tbutton;beginx := tbutton.Create(form1);x.visible := true;x.top := 200;x.left := 25;x.width := 400;x.caption := ‘I am a brand new button’;x.name := ‘button2’;x.parent := form1;end;procedure tform1.Button2Click(Sender: TObject);begin  showmessage (‘cool’); end;
Clicking on the new button does nothing. Help!

Answer:
Thank God for object-oriented environments! You’re doing everything prettymuch correctly, but there’s one thing you should know: You can assign anyobject’s method to another method as long as it has the same form. Look atthe code below:

{This method is from another button that when pressed will create the new button.}procedure TForm1.Button1Click(Sender: TObject);var  btnRunTime : TButton;begin  btnRunTime := TButton.Create(form1);  with btnRunTime do begin    Visible := true;    Top := 64;    Left := 200;    Width := 75;    Caption := ‘Press Me’;    Name := ‘MyNewButton’;    Parent := Form1;    OnClick := ClickMe;  end;end;{This is the method that gets assigned to the new button’s OnClick method}procedure TForm1.ClickMe(Sender : TObject);begin  with (Sender as TButton) do    ShowMessage(‘You clicked me’);end;
As you can see, I created a new method called ClickMe, which was declared inthe private section of Form1:
type  TForm1 = class(TForm  …  …  private    procedure ClickMe(Sender : TObject);  published  end;
There’s no way to write code at run time, so it has to pre-exist.Fortunately with Delphi, you can perform re-assignment of methods to othermethods in code. This duplicates assigning all the OnClick methodsof a bunch of buttons to a single button’s OnClick that you can do in theObject Inspector. You’re just doing it in code.

So why does this work?

Event handlers are really nothing more than pointers to procedures. In theobject code, they’re declared something like the following:

type  TNotifyEvent = procedure(Sender : TObject) of object; TMouseEvent = procedure (Sender: TObject; Button: TMouseButton; Shift:TShiftState; X, Y: Integer) of object;
Then, properties in the components are assigned these types. For instance,an OnClick for a button as seen in the Object Inspector is a TNotifyEvent and is declared in the component code as follows:
property OnClick : TNotifyEvent read FOnClick write FOnClick;
All this means is: When this event occurs, execute a method that has thestructure that’s what I’m expecting (the FOnClick var). In the case ofOnClick, it’s a method that has a single parameter of TObject ? (Sender :TObject). Note that I specifically say “method,” which implies that theprocedure must be a member function of some object (like a form or another button), and not a generic procedure.

Regarding to the FOnClick, that’s just a variable with the same type as the property; as such, it can be assigned any method that has the right structure.

In some but not all components, there’s underlying behavior associated with any event that’s performed byWindows message handlers. For instance, sometimes it’s not enough just todeclare an event handler. A button also gets its “button-ness” from theWindows messages it traps as well. For an OnClick, the specific Windowsmessage is WM_LBUTTONUP (OnClick in the help is explained as an event thatoccurs when the user presses the mouse button down and releases it, whichis why the user code is not executed until the button is released), and thatis handled in the component code behind the scenes. It executes regardlessof the code you assign to the OnClick procedure, and it is executedfirst. So here’s pecking order:

  1. User clicks on a button.
  2. Windows Message code gets executed to ellicit default behavior for thecomponent.
  3. Any code assigned to the user event handler is then executed by aspecific Windows message handler.

This is stuff you don’tnormally hear about, and it’s important to understand the intricaciesbehind why something works the way it does as opposed to me just giving youa “pat” answer. What I’ve essentially outlined here is the way in which anevent handler is created. If you want more information, I suggest youget a book that deals with this. Ray Konopka’s book Building DelphiComponents (or something like that) is a good reference.

Share the Post:
XDR solutions

The Benefits of Using XDR Solutions

Cybercriminals constantly adapt their strategies, developing newer, more powerful, and intelligent ways to attack your network. Since security professionals must innovate as well, more conventional endpoint detection solutions have evolved

AI is revolutionizing fraud detection

How AI is Revolutionizing Fraud Detection

Artificial intelligence – commonly known as AI – means a form of technology with multiple uses. As a result, it has become extremely valuable to a number of businesses across

AI innovation

Companies Leading AI Innovation in 2023

Artificial intelligence (AI) has been transforming industries and revolutionizing business operations. AI’s potential to enhance efficiency and productivity has become crucial to many businesses. As we move into 2023, several

data fivetran pricing

Fivetran Pricing Explained

One of the biggest trends of the 21st century is the massive surge in analytics. Analytics is the process of utilizing data to drive future decision-making. With so much of

kubernetes logging

Kubernetes Logging: What You Need to Know

Kubernetes from Google is one of the most popular open-source and free container management solutions made to make managing and deploying applications easier. It has a solid architecture that makes

ransomware cyber attack

Why Is Ransomware Such a Major Threat?

One of the most significant cyber threats faced by modern organizations is a ransomware attack. Ransomware attacks have grown in both sophistication and frequency over the past few years, forcing

data dictionary

Tools You Need to Make a Data Dictionary

Data dictionaries are crucial for organizations of all sizes that deal with large amounts of data. they are centralized repositories of all the data in organizations, including metadata such as