Articles   Members Online:
-Article/Tip Search
-News Group Search over 21 Million news group articles.
-Delphi/Pascal
-CBuilder/C++
-C#Builder/C#
-JBuilder/Java
-Kylix
Member Area
-Home
-Account Center
-Top 10 NEW!!
-Submit Article/Tip
-Forums Upgraded!!
-My Articles
-Edit Information
-Login/Logout
-Become a Member
-Why sign up!
-Newsletter
-Chat Online!
-Indexes NEW!!
Employment
-Build your resume
-Find a job
-Post a job
-Resume Search
Contacts
-Contacts
-Feedbacks
-Link to us
-Privacy/Disclaimer
Embarcadero
Visit Embarcadero
Embarcadero Community
JEDI
Links
Creating a component at runtime Turn on/off line numbers in source code. Switch to Orginial background IDE or DSP color Comment or reply to this aritlce/tip for discussion. Bookmark this article to my favorite article(s). Print this article
08-Jan-03
Category
VCL-General
Language
Delphi 2.x
Views
38
User Rating
No Votes
# Votes
0
Replies
0
Publisher:
DSP, Administrator
Reference URL:
DKB
			Author: Lou Adler

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.

Answer:

Thank God for object-oriented environments! First of all, you can assign any 
object's method to another method as long as it has the same form. Look at the code 
below:

1   {This method is from another button that when pressed will create
2    the new button.}
3   
4   procedure TForm1.Button1Click(Sender: TObject);
5   var
6     btnRunTime: TButton;
7   begin
8     btnRunTime := TButton.Create(form1);
9     with btnRunTime do
10    begin
11      Visible := true;
12      Top := 64;
13      Left := 200;
14      Width := 75;
15      Caption := 'Press Me';
16      Name := 'MyNewButton';
17      Parent := Form1;
18      OnClick := ClickMe;
19    end;
20  end;
21  
22  {This is the method that gets assigned to the new button's OnClick method}
23  
24  procedure TForm1.ClickMe(Sender: TObject);
25  begin
26    with (Sender as TButton) do
27      ShowMessage('You clicked me');
28  end;
29  
30  //As you can see, I created a new method called ClickMe, which was declared in the 
31  private section of Form1:
32  
33  type
34    TForm1 = class(TForm
35        ...
36        ...
37        private
38  
39  procedure ClickMe(Sender: TObject);
40  published
41    end;
42  
43  //There's no way to write code at run time, so it has to pre-exist. Fortunately 
44  with Delphi, you can perform re-assignment of methods to other methods in code. 
45  This duplicates assigning all the OnClick methods of a bunch of buttons to a single 
46  button's OnClick that you can do in the Object Inspector. You're just doing it in 
47  code.
48  
49  //So why does this work?
50  
51  //Event handlers are really nothing more than pointers to procedures. In the object 
52  code, they're declared something like the following:
53  
54  type
55    TNotifyEvent = procedure(Sender: TObject) of object;
56    TMouseEvent = procedure(Sender: TObject; Button: TMouseButton; Shift:
57      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 the structure 
that's what I'm expecting (the FOnClick var). In the case of OnClick, it's a method 
that has a single parameter of TObject &mdash (Sender : TObject). Note that I 
specifically say "method," which implies that the procedure 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 by Windows message handlers. For instance, sometimes it's 
not enough just to declare an event handler. A button also gets its "button-ness" 
from the Windows messages it traps as well. For an OnClick, the specific Windows 
message is WM_LBUTTONUP (OnClick in the help is explained as an event that occurs 
when the user presses the mouse button down and releases it, which is why the user 
code is not executed until the button is released), and that is handled in the 
component code behind the scenes. It executes regardless of the code you assign to 
the OnClick procedure, and it is executed first. So here's pecking order:

User clicks on a button.
Windows Message code gets executed to ellicit default behavior for the component.
Any code assigned to the user event handler is then executed by a specific Windows 
message handler.

This is stuff you don't normally hear about, and it's important to understand the intricacies behind why something works the way it does as opposed to me just giving you a "pat" answer. What I've essentially outlined here is the way in which an event handler is created. If you want more information, I suggest you get a book that deals with this. Ray Konopka's book Building Delphi Components (or something like that) is a good reference.

			
Vote: How useful do you find this Article/Tip?
Bad Excellent
1 2 3 4 5 6 7 8 9 10

 

Advertisement
Share this page
Advertisement
Download from Google

Copyright © Mendozi Enterprises LLC