/MajosaUtilities/KeyboardManager.cs
C# | 145 lines | 136 code | 6 blank | 3 comment | 27 complexity | 8b6048647dfd541a70e59ae4e5e1338c MD5 | raw file
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Threading.Tasks;
- using System.Runtime.InteropServices;
- using System.Windows;
- using System.Windows.Input;
- using System.Windows.Interop;
- using Majosa;
- namespace Majosa.Keyboard
- {
- public enum KeyboardMessageType
- {
- WM_KEYDOWN = 0x100,
- WM_KEYUP
- }
- public class GlobalKeyEventArgs : KeyboardEventArgs
- {
- private Key key;
- private bool isUp;
- private bool isHandled = false;
- private List<Key> pressedKeys = new List<Key>();
- private string printableKey;
- public GlobalKeyEventArgs(Key key, int timestamp,bool isUp,List<Key> keys,String printable) : base(System.Windows.Input.Keyboard.PrimaryDevice,timestamp)
- {
- this.key = key;
- this.isUp = isUp;
- this.pressedKeys=new List<Key>(keys);
- this.printableKey=printable;
- }
- public Key Key { get { return key; } }
- public bool IsUp { get { return isUp; } }
- public bool IsHandled { get { return isHandled; } set { isHandled = value; } }
- public List<Key> PressedKeys { get { return new List<Key>(pressedKeys); } }
- public string PrintableKey { get { return printableKey; } }
- }
- public class KeyboardManager
- {
- private IntPtr idHook;
- public delegate void GlobalKeyEventHandler(object sender,GlobalKeyEventArgs ev);
- public event GlobalKeyEventHandler KeyPressed;
- public event GlobalKeyEventHandler KeyUp;
- private static KeyboardManager instance;
- private HookManager hookM;
- private List<Key> pressedKeys;
- private KeyboardManager()
- {
- hookM = HookManager.Instance();
- idHook=hookM.AddHook(HookManager.HookType.WH_KEYBOARD_LL, HookKeyboardHandle);
- pressedKeys = new List<Key>();
- }
- public static KeyboardManager Instance()
- {
- if (instance == null)
- {
- instance = new KeyboardManager();
- }
- return instance;
- }
- private IntPtr HookKeyboardHandle(int nCode, IntPtr wParam, IntPtr lParam)
- {
- if (nCode > 0)
- {
- //Pass call
- return CallNextHookEx(idHook, nCode, wParam, lParam);
- }
- //Parse lParam
- uint vkCode = (uint)Marshal.ReadInt32(lParam, 0);
- uint scanCode = (uint)Marshal.ReadInt32(lParam, 32 + 1);
- uint flags = (uint)Marshal.ReadInt32(lParam, 32 * 2);
- uint time = (uint)Marshal.ReadInt32(lParam, 32 * 3);
- IntPtr extraPtr = Marshal.ReadIntPtr(lParam, 32 * 4);
- bool isExtended = (flags & 0x1) != 0;
- bool isInjected = (flags & 0x10) != 0;
- bool isContextCode = (flags & 0x20) != 0;
- bool isPressedBefore = (flags & 0x80) != 0;
- //Parse wParam
- GlobalKeyEventArgs evArgs;
- Key key=KeyInterop.KeyFromVirtualKey((int)vkCode);
- String printable = getPrintableCharFromKey(vkCode, scanCode);
- switch ((KeyboardMessageType)wParam)
- {
- case KeyboardMessageType.WM_KEYDOWN:
- if (!pressedKeys.Contains(key)) pressedKeys.Add(key);
- evArgs = new GlobalKeyEventArgs(KeyInterop.KeyFromVirtualKey((int)vkCode), (int)time, false, pressedKeys, printable);
- if (KeyPressed != null) KeyPressed(null, evArgs);
- break;
- case KeyboardMessageType.WM_KEYUP:
- if (pressedKeys.Contains(key)) pressedKeys.Remove(key);
- evArgs = new GlobalKeyEventArgs(KeyInterop.KeyFromVirtualKey((int)vkCode), (int)time, true, pressedKeys, printable);
- if (KeyUp != null) KeyUp(null, evArgs);
- break;
- default:
- evArgs = new GlobalKeyEventArgs(KeyInterop.KeyFromVirtualKey((int)vkCode), (int)time, false, pressedKeys,"");
- break;
- }
- if (evArgs.IsHandled)
- {
- return (IntPtr)0;
- }
- else
- {
- return CallNextHookEx(idHook, nCode, wParam, lParam);
- }
- }
- private string getPrintableCharFromKey(uint virtualKeyCode, uint scanCode)
- {
- var buffer = new StringBuilder(256);
- var keyboardState = new byte[256];
- foreach (var key in pressedKeys)
- {
- keyboardState[KeyInterop.VirtualKeyFromKey(key)] = 0xFF;
- if (key == Key.LeftShift || key == Key.RightShift)
- {
- keyboardState[0x10] = 0xFF;
- }
- if (key == Key.LeftCtrl || key == Key.RightCtrl)
- {
- keyboardState[0x11] = 0xFF;
- }
- if (key == Key.LeftAlt || key == Key.RightAlt)
- {
- keyboardState[0x12] = 0xFF;
- }
- }
- ToUnicode(virtualKeyCode, scanCode, keyboardState, buffer, 256, 0);
- return buffer.ToString();
- }
- ~KeyboardManager()
- {
- HookManager.Instance().RemoveHook(idHook);
- }
- [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
- private static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode, IntPtr wParam, IntPtr lParam);
- [DllImport("user32.dll")]
- public static extern int ToUnicode(uint virtualKeyCode, uint scanCode, byte[] keyboardState, [Out, MarshalAs(UnmanagedType.LPWStr, SizeConst = 64)]StringBuilder receivingBuffer, int bufferSize, uint flags);
- }
- }