Impossibile rilevare il mouse globale abbassato con MouseKeyHook

Dec 31 2020

Ho cercato nelle ultime ore per capire come rilevare i clic sinistro del mouse a livello globale (non focalizzato) e sono incappato in più post che menzionano l'uso di globalmousekeyhook che ho installato tramite NuGet che ho implementato come mostrato di seguito:

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

Quando lo eseguo, il mio mouse sullo schermo inizia improvvisamente a rallentare al punto in cui è inutilizzabile (ho anche faticato a chiudere il prompt dei comandi) e ho anche provato a fare clic sia a sinistra che a destra ma non viene registrato nulla. Sto facendo qualcosa di completamente stupido? Sento che mi manca qualcosa di veramente ovvio perché nessun altro ha questo problema, o se c'è un'altra soluzione sarei felice di provarla. Grazie.

Visual Studio 2019, Windows 10 Pro, Progetto: .NET Framework 4.7.2, Applicazione console, è stato eseguito con la modalità di debug

Risposte

EpicSpeedy Jan 03 2021 at 08:41

In realtà stavo giocando come al solito, cercando diversi modi per farlo e poi sono incappato nella funzione API di Windows per ottenere gli stati dei tasti (GetKeyStates) (incluso il mouse), quindi ho importato la DLL user32 e ho avviato un ciclo che controlla il pulsante sinistro del mouse dichiara ( 0x01) ogni 50 ms (ritenuto che sia il momento migliore) e lo inserisce in un thread in modo che non blocchi quello principale.

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

Probabilmente c'è una soluzione migliore per questo (che non sono riuscito a trovare) e quindi perché lo sto usando. Inizialmente ho basato questo di una risposta alla mia domanda esatta, ma invece è stato scritto in Python, quindi l'ho convertito in C #. Mi stavo stancando di vedere che l'unica risposta alla mia domanda era "utilizzare una libreria di terze parti" che non funziona correttamente per me per qualsiasi motivo e ha anche ridotto l'utilizzo della memoria da 30 MB a 7 MB :).

L'ho testato anche su Windows 7 e funziona a meraviglia.