当我这样写时,MouseDown
和MouseUp
会运行:
procedure TForm1.Edit1MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
Label1.Caption:='ddddddd';
end;
procedure TForm1.Edit1MouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
ShowMessage('mouseup');
end;
但是当我这样写的时候,WM_LBUTTONUP dispear和Edit1MouseUp将无法运行,为什么?
procedure TForm1.Edit1MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
ShowMessage('mousedown');
end;
procedure TForm1.Edit1MouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
ShowMessage('mouseup');
end;
答案 0 :(得分:1)
当您致电ShowMessage
时,会显示模态窗口。在模态窗口关闭之前,对ShowMessage
的调用不会返回。模态窗口运行自己的消息循环,然后吃掉鼠标消息。因此,消息队列中已经或即将放置在消息队列中的WM_LBUTTONUP
实际上是由消息框而不是您的Delphi表单处理的。
该邮件究竟是如何处理的?这得看情况。如果在显示模式窗口之前发布了消息,那么它将被分派到所有者窗口,该窗口被禁用。如果在显示模态窗口后发布,则可以将其分派到模态窗口。
这是通过鼠标向上而不是向下鼠标调用操作的原因之一。也许你还没有注意到,但是尝试点击任何常见应用程序中的按钮,并注意只有在鼠标上升时才会出现响应。实际上,如果您按下鼠标按钮,将光标移离按钮,然后松开按钮,动作就不会触发。
现在尝试与您的第二个代码示例类似的东西。在编辑控件中按下鼠标但不要立即释放它。请注意,鼠标停止的结果是现在显示模态窗口。它运行自己的消息循环,表单被禁用。现在释放鼠标按钮。很明显,WM_LBUTTONUP
消息将被模态窗口的消息循环从队列中拉出。
答案 1 :(得分:0)
在您的第二个方案中,编辑控件永远不会发布WM_LBUTTONUP
,因此不会触发OnMouseUp
事件。
当您在ShowMessage
中致电OnMouseDown
时,会启动一个对话框。这不仅会从编辑控件中释放鼠标捕获,还会禁用表单。使用这两个消息时,无法发布消息:不是带有捕获的窗口,而是指向光标下的窗口(参见documentation)。
您可以使用此代码模拟行为,而不显示消息:
procedure TForm1.Edit1MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
Assert(GetCapture = Edit1.Handle);
ReleaseCapture;
Enabled := False;
end;
procedure TForm1.Edit1MouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
ShowMessage('mouseup'); // will not fire.
end;
道德是:不要使用ShowMessage
来调试涉及激活/焦点的情况。因为在这种情况下可能不太明显,所以通常不要将它用作调试工具。