BCB:如何迭代表单上的控件?

时间:2010-03-06 04:14:06

标签: c++builder

我正在寻找一些BCB代码来迭代表单上的控件并获取有关它们的一些信息。

我尝试使用myForm->ControlCounttypeid(myForm->Controls[i]),但这给了我一些问题。

1)typeid(myForm->Controls[i])->Name总是给"TControl *"而我希望“TEdit *”,“TMemo *”等等

我可以使用

来解决这个问题
if (typeid(myForm->Controls[i]) == typeid(TEdit))

然后施法? (如果是这样,最好如何演员?)

2)我怎样才能(可能通过施法)获得控件的属性?例如,名称,宽度,高度等?

我真的非常感谢这里的实际代码(或一些实际代码的URL);谢谢。


更新:由于我只需要为我的特定情况测试5种不同类型的控件,我想我可以依次尝试每个dynamic_cast<>,但我似乎无法让它工作......

3 个答案:

答案 0 :(得分:8)

您认为投射是一个好主意并且使用dynamic_cast是最好的选择,这在某种程度上是正确的。

如果要迭代窗体(或任何其他容器)的控件。不幸的是,我没有在这台计算机上安装我的C ++ Builder,所以我无法测试我给你的代码,应该是一个简单的任务来创建。

// You wanna start my iterating through the controls of the container
for (int i = 0; i < container->ControlCount; i++)
{
    // Let us extract the control at index i
    TControl *control = container->Controls[i];

    // Now we want to test whether this is any specific type, for instance a
    // TEdit or any TEdit descendant.
    TEdit *edit = dynamic_cast<TEdit *>(control);

    // If this control is a TEdit or any control deriving from it, we will have 
    // a pointer to it, if this is any other type, we will be left with a zero
    // pointer.
    if (edit)
    {
        // This is a TEdit control... we can now access TEdit only properties.
        edit->Text = "This is an edit control.";
    }

    // We do the same if we want to test for a TButton...
    TButton *button = dynamic_cast<TButton *>(control);

    // Again we test whether this was actually a button
    if (button)
    {
        // It is a button, again we can access TButton only properties...
        button->Caption = "This is a button"; 
        // Yeah ok not a TButton only one, but couldn't think of any.
    }

    // And so on...
}

您不需要为子控件的子控件递归函数,这些也包含在VCL中。到目前为止,这是测试特定类型的最简单的解决方案。我也尽量避免使用RTTI功能,但这只是我。

正如您所看到的,我的示例还显示了如何访问控件的属性和功能,甚至是特定于某种类型的控件。不过你提到的那些:NameWidthHeight都是TControl共有的,并且没有必要强制转换来访问这些内容。

希望这对您有所帮助,从我的示例中可以清楚地看到变量container可以替换为您在其中使用的myForm

答案 1 :(得分:1)

这对你也有帮助:

for (int index = 0; index < ControlCount; index ++)
{
    if(Controls[index]->InheritsFrom(__classid(TCustomEdit)))
    {
        TCustomEdit *edit = (TEdit*) Controls[index];
        edit->Text = "Ok";
    }
}

答案 2 :(得分:1)

这里是:

void EnumerateAll(TComponent *container)
{
   // Enumarate its children
   for (int i = 0; i < container->ComponentCount; i++)
      {
      // extract the control at index i
      TComponent *child = container->Components[i];

      if ( child->InheritsFrom (__classid(TComponent)) )    //this check is optional
         Form3->Memo->Lines->Add(child->Name);
      }
}

用法:

EnumerateAll(MyForm);

上面的功能还将枚举菜单项。
另请参阅:C++ builder - enumerate components on TPanel

以下是有关VCL层次结构的更多详细信息:http://docwiki.embarcadero.com/RADStudio/Tokyo/en/Class_library