2012-02-06 4 views
2

私はC++ Builderを使ってVCLフォームアプリケーションを作成しています。今私は、私はまた、「追加」ボタンのコールを持っているコンポーネントの束を含むTFrameのをしていると、それはこのようになります...実行時にフォームからTFrameを削除する

enter image description here

。基本的にフォームのAddボタンを押すたびに、新しい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などに変更することも考えていました。そして、プログラムを削除すると、TFrameとTFrameXが一致し、削除するTFrameを特定します。たとえば、ボタン4を押すと、TFrame4と一致し、TFrame4が削除されます。

このアイデアの実装方法はわかりません。または、これを行う簡単な方法がありますか?

答えて

4

簡単な解決策は、TFrameインスタンスを自分自身のために解放することです。 OnClickイベントハンドラをXボタンに割り当て、PostMessage()を介して親のTFrameウィンドウにキューに入れられたメッセージをポストしてからTFrameクラスにそのメッセージが処理されるときにTFrameインスタンスを解放するメッセージハンドラを与えます(これはTForm::Release()メソッドの仕組みです)。 )、例えば:あなたが(例えば、下TFrameインスタンスを再配置するために)閉鎖されているTFrameが通知されるように、あなたの親TFormが必要な場合は

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

、あなたはTFrameクラスでカスタムTNotifyEventイベントを公開し、あなたを持つことができます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... 
} 
+0

ありがとうございます!私は数日間このことに立ち往生していましたが、これは私のプログラムの主要な部分です]] – livelaughlove

+0

これをもう一度読むと、これらのフレームの位置付けとその背後にあるロジックについての質問をお願いしたいと思います。真ん中のフレームを削除する必要がある場合は、すべてのフレームをシフトする必要があるという、本当に良い点がありました。しかし、私はこれらのフレームを配置する方法と名前を付けた方法のために、フレームを上にシフトすると、フレームの名前を変更し、位置を再計算する必要があります。私は私の質問は、位置を行うためのより良い方法があると思いますか?私は本当にありがとう助け、私はちょうど共同生徒であり、私はこれのようなプログラムに決して対処したことがない – livelaughlove

+2

'TList'、' std :: vector'、 'std ::'あなたが気に入っているものは何でも、リストなどです。特定の 'TFrame'インスタンスが閉じられているときは、そのポインタをリスト内で見つけてそれを削除し、閉じている' TFrame'の 'Height'によって' Top'プロパティを減らす残りのポインタをループすることができます。あなたは 'Name'値に頼る必要はありません。実際に' TFrame'オブジェクトに 'N​​ame'値を与えずに、' Name'を空の文字列に設定するだけです。それはうまく動作します。 –

関連する問題