我正在使用Delphi进行测试VCL应用程序。我有一个带有标签的空表单,我用FormMouseLeave
形式更改了该标签值。它可以工作,但如果我在离开表单的同时按下鼠标左键,则不会触发事件。
我尝试拦截WM_MOUSELEAVE
消息,但看起来根本没有触发(好吧,我猜FormMouseLeave
事件基于该消息)
我不需要触发任何拖拽,我只需要在鼠标离开我的表单时按下左键,我该怎么办?
答案 0 :(得分:4)
这是WM_MOUSELEAVE
消息的已知行为。您可以通过跟踪鼠标移动来绕过它,当鼠标离开形成边界时,您可以自己触发事件。
当您按下鼠标按钮时,您的窗口(窗体)已捕获鼠标,即使鼠标超出其范围,也会收到WM_MOUSEMOVE
个事件。 WM_MOUSELEAVE
消息用于在您未捕获鼠标时跟踪窗口内的鼠标。
如果您将MouseEnter
,MouseLeave
和MouseMove
个事件分配到表单,则可以执行以下操作:
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答案中概述的方法实际上是在任何情况下实现所需行为的正确方法,无论鼠标按钮是否关闭。