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

问题描述 投票:0回答:2

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

我找到了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;
        }
    }
}
c# winapi mouseevent mousekeyhook
2个回答
0
投票

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


0
投票

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

您可以开始记录starting a timer接收鼠标左键消息时的时间。如果定时器超时,将发送WM_TIMER消息,您可以将_rclick_activated设置为true以指示按下的左按钮足够长。当处理left mouse button up message检查_rclick_activated,如果它是真的send right mouse button down event。收到鼠标右键向下消息后发送鼠标右键向上事件。

以下代码是Windows desktop 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;
//...
© www.soinside.com 2019 - 2024. All rights reserved.