c# - 捕获没有焦点的击键

标签 c# java keyboard

例如使用 winamp(至少在 Windows 上),您可以在后台使用 winamp 全屏玩游戏,并使用媒体按钮*控制声音。 Winamp 不需要获得焦点,允许游戏继续全屏。

我更喜欢用 Java 编写,但这可能行不通(在 Java afaik 中捕获没有焦点的击键已经很困难),因此任何 C# 解决方案也可以。

所以基本问题是:如何在没有焦点的情况下捕获击键?

*) 我相信“后退/前进/停止/邮件/搜索/Collection 夹/网络/主页”按钮称为媒体按钮,但欢迎使用更好的名称:)。

最佳答案

Low-Level windows hooks 是一种方法。这是一个article这是来自 MSDN 的更多信息.

这是该代码的部分 View :

    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 声明,它就应该可以工作。 我在我的应用程序中使用了这种方法,并且效果很好。

关于c# - 捕获没有焦点的击键,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1161053/

相关文章:

c# - 如何在 Blazor 服务器应用程序中访问 WCF 服务

c# - MVC Web API 2 中的点字符 '.' 用于 api/people/STAFF.45287 等请求

c# - 这是门面模式吗?如果不是那又怎样?

java - 使用 Java Mail API 保存草稿消息?

iphone - 又一起 iPhone 内存泄漏事件呼救。寻求有关后续步骤的建议

macos - 无法在 emacs 中输入大括号和方括号

c# - Ninject Factory 扩展将多个具体类型绑定(bind)到一个接口(interface)

java - 检测Android App收到扫描请求时是否发送BLE扫描响应

java - 使用 GAE Blobstore API 删除 n' 交换文本 block

用于底部 TextView 和顶部搜索栏的 IOS 键盘