我想将一组System.Windows.Forms.Keys
和一个System.Windows.Forms.InputLanguage
翻译成相应的System.Char
。
尝试使用MapVirtualKeyEx
进行一些实验,但现在有办法考虑键盘状态,ToUnicodeEx
对死键感到痛苦。
我的目标是一个功能...
static char? FromKeys(Keys keys, InputLanguage inputLanguage)
{
// As I think what can be helpful and I got trying to find a solution for this problem:
Keys vkCode = keys & Keys.KeyCode;
Keys modifiers = keys & Keys.Modifiers;
byte[] keyboardState = new byte[256];
keyboardState[vkCode] = 1 << 7;
if (modifiers.HasFlag(Keys.Shift))
{
keyboardState[(int)Keys.ShiftKey] = 1 << 7;
}
if (modifiers.HasFlag(Keys.Control))
{
keyboardState[(int)Keys.ControlKey] = 1 << 7;
}
if (modifiers.HasFlag(Keys.Alt))
{
keyboardState[(int)Keys.Menu] = 1 << 7;
}
// [Put your code here]
}
...应该像这样调用:
FromKeys(Keys.A | Keys.Shift, InputLanguage.CurrentInputLanguage); // = 'A'
FromKeys(Keys.Escape, InputLanguage.DefaultInputLanguage); // = null
FromKeys(Keys.Oemtilde, InputLanguage.FromCulture(new CultureInfo("de-DE"))); // = 'ö'
FromKeys(Keys.E | Keys.Control | Keys.Alt, InputLanguage.FromCulture(new CultureInfo("de-DE"))); // = '€'
(请注意Keys.Shift
和Keys.ShiftKey
!)
这个功能怎么样?
我将选择的答案应提供一种方法,使用可选的修饰符组合(System.Windows.Forms.Keys
,Keys.Shift
,{{1}翻译一个“普通”Keys.Alt
}}到Keys.Control
。多个连续调用必须产生相同的字符。没有硬编码的键盘布局,System.Char
定义了要使用的布局。
帮助理解我要尝试的内容:仅使用InputLanguage
(以及正确的KeyPressEventArgs
)生成KeyEventArgs
。
死键 不应影响InputLangauge
!
答案 0 :(得分:5)
以下是一段似乎正在寻找的代码 - 如果我理解正确的话: - )
public static char? FromKeys(Keys keys, InputLanguage inputLanguage)
{
return FromKeys(keys, inputLanguage, true);
}
private static char? FromKeys(Keys keys, InputLanguage inputLanguage, bool firstChance)
{
if (inputLanguage == null)
{
inputLanguage = InputLanguage.CurrentInputLanguage;
}
byte[] keyStates = new byte[256];
const byte keyPressed = 0x80;
keyStates[(int)(keys & Keys.KeyCode)] = keyPressed;
keyStates[(int)Keys.ShiftKey] = ((keys & Keys.Shift) == Keys.Shift) ? keyPressed : (byte)0;
keyStates[(int)Keys.ControlKey] = ((keys & Keys.Control) == Keys.Control) ? keyPressed : (byte)0;
keyStates[(int)Keys.Menu] = ((keys & Keys.Alt) == Keys.Alt) ? keyPressed : (byte)0;
StringBuilder sb = new StringBuilder(10);
int ret = ToUnicodeEx(keys, 0, keyStates, sb, sb.Capacity, 0, inputLanguage.Handle);
if (ret == 1)
return sb[0];
if (ret == -1)
{
// dead letter
if (firstChance)
{
FromKeys(keys, inputLanguage, false);
}
return null;
}
return null;
}
[DllImport("user32.dll", CharSet = CharSet.Unicode)]
private static extern int ToUnicodeEx(Keys wVirtKey, uint wScanCode, byte[] lpKeyState, StringBuilder pwszBuff, int cchBuff, uint wFlags, IntPtr dwhkl);
答案 1 :(得分:0)
我不确定这会有效,但你可以看看ToUnicodeEx。它允许您设置键盘状态以及输入区域设置。
另一种可能性,虽然涉及很多,但是将您的事件转换为与SendKeys兼容的字符串,然后将字符串发送到您的应用程序。
您必须为主线程设置文化,并使用单独的线程进行发送。
我不知道这样的东西会有多好用,而且尝试它的时间也很贵(就时间而言)。