问题描述
我有一个创建的组件,然后将其传递到主窗体上的面板中。
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.
在我的主程序中,如果我 FreeAndNil
面板,下一次组件尝试更新面板时,我得到一个AV。我知道为什么:该组件对面板的引用现在指向一个未定义的位置。
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?
我尝试了 if(AStatusPanel = nil)
,但不是 nil
,它仍然有一个地址。
I tried if (AStatusPanel = nil)
but it is not nil
, it still has an address.
推荐答案
您必须致电小组的 FreeNotification( )
方法,然后让您的 TMy_Socket
组件覆盖虚拟的 Notification()
方法,例如(根据您的命名方案,我假设您可以向您的组件中添加多个 TPanel
控件):
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;
如果您仅跟踪一个 TPanel
改为时间:
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;
这篇关于如何检测组件已释放?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!