捕获按键没有焦点 [英] Capturing keystrokes without focus

查看:144
本文介绍了捕获按键没有焦点的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

例如。与AOL的Winamp(在Windows上至少),你可以玩游戏全屏背景AOL的Winamp,并使用多媒体按键*来控制声音。 Winamp的不需要获得焦点,允许比赛继续进行全屏。

E.g. with winamp (on Windows at least), you can play a game fullscreen with winamp in the background, and use the media buttons* to control the sound. Winamp doesn't need to get focus, allowing the game to continue fullscreen.

我宁愿用Java写这不过那可能是行不通的( 。捕捉按键没有焦点已经很难在Java中据我所知),所以任何C#解决方案也未尝不可。

I'd prefer to write this in Java but that probably isn't going to work (capturing keystrokes without focus is already difficult in Java afaik), so any C# solution is also fine.

所以,基本的问题是:如何捕捉击键没有焦点

So the basic question is: how to capture keystrokes without focus?

*)我相信前进/后退/停止/邮件/搜索/收藏夹/ Web /主页按钮被称为多媒体按键,而是一个更好的名字是欢迎的。

*) I believe the 'back/forward/stop/mail/search/favorites/web/home' buttons are called media buttons, but a better name would be welcome :).

推荐答案

低级别的Windows钩子就是做这件事。这里有一个文章,这里是从的MSDN

Low-Level windows hooks is one way to do it. Here is one article and here is a little more info from MSDN.

这是一个什么样的代码可以看起来像一个局部视图:

This is a partial view of what that code can look like:

    private IntPtr LowLevelKeyboardHook(int nCode, WindowsMessages wParam, [In] KBDLLHOOKSTRUCT lParam)
    {
        bool callNext = true;

        bool isKeyDown = (wParam == WindowsMessages.KEYDOWN || wParam == WindowsMessages.SYSKEYDOWN);
        bool isKeyUp = (wParam == WindowsMessages.KEYUP || wParam == WindowsMessages.SYSKEYUP);

        if ((nCode >= 0) && (isKeyDown || isKeyUp))
        {
            // the virtual key codes and the winforms Keys have the same enumeration
            // so we can freely cast back and forth between them
            Keys key = (Keys)lParam.vkCode;

            // Do your other processing here...
        }

        // if any handler returned false, trap the message
        return (callNext) ? User32.CallNextHookEx(_mainHook, nCode, wParam, lParam) : _nullNext;
    }


    /// <summary>
    /// Registers the user's LowLevelKeyboardProc with the system in order to
    /// intercept any keyboard events before processed in the regular fashion.
    /// This can be used to log all keyboard events or ignore them.
    /// </summary>
    /// <param name="hook">Callback function to call whenever a keyboard event occurs.</param>
    /// <returns>The IntPtr assigned by the Windows's sytem that defines the callback.</returns>
    private IntPtr RegisterLowLevelHook(LowLevelKeyboardProc hook)
    {
        IntPtr handle = IntPtr.Zero;

        using (Process currentProcess = Process.GetCurrentProcess())
        using (ProcessModule currentModule = currentProcess.MainModule)
        {
            IntPtr module = Kernel32.GetModuleHandle(currentModule.ModuleName);
            handle = User32.SetWindowsHookEx(HookType.KEYBOARD_LL, hook, module, 0);
        }

        return handle;
    }

    /// <summary>
    /// Unregisters a previously registered callback from the low-level chain.
    /// </summary>
    /// <param name="hook">IntPtr previously assigned to the low-level chain.
    /// Users should have stored the value given by 
    /// <see cref="Drs.Interop.Win32.LowLevelKeyboard.RegisterLowLevelHook"/>,
    /// and use that value as the parameter into this function.</param>
    /// <returns>True if the hook was removed, false otherwise.</returns>
    private bool UnregisterLowLevelHook(IntPtr hook)
    {
        return User32.UnhookWindowsHookEx(hook);
    }



就实现所有的P / Invoke需要声明,它应该工作。
我用这个方法在我的应用程序,它工作正常。

Just implement all the P/Invoke declarations needed, and it should work. I use this approach in my application and it works fine.

这篇关于捕获按键没有焦点的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆