当鼠标进入时使图像向下和向左移动 3 个像素,当鼠标离开时 return 到原始位置

Make Timage move down and left 3 pixels when Mouse enters and return to original position when mouse leaves

我有一个包含大约 168 个 Timage 对象的表单,其中包含用户可选择的图标。

我希望当鼠标悬停在 Timage 对象上时,每个图标都向下和向右移动 3 个像素。当鼠标离开 Timage 时,我希望它 return 回到原来的位置。这将为用户界面增添令人愉悦的效果。

我知道我可以在 OnMouseEnter 和 OnMouseLeave 事件中做到这一点并且效果很好 - 但是我忍不住认为必须有一种更优雅/更有效的方法来为所有 168 个 Timage 对象产生这种效果,而不是创建 168 个 OnMouseEnter 过程和 168 个 OnMouseLeave 过程。

非常感谢任何帮助...

创建一个 OnMouseEnter 事件处理程序并将其分配给每个组件就足够了(类似于 OnMouseLeave)。

如果这些组件是在设计时创建的(难以想象),那么您可以select Form Designer 中的所有 168 个图像,然后转到正如 Remy Lebeau 在评论中所写,Object Inspector 并一次性分配事件。替代方法 - 使用现有的组件列表(假设所有者是表单并且表单上没有其他 TImages):

for i := 0 to Components.Count - 1 do
  if Components[i] is TImage then  //perhaps more conditions to separate needed images
     TImage(Components[i]).OnMouseEnter := EnterHandler;

如果组件是在 运行 时间内创建的,并且它们存储在数组或列表中,则处理程序分配更简单:

for i := 0 to Images.Length - 1 do
   Images[i].OnMouseEnter := EnterHandler;

然后您可以使用事件的 Sender 参数处理每个组件:

procedure TMyForm.EnterHandler(Sender: TObject);
begin
  TImage(Sender).Left := TImage(Sender).Left + 3;
  TImage(Sender).Top := TImage(Sender).Top + 3;
end;

procedure TMyForm.LeaveHandler(Sender: TObject);
begin
  TImage(Sender).Left := TImage(Sender).Left - 3;
  TImage(Sender).Top := TImage(Sender).Top - 3;
end;

此处最干净的解决方案是创建一个自定义组件并净化您的设计,使其远离如此繁重且扁平的设计时布局。这些自然变得难以维护和修改。

就是说,如果你想快速破解以节省大量的打字和点击,你可以使用插入器 class 来注入这种鼠标行为。

在表单单元的 interface 部分,在表单的 class 声明上方添加以下 class:

type
  TImage = class(Vcl.ExtCtrls.TImage)
  private
    procedure CMMouseEnter(var Message: TMessage); message CM_MOUSEENTER;
    procedure CMMouseLeave(var Message: TMessage); message CM_MOUSELEAVE;
  end;       

  TForm1 = class(TForm)
    { ... rest of your form as normal }
  end;

然后,在 implementation 部分添加:

procedure TImage.CMMouseEnter(var Message: TMessage);
begin
  inherited;
  Top := Top + 3;   
  Left := Left + 3;
end;

procedure TImage.CMMouseLeave(var Message: TMessage);
begin
  inherited;
  Top := Top - 3;   
  Left := Left - 3;
end;

像这样定义插入器会有效地导致您修改的 TImage class 替换设计时放置在窗体上的所有现有 TImage 组件。

请注意,此示例仅适用于 Windows 上的 VCL。对于使用 FMX 的跨平台解决方案,所有 UI 控件都有虚拟 DoMouseEnter()DoMouseLeave() 方法,您可以 override 代替,例如:

type
  TImage = class(FMX.Objects.TImage)
  protected
    procedure DoMouseEnter; override;
    procedure DoMouseLeave; override;
  end;       

...

procedure TImage.DoMouseEnter;
begin
  inherited;
  Top := Top + 3;   
  Left := Left + 3;
end;

procedure TImage.DoMouseLeave;
begin
  inherited;
  Top := Top - 3;   
  Left := Left - 3;
end;