/// <summary> /// Replays this event. /// </summary> public override void ReplayEvent() { Cursor.Position = Point; if (MouseEventFlags != 0) { KeyboardKey.InjectMouseEvent(MouseEventFlags, 0, 0, (uint)_mouseData >> 16, new UIntPtr((ulong)ExtraInfo.ToInt64())); } }
/// <summary> /// Replays this event. /// </summary> public override void ReplayEvent() { KeyboardKey.InjectKeyboardEvent((Keys)_vkCode, (byte)_scanCode, KeyboardEventFlags, new UIntPtr((ulong)ExtraInfo.ToInt64())); }
private int LowLevelKeyboardHook_Callback(int code, IntPtr wParam, IntPtr lParam, ref bool callNext) { if (code == HC_ACTION) { var llh = (KBDLLHOOKSTRUCT)Marshal.PtrToStructure(lParam, typeof(KBDLLHOOKSTRUCT)); bool handled = false; var msg = (int)wParam; if (KeyIntercepted != null) { KeyIntercepted(msg, llh.vkCode, llh.scanCode, llh.flags, llh.time, llh.dwExtraInfo, ref handled); } if (MessageIntercepted != null) { MessageIntercepted( new LowLevelKeyboardMessage((int)wParam, llh.vkCode, llh.scanCode, llh.flags, llh.time, llh.dwExtraInfo), ref handled); } if (handled) { callNext = false; return(1); } if (CharIntercepted != null && (msg == 256 || msg == 260)) { // Note that dead keys are somehow tricky, since ToUnicode changes their state // in the keyboard driver. So, if we catch a dead key and call ToUnicode on it, // we will have to stop the hook; otherwise the deadkey appears twice on the screen. // On the other hand, we try to avoid calling ToUnicode on the key pressed after // the dead key (the one which is modified by the deadkey), because that would // drop the deadkey altogether. Resynthesizing the deadkey event is hard since // some deadkeys are unshifted but used on shifted characters or vice versa. // This solution will not lose any dead keys; its only drawback is that dead // keys are not properly translated. Better implementations are welcome. if (llh.vkCode == (int)Keys.ShiftKey || llh.vkCode == (int)Keys.LShiftKey || llh.vkCode == (int)Keys.RShiftKey || llh.vkCode == (int)Keys.LControlKey || llh.vkCode == (int)Keys.RControlKey || llh.vkCode == (int)Keys.ControlKey || llh.vkCode == (int)Keys.Menu || llh.vkCode == (int)Keys.LMenu || llh.vkCode == (int)Keys.RMenu) { // ignore shift keys, they do not get modified by dead keys. } else if (_currentDeadChar != '\0') { CharIntercepted(msg, "" + (llh.vkCode == (int)Keys.Space ? _currentDeadChar : '\x01'), true, llh.vkCode, llh.scanCode, llh.flags, llh.time, llh.dwExtraInfo); _currentDeadChar = '\0'; } else { short dummy = new KeyboardKey(Keys.Capital).State; // will refresh CAPS LOCK state for current thread var kbdState = new byte[256]; ApiHelper.FailIfZero(GetKeyboardState(kbdState)); var buff = new StringBuilder(64); int length = ToUnicode(llh.vkCode, llh.scanCode, kbdState, buff, 64, 0); if (length == -1) { _currentDeadChar = buff[0]; callNext = false; return(1); } if (buff.Length != length) { buff.Remove(length, buff.Length - length); } CharIntercepted(msg, buff.ToString(), false, llh.vkCode, llh.scanCode, llh.flags, llh.time, llh.dwExtraInfo); } } } return(0); }