You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何检测鼠标是否位于控件或其任意子控件上方?

解决Delphi面板鼠标移出收缩(含子控件)的问题

针对你遇到的鼠标移到面板子控件时触发父面板MouseLeave导致错误收缩,以及主窗体被覆盖无法触发MouseEnter的问题,可以通过TrackMouseEventAPI结合消息处理实现精准的鼠标离开检测,确保只有当鼠标完全离开面板及其所有子控件时才收缩面板。

具体实现步骤

1. 修改窗体类声明

在Unit1的private部分添加跟踪变量和消息处理方法:

type
  TForm14 = class(TForm)
    Panel1: TPanel;
    Panel2: TPanel;
    Panel3: TPanel;
    ComboBox1: TComboBox;
    Button1: TButton;
    procedure FormMouseEnter(Sender: TObject);
    procedure Panel1MouseEnter(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    FPanel1Tracking: Boolean; // 标记是否正在跟踪Panel1的鼠标离开状态
    procedure WMMouseLeave(var Message: TMessage); message WM_MOUSELEAVE;
    procedure ResetPanel1Tracking;
    procedure ResetPanel1MouseEnter(Sender: TObject); // 统一处理子控件MouseEnter
  public
    { Public declarations }
  end;

2. 实现核心方法

在implementation部分添加以下代码:

procedure TForm14.FormCreate(Sender: TObject);
var
  I: Integer;
  Child: TControl;
begin
  // 自动绑定Panel1所有子控件的MouseEnter事件,无需手动逐个添加
  for I := 0 to Panel1.ControlCount - 1 do
  begin
    Child := Panel1.Controls[I];
    Child.OnMouseEnter := ResetPanel1MouseEnter;
  end;
end;

procedure TForm14.ResetPanel1Tracking;
var
  TrackMouseEvent: TTrackMouseEvent;
begin
  if not FPanel1Tracking then
  begin
    FillChar(TrackMouseEvent, SizeOf(TrackMouseEvent), 0);
    TrackMouseEvent.cbSize := SizeOf(TrackMouseEvent);
    TrackMouseEvent.dwFlags := TME_LEAVE;
    TrackMouseEvent.hwndTrack := Panel1.Handle;
    // 启动鼠标离开跟踪
    FPanel1Tracking := Winapi.Windows.TrackMouseEvent(TrackMouseEvent);
  end;
end;

procedure TForm14.WMMouseLeave(var Message: TMessage);
begin
  inherited;
  // 确认是Panel1的鼠标离开消息
  if Message.WParam = Panel1.Handle then
  begin
    Panel1.Height := 25; // 收缩面板
    FPanel1Tracking := False;
  end;
end;

procedure TForm14.ResetPanel1MouseEnter(Sender: TObject);
begin
  // 鼠标进入子控件时重置跟踪,避免误触发父面板离开事件
  ResetPanel1Tracking;
end;

procedure TForm14.Panel1MouseEnter(Sender: TObject);
begin
  Panel1.Height := 64; // 展开面板
  ResetPanel1Tracking;
end;

// 原FormMouseEnter可保留,实际已由WM_MOUSELEAVE处理收缩逻辑
procedure TForm14.FormMouseEnter(Sender: TObject);
begin
  Panel1.Height := 25;
end;

3. 绑定FormCreate事件

在窗体设计器中,给Form14添加OnCreate事件,关联到FormCreate方法。

原理说明

  • TrackMouseEvent:Windows原生API,用于跟踪鼠标离开指定窗口的事件,当鼠标完全离开窗口(包括其子窗口)时,会发送WM_MOUSELEAVE消息。
  • 子控件MouseEnter统一处理:当鼠标移到Panel1的子控件时,重新启动跟踪状态,避免父面板误触发离开事件。
  • WM_MOUSELEAVE消息处理:仅当鼠标真正离开Panel1及其所有子控件时,才执行面板收缩操作,彻底解决子控件干扰问题。

这种方法无需依赖主窗体的MouseEnter事件,完全基于Panel1自身的鼠标跟踪逻辑,解决了窗体被覆盖无法触发事件的问题。

内容的提问来源于stack exchange,提问作者Koot33

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 03:35:03