Search code examples
c#.netwinformsmouseeventemgucv

Implementing double click event using timer


As I mentioned in this question, I am trying to implement a feature in my app whereby placing a cursor over some point for a while (say 3-5 seconds) triggers a double-click event. Based on the answers provided in that thread, I wrote the following. This code is not working as expected. Can someone please help?

    #region Timer Mouse Double Click event

    timer.Elapsed += new ElapsedEventHandler(timer_Elapsed);

    //Here, the timer for Timer click event will start when mouse hovers over an area
    private void form_MouseHover(object sender, System.EventArgs e)
    {
        timer.Start();
    }

    private void form_MouseLeave(object sender, System.EventArgs e)
    {
        timer.Stop();
    }

    void timer_Elapsed(object sender, ElapsedEventArgs e)
    {
        timer.Stop();
        DoubleClickEvent();
    }

    //This method allows the user to click a file/folder by hovering/keeping still the mouse for specified time
    void DoubleClickEvent()
    {

        DoClickMouse(0x2);      // Left mouse button down
        DoClickMouse(0x4);      // Left mouse button up
    }

    static void DoClickMouse(int mouseButton)
    {
        var input = new INPUT()
        {
            dwType = 0, // Mouse input
            mi = new MOUSEINPUT() { dwFlags = mouseButton }
        };

        if (SendInput(1, input, Marshal.SizeOf(input)) == 0)
        {
            throw new Exception();
        }
    }
    [StructLayout(LayoutKind.Sequential)]
    struct MOUSEINPUT
    {
        int dx;
        int dy;
        int mouseData;
        public int dwFlags;
        int time;
        IntPtr dwExtraInfo;
    }
    struct INPUT
    {
        public uint dwType;
        public MOUSEINPUT mi;
    }
    [DllImport("user32.dll", SetLastError = true)]
    static extern uint SendInput(uint cInputs, INPUT input, int size);

    #endregion

Solution

  • I hope it's not bad etiquette to provide two answers, however this is very different from my previous answer I felt editing for improvements wasn't correct.

    By the looks of it you only have an event handler on the form, once you hover over a control on your form that will trigger your MouseLeave event of the form.

    What you need is to add an event handler to every control on your form, something like this should do it.

    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
    
        private void Form1_Load(object sender, EventArgs e)
        {
    
            this.MouseHover += new EventHandler(MouseHoverEvent);
            this.MouseLeave +=new EventHandler(MouseLeaveEvent);
            timer1.Tick += new EventHandler(timer1_Tick);
    
            foreach (Control item in this.Controls)
            {
                item.MouseHover += new EventHandler(MouseHoverEvent);
                item.MouseLeave += new EventHandler(MouseLeaveEvent);
            }
    
        }
    
        void timer1_Tick(object sender, EventArgs e)
        {
            timer1.Stop();
            DoubleClickEvent();
        }
    
        void MouseLeaveEvent(object sender, EventArgs e)
        {
            timer1.Stop();
        }
    
        void MouseHoverEvent(object sender, EventArgs e)
        {
            timer1.Start();
        }
    }