代码之家  ›  专栏  ›  技术社区  ›  WobblyBob

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

  •  0
  • WobblyBob  · 技术社区  · 9 年前

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

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

    非常感谢您的帮助。。。

    2 回复  |  直到 9 年前
        1
  •  4
  •   MBo    9 年前

    只需创建一个 OnMouseEnter OnMouseLeave ).

    如果这些组件是在设计时创建的 ,然后您可以在表单设计器中选择所有168个图像,然后转到对象检查器并一次性分配事件,如Remy Lebeau在评论中所述。替代方法-使用现有组件列表(假设所有者是表单,表单上没有其他时间):

    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;
    
        2
  •  3
  •   Remy Lebeau    9 年前

    也就是说, 如果

    在 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 类来替换所有现有 设计时放置在表单上的组件。

    请注意,此示例仅适用于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;