How to loop through ALL controls of a form

Normal VCL components put on a form can be accessed using the Components array of the form. For some reason, Components that have an ElementID set no longer live in this array. They can instead be found in the Controls array of the form. So, in order to get hold of ALL controls/components of a form, I need to loop through both arrays. Unfortunately, controls in the Components array are also elements of the Controls array. So just looping through Components, then through Controls, gives duplicates. To fix this I put them in a sorted StringList.

While this approach seems to work, I have the impression that it is a little vague. So the question is: Is this the best way to catch ALL controls of a form, also those that have an ElementID set? Or is there a better, more reliable way?

As a side info: Why do I need this? The project needs to change the language on a button press. Language strings are loaded from a database and then need to be put in all affected controls.

I've gotten around this by explicitly having an array of TObjects, to which I add the components I'm interested in accessing often. Not sure it would help you if you have to add them manually, but when I'm creating lots of buttons dynamically, it is trivial to then just add them to an array to keep track of them separately, without being concerned about other objects I don't care about.

Thanks for your reply Andrew, but indeed I can not add them manually. I need a more generic approach because the funtion dealing with this has no idea about the actual number and type of components/controls on a form that the function has to process on. My function reads key/value strings from a db whose keys refer to the controls names for matching. So I need to be sure to catch ALL controls of the form.

Hopefully, someone else can confirm/deny that your approach of processing both arrays is required. You're right in that it seems less than optimal. How much of a problem that is depends on just how many elements are in play. The other thing I've done is to use JavaScript to iterate through elements that are rendered on the page (all the buttons for example), and update things that way, but not very convenient if you have a lot of different component types, and they don't end up with the same name on the page anyway, so your index isn't going to work there, unless you add the index as a class name or something, which seems redundant as compared to what you're doing now.

Bruno would you mind taking a look into this?
Thank you very much

This is not something we can easily change. It has a rather deep impact on the architecture and potential breaking behavior. It's on our list to further careful examination.