Search code examples
delphidelphi-10-seattle

Incompatible types: 'TCloseEvent' and 'Procedure'


Here is my code :

unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure Button1Click(Sender: TObject);
  private
    { Déclarations privées }
  public
    { Déclarations publiques }
  end;

  TForm2 = class(TForm)
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
  private
    { Déclarations privées }
  public
    { Déclarations publiques }
    // I try to put it here but the same problem
    //procedure FormClose(Sender: TObject; var Action: TCloseAction);
  end;
var
  Form1: TForm1;
  Form2: TForm2;
implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
Form2 := TForm2.CreateNew(Application);
Form2.Parent := Self;
Form2.OnClose := TForm2.FormClose;
Form2.Show;
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  ShowMessage('Form1Close');
end;

procedure TForm2.FormClose(Sender: TObject; var Action: TCloseAction);
begin
   ShowMessage('Form2Close');
end;
end.

When I try to assign FormClose to OnClose event of the Form2 , I got the following error Msg:

[Dcc32 Error] Unit1.pas (40): E2010 Incompatible types: 'TCloseEvent' and 'Procedure'

When I change it to :

Form2.OnClose := FormClose;

It works fine,but that is like Self.FormClose , not the TForm2.FormClose procedure.

How can I assign TForm2.FormClose to Form2.Onclose?


Solution

  • Change TForm2.FormClose to Form2.FormClose:

    Form2.OnClose := Form2.FormClose;
    

    However, since you want the OnClose event to be associated with a handler that belongs to the same object you just created, it would be better to just move TForm2 to a separate unit with its own design-time DFM, and then you can assign the TForm2.OnClose event at design-time and let the DFM hook it up for you when TForm2.Create() is called at runtime:

    unit Unit1;
    
    interface
    
    uses
      Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
      Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;
    
    type
      TForm1 = class(TForm)
        Button1: TButton;
        procedure FormClose(Sender: TObject; var Action: TCloseAction);
        procedure Button1Click(Sender: TObject);
      private
        { Déclarations privées }
      public
        { Déclarations publiques }
      end;
    
    var
      Form1: TForm1;
    
    implementation
    
    {$R *.dfm}
    
    uses
      Unit2;
    
    procedure TForm1.Button1Click(Sender: TObject);
    begin
      Form2 := TForm2.Create(Application);
      Form2.Parent := Self;
      Form2.Show;
    end;
    
    procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
    begin
      ShowMessage('Form1Close');
    end;
    
    end.
    

    unit Unit2;
    
    interface
    
    uses
      Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
      Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;
    
    type
      TForm2 = class(TForm)
        procedure FormClose(Sender: TObject; var Action: TCloseAction);
      private
        { Déclarations privées }
      public
        { Déclarations publiques }
      end;
    
    var
      Form2: TForm2;
    
    implementation
    
    {$R *.dfm}
    
    procedure TForm2.FormClose(Sender: TObject; var Action: TCloseAction);
    begin
       ShowMessage('Form2Close');
    end;
    
    end.