简体   繁体   中英

How to cancel left mouse down without click on C#?

I'm try to wrote app, that will send right click, when user take long press left mouse button.

I found https://github.com/gmamaladze/globalmousekeyhook project and hook events with it.

When I hook left up, then send right click with mouse event, first fire left click, than right click fire.

Is any method to cancel first left mouse down?

using Gma.System.MouseKeyHook;
using System;
using System.Windows.Forms;

namespace MouseRClick
{
    class ClassRightClick
    {
        // API
        [System.Runtime.InteropServices.DllImport("user32.dll")]
        public static extern void mouse_event(int dwFlags, int dx, int dy, int cButtons, int dwExtraInfo);
        public const int MOUSEEVENTF_LEFTDOWN = 0x02;
        public const int MOUSEEVENTF_LEFTUP = 0x04;
        public const int MOUSEEVENTF_RIGHTDOWN = 0x08;
        public const int MOUSEEVENTF_RIGHTUP = 0x10;

        // Hook module
        private IKeyboardMouseEvents _hook;

        private bool _rclick_activated = false;
        private int _down_cursor_x;
        private int _down_cursor_y;

        private Timer timer;

        public ClassRightClick(int delay)
        {
            timer = new Timer();
            timer.Interval = delay;
            timer.Tick += timer_Tick;
        }

        public void Subscribe()
        {
            _hook = Hook.GlobalEvents();

            _hook.MouseDownExt += onMouseDown;
            _hook.MouseUpExt += onMouseUp;
        }

        public void Unsubscribe()
        {
            _hook.MouseDownExt -= onMouseDown;
            _hook.MouseUpExt -= onMouseUp;

            //It is recommened to dispose it
            _hook.Dispose();
        }

        private void onMouseDown(object sender, MouseEventExtArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                _down_cursor_x = e.Location.X;
                _down_cursor_y = e.Location.Y;

                _rclick_activated = false;
                timer.Enabled = true;
            }
        }

        private void onMouseUp(object sender, MouseEventExtArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                timer.Enabled = false;

                Unsubscribe();

                if (_rclick_activated)
                {
                    mouse_event(MOUSEEVENTF_RIGHTDOWN, _down_cursor_x, _down_cursor_y, 0, 0);
                    mouse_event(MOUSEEVENTF_RIGHTUP, _down_cursor_x, _down_cursor_y, 0, 0);

                    e.Handled = true;
                }

                _rclick_activated = false;

                Subscribe();
            }
        }

        private void timer_Tick(object sender, EventArgs e)
        {
            _rclick_activated = true;
        }
    }
}

Actually, you cannot do this. Problem is, left mouse click is already fired by the time you dispatch the right-mouse click. You can't just go back in time.

I'm try to wrote app, that will send right click, when user take long press left mouse button.

You can start record the time when receive left mouse button down message by starting a timer . If the timer timeout a WM_TIMER message will be sent out and you can set the _rclick_activated to true to indicate the left button pressed long enough. When handle the left mouse button up message check the _rclick_activated , if it is true send right mouse button down event . After receive right mouse button down message send right mouse button up event.

The following code is Windows desktop API C++ implement as a simple example. You can use as a reference.

// Mouse hook
LRESULT CALLBACK MouseProc(int nCode, WPARAM wParam, LPARAM lParam)
{

    if (nCode < 0)  // do not process the message 
        return CallNextHookEx(NULL, nCode,
            wParam, lParam);
    if (WM_LBUTTONDOWN == wParam)
    {
        OutputDebugString(L"\n Left button down \n");
        _rclick_activated = false;
        SetTimer(m_windowHandle,   // handle to main window 
            IDT_TIMER1,            // timer identifier 
            2000,                  // 2-second interval 
            (TIMERPROC)NULL);      // no timer callback 
    }
    else if (WM_LBUTTONUP == wParam)
    {
        OutputDebugString(L"\n Left button up \n");

        if (_rclick_activated)
        {
            MOUSEINPUT mouseData = {};
            mouseData.dx = GET_X_LPARAM(lParam);
            mouseData.dy = GET_Y_LPARAM(lParam);
            mouseData.dwFlags = MOUSEEVENTF_RIGHTDOWN;


            INPUT inputData = {};
            inputData.type = INPUT_MOUSE;
            inputData.mi = mouseData;
            UINT result = SendInput(1, &inputData, sizeof(INPUT));
            if (result == 1)
            {
                OutputDebugString(L"\n successfully insert right button down \n");
            }
        }

    }
    else if (WM_RBUTTONDOWN == wParam)
    {
        OutputDebugString(L"\n Right button down \n");

        if (_rclick_activated)
        {
            MOUSEINPUT mouseData = {};
            mouseData.dx = GET_X_LPARAM(lParam);
            mouseData.dy = GET_Y_LPARAM(lParam);
            mouseData.dwFlags = MOUSEEVENTF_RIGHTUP;


            INPUT inputData = {};
            inputData.type = INPUT_MOUSE;
            inputData.mi = mouseData;
            UINT result = SendInput(1, &inputData, sizeof(INPUT));
            if (result == 1)
            {
                OutputDebugString(L"\n successfully insert right button up \n");
            }

            _rclick_activated = false;

        }
    }
    else if (WM_RBUTTONUP == wParam)
    {
        OutputDebugString(L"\n Right button up \n");
    }

    return CallNextHookEx(NULL, nCode, wParam, lParam);
}

//...
// Rigister mouse hook
HHOOK m_msgHook = SetWindowsHookEx(WH_MOUSE, MouseProc, NULL, GetCurrentThreadId());
//...

//...
case WM_TIMER:
    // process the 2-second timer 
    _rclick_activated = true;
    KillTimer(hWnd, IDT_TIMER1);
    return 0;
//...

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