Delphi自定义FMX TImage组件实现MouseEnter、MouseLeave事件问题求助
FMX自定义图片组件鼠标悬停无响应问题修复
代码核心错误点
- 框架单元混引:同时引入了VCL和FMX两类框架的单元,两类框架控件体系、消息逻辑完全独立,混引会导致逻辑冲突,
vcl.Controls、vcl.Dialogs等VCL单元不应该出现在FMX组件代码中。 - 消息机制误用:
CM_MOUSEENTER、CM_MOUSELEAVE是VCL框架的私有Windows消息,FMX控件不依赖Windows消息体系,用消息绑定的方式检测鼠标状态完全不生效。 - 事件逻辑错误:已有的
DoMouseEnter、DoMouseLeave方法中,将外部事件调用代码放在了非空判断外,未给组件赋值OnMouseEnter/OnMouseLeave时会触发空指针异常;且内部逻辑依赖外部事件赋值,不满足你无需调用外部事件就自动切换图片的需求。 - 资源访问越界:注释掉的构造函数中直接访问
MultiResBitmap.Items[0],未预先添加图片项时访问索引0会直接抛出数组越界异常。
修正后完整代码
unit ImageCustoms; interface uses System.SysUtils, System.Classes, FMX.Types, FMX.Objects, FMX.Dialogs; type TImageCustoms = class(TImage) private { Private declarations } FOnMouseLeave: TNotifyEvent; FOnMouseEnter: TNotifyEvent; protected { Protected declarations } procedure DoMouseEnter; override; procedure DoMouseLeave; override; public { Public declarations } constructor Create(AOwner: TComponent); override; destructor Destroy; override; published { Published declarations } property OnMouseEnter: TNotifyEvent read FOnMouseEnter write FOnMouseEnter; property OnMouseLeave: TNotifyEvent read FOnMouseLeave write FOnMouseLeave; end; procedure Register; implementation procedure Register; begin RegisterComponents('Samples', [TImageCustoms]); end; constructor TImageCustoms.Create(AOwner: TComponent); begin inherited Create(AOwner); // 预加载图片前先判断数量,避免越界 if MultiResBitmap.Count = 0 then MultiResBitmap.Add; // 这里可以换成你的资源加载逻辑,建议用资源文件而不是本地路径 // MultiResBitmap.Items[0].Bitmap.LoadFromFile('focus0.png'); end; destructor TImageCustoms.Destroy; begin inherited Destroy; end; procedure TImageCustoms.DoMouseEnter; begin inherited; // 内部逻辑直接写这里,不需要依赖外部事件赋值 ShowMessage('Enter'); // 切换悬停图片的逻辑可以写在这里 // 执行外部绑定的事件(如果有赋值) if Assigned(FOnMouseEnter) then FOnMouseEnter(Self); end; procedure TImageCustoms.DoMouseLeave; begin inherited; // 内部逻辑直接写这里 ShowMessage('Leave'); // 切换默认图片的逻辑可以写在这里 // 执行外部绑定的事件(如果有赋值) if Assigned(FOnMouseLeave) then FOnMouseLeave(Self); end; end.
功能说明
- 修正后的代码完全基于FMX原生框架逻辑,通过重写父类已有的
DoMouseEnter、DoMouseLeave虚方法实现鼠标状态检测,不需要绑定外部事件就能执行内部的图片切换逻辑。 - 保留了
OnMouseEnter、OnMouseLeave发布属性,不影响组件在使用时额外绑定自定义事件。 - 预加载图片逻辑建议使用资源文件嵌入,避免发布后本地路径不存在的问题。
内容的提问来源于stack exchange,提问作者Max_Poland
相关产品推荐
相关产品推荐

