Deleting TFrame from form at run time

我只是一个虾纸丫 提交于 2020-02-04 11:50:11

问题


I am using C++ Builder to create a VCL form application. Right now I have a TFrame containing a bunch of components and it looks like this...

I also have a button call "Add". Basically every time I press that Add button on the form, a new TFrame is added to it and below the previous one making something that looks like a table. And in order to add duplicates I have to rename the TFrame each time before it is created.

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

So then the naming of TFrame would be TFrame1, TFrame2, TFrame3, etc.

The problem now is I want to make it so then each time I press the 'X' button of a TFrame, it deletes that TFrame and I'm not quite sure how to do it. I was thinking maybe each time I create a TFrame I can also rename the 'X' button so then it's like Button1, Button2, Button3, etc. And then to delete the program would just match ButtonX with TFrameX to identify which TFrame to delete. For example, if I press Button 4, it should match up with TFrame4 and delete TFrame4.

I don't know how to implement this idea. Or would there be an easier way of doing this?


回答1:


A simple solution would be to let the TFrame instances free themselves for you. Assign an OnClick event handler to the X button and have it post a queued message to its parent TFrame window via PostMessage(), then give the TFrame class a message handler that frees the TFrame instance when that message is processed (this is how the TForm::Release() method works), eg:

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

If you need your parent TForm to be notified of the TFrame being closed (for instance, to reposition lower TFrame instances), you can expose a custom TNotifyEvent event in the TFrame class and have your TForm assign an event handler to it, eg:

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...
}


来源:https://stackoverflow.com/questions/9163664/deleting-tframe-from-form-at-run-time

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!