From your question (I added code-style
to make it more clear):
I have a Form called ENP
, defined in the EnpView
unit. The ENP
form,
is created and shown from the handler event of a click a toolbar item
in the Main Form (TPrincipal
).
procedure TPrincipal.ENP1Click(Sender: TObject);
begin
TENP.Create(self).Show();
end;
This does nothing with your ENP
form variable.
You create an instance of the TENP
form class and show it using Show
, but the ENP
variable is not assigned.
You cannot assign the instance to the ENP
variable, as each button click creates a new instance (so you have multiple instances of TENP
) around.
Then you create a convoluted depedency of a TAddEnp
instance and the (never assinged ENP
variable).
You do this by creating a TAddEnp
instance (why TAddEnp
here, and not TAddENP
?) show it using Show
(giving the users the opportunity to go back to the TENP
instance and again click on the opAgregar
button to create more instances of TAddEnp
):
procedure TENP.opAgregarClick(Sender: TObject);
begin
TAddEnp.Create(self).Show();
end;
Followed by having the TAddEnp
depend on the ENP
variable:
procedure TAddEnp.AgregarClick(Sender: TObject);
begin
//...
ENP.clearGrid();
ENP.populateGrid();
end;
This will indeed fail:
ClearGrid messages fails in line 1, with access violation:
procedure TENP.clearGrid();
begin
Self.StringGrid.RowCount := 2;
Self.StringGrid.Rows[1].Clear();
end;
The reason is that ENP
is not assigned (by default it will be nil
), so inside clearGrid
, the Self
will also be nil
.
Solutions you could implement
- Keep a single instance of
TENP
and TAddEnp
around, using ShowModal
to force modality to prevent the user from clicking on the same buttons multiple times.
- Keep your existing
Show
behaviour, but binding each TAddEnp
instance to the TENP
instance it was created from.
For the first solution, your code will become this:
procedure TPrincipal.ENP1Click(Sender: TObject);
begin
ENP := TENP.Create(Application);
ENP.ShowModal();
ENP.Release();
ENP := nil;
end;
and
procedure TENP.opAgregarClick(Sender: TObject);
begin
AddEnp := TAddEnp.Create(Application);
AddEnp.ShowModal();
AddEnp.Release();
AddEnp := nil;
end;
The second will take more effort, as you need to prevent the use of the existing variables.
- Delete the
ENP
variable.
- Delete the
AddENP
variable.
Fix the self
-> Self
in the methods
procedure TPrincipal.ENP1Click(Sender: TObject);
begin
TENP.Create(Self).Show();
end;
and
procedure TENP.opAgregarClick(Sender: TObject);
begin
TAddEnp.Create(Self).Show();
end;
Here add the dependency:
procedure TAddEnp.AgregarClick(Sender: TObject);
var
ENP: TENP;
begin
//...
ENP := Owner as TENP; // Owner will be of type TENP because of the Create(Self) in the ENP1Click method
ENP.clearGrid();
ENP.populateGrid();
end;