まず、コードが複数の を作成していることに注意してくださいTStringGrid
。フォームの同じ場所に同じ寸法でそれらをすべて作成しているだけなので、一番上にあるものだけが表示されます。
--
あなたができるようにしたいこと ( Form1->dynamically_created_TStringGrid
) は不可能ですが、同様の動作を得るために利用できる方法がいくつかあります。
std::vector メソッド
Unit1.h
#ifndef Unit1H
#define Unit1H
#include <vector>
//your other includes here
class PACKAGE Form1 : public TForm
{
__published: //IDE-managed Components
//your components here
private:
/.../
std::vector<TStringGrid *> SGridVec;
public:
/.../
AnsiString AddStringGrid();
TStringGrid * GetStringGridByName(const AnsiString &Name);
TStringGrid * GetStringGridByIndex(const unsigned int Index);
}
Unit1.cpp
AnsiString TForm1::AddStringGrid()
{
SGridVec.push_back(new TStringGrid(Form2)); //Form2 is owner and handles memory management
if (SGridVec.back())
{
SGridVec.back()->Parent = Form2;
SGridVec.back()->Name = "some uniquely generated name";
return SGridVec.back()->Name;
}
return ""; //add was unsuccessful
}
TStringGrid * TForm1::GetStringGridByName(const AnsiString &Name)
{
for(std::vector<TStringGrid *>::iterator sgItr = SGridVec.begin();
sgItr != SGridVec.end();
++sgItr)
{
if (*sgItr && (*sgItr)->Name == Name)
{
return *sgItr;
}
}
return NULL; //StringGrid with Name was not found
}
TStringGrid * TForm1::GetStringGridByIndex(const unsigned int Index)
{
if (Index < SGridVec.size() && SGridVec.at(Index) != NULL)
return SGridVec.at(Index);
return NULL; //StringGrid at Index was not found
}
このメソッドを使用するAddStringGrid()
と、戻り値を呼び出して保存できます。次に、与えられたを操作したい場合は、操作しTStringGrid
たいの名前をForm1
呼び出して渡します。メンバーとしても、a で非常によく似たものを実装することもできます。GetStringGridByName
TStringGrid
std::map
public
FindChildControl メソッド
Unit1.h
#ifndef Unit1H
#define Unit1H
#include <map>
//your other includes here
class PACKAGE Form1 : public TForm
{
__published: //IDE-managed Components
//your components here
public:
/.../
AnsiString AddStringGrid();
}
Unit1.cpp
AnsiString TForm1::AddStringGrid()
{
TStringGrid *temp_ptr = new TStringGrid(Form2); //Form2 is owner and handles memory management
if (temp_ptr)
{
temp_ptr->Parent = Form2;
temp_ptr->Name = "some uniquely generated name";
return temp_ptr->Name;
}
return ""; //add was unsuccessful
}
void SomeClass::SomeFunctionThatUsesForm2sTStrinGrids(/.../)
{
/.../ //some code
TStrinGrid *temp_ptr = static_cast<TStringGrid *>(Form2->FindChildControl("name of control"));
if (temp_ptr)
{
//do stuff to the string grid
}
/.../ //some other code
}
このバージョンは、基本的にParent -> Children
、動的に作成されたものを検索するためにリレーションシップを使用してTStringGrid
、それを a に保存する代わりに使用しstd::vector.
ますstd::vector
。StringGrid
また、指定した一意の名前を「忘れた」場合に sに到達するための簡単で信頼できる方法も提供しませんが、std::vector
ではインデックスによって、またはイテレータを使用可能にした場合はイテレータを介してそれらにアクセスできます。はありますがGetChildren
、直感的に使用できるようには見えません。
--
最初は、 を呼び出すたびにメモリ リークが発生すると思っていましたが、 Builder 6 のドキュメントを正しくTForm1::MyFunction
理解していれば、そうではありません。
TComponent クラスは、VCL および CLX 全体に伝播される所有権の概念も導入します。Owner と Components の 2 つのプロパティが所有権をサポートします。すべてのコンポーネントには、所有者として別のコンポーネントを参照する Owner プロパティがあります。コンポーネントは、他のコンポーネントを所有する場合があります。この場合、所有されているすべてのコンポーネントは、コンポーネントの Array プロパティで参照されます。
コンポーネントのコンストラクターは、新しいコンポーネントの所有者を指定するために使用される単一のパラメーターを取ります。渡された所有者が存在する場合、新しいコンポーネントが所有者の Components リストに追加されます。Components リストを使用して所有されているコンポーネントを参照する以外に、このプロパティは、所有されているコンポーネントの自動破棄も提供します。コンポーネントに所有者がいる限り、所有者が破棄されるとコンポーネントも破棄されます。たとえば、TForm は TComponent の子孫であるため、フォームが所有するすべてのコンポーネントは破棄され、フォームが破棄されるとメモリが解放されます。これは、フォーム上のすべてのコンポーネントが、デストラクタが呼び出されたときに適切にクリーンアップされることを前提としています。
[.pdf ページ 53]
new
そのため、 ed オブジェクトをその関数に渡すたびに Grid1 に割り当てていても、それらのオブジェクトはまだ所有されており、破棄Form2
されたときにクリーンアップされます。Form2
とは言っても、OP に投稿した実装に固執する場合は、最後のものを除いて文字列グリッドを操作できないことに注意してくださいForm2->Array
。