using System; using System.Collections.Generic; using System.Globalization; using System.Linq; using System.Runtime.InteropServices; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; namespace TradeIdeas.TIProGUI { public class KeyboardPointer : IDisposable { [DllImport("user32.dll", CharSet = CharSet.Unicode)] static extern short VkKeyScanEx(char ch, IntPtr dwhkl); [DllImport("user32.dll")] static extern bool UnloadKeyboardLayout(IntPtr hkl); [DllImport("user32.dll")] static extern IntPtr LoadKeyboardLayout(string pwszKLID, uint Flags); private readonly IntPtr pointer; public KeyboardPointer(int klid) { pointer = LoadKeyboardLayout(klid.ToString("X8"), 1); } public KeyboardPointer(CultureInfo culture) : this(culture.KeyboardLayoutId) { } public void Dispose() { UnloadKeyboardLayout(pointer); GC.SuppressFinalize(this); } ~KeyboardPointer() { UnloadKeyboardLayout(pointer); } // Converting to System.Windows.Forms.Key here, but // some other enumerations for similar tasks have the same // one-to-one mapping to the underlying Windows API values public bool GetKey(char character, out Keys key) { short keyNumber = VkKeyScanEx(character, pointer); if (keyNumber == -1) { key = Keys.None; return false; } key = (Keys)(((keyNumber & 0xFF00) << 8) | (keyNumber & 0xFF)); return true; } } }