首先,请注意您的代码正在创建多个TStringGrid
s. 它只是在表单的同一位置创建具有相同尺寸的所有它们,因此您只能看到顶部的那个。
--
您希望能够做的事情 ( Form1->dynamically_created_TStringGrid
) 是不可能的,但是您可以使用几种方法来获得类似的行为。
std::vector 方法
单元1.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);
}
单元1.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
的 on 时,Form1
您会调用GetStringGridByName
并传入TStringGrid
您想要操作的名称。std::map
即使作为public
成员,您也可以使用 a 实现非常相似的东西。
FindChildControl 方法
单元1.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();
}
单元1.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
的,而不是将其存储在std::vector.
我的直觉中,说它比该std::vector
方法更慢且更不安全,但我没有任何证据。StringGrid
如果您“忘记”您给它们的唯一名称,它也没有提供任何简单、可靠的方法来获取 s ,而sstd::vector
允许您通过索引访问它们,或者如果您提供一个迭代器,则通过迭代器访问它们。有GetChildren
,但使用起来看起来不是很直观。
--
起初我以为每次调用都会发生内存泄漏TForm1::MyFunction
,但如果我正确理解了 Builder 6 文档,情况并非如此:
TComponent 类还引入了在整个 VCL 和 CLX 中传播的所有权概念。两个属性支持所有权:所有者和组件。每个组件都有一个 Owner 属性,该属性引用另一个组件作为其所有者。一个组件可能拥有其他组件。在这种情况下,所有拥有的组件都在组件的 Array 属性中引用。
组件的构造函数采用单个参数,用于指定新组件的所有者。如果传入的所有者存在,则将新组件添加到所有者的组件列表中。除了使用组件列表来引用自有组件之外,此属性还提供了自有组件的自动销毁。只要组件有一个所有者,它就会在所有者被销毁时被销毁。例如,由于 TForm 是 TComponent 的后代,因此表单拥有的所有组件都将被销毁,并且在表单被销毁时释放它们的内存。这假设表单上的所有组件在调用它们的析构函数时都会正确地清理自己。
[.pdf 第 53 页]
因此,即使您new
每次将 ed 对象传递给该函数时都将其分配给 Grid1,但这些对象仍归该函数所有,并且在被破坏Form2
时将被清除。Form2
综上所述,您应该知道,如果您坚持在 OP 中发布的实现,您将无法操作除最后一个之外的任何字符串网格,除非您从Form2->Array
.