将String或Char转换为Keys对象

时间:2010-10-18 20:06:24

标签: c# macros key keystroke

如果我使用以下代码:

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

我只能获得大写字母的正确转换。问题是,我需要能够复制小写字符,并且我得到转换错误。例如,'e'转换为'NumPad5',其中'E'正确转换为'E'。我该怎么攻击这个?我将采用输入字符串并为我正在尝试开发的宏播放器创建虚拟按键。

3 个答案:

答案 0 :(得分:5)

这似乎是错误的做法。您考虑过使用SendKeys吗?

答案 1 :(得分:1)

Keys枚举不是按下该键时生成的字符的字符值的直接副本。有时它是,但有时它不是。 documentation

中描述了为每个按键编码值的方式
  

此类包含用于处理键盘输入的常量。键由键值标识,键值由键代码和组合成单个整数值的一组修饰符组成。键值的左侧四位数字包含键码(与Windows虚拟键码相同)。键值的四个右数位包含SHIFT,CONTROL和ALT键的修饰符位。

答案 2 :(得分:1)

答案是为您需要的字符构建反向查找表。代码可以进一步优化,但它是自我解释的。如果需要,您可以显式添加特殊字符。

你也可以同时建立一个字典,以便在你喜欢的时候走另一条路。多键字符需要一个简单的扩展,但无论如何它们都不会直接映射到Keys。 如果您需要,请仔细阅读和扩展:

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