예제 #1
0
        /// <summary>Initializes the keyboard hook.</summary>
        /// <param name="keyDown">The delegate to be called when a key down event occurs.</param>
        public KeyboardHook(int targetProcessID, KeyEventHandler keyDown)
        {
            if (keyDown == null)
            {
                throw new ArgumentNullException("keyDown");
            }

            // Store the user's KeyDown delegate
            _keyDown = keyDown;
            _pid     = targetProcessID;

            // Create the callback and pin it, since it'll be called
            // from unmanaged code
            _hookProc = new LowLevelKeyboardProc(HookCallback);

            // Set the hook for just the GUI thread
            using (Process curProcess = Process.GetCurrentProcess())
                using (ProcessModule curModule = curProcess.MainModule)
                {
                    _hookHandle = SafeWindowsHookHandle.SetWindowsHookEx(
                        WH_KEYBOARD_LL, _hookProc,
                        GetModuleHandle(curModule.ModuleName), 0);
                }
            if (_hookHandle.IsInvalid)
            {
                Exception exc = new Win32Exception();
                Dispose();
                throw exc;
            }
        }
예제 #2
0
        /// <summary>Callback from the installed hook.</summary>
        ///</returns>
        private IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam)
        {
            bool handled = false;

            try
            {
                if (nCode >= 0 && wParam == (IntPtr)WM_KEYDOWN)
                {
                    uint pid;
                    GetWindowThreadProcessId(GetForegroundWindow(), out pid);
                    if (pid == _pid)
                    {
                        KBDLLHOOKSTRUCT hookParam =
                            (KBDLLHOOKSTRUCT)Marshal.PtrToStructure(lParam,
                                                                    typeof(KBDLLHOOKSTRUCT));
                        Keys key = (Keys)hookParam.vkCode;
                        if (key == Keys.Packet)
                        {
                            key = (Keys)hookParam.scanCode;
                        }

                        KeyEventArgs e = new KeyEventArgs(key | ModifierKeys);
                        _keyDown(this, e);
                        handled = e.Handled | e.SuppressKeyPress;
                    }
                }
                // won't work because WH_KEYBOARD_LL doesn't fire for app commands
                // can't change it to WH_SHELL to get the app commands to fire because
                // only WH_KEYBOARD_LL and WH_MOUSE_LL are supported for global hooks like this one
                else if (nCode >= 0 && wParam == (IntPtr)WM_APPCOMMAND)
                {
                    //   LogToFile("app command detected");
                    uint pid;
                    GetWindowThreadProcessId(GetForegroundWindow(), out pid);
                    if (pid == _pid)
                    {
                        int cmd = (int)((uint)lParam >> 16 & ~0xf000);
                        //   LogToFile("app command is " + cmd);
                        Keys key = Keys.F24;

                        if (cmd == APPCOMMAND_MEDIA_PLAY)
                        {
                            key = Keys.Play;
                        }
                        KeyEventArgs e = new KeyEventArgs(key | ModifierKeys);

                        _keyDown(this, e);
                        handled = e.Handled | e.SuppressKeyPress;
                    }
                }

                return(handled ?
                       new IntPtr(1) :
                       SafeWindowsHookHandle.CallNextHookEx(
                           _hookHandle, nCode, wParam, lParam));
            }
            catch (Exception exc) { Error(this, new ErrorEventArgs(exc)); }
            return(new IntPtr(1));
        }
예제 #3
0
 /// <summary>Dispose the KeyboardHook.</summary>
 public void Dispose()
 {
     if (_hookHandle != null)
     {
         _hookHandle.Dispose();
         _hookHandle = null;
     }
 }
예제 #4
0
 public static extern IntPtr CallNextHookEx(SafeWindowsHookHandle hhk, int nCode, IntPtr wParam, IntPtr lParam);