当鼠标进入时,让Timage向下移动并留下3个像素,当鼠标离开时返回到原始位置

时间:2017-08-08 14:13:18

标签: delphi delphi-xe3 delphi-xe4

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

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

我知道我可以在OnMouseEnter和OnMouseLeave事件中执行此操作并且它运行良好 - 但我不禁认为必须有一个更优雅/有效的方法来为所有168个Timage对象生成此效果,而不是创建168 OnMouseEnter过程和168 OnMouseLeave过程。

任何帮助都非常感谢...

2 个答案:

答案 0 :(得分:4)

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

如果这些组件是在设计时创建的(很难想象),那么您可以在“表单设计器”中选择所有168个图像,然后转到“对象检查器”并分配事件。正如Remy Lebeau在评论中写道的那样。替代方式 - 使用现有的组件列表(假设所有者是表单,表单上没有其他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;

答案 1 :(得分:3)

这里最干净的解决方案是创建一个自定义组件,并从如此沉重和扁平的设计时布局中消除您的设计。这些自然变得难以维护和修改。

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

在表格单元的interface部分,在表格的类声明上方添加以下课程:

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类替换设计时放置在窗体上的所有现有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;