是有可能创造一个键盘布局是相同的键盘用过? [英] Is it possible to create a keyboard layout that is identical to the keyboard used?

查看:217
本文介绍了是有可能创造一个键盘布局是相同的键盘用过?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果我需要生成定制,看起来像他/她的键盘用户的键盘布局,我该怎么办呢?

If I need to generate a keyboard layout for customization to the user that looks like his/her keyboard, how can I do it?

例如是这样的:

法语,瑞典语,英语,加拿大等都会有不同的布局,正确的。这是很多的工作或使用某种形式的只是一个问题建于.NET区域类?

French, Swedish, English, Canadian, etc will have different layouts, right. Is this a lot of work or just a matter of using some sort of built in .NET regional classes?

推荐答案

一个关键preSS生成报告扫描code的Windows操作系统的硬件事件。这种扫描code,然后转换成一个虚拟键code的基础上扫描code和其他键盘状态因素( Caps Lock键状态,<大骨节病>移< /骨节病> / <大骨节病>替代 / <大骨节病>控制 keystate,以及任何未决死击键)。转换后的VK值所报告的的KeyDown 事件等。

A key press generates a hardware event that reports a "scan code" to the Windows operating system. This scan code is then converted into a "virtual key code" based on the scan code along with other keyboard state factors (Caps Lock state, Shift/Alt/Ctrl keystate, and also any pending dead key strokes). The converted VK value is what is reported by the KeyDown event etc.

从扫描code到VK code的转换是依赖于当前的输入语言环境 - 简单地说,输入法区域设置定义扫描codeS和虚拟按键codeS之间的映射。请参见 MSDN文档完整的说明的键盘输入。

The conversion from scan code to VK code is dependent on the current input locale - simplistically, the input locale defines a mapping between scan codes and virtual key codes. See the MSDN documentation for a full description of keyboard input.

通过逆转此查找过程,有可能确定对应于每个虚拟键code(当然,同一扫描code将映射到多个VK codeS扫描code由于移/ CTRL / ALT状态等)。 Win32 API提供了 MapVirtualKeyEx 函数来执行这种映射,使用 MAPVK_VK_TO_VSC_EX 选项。你可以用它来确定扫描code产生的特定的VK code。

By reversing this lookup process, it is possible to determine the scan code that corresponds to each virtual key code (of course, the same scan code will map to multiple VK codes because of shift/ctrl/alt state etc). The Win32 API provides the MapVirtualKeyEx function to perform this mapping, by using the MAPVK_VK_TO_VSC_EX option. You can use this to determine which scan code generates the particular VK code.

不幸的是,这是只要你可以去编程 - 有没有办法来确定键盘的物理布局或键每次扫描code的位置。然而,大多数的物理键盘的接线方式相同,所以(例如)左上键将对大多数物理键盘设计相同的扫描code。可以使用此假定惯例来推断对应于扫描code中的物理位置,根据基本物理键盘布局(101键,102键等)。它不能保证,但它是一个pretty的安全的猜测。

Unfortunately, this is as far as you can go programmatically - there is no way to determine the physical layout of the keyboard or the location of the key for each scan code. However, most physical keyboards are wired the same way, so (for example) the top-left key will have the same scan code on most physical keyboard designs. You can use this assumed convention to infer the physical location corresponding to a scan code, depending on the basic physical keyboard layout (101-key, 102-key etc). It's not guaranteed, but it's a pretty safe guess.

下面code是一个更大的键盘处理库,我写的摘录(我已经打算开源,但还没有时间)。该方法初始化数组( this._virtualKeyScan codeS )由VK code索引对于给定的输入法区域设置(存储在 this._inputLanguage 被声明为 System.Windows.Forms.InputLanguage ,你可以使用数组来确定扫描code表示如果扫描code是零,那么VK是不是 - 通过检查,例如 this._virtualKeyScan codeS [VK_NUMPAD0] 对应VK code可用键盘在当前的输入语言环境;如果不为零,它是扫描code,从中可以推断出物理按键

The following code is an excerpt from a larger keyboard-handling library that I wrote (I've been intending to open-source it but haven't had the time). The method initializes an array (this._virtualKeyScanCodes) that is indexed by VK code for a given input locale (stored in this._inputLanguage which is declared as a System.Windows.Forms.InputLanguage. You can use the array to determine the scan code that corresponds to the VK code by examining e.g. this._virtualKeyScanCodes[VK_NUMPAD0] - if the scan code is zero, then that VK is not available on the keyboard in the current input locale; if it is non-zero, it is the scan code from which you can infer the physical key.

不幸的是,事情稍微比这更复杂,当你进入死键(产生重音符号,例如多键组合)的领域。这一切都太复杂,进入的权利,但迈克尔·S。卡普兰写了一系列详细的博客文章,如果你想进一步探讨这一的。祝你好运!

Unfortunately, matters are slightly more complicated than this when you get into the realms of dead keys (multiple key combinations that produce accented characters, for example). That's all far too complicated to go into right now, but Michael S. Kaplan wrote a detailed series of blog posts if you want to explore this further. Good luck!

private void Initialize()
{
    this._virtualKeyScanCodes = new uint[MaxVirtualKeys];

    // Scroll through the Scan Code (SC) values and get the Virtual Key (VK)
    // values in it. Then, store the SC in each valid VK so it can act as both a 
    // flag that the VK is valid, and it can store the SC value.
    for (uint scanCode = 0x01; scanCode <= 0xff; scanCode++)
    {
        uint virtualKeyCode = NativeMethods.MapVirtualKeyEx(
            scanCode, 
            NativeMethods.MAPVK_VSC_TO_VK, 
            this._inputLanguage.Handle);
        if (virtualKeyCode != 0)
        {
            this._virtualKeyScanCodes[virtualKeyCode] = scanCode;
        }
    }

    // Add the special keys that do not get added from the code above
    for (KeysEx ke = KeysEx.VK_NUMPAD0; ke <= KeysEx.VK_NUMPAD9; ke++)
    {
        this._virtualKeyScanCodes[(uint)ke] = NativeMethods.MapVirtualKeyEx(
            (uint)ke, 
            NativeMethods.MAPVK_VK_TO_VSC, 
            this._inputLanguage.Handle);
    }

    this._virtualKeyScanCodes[(uint)KeysEx.VK_DECIMAL] =
        NativeMethods.MapVirtualKeyEx(
            (uint)KeysEx.VK_DECIMAL, NativeMethods.MAPVK_VK_TO_VSC, this._inputLanguage.Handle);
    this._virtualKeyScanCodes[(uint)KeysEx.VK_DIVIDE] =
        NativeMethods.MapVirtualKeyEx(
            (uint)KeysEx.VK_DIVIDE, NativeMethods.MAPVK_VK_TO_VSC, this._inputLanguage.Handle);
    this._virtualKeyScanCodes[(uint)KeysEx.VK_CANCEL] =
        NativeMethods.MapVirtualKeyEx(
            (uint)KeysEx.VK_CANCEL, NativeMethods.MAPVK_VK_TO_VSC, this._inputLanguage.Handle);

    this._virtualKeyScanCodes[(uint)KeysEx.VK_LSHIFT] =
        NativeMethods.MapVirtualKeyEx(
            (uint)KeysEx.VK_LSHIFT, NativeMethods.MAPVK_VK_TO_VSC, this._inputLanguage.Handle);
    this._virtualKeyScanCodes[(uint)KeysEx.VK_RSHIFT] =
        NativeMethods.MapVirtualKeyEx(
            (uint)KeysEx.VK_RSHIFT, NativeMethods.MAPVK_VK_TO_VSC, this._inputLanguage.Handle);
    this._virtualKeyScanCodes[(uint)KeysEx.VK_LCONTROL] =
        NativeMethods.MapVirtualKeyEx(
            (uint)KeysEx.VK_LCONTROL, NativeMethods.MAPVK_VK_TO_VSC, this._inputLanguage.Handle);
    this._virtualKeyScanCodes[(uint)KeysEx.VK_RCONTROL] =
        NativeMethods.MapVirtualKeyEx(
            (uint)KeysEx.VK_RCONTROL, NativeMethods.MAPVK_VK_TO_VSC, this._inputLanguage.Handle);
    this._virtualKeyScanCodes[(uint)KeysEx.VK_LMENU] =
        NativeMethods.MapVirtualKeyEx(
            (uint)KeysEx.VK_LMENU, NativeMethods.MAPVK_VK_TO_VSC, this._inputLanguage.Handle);
    this._virtualKeyScanCodes[(uint)KeysEx.VK_RMENU] =
        NativeMethods.MapVirtualKeyEx(
            (uint)KeysEx.VK_RMENU, NativeMethods.MAPVK_VK_TO_VSC, this._inputLanguage.Handle);
    this._virtualKeyScanCodes[(uint)KeysEx.VK_LWIN] =
        NativeMethods.MapVirtualKeyEx(
            (uint)KeysEx.VK_LWIN, NativeMethods.MAPVK_VK_TO_VSC, this._inputLanguage.Handle);
    this._virtualKeyScanCodes[(uint)KeysEx.VK_RWIN] =
        NativeMethods.MapVirtualKeyEx(
            (uint)KeysEx.VK_RWIN, NativeMethods.MAPVK_VK_TO_VSC, this._inputLanguage.Handle);
    this._virtualKeyScanCodes[(uint)KeysEx.VK_PAUSE] =
        NativeMethods.MapVirtualKeyEx(
            (uint)KeysEx.VK_PAUSE, NativeMethods.MAPVK_VK_TO_VSC_EX, this._inputLanguage.Handle);
    this._virtualKeyScanCodes[(uint)KeysEx.VK_VOLUME_UP] =
        NativeMethods.MapVirtualKeyEx(
            (uint)KeysEx.VK_VOLUME_UP, NativeMethods.MAPVK_VK_TO_VSC_EX, this._inputLanguage.Handle);
    this._virtualKeyScanCodes[(uint)KeysEx.VK_VOLUME_DOWN] =
        NativeMethods.MapVirtualKeyEx(
            (uint)KeysEx.VK_VOLUME_DOWN, NativeMethods.MAPVK_VK_TO_VSC_EX, this._inputLanguage.Handle);
    this._virtualKeyScanCodes[(uint)KeysEx.VK_VOLUME_MUTE] =
        NativeMethods.MapVirtualKeyEx(
            (uint)KeysEx.VK_VOLUME_MUTE, NativeMethods.MAPVK_VK_TO_VSC_EX, this._inputLanguage.Handle);

    this._virtualKeyScanCodes[(uint)KeysEx.VK_MEDIA_NEXT_TRACK] =
        NativeMethods.MapVirtualKeyEx(
            (uint)KeysEx.VK_MEDIA_NEXT_TRACK, NativeMethods.MAPVK_VK_TO_VSC_EX, this._inputLanguage.Handle);
    this._virtualKeyScanCodes[(uint)KeysEx.VK_MEDIA_PREV_TRACK] =
        NativeMethods.MapVirtualKeyEx(
            (uint)KeysEx.VK_MEDIA_PREV_TRACK, NativeMethods.MAPVK_VK_TO_VSC_EX, this._inputLanguage.Handle);
    this._virtualKeyScanCodes[(uint)KeysEx.VK_MEDIA_PLAY_PAUSE] =
        NativeMethods.MapVirtualKeyEx(
            (uint)KeysEx.VK_MEDIA_PLAY_PAUSE, NativeMethods.MAPVK_VK_TO_VSC_EX, this._inputLanguage.Handle);
    this._virtualKeyScanCodes[(uint)KeysEx.VK_MEDIA_STOP] =
        NativeMethods.MapVirtualKeyEx(
            (uint)KeysEx.VK_MEDIA_STOP, NativeMethods.MAPVK_VK_TO_VSC_EX, this._inputLanguage.Handle);

    this._stateController = new KeyboardStateController();
    this._baseVirtualKeyTable = new VirtualKeyTable(this);
}

编辑:亦见这个问题这类似于你。

这篇关于是有可能创造一个键盘布局是相同的键盘用过?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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