2012-12-11 59 views
1

我在运行时创建的标签类似这样在运行时删除标签:通过包含窗体的按钮

procedure TForm1.ShowFormOnTab(pProcName:String); 
var 
    Newform: TForm; 
    ClassToUse: TFormClass; 

    NewTab: TTabSheet; 
    FormName: String; 

begin 
    NewTab := TTabSheet.Create(PageControl1); 
    NewTab.PageControl:= PageControl1; 

    PageControl1.ActivePage := NewTab; 

    if pProcName='ProcfrmSetupItemCategories' then 
    ClassToUse := TfrmSetupItemCategories 
    else if pProcName='ProcfrmZones' then 
    ClassToUse := TfrmZones 
    else 
    ClassToUse := nil; 
    if Assigned(ClassToUse) then 
    begin 
     NewForm := ClassTouse.Create(NewTab); 
     NewTab.Caption := NewForm.Caption; 
    end; 

现在,标签显示正确,和形式出现在他们。我需要这样做,因为表单+标签是在运行时创建的。

但这里是我的问题: 表单上有一个关闭按钮,点击时可以释放表单的资源。但是我也希望TAB在单击窗体按钮时关闭。

我该如何解决这个问题?

谢谢!

+0

你需要使它在这个问题清楚,你正在使用Lazrus而不是Delphi。以及您定位的平台。 –

+0

@DavidHeffernan似乎Lazarus和Delphi在这方面的工作都是一样的。但我只限制使用Windows API。所以它必须同时适用于Lazarus和Delphi(尽管Delphi本身仅适用于Windows) – itsols

+0

请在问题主体中明确指出您使用Lazarus并列出您的目标平台。 –

回答

2

我不喜欢的事情变得复杂的

如何获得标签的形式(的PageControl)

TForm1 = class(TForm) 
    PageControl1 : TPageControl; 

    procedure NewTabbedForm; 
end; 

procedure TForm1.NewTabbedForm; 
var 
    LForm : TForm; 
begin 
    // Some code to get a new form instance into LForm 

    LForm := TTabForm.Create(Self); 

    // now the magic to put this form into PageControl as a TabSheet 
    LForm.ManualDock(PageControl1, PageControl1, alClient); 
    // Finally 
    LForm.Show; 
end; 

形式的标题将被自动用于自动创建标签页标题。

如何释放/删除标签形式

简短

TTabForm = class(TForm) 
    Close_Button : TButton; 
    procedure Close_ButtonClick(Sender : TObject); 
end; 

procedure TTabForm.Close_ButtonClick(Sender : TObject); 
begin 
    Self.Release; 
end; 

一点点

TTabForm = class(TForm) 
    Close_Button : TButton; 
    procedure Close_ButtonClick(Sender : TObject); 
    procedure FormClose(Sender : TObject; var Action : TCloseAction); 
end; 

procedure TTabForm.Close_ButtonClick(Sender : TObject); 
begin 
    Self.Close; 
end; 

procedure TTabForm.FormClose(Sender : TObject; var Action : TCloseAction); 
begin 
    Action := caFree; 
end; 
+0

感谢这个极好的概念。真的很感谢你已经采取了这样做的时候。 – itsols

+0

SirRufo,你为什么在这里使用的自我?它已经过时了这里:) – whosrdaddy

+0

这不是德尔福,而不是拉撒路? –

4

您可以简单地Free选项卡表。你不需要分开释放标签页的孩子。只需在标签页上拨打Free即可完成。

但是,如果按钮位于正在释放的选项卡表上,那将无法工作。从按钮的事件处理程序中释放按钮的父按钮是不可能的。

解决方法是发布自己的消息。该消息需要包含释放标签页所需的信息。通过发布消息,您可以允许OnClick事件处理程序在处理排队消息之前运行完成。

const 
    WM_FREECONTROL = WM_USER; 
.... 
PostMessage(Self.Handle, WM_FREECONTROL, 0, LParam(TabSheet)); 

那么对于消息添加处理程序的形式:

procedure WMFreeControl(var Message: TMessage); message WM_FREECONTROL; 

,并实现它是这样的:

procedure TForm1.WMFreeControl(var Message: TMessage); 
begin 
    TObject(Message.LParam).Free; 
end; 

现在,在写这篇冗长的响应,做到明确的是,第2款以后的建议仅适用于按钮是正在被释放的控件的孩子的情况。

+0

非常感谢这个信息。看一下代码行,它们看起来可行,但我相信这会限制我到MS-Windows。为什么我这么说是因为我认为这是使用Windows API。虽然我确信这是一个非常简单的技术,但我想知道您是否有一个不使用该API的替代方案。原谅我的无知。谢谢你的帮助! – itsols

+0

您正在被释放的标签页内的关闭按钮? –

+0

@大卫-hefferman是,关闭按钮是在表格上和形式是在标签纸上。我知道这是,就像你正确地指出:( – itsols