我有一个组件,我创建,然后在我的主窗体上传递给它一个面板.
这是一个非常简单的例子:
procedure TMy_Socket.StatusPanel_Add(AStatusPanel: TPanel);
Run Code Online (Sandbox Code Playgroud)
然后,该组件将在需要时更新面板标题.
在我的主程序中,如果我FreeAndNil在面板下次组件尝试更新面板时我得到一个AV.我理解为什么:组件对面板的引用现在指向一个未定义的位置.
如何在组件内检测面板是否已被释放,以便我知道我无法引用它?
我试过if (AStatusPanel = nil)但不是nil,它还有一个地址.
您必须调用Panel的FreeNotification()方法,然后让TMy_Socket组件覆盖虚拟Notification()方法,例如(假设您的命名方案,我假设您可以TPanel向组件添加多个控件):
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;
Run Code Online (Sandbox Code Playgroud)
如果您只是一次跟踪一个TPanel:
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;
Run Code Online (Sandbox Code Playgroud)