Невозможно обнаружить глобальное нажатие мыши с помощью MouseKeyHook

Dec 31 2020

В течение последних нескольких часов я исследовал, как определять щелчки левой кнопкой мыши глобально (не сфокусированные), и наткнулся на несколько сообщений, в которых упоминалось использование globalmousekeyhook, которое я установил через NuGet, который я реализовал, как показано ниже:

using Gma.System.MouseKeyHook;
using System;

namespace mouse_hook_test
{
    class Program
    {
        static private IKeyboardMouseEvents m_GlobalHook;

        static void Main(string[] args)
        {
            Subscribe();

            Console.ReadKey();
        }

        static public void Subscribe()
        {
            m_GlobalHook = Hook.GlobalEvents();

            m_GlobalHook.MouseDownExt += GlobalHookMouseDownExt;
        }

        static private void GlobalHookMouseDownExt(object sender, MouseEventExtArgs e)
        {
            Console.WriteLine("Mouse Click.");
        }
    }
}

Когда я запускаю его, моя экранная мышь внезапно начинает отставать до точки, когда она становится непригодной (я даже пытался закрыть командную строку), и я также пробовал щелкать как влево, так и вправо, но ничего не регистрируется. Я делаю что-то совершенно глупое? Я чувствую, что мне не хватает чего-то действительно очевидного, потому что ни у кого больше нет этой проблемы, или, если есть другое решение, я был бы рад попробовать его. Спасибо.

Visual Studio 2019, Windows 10 Pro, проект: .NET Framework 4.7.2, консольное приложение, работающее в режиме отладки

Ответы

EpicSpeedy Jan 03 2021 at 08:41

На самом деле я играл как обычно, искал разные способы сделать это, а затем наткнулся на функцию Windows API для получения состояний клавиш (GetKeyStates) (включая мышь), поэтому я импортировал DLL user32 и запустил цикл, который проверяет состояние левой кнопки мыши ( 0x01) каждые 50 мс (оказалось, что это лучшее время) и бросил его в поток, чтобы он не блокировал основной.

using System;
using System.Runtime.InteropServices;
using System.Threading;

namespace mouse_hook_test
{
    class Program
    {
        static void Main(string[] args)
        {
            Thread thread = new Thread(detect);
            thread.Start();
        }

        // Import the DLL that contains the function and grab it.
        [DllImport("user32.dll")]
        public static extern short GetKeyState(int vKey);

        // A very simple implementation for tracking the state of the left mouse button.
        static void detect()
        {
            short oldState = GetKeyState(0x01);

            while (true)
            {
                short newState = GetKeyState(0x01);                

                if (oldState != newState)
                {
                    oldState = newState;

                    if (newState < 0)
                    {
                        onMouseClick();
                    }
                }

                Thread.Sleep(50);
            }
        }

        static void onMouseClick()
        {
            Console.WriteLine("Clicked!");
        }
    }
}

Вероятно, для этого есть лучшее решение (которое я не мог найти), и поэтому я использую его. Первоначально я основывал это на ответе на мой точный вопрос, но вместо этого он был написан на Python, поэтому я преобразовал его в C #. Мне надоело видеть, что единственный ответ на мой вопрос заключался в том, чтобы «использовать какую-то стороннюю библиотеку», которая не работает для меня должным образом по какой-либо причине, а также снизила использование памяти с 30 МБ до 7 МБ :).

Я также тестировал его на Windows 7, и он отлично работает.