Capturing keystrokes without focus

后端 未结 2 1083
伪装坚强ぢ
伪装坚强ぢ 2020-12-15 00:18

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 t

相关标签:
2条回答
  • 2020-12-15 00:50

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

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

    0 讨论(0)
  • 2020-12-15 01:11

    In Java there are two libraries that can do this:

    • JIntellitype (Windows)
    • JXGrabKey (X11)
    0 讨论(0)
提交回复
热议问题