Không thể phát hiện chuột toàn cục với MouseKeyHook
Tôi đã nghiên cứu trong vài giờ qua để tìm ra cách phát hiện nhấp chuột trái của chuột trên toàn cầu (không tập trung) và tình cờ nhận được nhiều bài đăng đề cập đến việc sử dụng globalmousekeyhook mà tôi đã cài đặt qua NuGet mà tôi đã triển khai như hình dưới đây:
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.");
}
}
}
Khi tôi chạy nó, con chuột trên màn hình của tôi đột nhiên bắt đầu bị lag đến mức không thể sử dụng được (tôi thậm chí đã vật lộn để đóng dấu nhắc lệnh) và tôi cũng đã thử nhấp cả trái và phải nhưng không có gì được ghi lại. Tôi đang làm điều gì đó hoàn toàn ngu ngốc? Tôi cảm thấy có điều gì đó thực sự rõ ràng mà tôi đang thiếu vì không ai khác đang gặp vấn đề này, hoặc nếu có một giải pháp khác, tôi rất vui được thử nó. Cảm ơn bạn.
Visual Studio 2019, Windows 10 Pro, Dự án: .NET Framework 4.7.2, Ứng dụng bảng điều khiển, chạy với chế độ gỡ lỗi
Trả lời
Tôi thực sự đang chơi xung quanh như thường lệ, tìm kiếm các cách khác nhau để làm điều đó và sau đó tình cờ gặp hàm API Windows để nhận trạng thái của các phím (GetKeyStates) (bao gồm cả chuột), vì vậy tôi đã nhập DLL của user32 và bắt đầu một vòng lặp kiểm tra trạng thái nút chuột trái ( 0x01
) cứ sau 50ms (nhận thấy đó là thời điểm tốt nhất) và ném nó vào một luồng để nó không chặn luồng chính.
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!");
}
}
}
Có lẽ có một giải pháp tốt hơn cho điều này (mà tôi không thể tìm thấy) và vì vậy tại sao tôi lại sử dụng nó. Ban đầu tôi dựa trên câu trả lời cho câu hỏi chính xác của mình, nhưng thay vào đó, nó được viết bằng Python nên tôi đã chuyển đổi nó thành C #. Tôi đã phát ốm khi thấy câu trả lời duy nhất cho câu hỏi của mình là 'sử dụng một số thư viện của bên thứ 3' không hoạt động đúng với tôi vì bất kỳ lý do gì và cũng đã giảm mức sử dụng bộ nhớ từ 30mb xuống 7mb :).
Tôi cũng đã thử nghiệm nó trên Windows 7 và nó hoạt động tuyệt vời.