0

我从 C# 开始,用 Java 编写了很多代码,但在这里遇到了一些麻烦。我正在尝试学习如何将MouseKeyHook用于我正在开发的应用程序。我无法让实际的侦听器触发事件​​。这是我的监听器代码:

using System;
using System.Windows.Forms;
using Gma.System.MouseKeyHook;

namespace ChromaHeatmap
{
    class keyListener
    {
        private IKeyboardMouseEvents m_GlobalHook;

        public void Subscribe()
        {
            // Note: for the application hook, use the Hook.AppEvents() instead
            m_GlobalHook = Hook.GlobalEvents();
            m_GlobalHook.KeyPress += GlobalHookKeyPress;
        }

        private void GlobalHookKeyPress(object sender, KeyPressEventArgs e)
        {
            Console.WriteLine("blah");
        }

        public void Unsubscribe()
        {
            m_GlobalHook.KeyPress -= GlobalHookKeyPress;

            //It is recommened to dispose it
            m_GlobalHook.Dispose();
        }
    }
}

这是我的应用程序代码的一部分,我尝试对侦听器做一些事情。如果有人可以让我知道最好的方法是在这里循环并等待事件,我将不胜感激。

    //Listen for key presses
    keyListener heyListen = new keyListener();
    heyListen.Subscribe();

    while(true)
    {
    }
4

1 回答 1

2
    while(true) {}

这是一个 hold-and-catch-fire 语句,线程会烧掉 100% 核心,无法执行 hook 回调。你会注意到当你按下一个键时机器会死机 5 秒钟,操作系统正在等待调用回调的机会。但它不会永远等待,并且会毫不客气地破坏钩子,以便您重新控制机器。当您尝试调试事件处理程序时也会发生这种事故。

Windows 需要一个安全地调用钩子回调的机会。这要求您的程序处于“空闲”状态,而不是执行任何代码。这方面的技术术语是“泵送消息循环”,您的程序必须等待来自操作系统的通知,即发生了一些有趣的事情。

一个非常简单的方法是按原样使用 Winforms 项目模板,您还将获得一个窗口。请注意项目中的 Main() 方法如何进行您需要的调用,而不是 while() 循环。你必须打电话Application.Run()

检查这篇文章以获取避免显示窗口的代码。

于 2015-06-06T08:46:20.810 回答