Recent

Author Topic: How to convert strings to control items.(SOLVED)  (Read 3211 times)

JLWest

  • Hero Member
  • *****
  • Posts: 1293
How to convert strings to control items.(SOLVED)
« on: September 08, 2021, 11:05:21 pm »
How to convert  strings to control items.

This probably doesn't explain the problem well.

 I have a control   on a form called btnXX. It has a btnXXClick event programed.
I want to issues btnXXClick(Nil).

I know it's a button and I have  'XX' in a string when I want to issue the btnXXClick(Nil) call. Is there a way to do this?

Thanks
« Last Edit: September 10, 2021, 11:46:17 pm by JLWest »
FPC 3.2.0, Lazarus IDE v2.0.4
 Windows 10 Pro 32-GB
 Intel i7 770K CPU 4.2GHz 32702MB Ram
GeForce GTX 1080 Graphics - 8 Gig
4.1 TB

Gustavo 'Gus' Carreno

  • Hero Member
  • *****
  • Posts: 1112
  • Professional amateur ;-P
Re: How to convert strings to control items.
« Reply #1 on: September 08, 2021, 11:28:09 pm »
Hey JLWest,

There are 2 ways, at least in my mind, that you can do it.

First One

You have a big if..elseif..elseif that tests the XX and then calls the appropriate button event.

Code: Pascal  [Select][+][-]
  1. if targetXX = '01' then btn01Clcik(nil) else
  2. if targetXX = '02' then btn01Click(nil);
  3. // And so on

Second One

You construct the string you want to find, so btn01Click and store it on a variable you then use to compare on a for loop that goes through all the form's components and tests the string and the component's name.

Code: Pascal  [Select][+][-]
  1. for index = 0 to Pred(Form.Components.Count) do
  2. begin
  3.   if Form.Components[index].Name = 'btn'+targetXX then Form.Components[index].OnClick(nil); // Not completely sure about this one, you should check.
  4. end;

Hope that helps!

Cheers,
Gus
Lazarus 3.99(main) FPC 3.3.1(main) Ubuntu 23.10 64b Dark Theme
Lazarus 3.0.0(stable) FPC 3.2.2(stable) Ubuntu 23.10 64b Dark Theme
http://github.com/gcarreno

JLWest

  • Hero Member
  • *****
  • Posts: 1293
Re: How to convert strings to control items.
« Reply #2 on: September 08, 2021, 11:48:12 pm »
@Gustavo 'Gus' Carreno  Thanks.

I think I'll try the second solution.

  The names are btnL0Click thru btnL20Click. I was hoping there was a way to convert the string 'btnL15Click' to be able to issue the call btnL15Click(Nil).

I saw it done somewhere but can't find it. But then again I may have miss read the code or didn't understand what I was reading.
 
FPC 3.2.0, Lazarus IDE v2.0.4
 Windows 10 Pro 32-GB
 Intel i7 770K CPU 4.2GHz 32702MB Ram
GeForce GTX 1080 Graphics - 8 Gig
4.1 TB

Gustavo 'Gus' Carreno

  • Hero Member
  • *****
  • Posts: 1112
  • Professional amateur ;-P
Re: How to convert strings to control items.
« Reply #3 on: September 09, 2021, 12:11:23 am »
Hey JLWest,

@Gustavo 'Gus' Carreno  Thanks.

Quite welcome!

I saw it done somewhere but can't find it. But then again I may have miss read the code or didn't understand what I was reading.

It's funny you mention this, cuz not long ago someone asked the same thing but with a slight difference on the details: Define keyword (procedure name) inside running program.

What you're looking for is quite easy to achieve on interpreted/scripting languages, like Perl, PHP or Python, to name a few.
But Pascal is a strongly typed language that is compiled. Resolving names at run time is a no-no.
The compiler actually forgets all names and then just uses indexes to internally built tables.. Well, kind of, since it's a bit more complicated than that :)
So in a sense, names are irrelevant in a compiled environment, again, with a bit of humour since it is quite more complicated than that.

Cheers,
Gus
Lazarus 3.99(main) FPC 3.3.1(main) Ubuntu 23.10 64b Dark Theme
Lazarus 3.0.0(stable) FPC 3.2.2(stable) Ubuntu 23.10 64b Dark Theme
http://github.com/gcarreno

JLWest

  • Hero Member
  • *****
  • Posts: 1293
Re: How to convert strings to control items.
« Reply #4 on: September 09, 2021, 12:38:06 am »
@Gustavo 'Gus' Carreno

   
Code: Pascal  [Select][+][-]
  1.  for index := 0 to Pred(Form1.Components.Count) do   <#1 ERROR>
  2.     begin
  3.       if Form.Components[index].Name = 'btn'+targetXX then   <#2 ERROR
  4.         Form.Components[index].OnClick(nil);
  5.     end;

   it won't accept Components.Count  #1 ERROR and #2 ERROR
FPC 3.2.0, Lazarus IDE v2.0.4
 Windows 10 Pro 32-GB
 Intel i7 770K CPU 4.2GHz 32702MB Ram
GeForce GTX 1080 Graphics - 8 Gig
4.1 TB

Gustavo 'Gus' Carreno

  • Hero Member
  • *****
  • Posts: 1112
  • Professional amateur ;-P
Re: How to convert strings to control items.
« Reply #5 on: September 09, 2021, 01:41:17 am »
Hey JLWest,

For error #1:

Code: Pascal  [Select][+][-]
  1. Form1.Components.ComponentCount;

For error #2 I don't see the error... Unless you need:

Code: Pascal  [Select][+][-]
  1. if Form1.Components[index] is TButton then
  2. begin
  3.   if TButton(Form1.Components[index]).Name =  'btn'+targetXX then
  4.   begin
  5.     TButton(Form1.Components[index]).OnClick(nil);
  6.   end;
  7. end;

But I'm pulling this out of my arse, since I've not tested any of this on the IDE.

Have a go by yourself and try and figure it out. Isn't that half the fun? At least for me it is ;)

Cheers,
Gus
Lazarus 3.99(main) FPC 3.3.1(main) Ubuntu 23.10 64b Dark Theme
Lazarus 3.0.0(stable) FPC 3.2.2(stable) Ubuntu 23.10 64b Dark Theme
http://github.com/gcarreno

engkin

  • Hero Member
  • *****
  • Posts: 3112
Re: How to convert strings to control items.
« Reply #6 on: September 09, 2021, 01:43:12 am »
I have a control   on a form called btnXX. It has a btnXXClick event programed.
I want to issues btnXXClick(Nil).

I know it's a button and I have  'XX' in a string when I want to issue the btnXXClick(Nil) call. Is there a way to do this?

Code: Pascal  [Select][+][-]
  1. procedure TYourFormName.SomeProcName;
  2. var
  3.   m:TMethod;
  4. begin
  5.   m.Code:=MethodAddress('Btn'+XX+'Click');
  6.   if m.Code=nil then //Not found, XX is wrong
  7.     exit;
  8.  
  9.   m.Data:=Pointer(Self);
  10.   TNotifyEvent(m)(nil);//<--- use the correct type, if not TNotifyEvent
  11. end;

JLWest

  • Hero Member
  • *****
  • Posts: 1293
Re: How to convert strings to control items.
« Reply #7 on: September 09, 2021, 01:46:25 am »
@engkin I'll try it. thanks
FPC 3.2.0, Lazarus IDE v2.0.4
 Windows 10 Pro 32-GB
 Intel i7 770K CPU 4.2GHz 32702MB Ram
GeForce GTX 1080 Graphics - 8 Gig
4.1 TB

Remy Lebeau

  • Hero Member
  • *****
  • Posts: 1312
    • Lebeau Software
Re: How to convert strings to control items.
« Reply #8 on: September 09, 2021, 01:59:10 am »
You construct the string you want to find, so btn01Click and store it on a variable you then use to compare on a for loop that goes through all the form's components and tests the string and the component's name.

If the Form is the Owner of the Button, then TComponent has a FindComponent() method for this exact purpose, you don't need a manual loop, eg:

Code: Pascal  [Select][+][-]
  1. TButton(Form.FindComponent('btn'+targetXX)).Click;

On the other hand, if the Button has a different Owner than the Form, but is a child of another control (say, a Panel, etc), then TWinControl has a FindChildControl() method, eg:

Code: Pascal  [Select][+][-]
  1. TButton(ParentControl.FindChildControl('btn'+targetXX)).Click;
« Last Edit: September 09, 2021, 02:04:10 am by Remy Lebeau »
Remy Lebeau
Lebeau Software - Owner, Developer
Internet Direct (Indy) - Admin, Developer (Support forum)

JLWest

  • Hero Member
  • *****
  • Posts: 1293
Re: How to convert strings to control items.
« Reply #9 on: September 09, 2021, 02:16:01 am »
@ Remy Lebeau

Actually it's not a button but a Tlabel I'm trying to click on

I get a error unit1.pas(1757,55) Error: identifier idents no member "Click"
 
 TLabel(Form1.FindComponent('btn'+ 'AnsiMatchStr')).Click;

It doesn't like Click
FPC 3.2.0, Lazarus IDE v2.0.4
 Windows 10 Pro 32-GB
 Intel i7 770K CPU 4.2GHz 32702MB Ram
GeForce GTX 1080 Graphics - 8 Gig
4.1 TB

engkin

  • Hero Member
  • *****
  • Posts: 3112
Re: How to convert strings to control items.
« Reply #10 on: September 09, 2021, 03:22:52 am »
Code: Pascal  [Select][+][-]
  1. procedure TYourFormName.ClickLabel(XX:String);
  2. var
  3.   LabelName:String;
  4.   LComponent:TComponent;
  5. begin
  6.   LabelName:='Label'+XX;
  7.  
  8.   LComponent:=FindComponent(LabelName);
  9.   if assigned(LComponent) then
  10.     TLabel(LComponent).OnClick(LComponent)
  11. end;

Remy Lebeau

  • Hero Member
  • *****
  • Posts: 1312
    • Lebeau Software
Re: How to convert strings to control items.
« Reply #11 on: September 09, 2021, 05:56:02 pm »
Actually it's not a button but a Tlabel I'm trying to click on

Then why is it named 'btnXX'?  That is very misleading.

It has a btnXXClick event programed.
I want to issues btnXXClick(Nil).

Code: Pascal  [Select][+][-]
  1. TLabel(Form.FindComponent('btn'+targetXX)).OnClick(nil);
  2. TLabel(ParentControl.FindChildControl('btn'+targetXX)).OnClick(nil);

I get a error unit1.pas(1757,55) Error: identifier idents no member "Click"

That is because Click() is protected in TLabel, whereas it is public in TButton.
Remy Lebeau
Lebeau Software - Owner, Developer
Internet Direct (Indy) - Admin, Developer (Support forum)

JLWest

  • Hero Member
  • *****
  • Posts: 1293
Re: How to convert strings to control items.
« Reply #12 on: September 10, 2021, 05:58:19 am »
Yes it is confusing. 

 Actually they are TLabel's named L0 to L20 or 21 on the form. There is only 1 Form.
The Form can have endless or a lot of menue's . They names are loaded from a text file and assigned to the TLabel's captions at run time.

If you press on say L9 it may display a Level2 menu with 8 items L0 to L8. There are only two levels. Level1 has 66 items.

So if I'm looking at the 3rd page of the Level1 menu and I click on the L5 TLabel it is actually the 47 (zero based) item in the Level1 text list. So I get the Ln number with the following calculations:

Page :=    (Index / 21) + 1. or Page := 47/21 +1; This calc gives me  3 rounded down. That equates to the 3rd page in the Level1 menu. Ln := 47 - ((Page-1)* 21) = 5 or the L5 Tlabel. But what I have is 'L5' in a string. Now I need to convert 'L5' string  to make the following call "L5Click(Nil)".  I think.

Well at any rate that's the clearest its ever been to me.


     
FPC 3.2.0, Lazarus IDE v2.0.4
 Windows 10 Pro 32-GB
 Intel i7 770K CPU 4.2GHz 32702MB Ram
GeForce GTX 1080 Graphics - 8 Gig
4.1 TB

Remy Lebeau

  • Hero Member
  • *****
  • Posts: 1312
    • Lebeau Software
Re: How to convert strings to control items.
« Reply #13 on: September 11, 2021, 01:00:58 am »
But what I have is 'L5' in a string. Now I need to convert 'L5' string  to make the following call "L5Click(Nil)".  I think.

That has already been explained to you, using two different approaches:

- finding the TLabel using TComponent.FindComponent() or TWinContro.FindChildControl(), followed by calling TLabel.Click() or TLabel.OnClick.

- using MethodAddress() to fill a TNotifyEvent via TMethod.

Now that you have explained your situation a little more, I really don't understand what your menus have to do with this issue.  I think you are just confusing the matter by describing the menus.  Unless the menu items are somehow involved in this, like for instance if you need their OnClick events to access the TLabel's. In which case, I would suggest setting the TMenuItem.Tag property to point at the desired TLabel while you are building up your menus, and then you can just type-cast the Tag when needed, eg: TLabel(TMenuItem(Sender).Tag)
« Last Edit: September 11, 2021, 01:05:55 am by Remy Lebeau »
Remy Lebeau
Lebeau Software - Owner, Developer
Internet Direct (Indy) - Admin, Developer (Support forum)

JLWest

  • Hero Member
  • *****
  • Posts: 1293
Re: How to convert strings to control items.(SOLVED)
« Reply #14 on: September 11, 2021, 05:38:12 pm »
I have it somewhat working. How to click a label is easy with the solution supplied but it's figuring out which label to click on level2.

Thanks for you help.
FPC 3.2.0, Lazarus IDE v2.0.4
 Windows 10 Pro 32-GB
 Intel i7 770K CPU 4.2GHz 32702MB Ram
GeForce GTX 1080 Graphics - 8 Gig
4.1 TB

 

TinyPortal © 2005-2018