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資源,以定位各個組件並根據需要連接它們的屬性/事件值。