【问题标题】:How to prevent other mouse buttons from interrupting MouseMove?如何防止其他鼠标按键中断MouseMove?
【发布时间】:2011-11-05 05:08:30
【问题描述】:

如果你在一个新的 C# 项目中放置一个面板并像这样捕获它的 MouseMove 事件:

private void panel1_MouseMove(object sender, MouseEventArgs e)
{
    if (e.Button != MouseButtons.Left)
        return;

    Console.WriteLine("e.X: {0}, e.Y: {1}", e.X, e.Y);
}

它会告诉您在按住鼠标左键时鼠标的客户端坐标,即使光标超出了面板。

但是,如果您在容器中按住鼠标左键,然后在按住鼠标左键的同时单击鼠标上的任何其他鼠标按钮,则它不再在容器边界之外调用 MouseMove。

有什么办法可以改变吗?感谢阅读。

【问题讨论】:

    标签: c# winforms event-handling mouse mouseevent


    【解决方案1】:

    1:如果您想让它仅在按下左键时工作,请尝试以下操作:

    bool mouseDown = false;
    
    private void panel1_MouseMove(object sender, MouseEventArgs e)
    {
        if (!mouseDown)
            return;
    
        Console.WriteLine("e.X: {0}, e.Y: {1}", e.X, e.Y);
    }
    
    private void panel1_MouseDown(object sender, MouseEventArgs e)
    {
        if (e.Button == MouseButtons.Left)
            mouseDown = true;
    }
    
    private void panel1_MouseUp(object sender, MouseEventArgs e)
    {
        if (e.Button == MouseButtons.Left)
            mouseDown = false;
    }
    

    2:否则,如果您希望它在任何鼠标按钮按下时工作,请尝试以下操作:

    int mouseDown = 0;
    
    private void panel1_MouseMove(object sender, MouseEventArgs e)
    {
        if (mouseDown == 0)
            return;
    
        Console.WriteLine("e.X: {0}, e.Y: {1}", e.X, e.Y);
    }
    
    private void panel1_MouseDown(object sender, MouseEventArgs e)
    {
        mouseDown++;
    }
    
    private void panel1_MouseUp(object sender, MouseEventArgs e)
    {
        mouseDown--;
    }
    

    【讨论】:

    • 现在我手上没有 VS 可检查,但如果您在面板或应用程序之外进行左键按下、移动鼠标​​并将其释放到那里,这可能会导致问题。怀疑 panel1_MouseUp 会被调用。为此,应该足以将捕获设置为控制。查看我编辑的帖子。
    • @Tigran,即使在控件范围之外,它仍然会触发事件。
    • 你是对的。我刚刚在另一台机器上检查了它。我将编辑我的帖子。 +1
    • 这些都不起作用。在控件中单击并按住鼠标左键。在按住鼠标左键的同时单击并释放鼠标右键。将鼠标移到面板边界之外并在那里晃动。此时不再有控制台输出。
    • @John Smith 同意:总有办法打破这种机制。我从来没有找到任何安全的方法来解决这类问题。我仅针对发表的评论引用了此答案+1。但是,顺便说一下,它提供了可以应用的“解决方案”,实际上在我的一些项目中我使用了这个技巧。
    【解决方案2】:

    除了贾斯汀的解决方案会说:

    我认为这是因为,如果在拖动过程中您离开面板右键单击面板的 out,则会强制面板失去焦点,因此控件不再变为活动控件。

    如果您在面板内拖动鼠标并右键单击 inside 面板,会发生类似的情况。

    我刚刚用 Spy++ windows explorer 捕获并做了一个测试,所以用 LButton 向下移动鼠标,在某个时候没有释放它就右键单击。这是一个结果:

    我用箭头在我用右键单击的行上签名,WM_CAPTURECHANGED 发送的消息。根据文档,此消息是:

    发送到丢失鼠标捕获的窗口。

    用箭头查看下一行。下一个窗口的句柄为 0,因此没有任何窗口。所以这意味着,就像一个简单的命令:你失去了鼠标捕获。

    希望这会有所帮助。

    【讨论】:

    • 您实际上不需要参考 API 来解决问题。请参阅我的答案以获取两个示例。
    • @Justin:API 在这里澄清了它发生的原因。其余的你可以在我编辑的帖子中看到。
    猜你喜欢
    • 1970-01-01
    • 2013-10-08
    • 2020-08-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-01
    • 1970-01-01
    相关资源
    最近更新 更多