Convert String or Char to Keys object

耗尽温柔 提交于 2019-12-02 04:57:48

问题


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.ToString() + "|" + k.ToString());
    }

I can get a correct conversion for uppercase letters only. The problem is, I need to be able to replicate lower case characters as well, and I am getting conversion errors on them. For instance, 'e' converts to 'NumPad5', where 'E' converts correctly to 'E'. How do I attack this? I'm going to be taking input strings and creating virtual key presses for a macro player I am trying to develop.


回答1:


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




回答2:


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.




回答3:


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);


来源:https://stackoverflow.com/questions/3962944/convert-string-or-char-to-keys-object

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!