0

我正在尝试编写应用程序,当用户长按鼠标左键时,它将发送右键单击。

我找到了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;
        }
    }
}
4

2 回答 2

0

我正在尝试编写应用程序,当用户长按鼠标左键时,它将发送右键单击。

您可以通过启动计时器开始记录收到鼠标左键按下消息的时间。如果计时器超时,将发送 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;
//...
于 2019-04-15T08:34:07.020 回答
0

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

于 2019-04-14T08:07:27.917 回答