2
votes

So when you double click on a button and it autocompletes the buttonclick procedure, I'm curious about how the compiler knows which button the function is linked to. For example it would make TForm1.Button1Click(Sender: TObject);

So how does the compiler know which button that is linked too? Does it just parse the procedure name to see what button it is?

2

2 Answers

10
votes

You can name the method to any name, and Delphi doesn't parse or use the method name to identify the component or event associated.

If you do it at design time, the event association with a event handler is stored in the DFM file, where you find something like:

  object Button1: TButton
    Left = 104
    Top = 64
    Width = 75
    Height = 25
    Caption = 'Button1'
    TabOrder = 0
    OnClick = Button1Click
  end

The OnClick = Button1Click makes your program associate the method (also known as the event handler) to the event (a special kind of property) of the object at runtime, when the form is created.

You can also associate an event to any compliant method at runtime, for example with this code:

type
  TForm1 = class(TForm)
    Button1: TButton;
  private
    procedure MyClick(Sender: TObject);
    procedure MyOtherClick(Sender: TObject);


  ....

procedure TForm1.AssociateClickHandler;
begin
  Button1.OnClick := MyClick;
end;

procedure TForm1.MyClick(Sender: TObject);
begin
  Button1.OnClick := MyOtherClick; //from now, the other method with handle the event.
end;

Use any name you want

At design time, you can write the name you want for the event handler directly in the ObjectInspector, then press Enter and Delphi will create the method with that name for you. If you don't provide a name, Delphi auto-generates the name for the method using the component name, plus the event name without the "On". If the method already exists, the IDE just associate the event with that method.

Write the desired method name:

enter image description here

Press enter:

enter image description here

You can associate the same method to different events of the same object, or to the same event of different objects.

For example, you can associate the MyOwnMethodName shown above to the OnClick of any number of buttons. Usually, the Sender parameter contains a reference to the object that is firing the event.

4
votes

The compiler is not involved in any of this. The IDE is handling everything instead.

When you double-click on a control at design-time, the Form Designer knows which control is being clicked on, as it is a live object in memory.

The Form Designer uses the control's RTTI and registered TComponentEditor implementation (the VCL provides a default implementation if a user-defined implementation is not registered) to determine which event for that class type is the default event (in the case of TButton, that is the OnClick event), then uses the RTTI to check if that event already has a handler assigned to it.

If a handler is not assigned yet, the Form Designer uses the RTTI to read the control's Name property and the event's declared name, concatenates them together (dropping the On portion of the event name), and looks for a procedure of that name in the source code of the control's Owner. If that procedure is not found, it is created at that time.

Once the Form Designer finds the procedure, it uses the RTTI to validate that the procedure matches the signature of the event, then assigns the procedure as the new event handler if needed before then finally jumping to the procedure implementation in the Code Editor.

If you click on the control's event in the Object Inspector and rename the handler, the corresponding procedure in the source code is renamed to match the new name, and any other events, even in other components, that were linked to that same procedure are updated via their RTTI to match the new name as well.

When compiling the project, the IDE first utilizes RTTI and registered component streaming routines to create a .DFM file that contains all of the various component property/event values. Then it invokes the compiler, which compiles the source code and links in the .DFM file as a binary resource into the final executable.

At runtime, the RTL parses the DFM resource, using RTTI and registered custom component streaming routines, to locate the various components and hook up their property/event values as needed.