MouseLeave事件无法按下左键单击

时间:2016-04-01 07:43:50

标签: windows delphi winapi mouseevent vcl

我正在使用Delphi进行测试VCL应用程序。我有一个带有标签的空表单,我用FormMouseLeave形式更改了该标签值。它可以工作,但如果我在离开表单的同时按下鼠标左键,则不会触发事件。

我尝试拦截WM_MOUSELEAVE消息,但看起来根本没有触发(好吧,我猜FormMouseLeave事件基于该消息)

我不需要触发任何拖拽,我只需要在鼠标离开我的表单时按下左键,我该怎么办?

2 个答案:

答案 0 :(得分:4)

这是WM_MOUSELEAVE消息的已知行为。您可以通过跟踪鼠标移动来绕过它,当鼠标离开形成边界时,您可以自己触发事件。

当您按下鼠标按钮时,您的窗口(窗体)已捕获鼠标,即使鼠标超出其范围,也会收到WM_MOUSEMOVE个事件。 WM_MOUSELEAVE消息用于在您未捕获鼠标时跟踪窗口内的鼠标。

如果您将MouseEnterMouseLeaveMouseMove个事件分配到表单,则可以执行以下操作:

procedure TForm1.FormMouseEnter(Sender: TObject);
begin
  Label1.Caption := '';
end;

procedure TForm1.FormMouseLeave(Sender: TObject);
begin
  Label1.Caption := 'left';
end;

procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
begin
  if not PtInRect(ClientRect, TPoint.Create(x, y)) then Label1.Caption := 'left move';
end;

答案 1 :(得分:4)

当左键按下时,如果鼠标下方的控件在其控件样式中有csCaptureMouse,则VCL框架会捕获鼠标。捕获鼠标时,在释放捕获之前不会生成WM_MOUSELEAVE消息。当左按钮上升时会发生这种情况。

如果您从鼠标下方的控件中删除了csCaptureMouse,则鼠标离开窗口后会立即生成WM_MOUSELEAVE消息,因为鼠标不会被捕获。

procedure TForm1.FormCreate(Sender: TObject);
begin
  ControlStyle := ControlStyle - [csCaptureMouse];
end;

当然,为了达到这个效果而改变这种风格肯定不是你应该做的。我只是指出这个问题是因为鼠标捕获和鼠标跟踪之间的相互作用。

但我认为鼠标跟踪和WM_MOUSELEAVE并不是你想要的。将鼠标悬停在表单上的控件上时会触发WM_MOUSELEAVE,这肯定不是您想要的。

所以我认为Dalija答案中概述的方法实际上是在任何情况下实现所需行为的正确方法,无论鼠标按钮是否关闭。