简体   繁体   English

如何在不点击C#的情况下取消鼠标左键?

[英]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. 我发现https://github.com/gmamaladze/globalmousekeyhook项目和挂钩的事件吧。

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. 如果定时器超时,将发送WM_TIMER消息,您可以将_rclick_activated设置为true以指示按下左按钮的时间足够长。 When handle the left mouse button up message check the _rclick_activated , if it is true send right mouse button down event . 当处理鼠标左键消息时检查_rclick_activated ,如果是真,则发送鼠标右键按下事件 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. 以下代码是Windows桌面API C ++实现的一个简单示例。 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;
//...

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

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