简体   繁体   中英

Key listener not firing (MouseKeyHook)

I'm starting out in C#, coded a lot in Java but having some trouble here. I'm trying to learn how to use MouseKeyHook for an application I'm developing. I cannot get the actual listener to fire off an event. Here's my listener code:

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();
        }
    }
}

And here's the part of my application code where I attempt to do something with the listener. If anyone can let me know what the best way is to loop here and wait for events, I'd appreciate it.

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

    while(true)
    {
    }
    while(true) {}

This is a hold-and-catch-fire statement, the thread will burn 100% core and cannot execute the hook callback. You'll notice that the machine goes dead for 5 seconds when you press a key, the operating system is waiting for an opportunity to invoke the callback. But it won't wait forever and unceremoniously will destroy the hook so you regain control over the machine. Also the kind of mishap that will occur when you try to debug your event handler.

Windows needs an opportunity to safely call the hook callback. That requires your program to be "idle", not executing any code. The technical term for this is "pumping the message loop", your program must wait for a notification from the operating system that something interesting happened.

A very simple way is to use the Winforms project template as-is, you'll also get a window. Note how the Main() method in the project makes the call that you need instead of the while() loop. You must call Application.Run() .

Check this post for code that avoids displaying a window.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM