Get a list of all controls in your Delphi VCL form
Examples included a flat list and a hierarchical “tree” list
Related Posts – FireMonkey (FMX) version of this post
This will show three different ways to get a list of the controls in your form
- Controls List
This contains the first level controls on the form.
For example, if a button is on a panel and the panel is on the form the panel will be included but the button will not
- Components List
All components on the form, from all levels.
For example, if a button is on a panel and the panel is on the form – both the panel and the button will be included
Does not include components within frames
- Hierarchical “Tree” list
This includes components from all levels.
It includes components that are within frames
The code for the first two flat lists is straight forward.
Simply loop through the forms controls and components lists.
Piece of cake
var i : integer; begin // loop through all controls (first level only) memo1.lines.add ('*** Controls ***'); for i := 0 to self.ControlCount - 1 do memo1.lines.add (self.controls[i].name); // loop through all components (all levels) memo1.lines.add ('*** Components ***'); for i := 0 to self.ComponentCount- 1 do memo1.lines.add (self.components[i].name); end;
The code for hierarchical list is more complex
The magic procedure
procedure TForm1.ProcessControl ( aControl : TControl; aLevel : integer = 0 ); // process the control including its child objects // aLevel is the level of the control // 0 for the form // 1 for controls directly owned by the form // 2 for a button that is on a panel on the form // etc var i : integer; begin inc (aLevel); // do something with the control here // example: display indented control name // you will need LeftPadString from the download source memo1.lines.Add( LeftPadString ('', (aLevel -1) * 6, ' ') // indent + aControl.name ); // process child objects such as a button on a panel // only TWinControls (such as TPanels and TFrame) // have child controls if aControl is TWinControl then for i := 0 to (aControl as TWinControl).ControlCount - 1 do ProcessControl( (aControl as TWinControl).Controls[i] ,aLevel); end;
Call it like this
begin // self is the form. // you can also specify a container // such as a panel ProcessControl (self); end;
You dont need to specify the value for aLevel as the procedure will track the level for you.
Controls vs Components List
This posts mentions Controls and Components.
Controls are visual, components can be visual or non visual
For example a DataSource that is owned by the form is a component, but it is not a control.
There are other difference between the two but I wont go into great detail about that here.
The key thing for this post is the controls list includes the first level only whereas the components list includes all levels.
For example, a button on a panel is included in the controls list, but is not included in the components list
Ill work on a FireMonkey version of this soon.
There are some differences that need to be taken into account for FMX
I haven’t test this for all types of controls, but it should be good enough for most situations.
See this related post for a FireMonkey (FMX) version of this code
Download full source code (Delphi 10.1) and pre-compiled demo
+1 this post
and here on BeginEnd
Thank You !
About The Author
The Usual Suspect
– Scott Hollows –
- Oracle and Delphi software developer.
- Australian Delphi User Group – Western Australia Chief Cat Herder
- Australian Delphi User Group – President