-3

I will assign this procedure into OnMouseEnter. I have some TImage that will change it's picture OnMouseEnter. It is easier to make each procedure of it on event handler. But i don't like to repeat the same code.

var
  i: Integer;
  CoName: TComponent;
  png: TPngImage;
  s: string;
begin
  s := '';
  for i := 1 to 16 do
  begin
    CoName := Form1.Components[i];
    if CoName is TImage then
    begin
      s := CoName.Name;
      Break;
    end;
  end;
  if Trim(s) <> '' then
  begin
    png := TPngImage.Create;
    try
      png.LoadFromResourceName(hInstance, 'ResImgA');
      // s.picture.Assign(png);  > i can not do this
    finally
      FreeAndNil(png);
    end;
  end;
end;

How can i allow s into TImage.Name ?

Bianca
  • 973
  • 2
  • 14
  • 33
  • I'm not sure I understand what you want. instead of referring to `s`, use the reference of `CoName as TImage` (bad variable name BTW). or use `FindComponent(s) as TImage` – kobik Aug 08 '17 at 10:21
  • @kobik i need to catch the name of `CoName` and then this name will assign the resource. @Victoria thanks, just correct it. – Bianca Aug 08 '17 at 10:25
  • So many things wrong here. 1 to 16? Why those magic numbers? You seem to want to make everything be a string. Don't. Why are you searching for TImage controls? Why not refer to them directly. – David Heffernan Aug 08 '17 at 10:27
  • No you don't need to remember the name. Remember the component. You can access its name any time. And why did you forget the reference to the component in the first place. – David Heffernan Aug 08 '17 at 10:28
  • 1
    The `TImage` should change `OnMouseEnter`? Then the `Sender` parameter will be the `TImage` you are interested in. – nil Aug 08 '17 at 10:32
  • @kobik I got `[dcc32 Error] Unit1.pas(160): E2233 Property 'Picture' inaccessible here ` when i make FindComponent(s) as TImage.picture.Assign(png); @DavidHeffernan no sir, those were the amounts of my TImages, at the moment. I need to have this feature, so i will not make the same code over and over again. Why such style is unadvised ? – Bianca Aug 08 '17 at 10:32
  • I don't understand why even you need a String variable when you can access the component directly? – Ilyes Aug 08 '17 at 10:35
  • 2
    If you are sure that you have to do it this way, that's fine. Carry on. I'm quite sure you are doing it wrong, but I don't want to expend effort persuading you. – David Heffernan Aug 08 '17 at 10:41
  • I plan will use this procedure to all my TImages on mouse enter / leave event, and perhaps it will be load different resource. So, it is dynamic not a single name. ImageA.OnMouseEnter := ThisProcedure and so on .... I hope you you understand what i mean. – Bianca Aug 08 '17 at 10:42
  • 1
    You would not need different procedures if you don't plan on doing anything special for certain Images. Delphi events will typically give you the `Sender` as a way to determine where the event has been triggered. In your case it is the `TImage` you are trying to find. – nil Aug 08 '17 at 10:48

2 Answers2

7

Set the OnMouseEnter event of all the TImage objects to point to the same event handler, and use its Sender parameter to identify which TImage is calling the handler:

procedure TForm38.ImageMouseEnter(Sender: TObject);
var
  ResName: string;
  im: TImage;
  png: TPngImage;
begin
  im := Sender as TImage;

  // if your image resources are named as 'Res' + name of TImage (eg. 'ImgA')
  // you can combine these as
  ResName := 'Res' + im.Name;

  png := TPngImage.Create;
  try
    png.LoadFromResourceName(hInstance, ResName);
    im.picture.Assign(png);
  finally
    png.Free;
  end;
end;
Tom Brunberg
  • 20,312
  • 8
  • 37
  • 54
  • I think OP wants `LoadFromResourceName(hInstance, 'Res' + cn);`... not sure :/ BTW, any reason for `FreeAndNil` here? – kobik Aug 08 '17 at 10:44
  • Thanks @kobik yes, that's possible, added a comment about it. FAN, no, definitely not. – Tom Brunberg Aug 08 '17 at 10:50
  • @kobik (PNG) I accustomed to `FreeAndNil` on this case. Should i change to just `free` ? – Bianca Aug 08 '17 at 10:53
  • @Bianca It really doesn't matter which you use. – David Heffernan Aug 08 '17 at 10:54
  • 1
    @DavidHeffernan, `FreeAndNil` is used for a reason. this is not it. – kobik Aug 08 '17 at 10:55
  • @kobik Given how confused the asker is on so many more important matters I feel it is best not to digress to FAN discussions. – David Heffernan Aug 08 '17 at 10:57
  • It's really matter when you should use `FreeAndNil()` or `Free` – Ilyes Aug 08 '17 at 10:57
  • 1
    @Bianca There is no reason to nil a reference that is just about to got out of scope, otoh it does no harm either. It's a question of coding style. Some people are sensitive to such things. – Tom Brunberg Aug 08 '17 at 10:57
  • I use FAN just because the compiler (sometimes) give annoying red underline remarks on those x.free but always fine when i use FAN. Anyways, i accept this as my solution. Thank you Tom. I also use the same approach on some other event based from this solution. By this way, my code lines reduced dramatically. – Bianca Aug 08 '17 at 13:59
0

I do this and it's work fine, you don't need String variable or loops:

procedure TForm1.Image1MouseEnter(Sender: TObject);
Var PngImg : TPngImage;
   // Image : TImage;   < -- If you need to handle error
begin
   //Image := Sender as TImage;  and remove IF
   if Sender is TImage then
    begin
      PngImg := TPngImage.Create;
      try
        PngImg.LoadFromResourceName(HInstance , 'PngImage_1');
        TImage(Sender).Picture.Assign(PngImg);
      finally
        PngImg.Free;
      end ;

    end;
end;

For all the other Timage (15) , you can set the event without repeat the code from the object inspector as:

enter image description here

Ilyes
  • 14,640
  • 4
  • 29
  • 55
  • 3
    Wasteful to declare more than one event handler. Further, you should not ignore errors when something other than an image is passed. Use `as` instead of `is`. – David Heffernan Aug 08 '17 at 10:49
  • So this is what the people talking about. again, i learned a new lesson here about accessing directly into component. `you don't need to remember the name. Remember the component.` - my mentor said ^_^ – Bianca Aug 08 '17 at 10:57
  • I don't think the OP want to handle error when something not TImage is passed . – Ilyes Aug 08 '17 at 11:03
  • 2
    @Sami That would be a mistake, not to deal with an error. – David Heffernan Aug 08 '17 at 11:07
  • Yeah I know , but he ask and I answer as the question, no more , no less. – Ilyes Aug 08 '17 at 11:10
  • That's fine. My voting reflects my opinions of the answer that does the bare minimum and the one that goes the extra mile. – David Heffernan Aug 08 '17 at 11:17
  • I think there is a dropdown in events in object inspector where you do that, and its too easy to set events of all the 16 images – Ilyes Aug 08 '17 at 11:38