【问题标题】:TImage - dynamically load resource by component nameTImage - 按组件名称动态加载资源
【发布时间】:2018-01-15 20:40:56
【问题描述】:

我将把这个过程分配给OnMouseEnter。我有一些TImage 会改变它的图片OnMouseEnter。在事件处理程序上制作它的每个过程更容易。但我不喜欢重复相同的代码。

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;

我怎样才能允许s 进入TImage.Name

【问题讨论】:

  • 我不确定我理解你想要什么。不要引用s,而是使用CoName as TImage 的引用(BTW 变量名错误)。或使用FindComponent(s) as TImage
  • @kobik 我需要获取CoName 的名称,然后这个名称将分配资源。 @Victoria 谢谢,请纠正它。
  • TImage 应该更改为OnMouseEnter?那么Sender参数就是你感兴趣的TImage
  • 如果您确定必须这样做,那很好。继续。我很确定你做错了,但我不想费力说服你。
  • 如果您不打算对某些图像执行任何特殊操作,则不需要不同的程序。 Delphi 事件通常会给您Sender 作为确定事件触发位置的一种方式。在您的情况下,它是您要查找的 TImage

标签: delphi components timage


【解决方案1】:

将所有TImage对象的OnMouseEnter事件设置为指向同一个事件处理程序,并使用其Sender参数来识别哪个TImage正在调用该处理程序:

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;

【讨论】:

  • 我认为 OP 想要 LoadFromResourceName(hInstance, 'Res' + cn);... 不确定:/ 顺便说一句,这里有 FreeAndNil 的任何理由吗?
  • 谢谢@kobik 是的,这是可能的,添加了关于它的评论。范,不,绝对不是。
  • @kobik (PNG) 在这种情况下,我习惯使用FreeAndNil。我应该改为 free 吗?
  • @DavidHeffernan, FreeAndNil 的使用是有原因的。不是这个。
  • @Bianca 没有理由将即将超出范围的引用归零,但它也无害。这是编码风格的问题。有些人对这些事情很敏感。
【解决方案2】:

我这样做了,它工作正常,你不需要String 变量或循环:

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;

对于所有其他 Timage (15) ,您可以将事件设置为无需重复来自对象检查器的代码:

【讨论】:

  • 声明多个事件处理程序很浪费。此外,当传递图像以外的内容时,您不应忽略错误。使用as 而不是is
  • 这就是人们所说的。再次,我在这里学到了关于直接访问组件的新课程。 you don't need to remember the name. Remember the component. - 我的导师说^_^
  • 我认为 OP 不想在传递不是 TImage 的东西时处理错误。
  • @Sami 那将是一个错误,而不是处理错误。
  • 是的,我知道,但他问我回答问题,不多也不少。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-06-12
  • 1970-01-01
  • 1970-01-01
  • 2020-12-09
  • 2017-11-05
相关资源
最近更新 更多