背景
我正在使用非托管函数SendInput(https://msdn.microsoft.com/en-us/library/windows/desktop/ms646310(v=vs.85).aspx)模拟击键。有三种方法可以调用此函数:
所有工作,但为了能够模拟CTRL + P等快捷方式我想使用虚拟键码。我目前手动将字符映射到虚拟键码,但这不是一个好方法,因为它对用户的OS键盘布局不敏感。例如,在英语(英国)键盘上的“。”字符可以映射到VirtualKeyCode.OEM_PERIOD,但如果操作系统键盘布局是法语,那么“。”是VirtualKeyCode.OEM_PERIOD + SHIFT。
为了使我的代码更健壮,我想调用方法VkKeyScan(https://msdn.microsoft.com/en-us/library/windows/desktop/ms646329(v=vs.85).aspx)传入一个字符来获取虚拟键码(加上shift / ctrl / alt)。从理论上讲,这种方法可以解决所有问题。
问题:
声明:
[DllImport("user32.dll", CharSet = CharSet.Unicode)]
static extern short VkKeyScan(char ch);
用法:
var vkKeyScanResult = PInvoke.VkKeyScan(character);
var vk = vkKeyScanResult & 0xff;
var shift = (vkKeyScanResult >> 8 & 1) == 1;
var ctrl = (vkKeyScanResult >> 8 & 2) == 1;
var alt = (vkKeyScanResult >> 8 & 4) == 1;
if (vk != -1)
{
Log.InfoFormat("'{0}' => virtual key code {1}{2}{3}{4}",
character, vk, shift ? "+shift" : null, ctrl ? "+ctrl" : null, alt ? "+alt" : null);
}
使用英语(英国)的OS键盘布局,我看到以下结果:
N.B。 69是HEX中的0x45,它对应于虚拟键码列表中的“E”键,例如此http://www.kbdedit.com/manual/low_level_vk_list.html
'e'和'é'如何生成相同的虚拟密钥代码?通过按'e'+ ctrl + alt或'e'+ altgr输出英语(英国)键盘上的'é'。
理论
答案 0 :(得分:1)
看起来像理论1 - 我没有正确地提取修改器位。此代码有效:
var vkKeyScan = PInvoke.VkKeyScan(character);
var vkCode = vkKeyScan & 0xff;
var shift = (vkKeyScan & 0x100) > 0;
var ctrl = (vkKeyScan & 0x200) > 0;
var alt = (vkKeyScan & 0x400) > 0;
所以这个问题要么与操作员的订购有关(即&可能优先于>>(位移)),尽管我不这么认为,因为我尝试用括号在位移位附近,或者换档本身没有按预期工作。
如果您感兴趣,可以使用以下代码提交工作代码:https://github.com/JuliusSweetland/OptiKey/commit/0e61c52371638c61e0ef05834cd31a363181ea0d