我有一个表单,然后我有一个'TPageControl'对象(名为'MyPages')和一个'TButton'对象(名为'MyButton')在它上面设计时间。 然后我有一个名为'TTab'的新类,它扩展了'TTabSheet'。 'TTab'类有一个'TButton'对象作为其成员变量之一,如下所示。如何将消息从对象传递到Free Pascal中的另一个对象
class TTab = class(TTabSheet)
private
m_btnCloseTab: TButton;
end;
当我点击“为myButton”,它会创建一个新的“TTAB”对象,初始化标签(如实例化“m_btnCloseTab”),并在运行时添加到“MyPages”。
Procedure TForm1.MyButtonClick(Sender:TObject);
var
newTab: TTab;
newCaption: AnsiString;
begin
newCaption:= 'Tab' + IntToStr(count); //count is a global var
inc(count);
newTab:= TTab.Create(nil);
newTab.Init(newCaption);
newTab.Parent(MyPages);
end;
这就是TTab.Init(newCaption:AnsiString)过程的样子。
Procedure TTab.Init(newCaption: AnsiString);
begin
Self.Caption:= newCaption;
m_btnCloseTab:= TButton.Create(nil);
with m_btnCloseTab do begin
Parent:= Self;
Left:= 10;
Top:= 10;
Caption:= 'Close Tab';
Visible:= True;
OnClick:= @closeTab;
end;
end;
这增加了一个新的标签好吧。关闭按钮也显示在每个选项卡上。
如何在每个选项卡上单击'm_btnCloseTab'以关闭该特定选项卡?
如果我为TTab定义一个析构函数(通过重写TTabSheet的析构函数),我可以从外部调用它。
Destructor TTab.Destroy;
begin
if m_btnCloseTab <> nil then begin
m_btnCloseTab.Destroy;
m_btnCloseTab:= nil;
end;
inherited;
end;
但我不能从标签内部调用析构函数(可以)。如果我这样做了,我不能释放m_btnCloseTab对象,因为它会发出异常,因为我们仍然是它的事件处理程序。如果我没有释放它,那么标签会很好地关闭,但内存会泄漏(因为我们没有释放m_btnCloseTab)。
我相信我必须触发一个事件,才能从'TTab'的外部调用析构函数。我不知道该怎么做。
任何帮助,将不胜感激。
谢谢。
我不确定是否正确理解了一切。但是,如果您创建mbtnCloseTab并将Tab作为其所有者(mbtn_CloseTab:= TButton.Create(self),而不是... Create(nil)),那么该按钮会随选项卡一起自动销毁。另外,TTab应该有一个Notification方法,当它的一个子节点被销毁并且你可以使用它来设置mbtn_CloseTab为零时,它会被调用:这样可以避免Tab在按钮被销毁之前调用按钮的析构函数一些原因。 –
谢谢您的评论(我认为没有人再使用Free Pascal),但它对实际结果没有影响。 通过使用create(nil),我必须在析构函数中释放m_btnCloseTab。通过使用Create(Self),TTab类的析构函数会自动执行它。 什么是通知方法?我如何实现一个?我认为这是我需要做的事情,有点像C#中的Delegate函数。欣赏它,如果你能指向我的教程或文档如何做到这一点。 –
你错了。访问Lazarus论坛,查看活跃的Pascal社区。 –