VkKeyScan返回相同的代码,但没有带重音符号和无重音字母的修饰符 [英] VkKeyScan returning same code without modifiers for accented and unaccented letter

查看:346
本文介绍了VkKeyScan返回相同的代码,但没有带重音符号和无重音字母的修饰符的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

背景:

我正在使用非托管函数SendInput( https://msdn.microsoft.com/zh-CN/library/windows/desktop/ms646310(v = vs.85).aspx ).有3种方法可以调用此函数:

I am simulating keystrokes using the unmanaged function SendInput (https://msdn.microsoft.com/en-us/library/windows/desktop/ms646310(v=vs.85).aspx). There are 3 ways to call this function:

  1. 指定键盘扫描码
  2. 指定字符unicode
  3. 指定虚拟键码

所有工作正常,但是为了能够模拟诸如CTRL + P之类的快捷方式,我想使用虚拟键代码.我目前有一个字符到虚拟键码的手动映射,但这不是一个好方法,因为它对用户的OS键盘布局不敏感.例如,在英语(英国)键盘上,.".字符可以映射到VirtualKeyCode.OEM_PERIOD,但是如果OS键盘布局为法语,则为.".是VirtualKeyCode.OEM_PERIOD + SHIFT.

All work, but to be able to simulate shortcuts such as CTRL+P I want to use the virtual key code. I currently have a manual mapping of character to virtual key code, but this is not a good approach as it is not sensitive to the user's OS keyboard layout. For example on an English (UK) keyboard the "." character can be mapped to VirtualKeyCode.OEM_PERIOD, but if the OS keyboard layout is French then "." is VirtualKeyCode.OEM_PERIOD + SHIFT.

为使代码更健壮,我想调用方法VkKeyScan(

To make my code more robust I want to call the method VkKeyScan (https://msdn.microsoft.com/en-us/library/windows/desktop/ms646329(v=vs.85).aspx) passing in a character to get the virtual key code (plus shift/ctrl/alt). This approach, in theory, takes care of everything.

问题:

声明:

[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键盘布局,我看到以下结果:

With an OS keyboard layout of English (UK) I am seeing the following results:

  • 'e'=>虚拟键码69
  • 'E'=>虚拟键码69 + shift
  • 'é'=>虚拟键码69

N.B. 69在HEX中为0x45,它对应于虚拟键代码列表中的"E"键,例如 http ://www.kbdedit.com/manual/low_level_vk_list.html

"e"和é"如何产生相同的虚拟键码?通过按'e'+ ctrl + alt或'e'+ altgr来输出英语(UK)键盘上的'é'.

How can 'e' and 'é' both produce the same virtual key code? 'é' on an English (UK) keyboard is output by pressing 'e'+ctrl+alt or 'e'+altgr.

理论:

  1. 我的代码错误,并且我没有正确提取ctrl和alt位.
  2. VkScanKey无法按我预期的方式工作,并且无法以'e'+ ctrl + alt的形式返回'é'之类的东西(尽管MSDN文档建议这样做).
  3. 还有其他事情.

推荐答案

看起来像理论1-我没有正确提取修饰符位.这段代码有效:

It looks like theory 1 - that I wasn't extracting the modifier bits correctly. This code works:

var vkKeyScan = PInvoke.VkKeyScan(character);
var vkCode = vkKeyScan & 0xff;
var shift = (vkKeyScan & 0x100) > 0;
var ctrl = (vkKeyScan & 0x200) > 0;
var alt = (vkKeyScan & 0x400) > 0;

所以问题可能与操作员的排序有关(即&可能一直优先于>>(位移)),尽管我不这样认为,因为我确实尝试使用括号括起来位移,或者位移本身没有按预期工作.

So the problem was either something to do with the operator ordering (i.e. the & may have been taking priority over the >> (bit shift)), although I don't think so as I did try with brackets around the bit shift, OR the shift itself wasn't working as expected.

如果您对此感兴趣,可以使用工作代码进行提交: https://github.com/JuliusSweetland/OptiKey/commit/0e61c52371638c61e0ef05834cd31a363181ea0d

Here is the commit with working code if you're interested: https://github.com/JuliusSweetland/OptiKey/commit/0e61c52371638c61e0ef05834cd31a363181ea0d

这篇关于VkKeyScan返回相同的代码,但没有带重音符号和无重音字母的修饰符的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆