MouseKeyHook으로 글로벌 마우스 다운을 감지 할 수 없습니다.

Dec 31 2020

지난 몇 시간 동안 전 세계적으로 마우스 왼쪽 클릭을 감지하는 방법을 알아 내고 (집중되지 않음) 아래에서 볼 수 있듯이 NuGet을 통해 설치 한 globalmousekeyhook 을 사용 하는 것을 언급하는 여러 게시물을 우연히 발견했습니다 .

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

나는 실제로 평소대로 놀면서 다른 방법을 찾고 키 상태 (GetKeyStates) (마우스 포함 )를 가져 오는 Windows API 기능을 우연히 발견하여 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로 낮추는 '제 3 자 라이브러리 사용'이었습니다.

나는 또한 Windows 7에서 테스트했으며 놀랍게 작동합니다.