Não é possível detectar o mouse global para baixo com MouseKeyHook
Estive pesquisando nas últimas horas para descobrir como detectar cliques com o botão esquerdo do mouse globalmente (não focado) e deparei com vários posts mencionando o uso de globalmousekeyhook que instalei via NuGet que implementei como visto abaixo:
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 eu o executo, meu mouse na tela de repente começa a ficar inutilizável (eu até tive dificuldade para fechar o prompt de comando) e também tentei clicar à esquerda e à direita, mas nada é registrado. Estou fazendo algo completamente estúpido? Sinto que estou faltando algo realmente óbvio porque ninguém mais está tendo esse problema ou, se houver outra solução, ficaria feliz em tentar. Obrigada.
Visual Studio 2019, Windows 10 Pro, Projeto: .NET Framework 4.7.2, Aplicativo de console, executado com modo de depuração
Respostas
Na verdade, eu estava brincando como de costume, procurando maneiras diferentes de fazer isso e então me deparei com a função da API do Windows para obter estados de chaves (GetKeyStates) (incluindo o mouse), então importei a DLL user32 e iniciei um loop que verifica o botão esquerdo do mouse estado ( 0x01
) a cada 50ms (descobri que esse é o melhor momento) e jogou-o em um thread para que não bloqueasse o principal.
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!");
}
}
}
Provavelmente há uma solução melhor para isso (que não consegui encontrar) e por que estou usando isso. Originalmente, baseiei isso em uma resposta exata à minha pergunta, mas em vez disso foi escrito em Python, então converti para C #. Eu estava ficando cansado de ver que a única resposta à minha pergunta era 'usar alguma biblioteca de terceiros' que não funciona corretamente para mim por qualquer motivo e também reduziu o uso de memória de 30 MB para 7 MB :).
Eu também testei no Windows 7 e funciona maravilhosamente bem.