Find out what components are on a TForm (VCL)

Recently, I found a blog post about how to list components that are part of a form. I am a big fan of “good old programming principles” and thus I will provide a solution that is based on recursion. As a proof of concept I will provide a component at a later time that will once again show the luxury we have as a Delphi developer to wrap things in a component.

In order to list all the components on the form, I also dropped a TMemo  and an additional button to initate the “logging” process.

procedure TFrmMain.btLogStartClick(Sender: TObject);
begin
  // start logging with form
  LogComponent( self, 0 );
end;

procedure TFrmMain.LogComponent(Root: TComponent; Level: Integer);
var
  lLogLevel : string;
  i: Integer;

begin
  // add spaces to signify the level
  lLogLevel := '';
  for i  := 0 to Level do
  begin
    lLogLevel := '  ' + lLogLevel;
  end;

  // log the component
  Log.Lines.Add( lLogLevel + Root.ToString + ' (' + Root.Name + ')' );

  // call LogComponent for owned components
  for i := 0 to Root.ComponentCount - 1 do
  begin
    LogComponent( Root.Components[i], Level + 1 );
  end;
end;

Here we see a typical recursion. The button click event starts the process by providing the form itself and a “level” of 0. Every increment in level causes 2 spaces to be inserted in front of the component type and its name. In order to iterate all the components you only need two properties:

  • ComponentCount : returns the number of components that a component owns
  • Components[] : an array that contains all the components that a component owns

So, that’s it. It is only one for-loop and due to the fact that all components are derived from TComponent this will work for any component that might be dropped (or “added”) to a TForm. LogComponent will be called for every component and using the list of the component it owns, these components will be logged as well. The termination criteria is that there are only a limited number of components on a form, the number is not infinite and thus we have a recursion that will terminate at some point.

Here’s the demo in action. I simply added the logging to the last demo I presented on this blog. Stay tuned for the component.

recurse

Tags: , , , ,

Partnerships




Top