From 83d7c76314feb28daa63efb6f0a27cdacd5082f5 Mon Sep 17 00:00:00 2001 From: Boris Fritscher Date: Sat, 15 Jul 2017 21:10:42 +0200 Subject: [PATCH 1/2] Support to show keyboard keys based on locales --- src/Carnac.Logic/KeyProvider.cs | 15 ++------- src/Carnac.Logic/ReplaceKey.cs | 54 +++++++++++++++++++++++++++------ 2 files changed, 46 insertions(+), 23 deletions(-) diff --git a/src/Carnac.Logic/KeyProvider.cs b/src/Carnac.Logic/KeyProvider.cs index d5272adb..893405ba 100644 --- a/src/Carnac.Logic/KeyProvider.cs +++ b/src/Carnac.Logic/KeyProvider.cs @@ -136,22 +136,11 @@ static IEnumerable ToInputs(bool isLetter, bool isWinKeyPressed, Interce if (shiftPressed) yield return "Shift"; - yield return interceptKeyEventArgs.Key.Sanitise(); + yield return interceptKeyEventArgs.Key.SanitiseLower(); } else { - string input; - var shiftModifiesInput = interceptKeyEventArgs.Key.SanitiseShift(out input); - - if (!isLetter && !shiftModifiesInput && shiftPressed) - yield return "Shift"; - - if (interceptKeyEventArgs.ShiftPressed && shiftModifiesInput) - yield return input; - else if (isLetter && !interceptKeyEventArgs.ShiftPressed) - yield return interceptKeyEventArgs.Key.ToString().ToLower(); - else - yield return interceptKeyEventArgs.Key.Sanitise(); + yield return interceptKeyEventArgs.Key.Sanitise(); } } diff --git a/src/Carnac.Logic/ReplaceKey.cs b/src/Carnac.Logic/ReplaceKey.cs index 6905a56d..cbc8aec7 100644 --- a/src/Carnac.Logic/ReplaceKey.cs +++ b/src/Carnac.Logic/ReplaceKey.cs @@ -1,6 +1,9 @@ using System; using System.Collections.Generic; +using System.Runtime.InteropServices; +using System.Text; using System.Windows.Forms; +using System.Windows.Input; namespace Carnac.Logic { @@ -80,6 +83,7 @@ public static class ReplaceKey {Keys.RWin, "Win"}, }; + // kept to continue to support keymaps parsing public static Keys? ToKey(string keyText) { foreach (var shiftReplacement in ShiftReplacements) @@ -99,21 +103,51 @@ public static class ReplaceKey return null; } - public static string Sanitise(this Keys key) + // new implementation of sanitize to support locals + // https://stackoverflow.com/questions/318777/c-sharp-how-to-translate-virtual-keycode-to-char + static public string KeyCodeToUnicode(Keys key, bool lowerOnly = false) { - return Replacements.ContainsKey(key) ? Replacements[key] : string.Format(key.ToString()); + byte[] keyboardState = new byte[255]; + if (!lowerOnly) + { + bool keyboardStateStatus = GetKeyboardState(keyboardState); + if (!keyboardStateStatus) + { + return ""; + } + } + + uint virtualKeyCode = (uint)key; + uint scanCode = MapVirtualKey(virtualKeyCode, 0); + IntPtr inputLocaleIdentifier = GetKeyboardLayout(0); + + StringBuilder result = new StringBuilder(); + ToUnicodeEx(virtualKeyCode, scanCode, keyboardState, result, (int)5, (uint)0, inputLocaleIdentifier); + + return result.ToString(); } - public static bool SanitiseShift(this Keys key, out string sanitisedKeyInput) + [DllImport("user32.dll")] + static extern bool GetKeyboardState(byte[] lpKeyState); + + [DllImport("user32.dll")] + static extern uint MapVirtualKey(uint uCode, uint uMapType); + + [DllImport("user32.dll")] + static extern IntPtr GetKeyboardLayout(uint idThread); + + [DllImport("user32.dll")] + static extern int ToUnicodeEx(uint wVirtKey, uint wScanCode, byte[] lpKeyState, [Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder pwszBuff, int cchBuff, uint wFlags, IntPtr dwhkl); + + public static string Sanitise(this Keys key) { - if (ShiftReplacements.ContainsKey(key)) - { - sanitisedKeyInput = ShiftReplacements[key]; - return true; - } + return KeyCodeToUnicode(key); + } - sanitisedKeyInput = key.Sanitise(); - return false; + public static string SanitiseLower(this Keys key) + { + return KeyCodeToUnicode(key, true); } + } } \ No newline at end of file From 2a4649c931ebed99e47ce6cc7aec04d7dd3b1acc Mon Sep 17 00:00:00 2001 From: Boris Fritscher Date: Mon, 17 Jul 2017 12:50:22 +0200 Subject: [PATCH 2/2] fix special cases key getting transformed to empty string --- src/Carnac.Logic/ReplaceKey.cs | 42 ++++++++++++++++++++++++++++++++-- 1 file changed, 40 insertions(+), 2 deletions(-) diff --git a/src/Carnac.Logic/ReplaceKey.cs b/src/Carnac.Logic/ReplaceKey.cs index cbc8aec7..9c1d4611 100644 --- a/src/Carnac.Logic/ReplaceKey.cs +++ b/src/Carnac.Logic/ReplaceKey.cs @@ -83,6 +83,26 @@ public static class ReplaceKey {Keys.RWin, "Win"}, }; + static readonly Dictionary SpecialCases = new Dictionary + { + {Keys.Divide, " / "}, + {Keys.Multiply, " * "}, + {Keys.Subtract, " - "}, + {Keys.Add, " + "}, + {Keys.LShiftKey, "Shift"}, + {Keys.RShiftKey, "Shift"}, + {Keys.LWin, "Win"}, + {Keys.RWin, "Win"}, + {Keys.LControlKey, "Ctrl"}, + {Keys.RControlKey, "Ctrl"}, + {Keys.Alt, "Alt"}, + {Keys.LMenu, "Alt"}, + {Keys.Tab, "Tab"}, + {Keys.Back, "Back"}, + {Keys.Return, "Return"}, + {Keys.Escape, "Escape"}, + }; + // kept to continue to support keymaps parsing public static Keys? ToKey(string keyText) { @@ -141,12 +161,30 @@ static public string KeyCodeToUnicode(Keys key, bool lowerOnly = false) public static string Sanitise(this Keys key) { - return KeyCodeToUnicode(key); + if (SpecialCases.ContainsKey(key)) + { + return SpecialCases[key]; + } + string result = KeyCodeToUnicode(key); + if (result.Length > 0) + { + return result; + } + return key.ToString(); } public static string SanitiseLower(this Keys key) { - return KeyCodeToUnicode(key, true); + if (SpecialCases.ContainsKey(key)) + { + return SpecialCases[key]; + } + string result = KeyCodeToUnicode(key, true); + if (result.Length > 0) + { + return result; + } + return key.ToString(); } }