Convert String or Char to Keys object

后端 未结 3 898
攒了一身酷
攒了一身酷 2021-01-23 00:06

If I use the following code:

for (int i = 0; i < text.Length; i++)
    {
        char c = text[i];
        Keys k = (Keys)(byte)c;
        MessageBox.Show(c.T         


        
相关标签:
3条回答
  • 2021-01-23 00:24

    The answer is to build a reverse lookup table for the chars you need. The code could be optimized further but it is self explanatory. You could add special chars explicitly if needed.

    You could also simultaneously build a dictionary to go the other way also should it take your fancy. Multi-key chars would require a trivial extension but they don't map directly to Keys anyway. For your perusal and possible extension should you require it:

    using System.Windows.Forms;
    static ImmutableDictionary<char, Keys> CharVKeyLookup;
    static void PopulateVKeyCharDictionary(){
        var keyboardStateNormal = new byte[255]; //All keys up
        var keyboardStateShift = new byte[255];
        keyboardStateShift[(int)Keys.ShiftKey] = 0x80;
        var charlookup = new Dictionary<char, Keys>();
        for (var i = 1; i < (int) Keys.OemClear; i++){
            var keys = (Keys) i;
            //Verbose condition to ignore unnecessary conversions - probably a quicker way e.g. statically
            if (keys == Keys.Enter || keys == Keys.Tab || keys == Keys.Space
                    || (keys >= Keys.D0 && keys <= Keys.D9)
                    || (keys >= Keys.A && keys <= Keys.Z)
                    || (keys >= Keys.Multiply && keys <= Keys.Divide)
                    || (keys >= Keys.Oem1 && keys <= Keys.Oem102)){
                var normal = KeyCodeToUnicode(keys);
                var shift = KeyCodeToUnicode(keys, true);
                if (normal.Item2 == 1) //Ignore wierdos - extend this if you need it
                    charlookup[normal.Item1[0]]=keys;
                if (shift.Item2 ==1)
                    charlookup[shift.Item1[0]]=keys|Keys.Shift; //Incl shift mod
            }
        }
        charlookup['\n'] =  Keys.Return;
        charlookup['\r'] = Keys.Return;
        CharVKeyLookup = charlookup.ToImmutableDictionary();
    }
    /// <returns>string if it exists and return code. -1=dead char, 0=no translation, 1=1 char, 2=special char </returns>
    public static Tuple<string, int> KeyCodeToUnicode(Keys key, byte[] keyboardState){
        var scanCode = MapVKToScanCode(key);
        var result = new StringBuilder(10,10);
        var language = InputLanguage.CurrentInputLanguage.Handle;//Or other method such as GetKeyboardLayout
        var returnState = ToUnicodeEx(key, scanCode, keyboardState, result, 10, 0,  language);
        return new Tuple<string, int>(result.ToString(),returnState);
    }
    [DllImport("user32.dll")]
    internal static extern int ToUnicodeEx(Keys wVirtKey, uint wScanCode, byte[] lpKeyState, [Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder pwszBuff, int cchBuff, uint wFlags, IntPtr dwhkl);
    [DllImport("user32.dll", CharSet = CharSet.Auto)]
    internal static extern IntPtr GetKeyboardLayout(int dwLayout);
    
    0 讨论(0)
  • 2021-01-23 00:32

    The Keys enumeration is not a straight copy of the character values of the character generated when the key is pressed. Sometimes it is, but sometimes it is not. The way the value is encoded for each keypress is described in the documentation:

    This class contains constants to use for processing keyboard input. Keys are identified by key values, which consist of a key code and a set of modifiers combined into a single integer value. The four left digits of a key value contain the key code (which is the same as a Windows virtual key code). The four right digits of a key value contain modifier bits for the SHIFT, CONTROL, and ALT keys.

    0 讨论(0)
  • 2021-01-23 00:33

    That seems like the wrong approach. Have you considered using SendKeys?

    0 讨论(0)
提交回复
热议问题