在运行时从窗体删除TFrame

liv*_*ove 2 c++ runtime c++builder tframe

我正在使用C ++ Builder创建VCL表单应用程序。现在我有一个包含许多组件的TFrame,看起来像这样...

在此处输入图片说明

我也有一个按钮调用“添加”。基本上,每当我按下表单上的“添加”按钮时,都会向其中添加一个新的TFrame,并在前一个TFrame下方添加一个看起来像表格的东西。为了添加重复项,我必须在创建TFrame之前每次都对其重命名。

    int __fastcall TForm1::AddMapCells(void)
    {
        Num++;
        TFrame1 * MyFrame = new TFrame1(Form1);
        MyFrame->Parent=Form1;
        MyFrame->Name = "TFrame" + IntToStr(Num);
        MyFrame->Top = 23*Num;
        return Num;
    }
Run Code Online (Sandbox Code Playgroud)

因此,TFrame的命名为TFrame1,TFrame2,TFrame3等。

现在的问题是我要制造它,因此每当我按下TFrame的“ X”按钮时,它都会删除该TFrame,并且我不确定该怎么做。我在想,也许每次创建TFrame时,我都可以重命名“ X”按钮,所以它就像Button1,Button2,Button3等。然后删除程序,只需将ButtonX与TFrameX匹配即可识别要删除的TFrame。例如,如果我按下按钮4,它应该与TFrame4匹配并删除TFrame4。

我不知道如何实现这个想法。还是会有更简单的方法来做到这一点?

Rem*_*eau 5

一个简单的解决方案是让TFrame实例为您释放自己。将OnClick事件处理程序分配给X按钮,并使其TFrame通过PostMessage(),将排队的消息发布到其父窗口,然后为TFrame该类提供一个消息处理程序,该消息处理程序在处理TFrame该消息时释放实例(这是TForm::Release()方法的工作方式),例如:

void __fastcall TFrame1::CloseButtonClick(TObject *Sender)
{
    // CM_RELEASE is defined in Controls.hpp
    PostMessage(Handle, CM_RELEASE, 0, 0);
} 

void __fastcall TFrame1::WndProc(TMessage &Message)
{
    if (Message.Msg == CM_RELEASE)
    {
        delete this;
        return;
    }

    TFrame::WndProc(Message);
}
Run Code Online (Sandbox Code Playgroud)

如果您需要TForm通知父母TFrame关闭的消息(例如,重新定位较低级的TFrame实例),则可以TNotifyEventTFrame类中公开一个自定义事件,并TForm为其分配事件处理程序,例如:

class TFrame1 : public TFrame
{
private:
    TNotifyEvent FOnClose;
    ...
public:
    ...
    __property TNotifyEvent OnClose = {read=FOnClose, write=FOnClose};
};

void __fastcall TFrame1::CloseButtonClick(TObject *Sender)
{
    if (FOnClose != NULL) FOnClose(this);
    PostMessage(Handle, CM_RELEASE, 0, 0);
} 

void __fastcall TFrame1::WndProc(TMessage &Message)
{
    if (Message.Msg == CM_RELEASE)
    {
        delete this;
        return;
    }

    TFrame::WndProc(Message);
}
Run Code Online (Sandbox Code Playgroud)

int __fastcall TForm1::AddMapCells(void) 
{ 
    Num++; 
    TFrame1 * MyFrame = new TFrame1(this); 
    MyFrame->Parent = this; 
    MyFrame->Name = "TFrame" + IntToStr(Num); 
    MyFrame->Top = 23*Num; 
    MyFrame->OnClose = &FrameClosed;
    return Num; 
} 

void __fastcall TForm1::FrameClosed(TObject *Sender)
{
    // Sender is the TFrame1 instance whose X button was clicked.
    // It will auto-free itself after this method exits...
}
Run Code Online (Sandbox Code Playgroud)

  • 将您的TFrame指针存储在TList,std :: vector,std :: list等中,无论您喜欢什么。当一个给定的TFrame实例被关闭时,您可以在列表中找到该指针,将其删除,然后遍历剩余的指针,使它们的Top属性减一,将被关闭的TFrame的Height减低。 。您不必依赖于它们的`Name`值,实际上,我始终不给我的`TFrame`对象完全没有`Name`值,只需将`Name`设置为空白字符串即可。工作正常。 (2认同)