Recent

Author Topic: How to recursively find all children inside other child controls  (Read 11850 times)

beefycoder

  • New Member
  • *
  • Posts: 24
I am trying to list/enumerate all child ccontrols inside form, but i can't get consistent way of checking if any control on form can hold other child controls or how many.

I tried looking for common property of all controls, tried using "as" keyword to typecast TControl, tried try/finally block and none worked.

Is it absolutely necessary to check current control inside loop for all possible class names and then try using ControlCount ? Seems too much for such a simple thing.

The following failed to work :

Code: [Select]
//fails on first control that does not have this property
x:= MainForm.Controls [ControlIndex] as TWinControl).ControlCount;

//same as above
x:= MainForm.Controls [ControlIndex] as TPanel).ControlCount;

//even this failed, either i did not properly code try/finally block or even this block can't stop such errors?
try
  x:= MainForm.Controls [ControlIndex] as TWinControl).ControlCount;
finally
  x:=0
end;

taazz

  • Hero Member
  • *****
  • Posts: 5368
Re: How to recursively find all children inside other child controls
« Reply #1 on: October 05, 2012, 05:44:36 pm »
All controls that can be parents for other controls have as common ancestor the TWinVontrol.
this makes things easier to handle for example

Code: Pascal  [Select][+][-]
  1. function EnumControls(const aControl:TWinControl; const StartSpace :string=''):String;
  2. var
  3.   Res : string;
  4. begin
  5.   for Cnt := 0 to aControl.ControlCount -1 do
  6.   begin
  7.     WriteStr(Res,StartSpace + aControl.Controls[Cnt].Name);
  8.     Result:= Result + Res + LineEnding;
  9.     if aControl.Controls[Cnt] is TWinControl then
  10.       EnumControls(TwinControl(aControl.Controls[Cnt]), StartSpace+'  ')
  11.   end;
  12. end;
  13.  

as you can see I use the is keyword that tests if a variable supports the type I want and returns true or false. It is far better than the as keyword which equivalent to TWonControl(MyVariable) hard cast.

Your two problem are that
1) try..finally is not designed to stop exception just to give you the chance to clean up if anything goes wrong. to stop an exception you need to use try..except blocks.
2) the as keyword is deisgned to raise an exception if a control does not support the cast you are trying to support.

regards
jo
Good judgement is the result of experience … Experience is the result of bad judgement.

OS : Windows 7 64 bit
Laz: Lazarus 1.4.4 FPC 2.6.4 i386-win32-win32/win64

Avishai

  • Hero Member
  • *****
  • Posts: 1021
Re: How to recursively find all children inside other child controls
« Reply #2 on: October 05, 2012, 05:51:11 pm »
This is a piece of my code that might help:

Code: [Select]
procedure InitRtlForm(AForm: TForm);
var
  I: Integer;
begin
  for I:= 0 to AForm.ComponentCount-1 do begin
    if AForm.Components[I] is TEdit then begin
      TEdit(AForm.Components[I]).ParentBiDiMode:= False;
      TEdit(AForm.Components[I]).BiDiMode:= bdRightToLeftNoAlign;
    end;
    if AForm.Components[I] is TMemo then begin
      TMemo(AForm.Components[I]).ParentBiDiMode:= False;
      TMemo(AForm.Components[I]).BiDiMode:= bdRightToLeftNoAlign;
    end;
  end;
end;
Lazarus Trunk / fpc 2.6.2 / Win32

beefycoder

  • New Member
  • *
  • Posts: 24
Re: How to recursively find all children inside other child controls
« Reply #3 on: October 05, 2012, 07:20:43 pm »
All controls that can be parents for other controls have as common ancestor the TWinVontrol.

Ahh so simple ! Thank you !

as you can see I use the is keyword that tests if a variable supports the type I want and returns true or false. It is far better than the as keyword which equivalent to TWonControl(MyVariable) hard cast.

 I rarely had to use "as" and "is", even in this particular case i might go around it but it would be cumbersome, and if i ever needed to add many controls during runtime, it would be even worse.

Thanks again !

 

TinyPortal © 2005-2018