Recent

Author Topic: [Solved] Find child controls by name  (Read 2290 times)

Joanna from IRC

  • Hero Member
  • *****
  • Posts: 1235
[Solved] Find child controls by name
« on: April 17, 2024, 11:51:37 pm »
Hi everyone, I just wrote some clunky code for a twincontrol helper but in retrospect is there a better way to determine if a twincontrol already contains a child control with a particular name?
 I’ve seen the method containsthiscontrol() but that doesn’t work for the name. As you all probably know, duplicate names cause a crash. If I remember correctly, more than one unnamed control will also be interpreted as duplicate names.
here is what i did
Code: Pascal  [Select][+][-]
  1. FUNCTION TWINCONTROL_HELPER.CONTAINS_NAME( CONST ANAME: STRING) : BOOLEAN;
  2.            VAR X:INTEGER;
  3.  BEGIN
  4.  FOR X:= 0 TO {SELF.}ControlCount -1 DO
  5.      IF UPCASE(Controls[X].NAME) = UpCase(ANAME)
  6.         THEN EXIT(TRUE);
  7.  RESULT:= FALSE;
  8.  END;
Another strange thing is I couldn't get the controlcount to appear in the helper autocomplete list without typing self first. i have often noticed that the auto complete behavior inside helpers doesn't seem to work as well as other places..
« Last Edit: April 18, 2024, 01:58:33 pm by Joanna »
✨ 🙋🏻‍♀️ More Pascal enthusiasts are needed on IRC .. https://libera.chat/guides/ IRC.LIBERA.CHAT  Ports [6667 plaintext ] or [6697 secure] channel #fpc  #pascal Please private Message me if you have any questions or need assistance. 💁🏻‍♀️

Josh

  • Hero Member
  • *****
  • Posts: 1344
Re: Find child controls by name
« Reply #1 on: April 18, 2024, 12:02:31 am »
search for
findcontrol or findcomponent

containers have these

ie

form1.findcomponent

panel1.findcomponent

non tested code, to show idea

Code: Pascal  [Select][+][-]
  1. var c:tcontrol;
  2. ...
  3.  
  4. begin
  5.   c:=mypanel.findcontrol('mycontrol');
  6.   if c is mycontroltype then  
  7.   begin
  8.     with c as mycontroltype do  
  9.     begin
  10.        ...
  11.     end;
  12.   end;
  13. end;
  14.  
The best way to get accurate information on the forum is to post something wrong and wait for corrections.

Joanna from IRC

  • Hero Member
  • *****
  • Posts: 1235
Re: Find child controls by name
« Reply #2 on: April 18, 2024, 02:03:50 am »
Quote
function FindControl(Handle: HWND): TWinControl;
C:\lazarus\lcl\controls.pp(2705,10)
Description
Return the TWinControl of the given Handle.
The result is very interface specific. Use FindOwnerControl when Handle may be a non-TWinControl handle.
im not sure how to use handle for a name
✨ 🙋🏻‍♀️ More Pascal enthusiasts are needed on IRC .. https://libera.chat/guides/ IRC.LIBERA.CHAT  Ports [6667 plaintext ] or [6697 secure] channel #fpc  #pascal Please private Message me if you have any questions or need assistance. 💁🏻‍♀️

Handoko

  • Hero Member
  • *****
  • Posts: 5378
  • My goal: build my own game engine using Lazarus
Re: Find child controls by name
« Reply #3 on: April 18, 2024, 04:17:05 am »
Done.

This demo below shows how to use FindChildControl as suggested by Josh and writing yourself a function for checking the existance of the control:

Code: Pascal  [Select][+][-]
  1. unit Unit1;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.   Classes, SysUtils, Forms, Controls, Dialogs, StdCtrls, ExtCtrls;
  9.  
  10. type
  11.  
  12.   { TForm1 }
  13.  
  14.   TForm1 = class(TForm)
  15.     btnFind: TButton;
  16.     Button1: TButton;
  17.     CheckBox1: TCheckBox;
  18.     Edit1: TEdit;
  19.     lbeName: TLabeledEdit;
  20.     Memo1: TMemo;
  21.     Panel1: TPanel;
  22.     RadioButton1: TRadioButton;
  23.     Shape1: TShape;
  24.     procedure btnFindClick(Sender: TObject);
  25.   end;
  26.  
  27. var
  28.   Form1: TForm1;
  29.  
  30. implementation
  31.  
  32. function HasControl(Container: TWinControl; const aName: string): Boolean;
  33. var
  34.   S: string;
  35.   i: Integer;
  36. begin
  37.   Result := False;
  38.   S := aName.ToUpper;
  39.   for i := 0 to Container.ControlCount-1 do
  40.   begin
  41.     if S = Container.Controls[i].Name.ToUpper then
  42.     begin
  43.       Result := True;
  44.       Exit;
  45.     end;
  46.   end;
  47. end;
  48.  
  49. {$R *.lfm}
  50.  
  51. { TForm1 }
  52.  
  53. procedure TForm1.btnFindClick(Sender: TObject);
  54. var
  55.   C: TControl;
  56.   S: string;
  57. begin
  58.   case HasControl(Panel1, lbeName.Text) of
  59.     True:
  60.       begin
  61.         C := Panel1.FindChildControl(lbeName.Text);
  62.         S := lbeName.Text + ' is found in Panel1.' + LineEnding +
  63.              'Class: ' +  C.ClassName              + LineEnding +
  64.              'Left: ' +   C.Left.ToString          + LineEnding +
  65.              'Top: ' +    C.Top.ToString           + LineEnding +
  66.              'Width: ' +  C.Width.ToString         + LineEnding +
  67.              'Height: ' + C.Height.ToString        + LineEnding;
  68.         ShowMessage(S);
  69.       end;
  70.     False:
  71.       ShowMessage(lbeName.Text + ' cannot be found in Panel1.');
  72.   end;
  73. end;
  74.  
  75. end.
« Last Edit: April 18, 2024, 04:24:10 am by Handoko »

Joanna from IRC

  • Hero Member
  • *****
  • Posts: 1235
Re: Find child controls by name
« Reply #4 on: April 18, 2024, 01:57:59 pm »
Thanks for the answers. Is there a reason to use string helper method instead of upcase ()?
✨ 🙋🏻‍♀️ More Pascal enthusiasts are needed on IRC .. https://libera.chat/guides/ IRC.LIBERA.CHAT  Ports [6667 plaintext ] or [6697 secure] channel #fpc  #pascal Please private Message me if you have any questions or need assistance. 💁🏻‍♀️

KodeZwerg

  • Hero Member
  • *****
  • Posts: 2269
  • Fifty shades of code.
    • Delphi & FreePascal
Re: [Solved] Find child controls by name
« Reply #5 on: April 18, 2024, 02:21:13 pm »
As you all probably know, duplicate names cause a crash. If I remember correctly, more than one unnamed control will also be interpreted as duplicate names.
Than all my dynamic created controls would fail and crash since I never assign a name to them, but hey, they dont.
Maybe the reason is that a handle is the master and not a name.
A name I just assign if I need to store some (unique) info and have no other possibility left.
« Last Edit: Tomorrow at 31:76:97 xm by KodeZwerg »

cdbc

  • Hero Member
  • *****
  • Posts: 1673
    • http://www.cdbc.dk
Re: [Solved] Find child controls by name
« Reply #6 on: April 18, 2024, 02:28:56 pm »
Hi
@KodeZwerg: +1
@Joanna:
Quote
If I remember correctly, more than one unnamed control will also be interpreted as duplicate names.
NO, You remember wrong! If the controlname is empty = '' = nil etc. it is ignored, only when you assign something to the name, it has to be unique to the container.
Regards Benny
If it ain't broke, don't fix it ;)
PCLinuxOS(rolling release) 64bit -> KDE5 -> FPC 3.2.2 -> Lazarus 2.2.6 up until Jan 2024 from then on it's: KDE5/QT5 -> FPC 3.3.1 -> Lazarus 3.0

Handoko

  • Hero Member
  • *****
  • Posts: 5378
  • My goal: build my own game engine using Lazarus
Re: Find child controls by name
« Reply #7 on: April 18, 2024, 03:01:47 pm »
Is there a reason to use string helper method instead of upcase ()?

It is more about personal choice. I prefer to put the component at the beginning followed by action. For example: CustomerSave, CustomerEdit,  DataLoad, DataClose.

And I am sure many users will agree with me, pressing a dot is easier than 2 brackets. You can try, type a pair of brackets while both eyes are closed. Can you? I can't.
« Last Edit: April 18, 2024, 03:07:35 pm by Handoko »

Joanna from IRC

  • Hero Member
  • *****
  • Posts: 1235
Re: [Solved] Find child controls by name
« Reply #8 on: April 19, 2024, 09:53:43 am »
i remember a long time ago i was creating many copies of the same control and it gave me a duplicate name error and i had to add code to give each one a unique name. maybe something has changed since then.In any case i always name my variables now.
✨ 🙋🏻‍♀️ More Pascal enthusiasts are needed on IRC .. https://libera.chat/guides/ IRC.LIBERA.CHAT  Ports [6667 plaintext ] or [6697 secure] channel #fpc  #pascal Please private Message me if you have any questions or need assistance. 💁🏻‍♀️

 

TinyPortal © 2005-2018