2

C++ Builder を使用して VCL フォーム アプリケーションを作成しています。現在、一連のコンポーネントを含む 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インスタンスが自分自身を解放できるようにすることです。X ボタンにイベント ハンドラーを割り当て、を介しOnClickてキューに入れられたメッセージをその親TFrameウィンドウに投稿し、そのメッセージが処理されたときにインスタンスを解放するメッセージ ハンドラーをクラスPostMessage()に与えます (これがメソッドの動作です)。TFrameTFrameTForm::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イベントを公開し、それにイベント ハンドラーを割り当てることができます。次に例を示します。TFrameTForm

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 に答える