Удаление TFrame из формы во время выполнения - PullRequest
2 голосов
/ 06 февраля 2012

Я использую C ++ Builder для создания приложения формы VCL.Прямо сейчас у меня есть TFrame, содержащий кучу компонентов, и это выглядит так ...

enter image description here

У меня также есть кнопка вызова «Добавить».По сути, каждый раз, когда я нажимаю кнопку «Добавить» в форме, к ней добавляется новый 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 и т. Д.

Теперь проблема заключается в том, что я хочу сделать так, чтобы каждый раз, когда я нажимал «X»кнопка TFrame, он удаляет этот TFrame, и я не совсем уверен, как это сделать.Я думал, что, возможно, каждый раз, когда я создаю TFrame, я также могу переименовывать кнопку «X», чтобы она выглядела как Button1, Button2, Button3 и т.д.Например, если я нажму кнопку 4, она должна совпадать с TFrame4 и удалить TFrame4.

Я не знаю, как реализовать эту идею.Или был бы более легкий способ сделать это?

1 Ответ

4 голосов
/ 07 февраля 2012

Простым решением было бы позволить экземплярам 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...
}
...