【发布时间】:2019-07-23 18:53:29
【问题描述】:
在WindowsForms 中我刚刚添加了如下事件处理程序:
private void Form1_MouseDown(object sender, MouseEventArgs e)
{
Debug.WriteLine($"=> Form1_MouseDown, Clicks: {e.Clicks}, Location: {e.Location}");
}
private void Form1_MouseUp(object sender, MouseEventArgs e)
{
Debug.WriteLine($"=> Form1_MouseUp, Clicks: {e.Clicks}, Location: {e.Location}");
}
private void Form1_MouseMove(object sender, MouseEventArgs e)
{
Debug.WriteLine($"=> Form1_MouseMove, Clicks: {e.Clicks}, Location: {e.Location}");
}
输出是:
=> Form1_MouseMove, Clicks: 0, Location: {X=17,Y=21}
=> Form1_MouseDown, Clicks: 1, Location: {X=17,Y=21}
=> Form1_MouseUp, Clicks: 1, Location: {X=17,Y=21}
=> Form1_MouseMove, Clicks: 0, Location: {X=17,Y=21}
你可以看到所有事件都发生在同一个位置,所以我的问题是为什么MouseUp事件之后还有MouseMove事件?
我也在 WPF 中尝试了类似的代码,并且发生了MouseMove 事件 NOT。
我在 C++ 中尝试了类似的代码,MouseMove 发生了 NOT 事件:
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
...
case WM_MOUSEMOVE:
OutputDebugString(L"WM_MOUSEMOVE\n");
break;
case WM_LBUTTONDOWN:
OutputDebugString(L"WM_LBUTTONDOWN\n");
break;
case WM_LBUTTONUP:
OutputDebugString(L"WM_LBUTTONUP\n");
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
【问题讨论】:
-
鼠标在移动吗?如果是这样,它将生成运动事件。
-
假定到达 Windows 回调函数的消息顺序与您的身体动作相匹配是不正确的。它不是 FIFO 队列。
-
您必须始终假设操作系统可能会合成 MouseMove 通知,即使鼠标没有移动。例如,它会触发一系列影响光标形状的其他消息。在这种情况下,它发生是因为鼠标捕获状态发生了变化。将
this.Capture = false;添加到 MouseDown 事件处理程序以查看差异。 -
您为回应@Jeff 的评论而发布的链接只是支持他所写的内容。至于你的问题本身,“为什么?”问题通常主要基于意见,这也不例外。你需要问微软为什么在 WM_MOUSEUP 之后会生成 WM_MOUSEMOVE。也就是说,您的代码应该始终准备好处理鼠标移动,并且 Windows 或 .NET 可能会在这种情况下生成一个来解决不具有例如错误的程序的问题。在鼠标上移时重置其光标状态(大多数程序会在鼠标移动时检查光标状态)。
标签: c# .net windows winforms visual-c++