Recent

Author Topic: Referring to objects in variables  (Read 4738 times)

heebiejeebies

  • Full Member
  • ***
  • Posts: 127
Referring to objects in variables
« on: January 23, 2022, 09:12:18 pm »
Feel like this is a dumb question, but can't find an answer anywhere.  How do I refer to an object name using a variable?

I've been getting around this with routines like this:

Code: Pascal  [Select][+][-]
  1. var
  2. Weather: Shortint;  
  3. begin
  4. if weather = 1 then Sunnyicon.visible :=true;
  5. if weather = 2 then Cloudyicon.visible :=true;
  6.  

But I'm currently working on a complicated routine that will take me forever to program like that.  Is there a way to just put the name of the object into a variable and then refer to it directly?  So theoretically it would be something more like:

Code: Pascal  [Select][+][-]
  1. var
  2. Weather: object;  
  3. begin
  4. Weather.visible :=true;
  5.  

Thanks!  :D
Fedora 38/Lazarus 2.2.4- FPC 3.3.1

howardpc

  • Hero Member
  • *****
  • Posts: 4144
Re: Referring to objects in variables
« Reply #1 on: January 24, 2022, 12:31:18 am »
For classes that descend from TComponent (such as TImage) you can use the FindComponent method. For example:
Code: Pascal  [Select][+][-]
  1. type
  2.   TForm1 = class(TForm)
  3.     Image1: TImage;
  4.     procedure FormCreate(Sender: TObject);
  5.   public
  6.     sunny, cloudy: TImage;
  7.     procedure CreateImages;
  8.     function IconVisibleSetOK(const aImageName: String; isVisable: Boolean): Boolean;
  9.     procedure ShowSunWithNoClouds;
  10.   end;
  11.  
  12. var
  13.   Form1: TForm1;
  14.  
  15. implementation
  16.  
  17. {$R *.lfm}
  18.  
  19. procedure TForm1.CreateImages;
  20. begin
  21.   cloudy := TImage.Create(Self);
  22.   cloudy.Name := 'cloudy';
  23.   //cloudy.Picture.Icon.LoadFromFile(...);
  24.   sunny := TImage.Create(Self);
  25.   sunny.Name := 'sunny';
  26.   //sunny.Picture.Icon.LoadFromFile(...);
  27. end;
  28.  
  29. procedure TForm1.FormCreate(Sender: TObject);
  30. begin
  31.   CreateImages;
  32.   ShowSunWithNoClouds;
  33. end;
  34.  
  35. function TForm1.IconVisibleSetOK(const aImageName: String; isVisable: Boolean): Boolean;
  36. var
  37.   cmp: TComponent;
  38. begin
  39.   cmp := FindComponent(aImageName);
  40.   Result := Assigned(cmp) and (cmp is TImage);
  41.   if Result then
  42.     TImage(cmp).Visible := isVisible;
  43. end;
  44.  
  45. procedure TForm1.ShowSunWithNoClouds;
  46. begin
  47.   Assert(IconVisibleSetOK('sunny', True), 'missing sunny icon!');
  48.   Assert(IconVisibleSetOK('cloudy', False), 'missing cloudy icon!');
  49. end;
                                                                 

heebiejeebies

  • Full Member
  • ***
  • Posts: 127
Re: Referring to objects in variables
« Reply #2 on: January 24, 2022, 08:39:33 pm »
Thanks guys! It seems that using a TComponent variable is the easiest way, especially since I've already created a lot of my components.

Now, how does one clear a TComponent variable?  Normally I just set an int to 0 or set a string to two apostrophes.  The TComponent variables are having none of that!

Also, I should point out that my code is much simpler than Howardpc's code above.  I've simply gone with:

Code: Pascal  [Select][+][-]
  1.  var
  2.  ObjectAVar : TComponent;
  3. begin
  4.   TImage(ObjectAVar).Visible :=true;  
  5.  

I haven't bothered with FindComponent or anything and the code works.  Am I exposing myself to some danger by doing it this simple way?
« Last Edit: January 24, 2022, 09:25:56 pm by heebiejeebies »
Fedora 38/Lazarus 2.2.4- FPC 3.3.1

howardpc

  • Hero Member
  • *****
  • Posts: 4144
Re: Referring to objects in variables
« Reply #3 on: January 24, 2022, 10:15:13 pm »
I haven't bothered with FindComponent or anything and the code works.  Am I exposing myself to some danger by doing it this simple way?
You only show code snippets so others cannot assess the safety or otherwise of your approach. But the unprotected cast of ObjectAVar to a TImage looks risky to me. Why is the cast needed? What is ObjectAVar?
It is not clear what you are asking by "clearing" a TComponent variable. If you are talking about a TImage or TImage descendant, do you mean TImageInstance.Free, or TImageInstance.Graphic.Clear?

heebiejeebies

  • Full Member
  • ***
  • Posts: 127
Re: Referring to objects in variables
« Reply #4 on: January 25, 2022, 02:25:54 am »
Sorry even though I've been at this a while I'm still a bit of a n00b - I don't really understand what you mean by unprotected casts.   %)

Anyway, I should have explained more clearly.  I have a number of screens that the user can click through, and I am trying to create a back button here.  Each screen has a series of varying objects like text fields, list boxes and various image choices.  The user chooses which image is visible by clicking on various buttons.  Only one image is visible at a time.  The different screens can be reused for various purposes, so I need to store all the user-changeable data on each screen, so that it can be restored back to its former state when the user clicks the back button.  I have various string/int arrays that store the data in the other fields, and that all seems to work fine.  The question here is purely about storing which image is visible.

ObjectAVar is a global variable of TComponent that saves the name of the currently visible image.  There is also a corresponding array of TComponent, called ObjectA, so when the user changes screen, a new line gets created in the TComponent array and ObjectAVar is saved there.

So, the code on the user screen for selecting Image1 will be something like this:

Code: Pascal  [Select][+][-]
  1. begin
  2. // code here to hide all other images, then ...
  3.  
  4. Image1.Visible :=true;
  5. ObjectAVar :=Image1;
  6. end
  7.  

It gets put into the ObjectA array when the user goes to a new screen.

Then in the back button, when we return to this screen, we'll fetch the correct visible image from the ObjectA array, then show that image:

Code: Pascal  [Select][+][-]
  1. begin
  2. // code here to hide all other images, then ...
  3.  
  4.   ObjectAVar := ObjectA[High(ObjectA)];
  5.   TImage(ObjectAVar).Visible :=true;  
  6.  

Having tried it, this works. So I'm just a bit confused what all the other code in your example was about, and whether I've missed something crucial by making mine so simple.  Thanks !  :D
« Last Edit: January 25, 2022, 02:53:25 am by heebiejeebies »
Fedora 38/Lazarus 2.2.4- FPC 3.3.1

heebiejeebies

  • Full Member
  • ***
  • Posts: 127
Re: Referring to objects in variables
« Reply #5 on: January 27, 2022, 12:24:39 am »
I guess I'm just going to keep doing it this way. I can't see any dangers with it.

Thanks for your help guys!
Fedora 38/Lazarus 2.2.4- FPC 3.3.1

heebiejeebies

  • Full Member
  • ***
  • Posts: 127
Re: Referring to objects in variables
« Reply #6 on: January 27, 2022, 10:24:56 pm »
Good point, that could have been embarrassing.  Thanks  :D
Fedora 38/Lazarus 2.2.4- FPC 3.3.1

 

TinyPortal © 2005-2018