繁体   English   中英

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

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

我试着编写应用程序,当用户长按鼠标左键时会发出右键单击。

我发现https://github.com/gmamaladze/globalmousekeyhook项目和挂钩的事件吧。

当我向左挂钩时,然后用鼠标事件发送右键单击,首先点击左键,然后点击右击。

是否有任何方法可以取消第一个鼠标左键?

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;
        }
    }
}

实际上,你不能这样做。 问题是,在您发送鼠标右键单击时,左键单击已经被触发。 你不能只是回到过去。

我试着编写应用程序,当用户长按鼠标左键时会发出右键单击。

您可以通过启动计时器开始记录接收鼠标左键消息的时间。 如果定时器超时,将发送WM_TIMER消息,您可以将_rclick_activated设置为true以指示按下左按钮的时间足够长。 当处理鼠标左键消息时检查_rclick_activated ,如果是真,则发送鼠标右键按下事件 收到鼠标右键向下消息后发送鼠标右键向上事件。

以下代码是Windows桌面API C ++实现的一个简单示例。 您可以将其用作参考。

// 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