Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to close an MDI child without using the system Close button

I am using the code below to close an MDI child form by clicking on the system close button, and it works fine:

procedure Tfrm_main.FormClose(Sender: TObject;
  var Action: TCloseAction);
begin
  Action := caFree;
end;

But how if I want to close the MDI child form by using a standard button (inside the child form itself). If I call Close within an event handler, then I get an access violation exception.

Is there any way to close the MDI child form by using a standard button (not the system close button) placed inside the child form itself, without raising an access violation exception?

I've done searching similar questions, and tried various code, but still got the exception.

like image 868
Aliana Donovan Avatar asked Nov 25 '16 08:11

Aliana Donovan


People also ask

How to disable minimize button of MDI form?

If you want it to be able to be resized then change to maxbutton property to false. If you want it to not be resized then change the borderstyle to '1-Fixed Single' and the minibutton property to true.


1 Answers

Calling Close() on a child MDI Form from inside a button OnClick event of the same child Form is perfectly safe. Internally, Close() triggers the OnClose event, and if the Action parameter is set to caFree then the Form will call Release() on itself, which is a delayed action that will free the Form from memory when it is safe to do so.

The following code works perfectly fine for me in Delphi 7:

unit ChildUnit;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TChildForm = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  ChildForm: TChildForm;

implementation

{$R *.dfm}

procedure TChildForm.Button1Click(Sender: TObject);
begin
  Close;
end;

procedure TChildForm.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  Action := caFree;
end;

end.

If you are getting an Access Violation when calling Close(), the most likely culprit is you are calling Close() on an invalid Form pointer.

like image 174
Remy Lebeau Avatar answered Oct 07 '22 01:10

Remy Lebeau