private void UpdateLiftedKeys(GlobalKeyboardHook.GlobalKeyboardHookEventArgs e) { if (pressedKeys.Contains(e.Key.ToString())) { pressedKeys.Remove(e.Key.ToString()); } if (pressedNonModifierKeys.Contains(e.Key.ToString())) { pressedNonModifierKeys.Remove(e.Key.ToString()); } }
private void UpdateNewlyPressedKeys(GlobalKeyboardHook.GlobalKeyboardHookEventArgs e) { if (!pressedKeys.Contains(e.Key.ToString())) { pressedKeys.Add(e.Key.ToString()); } if (!pressedNonModifierKeys.Contains(e.Key.ToString()) && !modifierKeys.Contains(e.Key.ToString())) { pressedNonModifierKeys.Add(e.Key.ToString()); } }
private void KeyChangedEvent(GlobalKeyboardHook.GlobalKeyboardHookEventArgs e, string pressedKeysAsConfig) { var stopwatch = new Stopwatch(); stopwatch.Start(); try { KeyEvent?.Invoke(this, new MultiKeyGlobalHotkeyServiceEventArgs(e.KeyDown, pressedKeys, pressedNonModifierKeys, pressedKeysAsConfig)); } catch (Exception ex) { // "silently" ignore any errors when triggering events logger.Error(ex, $"{nameof(MultiKeyGlobalHotkeyService)} An error occurred trying to trigger the custom hotkeyservice event."); } logger.Info($"{nameof(MultiKeyGlobalHotkeyService)} invoked KeyEvent and took: {stopwatch.ElapsedMilliseconds} ms"); }
private void KeyboardHookEvent(object sender, GlobalKeyboardHook.GlobalKeyboardHookEventArgs e) { var stopwatch = new Stopwatch(); stopwatch.Start(); if (e.KeyDown) { UpdateNewlyPressedKeys(e); var pressedKeysAsConfig = GetPressedKeysAsSetting(pressedKeys); if (ProcessingHotkeys) { ProcessHotkeysDown(pressedKeysAsConfig); } KeyChangedEvent(e, pressedKeysAsConfig); logger.Info($"{nameof(MultiKeyGlobalHotkeyService)} monitored keys pressed: ({string.Join('-', pressedKeys)}) non modifiers: ({string.Join('-', pressedNonModifierKeys)})"); logger.Info($"{nameof(MultiKeyGlobalHotkeyService)} processed KeyDown event with setting string ({pressedKeysAsConfig}) and took: {stopwatch.ElapsedMilliseconds} ms"); } else if (e.KeyUp) { UpdateLiftedKeys(e); var pressedKeysAsConfig = GetPressedKeysAsSetting(pressedKeys); if (ProcessingHotkeys) { ProcessHotkeysUp(); } // ensure hotkeys are not pressed even if not in ProcessingHotkeys mode ResetHotkeyPressedStates(); KeyChangedEvent(e, pressedKeysAsConfig); logger.Info($"{nameof(MultiKeyGlobalHotkeyService)} monitored keys pressed: ({string.Join('-', pressedKeys)}) non modifiers: ({string.Join('-', pressedNonModifierKeys)})"); logger.Info($"{nameof(MultiKeyGlobalHotkeyService)} processed KeyUp event with setting string ({pressedKeysAsConfig}) and took: {stopwatch.ElapsedMilliseconds} ms"); } }
/// <summary> /// processes the passed PressedKeysInfo through possible quickcast (keydown) or on release hotkeys (keyup) /// modifies the passed PressedKeysInfo to reflect the updated keystates after hotkey processing /// </summary> /// <param name="e"></param> /// <param name="pressedKeysInfo"></param> private void ProcessKeyHook(GlobalKeyboardHook.GlobalKeyboardHookEventArgs e) { if (ProcessingHotkeys) { if (e.KeyDown) { ProcessHotkeysDown(); } else if (e.KeyUp) { ProcessHotkeysUp(); ResetHotkeyPressedStates(); // should this happen conditionally? // if you hold down some keys and lift ANY of them, keystate will be reset // a hotkey on release [shift] + [pause] will trigger if both held down and pause is released // (shift could be held down and pause pressed repeatedly and that works - BUT if pause were to be held down and shift is pressed repeatedly the hotkey only triggeres the first time) // this also applies to quickcast hotkeys pressing THE "key" repeatedly works, but for modifiers: NO // flipping modifier key seems pretty odd (just think about the annoying windows messages when spamming shift) so i think im okay with this :D pressedKeysInfo = PressedKeysInfo.Empty; } } }
/// <summary> /// this event will be passed to KeyEvent on the underlying keyboard hook /// it will be triggered EACH time, a key event inside keyboard hook comes along /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void KeyboardHookEvent(object sender, GlobalKeyboardHook.GlobalKeyboardHookEventArgs e) { //#if DEBUG // var stopwatch = new Stopwatch(); // stopwatch.Start(); //#endif pressedKeysInfo.Keys = e.Key; pressedKeysInfo.IsWinPressed = Convert.ToBoolean(GetAsyncKeyState((int)VirtualKeyStates.VK_LWIN) & KEY_PRESSED) || Convert.ToBoolean(GetAsyncKeyState((int)VirtualKeyStates.VK_RWIN) & KEY_PRESSED) || (e.KeyDown && (e.Key == Keys.LWin || e.Key == Keys.RWin)); pressedKeysInfo.IsAltPressed = Convert.ToBoolean(GetAsyncKeyState((int)VirtualKeyStates.VK_LMENU) & KEY_PRESSED) || Convert.ToBoolean(GetAsyncKeyState((int)VirtualKeyStates.VK_RMENU) & KEY_PRESSED) || (e.KeyDown && (e.Key == Keys.LMenu || e.Key == Keys.RMenu)); pressedKeysInfo.IsCtrlPressed = Convert.ToBoolean(GetAsyncKeyState((int)VirtualKeyStates.VK_LCONTROL) & KEY_PRESSED) || Convert.ToBoolean(GetAsyncKeyState((int)VirtualKeyStates.VK_RCONTROL) & KEY_PRESSED) || (e.KeyDown && (e.Key == Keys.LControlKey || e.Key == Keys.RControlKey)); pressedKeysInfo.IsShiftPressed = Convert.ToBoolean(GetAsyncKeyState((int)VirtualKeyStates.VK_LSHIFT) & KEY_PRESSED) || Convert.ToBoolean(GetAsyncKeyState((int)VirtualKeyStates.VK_RSHIFT) & KEY_PRESSED) || (e.KeyDown && (e.Key == Keys.LShiftKey || e.Key == Keys.RShiftKey)); //#if DEBUG // logger.Info($"{nameof(SimpleGlobalHotkeyService)} @{nameof(KeyboardHookEvent)} querying modifier keys took: {stopwatch.ElapsedTicks} ticks ({stopwatch.ElapsedMilliseconds} ms)"); // stopwatch.Restart(); //#endif ProcessKeyHook(e); //#if DEBUG // logger.Info($"{nameof(SimpleGlobalHotkeyService)} @{nameof(KeyboardHookEvent)} processing {nameof(ProcessKeyHook)} took: {stopwatch.ElapsedTicks} ticks ({stopwatch.ElapsedMilliseconds} ms)"); // stopwatch.Restart(); //#endif if (KeyEvent != null) { try { KeyEvent?.Invoke(this, new SimpleGlobalHotkeyServiceEventArgs(e.KeyDown, pressedKeysInfo)); } catch (Exception ex) { // "silently" ignore any errors when triggering events //logger.Error(ex, $"{nameof(SimpleGlobalHotkeyService)} @{nameof(KeyEvent)} An error occurred trying to trigger the custom hotkeyservice event."); } } //#if DEBUG // logger.Info($"{nameof(SimpleGlobalHotkeyService)} @{nameof(KeyboardHookEvent)} processing {nameof(KeyEvent)} took: {stopwatch.ElapsedTicks} ticks ({stopwatch.ElapsedMilliseconds} ms)"); //#endif }