i have the code as follows:
begin
Application.Initialize;
Application.Title := 'Controle Bancário';
Application.CreateForm(T_DMEstagio, _DMEstagio);
Application.CreateForm(T_frmLogin, _frmLogin);
if (_frmLogin.ShowModal = 1) then
begin
FreeAndNil(_frmLogin);
Application.CreateForm(T_frmPrincipal, _frmPrincipal);
Application.Run;
end;
_DMEstagio.Free;
end.
If I DONT explicitly free the DM as I did in the code, I get an Access Violation Exception, but in another application that the code is like this:
begin
Application.Initialize;
Application.Title := ' > Sistema de Gestão Comercial <';
if HPrevInst = 0 then
begin
Application.CreateForm(TFrmPrincipal, FrmPrincipal);
Application.CreateForm(TIBDM, IBDM);
Application.Run;
end ;
end.
I dont have to free the DM and i dont get any exception. Why is that?
Answer to your question
"When do I need to free a Data Module created by the Application?"
is never.
All data modules and/or forms created with Application.CreateForm
method will be owned by Application
and automatically handled.
But as it seems, you issues are not related to automatic destruction process. Following code should resolve your issues as some components and classes need application to complete its full initialization/running cycle in order to destroy gracefully. It is possible that RXHook
is one of them.
begin
Application.Initialize;
Application.Title := 'Controle Bancário';
Application.ShowMainForm := false;
Application.CreateForm(T_DMEstagio, _DMEstagio);
Application.CreateForm(T_frmLogin, _frmLogin);
if (_frmLogin.ShowModal = 1) then
begin
FreeAndNil(_frmLogin);
Application.ShowMainForm := true;
Application.CreateForm(T_frmPrincipal, _frmPrincipal);
end
else Application.Terminate;
Application.Run;
end.
So what is exactly happening in above code?
You are trying to show login form and depending on login result proceed with running your application or terminate it.
It is important to note that first form you create will become Application.MainForm
, if that form is released before Application.Run
executes Application.MainForm
will be set back to nil
. That will ensure that next created form can become main form.
In your case that means that _frmLogin
will be set as your Application.MainForm
. If login is successful, it will be released and _frmPrincipal
will take over. But if the login is not successful _frmLogin
will still be Application.MainForm
when Application.Run
is executed and will be shown again.
This is where Application.ShowMainForm
comes into place. When it is set to false
Application.Run
will just run without showing any forms. In your case it will prevent _frmLogin
to reappear again. Of course, on successful login you want to set Application.ShowMainForm
back to true
to ensure normal application startup.
Calling Application.Terminate
in case of unsuccessful login will ensure that your application exits application main message loop that will start with call to Application.Run
and terminate gracefully.