I have a component that I create and then pass into it a panel on my main form.
Here is a very simplified example:
procedure TMy_Socket.StatusPanel_Add(AStatusPanel: TPanel);
This component will then update the panels caption as the need arises.
In my main program if I FreeAndNil
the panel the next time the component tries to update the panel I get an AV. I understand why: the component's reference to the panel now is pointing to an undefined location.
How can I detect within the component if the panel has been freed so I know I can not reference it?
I tried if (AStatusPanel = nil)
but it is not nil
, it still has an address.
You have to call the Panel's FreeNotification()
method, and then have your TMy_Socket
component override the virtual Notification()
method, eg (given your naming scheme, I assume you can add multiple TPanel
controls to your component):
type
TMy_Socket = class(TWhatever)
...
protected
procedure Notification(AComponent: TComponent; Operation: TOperation); override;
...
public
procedure StatusPanel_Add(AStatusPanel: TPanel);
procedure StatusPanel_Remove(AStatusPanel: TPanel);
...
end;
procedure TMy_Socket.StatusPanel_Add(AStatusPanel: TPanel);
begin
// store AStatusPanel as needed...
AStatusPanel.FreeNotification(Self);
end;
procedure TMy_Socket.StatusPanel_Remove(AStatusPanel: TPanel);
begin
// remove AStatusPanel as needed...
AStatusPanel.RemoveFreeNotification(Self);
end;
procedure TMy_Socket.Notification(AComponent: TComponent; Operation: TOperation);
begin
inherited;
if (AComponent is TPanel) and (Operation = opRemove) then
begin
// remove TPanel(AComponent) as needed...
end;
end;
If you are only tracking one TPanel
at a time instead:
type
TMy_Socket = class(TWhatever)
...
protected
FStatusPanel: TPanel;
procedure Notification(AComponent: TComponent; Operation: TOperation); override;
...
public
procedure StatusPanel_Add(AStatusPanel: TPanel);
...
end;
procedure TMy_Socket.StatusPanel_Add(AStatusPanel: TPanel);
begin
if (AStatusPanel <> nil) and (FStatusPanel <> AStatusPanel) then
begin
if FStatusPanel <> nil then FStatusPanel.RemoveFreeNotification(Self);
FStatusPanel := AStatusPanel;
FStatusPanel.FreeNotification(Self);
end;
end;
procedure TMy_Socket.Notification(AComponent: TComponent; Operation: TOperation);
begin
inherited;
if (AComponent = FStatusPanel) and (Operation = opRemove) then
FStatusPanel := nil;
end;
If your component needs to be notified when another component is freed, have a look at TComponent.FreeNotification
. It should be just what you need.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With