Title: A form that cleans up after itself
Question: Sick and tired of always cleaning up a form variable, after closing/destroying the form? Wouldn't it be nice if it was all automatic? Here's how....
Answer:
To do this, we need to create a base form class, that we will use for all of the forms in our application. In this class, create a class procedure for creating the form. This way, we can store the location of the form variable, and clean it up as the form is being closed. This has another benefit of allowing you to call a single procedure, not having to worry about creation of the form, or detection of if it already exists.
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs;
type
TfrmBaseClass = class of TfrmBase;
TfrmBase = class(TForm)
procedure FormClose(Sender: TObject; var Action: TCloseAction);
private
{ Private declarations }
FFormPtrSet: Boolean;
FFormPtr: ^TfrmBase;
public
{ Public declarations }
procedure SetFormPtr(var l_FormVar);
class procedure OpenForm(l_FormClass: TfrmBaseClass;
var l_FormVar; l_Show: Boolean); overload;
end;
var
frmBase: TfrmBase;
implementation
{$R *.DFM}
class procedure TfrmBase.OpenForm(l_FormClass: TfrmBaseClass; var l_FormVar;
l_Show: Boolean);
{------------------------------------------------------------------------------
OpenForm
The OpenForm starts the process of not having to check for pointers etc.
when closing a form. This also provides a generic call to open a form of
any type (as long as it is a descendant of TfrmBase).
------------------------------------------------------------------------------}
begin
if not Assigned(TfrmBase(l_FormVar)) then
Application.CreateForm(l_FormClass, l_FormVar);
TfrmBase(l_FormVar).SetFormPtr(l_FormVar);
if l_Show then
begin
TfrmBase(l_FormVar).Show;
end;
end;
procedure TfrmBase.SetFormPtr(var l_FormVar);
{------------------------------------------------------------------------------
SetFormPtr
Hold the location of the variable that references this form.
This function allows this form to clean up that variable, when closing.
------------------------------------------------------------------------------}
begin
FFormPtr := @l_FormVar;
FFormPtrSet := True;
end;
procedure TfrmBase.FormClose(Sender: TObject; var Action: TCloseAction);
{------------------------------------------------------------------------------
FormClose
It is assumed that all forms are to be freed when closed. Also, this will
clear out the varaible that was pointing to this object.
------------------------------------------------------------------------------}
begin
Action := caFree;
if FFormPtrSet then
FFormPtr^ := nil;
end;
end.
To use this, you will need to descend a form from this class. Then, to open an existing form, or create a new form, it is simply a matter of calling the OpenForm class procedure:
TfrmBase.OpenForm(TfrmBaseChild, frmBaseChild);