ไม่สามารถตรวจจับเมาส์ส่วนกลางด้วย 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) (รวมถึงเมาส์) ดังนั้นฉันจึงนำเข้า user32 DLL และเริ่มลูปที่ตรวจสอบ สถานะปุ่มซ้ายของเมาส์ ( 0x01) ทุก ๆ 50ms (พบว่าเป็นเวลาที่ดีที่สุด) และโยนลงในเธรดเพื่อที่จะไม่ปิดกั้นปุ่มหลัก

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 # ฉันรู้สึกเบื่อที่จะเห็นคำตอบเดียวสำหรับคำถามของฉันคือ 'ใช้ไลบรารีของบุคคลที่สาม' ซึ่งใช้งานไม่ได้กับฉันไม่ว่าด้วยเหตุผลใดก็ตามและยังลดการใช้หน่วยความจำจาก 30mb เป็น 7mb :)

ฉันได้ทดสอบบน Windows 7 แล้วและใช้งานได้ดีเยี่ยม