Lazarus

Programming => General => Topic started by: pixelink on August 12, 2019, 04:15:24 pm

Title: [SOLVED] Convert String to Control Name
Post by: pixelink on August 12, 2019, 04:15:24 pm
 A user can pick from many Images in Image Controls.
When they dbl-click to use image, I save the a text string as the same name of an image control name

How do convert my saved string to the control name and then access it's properties in code?
Or is there a better way?

Example.

Str = Style_01
Get control = 'Style_01' + '.Picture.Bitmap'

I know the string will have to be converted to a control name as far as type so the string actually becomes the control name in code only

Because the image control doesn't have a tag string format attached to it, I don't know how to refer the controls property using my saved string (psuedo control name).

Make sense??
Title: Re: Convert String to Control Name
Post by: pixelink on August 12, 2019, 04:46:32 pm
 %)

I do have one idea.
What about a function?

Code: Pascal  [Select]
  1. function getContol(str: String; ImgControl: TImage)
  2. If string = 'Style_01' then
  3.    return Image1.Autosize;
  4. else If string = 'Style_02' then
  5.    return Image2.Autosize;

Will the return value be used as a rela control syntax in code?
Title: Re: Convert String to Control Name
Post by: pixelink on August 12, 2019, 05:04:44 pm
Well... I did figure out how to do it within 1 button click.

Code: Pascal  [Select]
  1. procedure TForm1.Button3Click(Sender: TObject);
  2. var
  3.   str: String;
  4.   TImg: TImage;
  5. begin
  6.  
  7.   str:='Style_01';
  8.   If str = 'Style_01' then
  9.      begin
  10.         TImg:= Style_01;
  11.      end;
  12.  
  13.   TImg.AutoSize:=True;
  14.  
  15. end;


Now, I need to to convert it to a function
Title: Re: Convert String to Control Name
Post by: lainz on August 12, 2019, 05:10:45 pm
Something like this
Code: Pascal  [Select]
  1. var
  2.   aImage: TImage;
  3. begin
  4.   aImage := TImage(FindComponent('Style_01'));
  5.   aImage.AutoSize := True;
Title: Re: Convert String to Control Name
Post by: pixelink on August 12, 2019, 05:13:10 pm
I am trying to setup my function, but I get this error
"Fatal: Syntax error, ":" expected but ";" found"


Code: Pascal  [Select]
  1. function getImgControl(str: String; TImg: TImage);



Why?  I always use ";" in procedures and functions
Title: Re: Convert String to Control Name
Post by: Thaddy on August 12, 2019, 05:16:05 pm
Code: Pascal  [Select]
  1. function getImgControl(str: String; TImg: TImage) : {function result type is missing};  // <======= error
  2.  
Title: Re: Convert String to Control Name
Post by: pixelink on August 12, 2019, 05:16:46 pm
Something like this
Code: Pascal  [Select]
  1. var
  2.   aImage: TImage;
  3. begin
  4.   aImage := TImage(FindComponent('Style_01'));
  5.   aImage.AutoSize := True;

Okay.. I just saw this...
It works perfectly.


I would still like to know why my function call has an error though.

Thanks again LAINZ
Title: Re: Convert String to Control Name
Post by: RAW on August 12, 2019, 05:21:38 pm
Reply #5 on: Today
Title: Re: Convert String to Control Name
Post by: pixelink on August 12, 2019, 05:22:29 pm
Code: Pascal  [Select]
  1. function getImgControl(str: String; TImg: TImage) : {function result type is missing};  // <======= error
  2.  

I would assume Type is either TImage or TControl.
Right?
Title: Re: [SOLVED] Convert String to Control Name
Post by: pixelink on August 12, 2019, 06:01:29 pm
I finally got the function working too.

LAINZ solution is easier.

But, for my own learning, I wanted to get the function working too.
Here is what I got working

Code: Pascal  [Select]
  1. uses
  2.   Classes, LCLType, SysUtils, Forms, Controls, Graphics, Dialogs, ExtCtrls,
  3.   StdCtrls, Buttons, Menus;
  4.  
  5.  
  6.  ...
  7.  public
  8.     function getImgControl(str: String): TImage;
  9.   end;
  10.  
  11. function TForm1.getImgControl(str: String): TImage;
  12. var
  13. TImg: TImage;
  14. begin
  15.  
  16.   If str = 'Style_01' then
  17.      begin
  18.         TImg:= TImage(FindComponent(str));
  19.         result:= TImg;
  20.      end
  21.   else If str = 'Style_02' then
  22.      begin
  23.         TImg:= TImage(FindComponent(str));
  24.         result:= TImg;
  25.      end
  26.    else If str = 'Style_03' then
  27.      begin
  28.         TImg:= TImage(FindComponent(str));
  29.         result:= TImg;
  30.      end
  31.    else If str = 'Style_04' then
  32.      begin
  33.         TImg:= TImage(FindComponent(str));
  34.         result:= TImg;
  35.      end
  36. end;
  37.  
  38. procedure TForm1.Button1Click(Sender: TObject);
  39. var
  40.   str: String;
  41.   TImg: TImage;
  42. begin
  43.  
  44.   str:='Style_01'; //just for testing
  45.   TImg:=getImgControl(str);
  46.   TImg.AutoSize:=True;
  47. end;
  48.  
  49. end.
  50.  
Title: Re: [SOLVED] Convert String to Control Name
Post by: mangakissa on August 13, 2019, 09:12:52 am
You don't need a function.
Code: Pascal  [Select]
  1. procedure TForm1.Button1Click(Sender: TObject);
  2. var
  3.   str: String;
  4.   Img: TImage;
  5. begin
  6.    str:='Style_01'; //just for testing
  7.   Img:=TImage(FindComponent(str);
  8.   Img.AutoSize:=True;
  9. end;
  10.  
But if you want to, use a procedure instead of a function. Your component is global in your form object.
Code: Pascal  [Select]
  1. procedure TForm1.getImgControl(const str: String);
  2. var Img: TImage;
  3. begin
  4.    Img:= TImage(FindComponent(str));
  5.     Img.AutoSize:=True
  6.  end;
  7.  
Most clean of all
Code: Pascal  [Select]
  1. procedure TForm1.getImgControl(const str: String);
  2. var Img: TImage;
  3. begin
  4.    Img:= TImage(FindComponent(str)).AutoSize := true
  5.  end;
  6.  

TIP: Don't use T+<name> for your vars. Especially by local vars. The combination is used to tell the developper it's a class definition.
Title: Re: [SOLVED] Convert String to Control Name
Post by: pixelink on August 13, 2019, 02:24:58 pm
You don't need a function.
Code: Pascal  [Select]
  1. procedure TForm1.Button1Click(Sender: TObject);
  2. var
  3.   str: String;
  4.   Img: TImage;
  5. begin
  6.    str:='Style_01'; //just for testing
  7.   Img:=TImage(FindComponent(str);
  8.   Img.AutoSize:=True;
  9. end;
  10.  
But if you want to, use a procedure instead of a function. Your component is global in your form object.
Code: Pascal  [Select]
  1. procedure TForm1.getImgControl(const str: String);
  2. var Img: TImage;
  3. begin
  4.    Img:= TImage(FindComponent(str));
  5.     Img.AutoSize:=True
  6.  end;
  7.  
Most clean of all
Code: Pascal  [Select]
  1. procedure TForm1.getImgControl(const str: String);
  2. var Img: TImage;
  3. begin
  4.    Img:= TImage(FindComponent(str)).AutoSize := true
  5.  end;
  6.  

TIP: Don't use T+<name> for your vars. Especially by local vars. The combination is used to tell the developper it's a class definition.

No, I don't need one.
But, if I have to evaluate a bunch of strings (100+), I a function would be useful just for tidiness of code, plus I can reuse the function from any procedure.
That is what functions are for... to reuse the same code or to keep things tidy.

I, wanted to get mine working juts for learning purposes.
Title: Re: [SOLVED] Convert String to Control Name
Post by: lucamar on August 13, 2019, 02:57:30 pm
Two things about your function:

1) If you pass a string which is  not oine of the names tested for, the function's resultis indeterminate; and

2) you do exactly the same thing when the name is a known one.

All of which means that instead of that "if" chain you can implement it as:

Code: Pascal  [Select]
  1. function TForm1.getImgControl(str: String): TImage;
  2. var
  3.   AComponent: TComponent;
  4. begin
  5.   AComponent :=  FindComponent(str);
  6.   if Assigned(AComponent) and AComponent.InheritsFrom(TImage) then
  7.     Result := TImage(AComponent)
  8.   else
  9.     Result := Nil;
  10. end;

Note that it will then return Nil if the name is not that of a TImage so you should check for this whenever it's used:

Code: Pascal  [Select]
  1. procedure TForm1.Button1Click(Sender: TObject);
  2. var
  3.   str: String;
  4.   Img: TImage;
  5. begin
  6.   str:='Style_01'; //just for testing
  7.   Img := getImgControl(str);
  8.   if Assigned(Img) then
  9.     Img.AutoSize:=True;
  10. end;
Title: Re: [SOLVED] Convert String to Control Name
Post by: howardpc on August 13, 2019, 03:45:58 pm
Building on lucamar's suggestion.

It is often useful to have both a boolean function in these circumstances, and simultaneously obtain a TImage value. You can obtain both with a single function call such as the following:
Code: Pascal  [Select]
  1. function TForm1.ControlNameIsTImage(const aControlName: String; out Image: TImage): Boolean;
  2. var
  3.   AComponent: TComponent;
  4. begin
  5.   AComponent := FindComponent(aControlName);
  6.   Result := Assigned(AComponent) and AComponent.InheritsFrom(TImage);
  7.   case Result of
  8.     True:  Image := TImage(AComponent);
  9.     False: Image := Nil;
  10.   end;
  11. end;
Title: Re: [SOLVED] Convert String to Control Name
Post by: mangakissa on August 14, 2019, 08:33:13 am
But why sending a component back if this already can be reached on form. And why can't the whole procedure not run in the function itself. Now you're jumping from register to register for nothing and using resources unnessensary.