Skip to content

Instantly share code, notes, and snippets.

@saitonakamura
Created October 16, 2019 16:32
Show Gist options
  • Save saitonakamura/d780018ff2a438c0fcbacdd27e3f5679 to your computer and use it in GitHub Desktop.
Save saitonakamura/d780018ff2a438c0fcbacdd27e3f5679 to your computer and use it in GitHub Desktop.
using System;
using System.Globalization;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Windows.Forms;
namespace KeyFinder
{
class Program
{
[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);
public class KeyboardPointer : IDisposable
{
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 = System.Windows.Forms.Keys.None;
return false;
}
key = (System.Windows.Forms.Keys) (((keyNumber & 0xFF00) << 8) | (keyNumber & 0xFF));
return true;
}
}
private static string DescribeKey(Keys key)
{
StringBuilder desc = new StringBuilder();
if ((key & Keys.Shift) != Keys.None)
desc.Append("Shift: ");
if ((key & Keys.Control) != Keys.None)
desc.Append("Control: ");
if ((key & Keys.Alt) != Keys.None)
desc.Append("Alt: ");
return desc.Append(key & Keys.KeyCode).ToString();
}
public static void Main(string[] args)
{
var testChars = new[]
{
'@',
'"',
// 'A',
// 'é',
// 'ש'
};
Keys key;
foreach (var culture in (new string[]
{
"en-US",
// "en-IE",
"en-UK"
}).Select(code =>
CultureInfo.GetCultureInfo(code)))
{
Console.WriteLine(culture.Name);
using (var keyboard = new KeyboardPointer(culture))
foreach (var test in testChars)
{
Console.Write(test);
Console.Write('\t');
if (keyboard.GetKey(test, out key))
Console.WriteLine(DescribeKey(key));
else
Console.WriteLine("No Key");
}
}
Console.Read(); //Stop window closing
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment