简体   繁体   English

为什么在MouseUp事件发生后会发生MouseMove事件?

[英]Why MouseMove event occurs after MouseUp event?

In WindowsForms I just added event handlers as follows: 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}");
    }

And the output is: 输出是:

=> 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}

You can see that all events occurs in the same location, So my question is why is there a MouseMove event after MouseUp event? 您可以看到所有事件都发生在同一个位置,所以我的问题是为什么在MouseUp事件之后会出现MouseMove事件?

Also I tried similar code in WPF and MouseMove event NOT occurred. 我也试过在WPF和类似代码MouseMove事件没有发生。

And I tried similar code in C++ and MouseMove event NOT occurred: 我试图用C类似的代码++和MouseMove 发生的事件:

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;
}

If your mouse had previously been focused on a separate window, then clicking on a new window and shifting the focus of the mouse will generate a mouse move event (even if the mouse didn't move immediately before or after you clicked your mouse). 如果您的鼠标之前已经聚焦在一个单独的窗口上,那么单击一个新窗口并移动鼠标的焦点将产生一个鼠标移动事件(即使鼠标在您单击鼠标之前或之后没有立即移动)。

Here is a link to a similar StackOverflow response "Ghost" MouseMove Event 这是一个类似StackOverflow响应“Ghost”MouseMove事件的链接

This is because the mouse capture by the MouseDown is released on MouseUp . 这是因为MouseDown上的鼠标捕获是在MouseUp上释放的。 And this extra MouseMove may be to ensure the cursor position. 而这个额外的MouseMove可能是为了确保光标位置。 As a workaround you can do this 作为一种解决方法,您可以执行此操作

        Point LastLocation = Point.Empty;

        private void Form1_MouseDown(object sender, MouseEventArgs e)
        {
            Debug.WriteLine("=> Form1_MouseDown, Clicks: " + e.Location + ", Location: " + e.Location + "");
        }

        private void Form1_MouseUp(object sender, MouseEventArgs e)
        {
            Debug.WriteLine("=> Form1_MouseUp, Clicks: " + e.Location + ", Location: " + e.Location + "");

        }

        private void Form1_MouseMove(object sender, MouseEventArgs e)
        {
            if (LastLocation != e.Location)
            {
                LastLocation = e.Location;
                Debug.WriteLine("=> Form1_MouseMove, Clicks: " + e.Location + ", Location: " + e.Location + "");
            }
        }

This is the intended behavior and will also be trigger whenever app is being switched (Eg: Alt+Tab). 这是预期的行为,并且每当切换应用程序时也会触发(例如:Alt + Tab)。

You should go with workaround as suggested by @VishnuBabu's workaround. 您应该根据@ VishnuBabu的解决方法建议采用解决方法。 And to ignore initial mousemove trigger, you can get the current position of cursor once window is loaded instead of setting the LastLocation to Empty. 要忽略初始mousemove触发器,可以在加载窗口后获取光标的当前位置,而不是将LastLocation设置为Empty。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM