Tidak dapat mendeteksi mouse global turun dengan MouseKeyHook

Dec 31 2020

Saya telah meneliti selama beberapa jam terakhir untuk mencari tahu cara mendeteksi klik kiri mouse secara global (tidak fokus) dan menemukan banyak posting yang menyebutkan untuk menggunakan globalmousekeyhook yang saya instal melalui NuGet yang telah saya terapkan seperti yang terlihat di bawah ini:

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.");
        }
    }
}

Ketika saya menjalankannya, mouse di layar saya tiba-tiba mulai tertinggal ke titik di mana tidak dapat digunakan (saya bahkan berjuang untuk menutup command prompt) dan saya juga mencoba mengklik kiri dan kanan tetapi tidak ada yang dicatat. Apakah saya melakukan sesuatu yang sangat bodoh? Saya merasa ada sesuatu yang sangat jelas saya lewatkan karena tidak ada orang lain yang mengalami masalah ini, atau jika ada solusi lain, saya akan dengan senang hati mencobanya. Terima kasih.

Visual Studio 2019, Windows 10 Pro, Proyek: .NET Framework 4.7.2, Aplikasi Konsol, berjalan dengan mode debug

Jawaban

EpicSpeedy Jan 03 2021 at 08:41

Saya benar-benar bermain-main seperti biasa, mencari cara berbeda untuk melakukannya dan kemudian menemukan fungsi Windows API untuk mendapatkan status kunci (GetKeyStates) (termasuk mouse), jadi saya mengimpor user32 DLL dan memulai loop yang memeriksa tombol kiri mouse state ( 0x01) setiap 50ms (dianggap sebagai waktu terbaik) dan melemparkannya ke thread sehingga tidak akan memblokir thread utama.

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!");
        }
    }
}

Mungkin ada solusi yang lebih baik untuk ini (yang tidak dapat saya temukan) dan mengapa saya menggunakan ini. Saya awalnya mendasarkan ini dari jawaban atas pertanyaan saya yang sebenarnya, tetapi sebaliknya itu ditulis dengan Python jadi saya mengubahnya menjadi C #. Saya muak melihat satu-satunya jawaban untuk pertanyaan saya adalah 'menggunakan beberapa perpustakaan pihak ke-3' yang tidak berfungsi dengan baik untuk saya karena alasan apa pun dan juga telah menurunkan penggunaan memori dari 30mb menjadi 7mb :).

Saya juga telah mengujinya di Windows 7 dan hasilnya luar biasa.