简体   繁体   中英

How to prevent right mouse click from changing the mouse capture control

This is an annoyance I am seeing with .NET WinForms mouse events. To reproduce, do the following:

  1. Left mouse down on a Button Control. (This changes the capture control to that button)
  2. Move mouse off of that button.
  3. While still holding on to the left mouse button, click the right mouse button. (This changes the capture control to whatever the mouse cursor is over now)
  4. Release the left mouse button. The button never receives the mouse up event. (The mouse up event goes to the current capture control.)

I only care about the left mouse button, but a user accidentally pressing the right button prevents the left-mouse-up event from getting back to the originally clicked button.

One possible solution is to use the MouseLeave or MouseCaptureChanged events to detect when the right click is happening off of the button and know when the capture control has changed. I have tried this, and it works pretty well.

Another way is to use MessageFilters and filter out right button events. But some buttons needs the right clicks, so you don't want to filter out ALL right clicks, just for buttons that need this feature.

So I am asking to see if anyone knows of a better solution. It would be nice if windows had some kind of flag to do the following: button1.RightMouseButtonCanChangeMouseCapture = false;

This seems to work well in my testing with the MessageFilter approach:

public partial class Form1 : Form
{

    private MyFilter mf;

    public Form1()
    {
        InitializeComponent();
    }

    private void Form1_Load(object sender, EventArgs e)
    {
        mf = new MyFilter();
        Application.AddMessageFilter(mf);
        mf.MouseLeftUp += Mf_MouseLeftUp;
    }

    private void button1_MouseDown(object sender, MouseEventArgs e)
    {
        if (e.Button == MouseButtons.Left)
        {
            mf.ButtonDown = true;
            Console.WriteLine("Transmitting...");
        }            
    }

    private void Mf_MouseLeftUp()
    {
        Console.WriteLine("Transmission Stopped.");
    }

}

public class MyFilter : IMessageFilter
{

    public bool ButtonDown = false;

    private const int WM_LBUTTONUP = 0x0202;

    public event dlgMouseLeftUp MouseLeftUp;
    public delegate void dlgMouseLeftUp();

    public bool PreFilterMessage(ref Message m)
    {
        switch (m.Msg)
        {
            case WM_LBUTTONUP:
                if (ButtonDown)
                {
                    ButtonDown = false;
                    MouseLeftUp?.Invoke();
                }
                break;

        }
        return false; // allow normal dispatching of messages
    }

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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