Delphi中鼠标悬停TImage组件时显示窗体、离开后隐藏的实现方法
TImage悬停显示自定义窗体、离开自动隐藏的实现方案
方案1:捕获CM_MOUSELEAVE消息实现(推荐,无额外性能消耗)
- 首先在TImage所在的主窗体类的私有声明区,添加消息处理函数和提示窗体变量声明:
private procedure CMMouseLeave(var Message: TMessage); message CM_MOUSELEAVE; FHintForm: TForm; // 你自定义的提示窗体实例
- 实现TImage的
OnMouseMove事件,用来触发提示窗体显示:
procedure TMainForm.Image1MouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); begin // 首次触发时创建提示窗体,可根据需求自定义窗体样式 if not Assigned(FHintForm) then begin FHintForm := TCustomHintForm.Create(Self); FHintForm.BorderStyle := bsNone; FHintForm.FormStyle := fsStayOnTop; FHintForm.ClientWidth := 200; FHintForm.ClientHeight := 100; end; // 窗体未显示时更新位置并显示 if not FHintForm.Visible then begin FHintForm.Left := Mouse.CursorPos.X + 15; FHintForm.Top := Mouse.CursorPos.Y + 15; FHintForm.Show; end; end;
- 实现CM_MOUSELEAVE消息处理函数,鼠标离开TImage时自动隐藏窗体:
procedure TMainForm.CMMouseLeave(var Message: TMessage); begin inherited; // 判断离开的控件是否为目标TImage if (Message.LParam = LPARAM(Image1)) and Assigned(FHintForm) and FHintForm.Visible then FHintForm.Hide; end;
方案2:Timer轮询实现(兼容性更强,无需处理自定义消息)
适合不想处理Windows消息、或者使用老版本Delphi的场景:
- 往主窗体拖入一个
TTimer组件,设置Interval = 100,默认Enabled = False - 调整TImage的
OnMouseMove事件,显示窗体的同时启动Timer:
procedure TMainForm.Image1MouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); begin // 创建、显示提示窗体的逻辑和方案1一致 Timer1.Enabled := True; end;
- 实现Timer的
OnTimer事件,定期检测鼠标位置判断是否要隐藏窗体:
procedure TMainForm.Timer1Timer(Sender: TObject); var CurPos: TPoint; CurControl: TControl; begin GetCursorPos(CurPos); CurControl := ControlAtPos(ScreenToClient(CurPos), True); // 鼠标不在目标TImage上方时隐藏窗体,关闭Timer节省资源 if CurControl <> Image1 then begin if Assigned(FHintForm) and FHintForm.Visible then FHintForm.Hide; Timer1.Enabled := False; end; end;
注意事项
如果你的自定义提示窗体需要支持鼠标交互(比如上面有可点击的按钮、链接),需要在隐藏判断逻辑中新增
鼠标是否落在提示窗体范围内的判断,避免鼠标移到提示窗体时被误关闭。
内容的提问来源于stack exchange,提问作者Coding247
相关产品推荐
相关产品推荐

