2012-09-19 65 views
4

我有一個組件創建,然後在主窗體上傳入一個面板。如何檢測組件是否已被釋放?

這裏是一個非常簡化的例子:

procedure TMy_Socket.StatusPanel_Add(AStatusPanel: TPanel); 

然後此組件將在必要時更新該面板字幕。

在我的主程序中,如果我FreeAndNil面板下一次組件嘗試更新面板我得到一個AV。我明白爲什麼:組件對面板的引用現在指向一個未定義的位置。

如何在組件內檢測面板是否已釋放,因此我知道我無法引用它?

我試過if (AStatusPanel = nil)但它不是nil,它仍然有一個地址。

回答

6

你必須調用小組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; 

如果只在一個時間,而不是跟蹤一個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; 
3

如果在另一個組件被釋放時需要通知組件,請查看TComponent.FreeNotification。它應該是你需要的。

+0

@Steve:你把通知PROC上你的'TMy_Socket'類。查看文檔頁面底部的示例。 –