2

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

在此处输入图像描述

我还有一个名为“添加”的按钮。基本上每次我按下表单上的 Add 按钮时,都会在其中添加一个新的 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;
    }

那么 TFrame 的命名将是 TFrame1、TFrame2、TFrame3 等。

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

我不知道如何实现这个想法。或者会有更简单的方法吗?

4

1 回答 1

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);
}

如果您需要TForm通知您的父母TFrame正在关闭(例如,重新定位较低的TFrame实例),您可以在类中公开一个自定义TNotifyEvent事件TFrame并让您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);
}

.

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...
}
于 2012-02-06T23:47:32.557 回答