c++builderrad-studio

How to obtain all children of a Form in RAD Studio designer code?


I would be glad if someone could help me in completing this tiny task:

I want to get a list of all child elements in a Form.

TCustomForm has a GetChildren() method that I found in the docs, but I do not understand what the first argument is used for, nor do I understand why I should insert a reference to the calling instance of TCustomForm as the second argument. In addition, I have no hint what to expect as the returned value.

I simply do not know how to use this method properly. Can someone give me an example? This is what I am missing in the documentation, unfortunately.


Solution

  • The 1st parameter of GetChildren() is a pointer to a callback method. You pass in a method that you want GetChildren() to call for each child object, eg:

    void __fastcall TMyClass::GetChildProc(TComponent *Child)
    {
        // do something with Child...
    }
    
    void __fastcall TMyClass::DoSomething()
    {
        //...
        SomeForm->GetChildren(&GetChildProc, SomeForm);
        //...
    }
    

    Note, however, that the callback is invoked only for child components whose HasParent() method returns false (ie, for non-UI components, or for TControl descendants whose Parent property is NULL). IOW, GetChildren() is typically used only by the DFM streaming system to discover a Form's non-visual components that are not children of the Form's UI window at runtime. Which is why the documentation suggests you not call GetChildren() directly:

    GetChildren is used internally in the component streaming system. It is not necessary to call it directly.

    That being said, all components placed on a Form at design-time are owned by the Form. So, you could just enumerate the Form's owned components directly via its Components[] property, eg:

    void __fastcall TMyClass::DoSomething()
    {
        for(int i = 0; i < SomeForm->ComponentCount; ++i)
        {
            TComponent *Child = SomeForm->Components[i];
            // do something with Child...
        }
    }
    

    This is essentially what GetChildren() does internally when the Root parameter is set to the Form itself.