2

所以,当你双击一个按钮,它自动完成buttonclick过程,我很好奇编译器知道该函数链接到哪个按钮。例如,它会使TForm1.Button1Click(发件人:TObject);Delphi自动完成ButtonClick过程

那么编译器如何知道链接了哪个按钮呢?它只是解析过程名称,看看它是什么按钮?

回答

10

您可以将方法命名为任意名称,并且Delphi不会解析或使用方法名称来标识关联的组件或事件。

如果你在设计时做到这一点,有一个事件处理函数的事件关联存储在DFM文件,其中你会发现这样的:

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

OnClick = Button1Click使你的程序的方法联系起来(也称为作为事件处理程序)在运行时创建表单时的对象的事件(一种特殊的属性)。

你也可以一个事件,任何兼容的方法在运行时,例如与该代码相关联:

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; 

使用要

在设计时的任何名称,你可以写你想要的名称对于直接在ObjectInspector中的事件处理程序,然后按Enter键,Delphi将为您创建具有该名称的方法。如果您没有提供名称,Delphi会自动为使用组件名称的方法生成名称,并在没有“开”的情况下生成事件名称。如果该方法已经存在,则IDE将该事件与该方法关联。

写入所需的方法名称:

enter image description here

按ENTER键:

enter image description here

您可以对同一个对象的不同事件的相同方法相关联,或者同一事件不同的对象。

例如,您可以将上面显示的MyOwnMethodName关联到任意数量的按钮的OnClick。通常,发件人参数包含对引发事件的对象的引用。

4

编译器没有涉及任何这一点。 IDE正在处理所有事情。

当您在设计时双击控件时,窗体设计器会知道正在单击哪个控件,因为它是内存中的活动对象。

表单设计器使用控制的RTTI和注册TComponentEditor实现(VCL提供如果一个用户定义的执行未注册的默认实现)(以确定哪些事件该类类型是默认的事件中的TButton的情况下,即OnClick事件),然后使用RTTI来检查该事件是否已分配处理程序。

如果处理程序尚未分配,表单设计器将使用RTTI读取控件的属性和事件的声明名称,将它们连接在一起(删除事件名称的On部分),然后查找过程该名称在控件的源代码Owner中。如果没有找到该过程,那么该过程将在当时创建。

表单设计程序找到过程后,它使用RTTI来验证过程是否与事件的签名相匹配,然后在需要之前将过程指定为新的事件处理程序,然后才能最终跳转到代码中的过程实现编辑。

如果在对象检查器中单击控件的事件并重命名处理程序,则会重命名源代码中的相应过程以匹配新名称以及任何其他事件(即使在其他组件中)同样的过程通过它们的RTTI更新以匹配新的名字。

编译项目时,IDE首先使用RTTI和注册组件流程例程来创建包含所有各种组件属性/事件值的.DFM文件。然后它调用编译器,该编译器将.DFM文件中的源代码和链接编译为最终可执行文件中的二进制资源。

在运行时,RTL使用RTTI和注册的自定义组件流程例程来解析DFM资源,以定位各个组件并根据需要连接它们的属性/事件值。