Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/windows/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何编写本地化的屏幕键盘_C#_Windows_Keyboard_Screen_Localized - Fatal编程技术网

C# 如何编写本地化的屏幕键盘

C# 如何编写本地化的屏幕键盘,c#,windows,keyboard,screen,localized,C#,Windows,Keyboard,Screen,Localized,我必须为我们公司的程序编写一个屏幕键盘,该程序主要用于具有触摸功能的工业PC 我们不能使用windows默认键盘,因为我们不需要键盘上的所有键。所以我被要求用C#写一个自定义的 我已经找到了作为参考,但我不知道如何开始 我创建了一个小型的原型GUI,为每个键分配一个扫描码,并将这些扫描码转换为相关字符。并将它们发送到活动控件。但我不确定我应该使用什么扫描码 所以我的问题是,这样写OSK正确吗?如果是的话,我应该使用哪些扫描码?有链接吗 我也不知道如何处理换档状态 编辑: 好的,我做了更多的研究,

我必须为我们公司的程序编写一个屏幕键盘,该程序主要用于具有触摸功能的工业PC

我们不能使用windows默认键盘,因为我们不需要键盘上的所有键。所以我被要求用C#写一个自定义的

我已经找到了作为参考,但我不知道如何开始

我创建了一个小型的原型GUI,为每个键分配一个扫描码,并将这些扫描码转换为相关字符。并将它们发送到活动控件。但我不确定我应该使用什么扫描码

所以我的问题是,这样写OSK正确吗?如果是的话,我应该使用哪些扫描码?有链接吗

我也不知道如何处理换档状态

编辑:

好的,我做了更多的研究,设计了一个osk,它可以读取当前的键盘布局,甚至可以处理简单的移位状态(shift和Alt-Gr)。我编写了一个继承自
Button
KeyButton
类,该
KeyButton
具有类型为byte的
ScanCode
属性,如果为其分配了有效的扫描码,则
KeyButton
将调用相关函数以获得正确的文本。我使用了MichaelKaplan博客中的函数,做了一些小改动。最后,我不得不和他做同样的事

所以我的问题的答案是:是的,你必须在你的按钮上使用扫描码,然后从键盘布局中获得virtualkey和unicode


现在我得到了字符,唯一剩下的就是发送这些字符。

我认为这相当简单,只需制作一系列按钮并为每个按钮分配一个字母,在按钮单击方法中,您可以执行一个简单的操作

SendKeys.Send("A"); 

基于按钮等更改键

我为WPF应用程序编写了将键代码映射到字符的映射类。 也许这会有帮助

public class KeyMapper
{
    /// <summary>
    /// Map key code to character.
    /// If key code cannot be mapped returns empty char.
    /// </summary>
    public static char MapKey(Key key, bool shiftPressed, string culture)
    {
        CheckCulture(culture);
        int englishVirtuaCode = KeyInterop.VirtualKeyFromKey(key);
        return EnglishVirtualCodeToChar(englishVirtuaCode, shiftPressed, culture);
    }

    private static void CheckCulture(string culture)
    {
        InputLanguage language = InputLanguage.FromCulture(new CultureInfo(culture));
        if (language == null)
            throw new ArgumentException(string.Format("culture {0} does not exist.", culture));
    }

    private static char EnglishVirtualCodeToChar(int enlishVirtualCode, bool shiftPressed, string culture)
    {
        var scanCode = KeyMappingWinApi.MapVirtualKeyEx((uint)enlishVirtualCode, 0, EnglishCultureHandle);
        var vitualKeyCode = KeyMappingWinApi.MapVirtualKeyEx(scanCode, 1, GetCultureHandle(culture));
        byte[] keyStates = GetKeyStates(vitualKeyCode, shiftPressed);
        const int keyInformationSize = 5;
        var stringBuilder = new StringBuilder(keyInformationSize);
        KeyMappingWinApi.ToUnicodeEx(vitualKeyCode, scanCode, keyStates, stringBuilder, stringBuilder.Capacity, 0, GetCultureHandle(culture));
        if (stringBuilder.Length == 0)
            return ' ';
        return stringBuilder[0];
    }

    private static IntPtr EnglishCultureHandle
    {
        get { return GetCultureHandle("en-US"); }
    }

    private static IntPtr GetCultureHandle(string culture)
    {
        return InputLanguage.FromCulture(new CultureInfo(culture)).Handle;
    }

    /// <summary>
    /// Gets key states for ToUnicodeEx function
    /// </summary>
    private static byte[] GetKeyStates(uint keyCode, bool shiftPressed)
    {
        const byte keyPressFlag = 0x80;
        const byte shifPosition = 16; // position of Shift key in keys array
        var keyStatses = new byte[256];
        keyStatses[keyCode] = keyPressFlag;
        keyStatses[shifPosition] = shiftPressed ? keyPressFlag : (byte)0;
        return keyStatses;
    }
}

public class KeyMappingWinApi
{
    [DllImport("user32.dll")]
    public static extern uint MapVirtualKeyEx(uint uCode, uint uMapType, IntPtr dwhkl);

    [DllImport("user32.dll")]
    public static extern int ToUnicodeEx(uint wVirtKey, uint wScanCode, byte[] lpKeyState,
        [Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder pwszBuff, int cchBuff, uint wFlags, IntPtr dwhkl);

    [DllImport("user32.dll")]
    public static extern short VkKeyScanEx(char ch, IntPtr dwhkl);
}
公共类密钥映射器
{
/// 
///将键代码映射到字符。
///如果无法映射键代码,则返回空字符。
/// 
公共静态字符映射键(键键、bool-shiftPressed、字符串区域性)
{
文化(文化);
int englishVirtualCode=KeyInterop.VirtualKeyFromKey(key);
返回英语irtualcodec(英语irtualcode,shiftPressed,culture);
}
私有静态void CheckCulture(字符串区域性)
{
InputLanguage=InputLanguage.FromCulture(新文化信息(文化));
if(语言==null)
抛出新ArgumentException(string.Format(“区域性{0}不存在。”,区域性));
}
私有静态字符EnglishVirtualCode(int enlishVirtualCode,bool shiftPressed,字符串区域性)
{
var scanCode=KeyMappingWinApi.MapVirtualKeyEx((uint)enlishVirtualCode,0,EnglishCultureHandle);
var vitualKeyCode=KeyMappingWinApi.MapVirtualKeyEx(scanCode,1,GetCultureHandle(culture));
字节[]keyStates=GetKeyStates(vitualKeyCode,shiftPressed);
常数int keyInformationSize=5;
var stringBuilder=新的stringBuilder(keyInformationSize);
KeyMappingWinApi.tounicodex(vitualKeyCode、scanCode、keyStates、stringBuilder、stringBuilder.Capacity、0、GetCultureHandle(culture));
如果(stringBuilder.Length==0)
返回“”;
返回stringBuilder[0];
}
私人静态IntPtr英语文化处理
{
获取{return GetCultureHandle(“en-US”);}
}
私有静态IntPtr GetCultureHandle(字符串区域性)
{
返回InputLanguage.FromCulture(新文化信息(文化)).Handle;
}
/// 
///获取tounicodex函数的键状态
/// 
私有静态字节[]GetKeyStates(uint keyCode,bool shiftPressed)
{
常量字节keyPressFlag=0x80;
常量字节shifPosition=16;//键数组中Shift键的位置
var keyStatses=新字节[256];
keyStatses[keyCode]=keyPressFlag;
keyStatses[ShiftPosition]=换档压力?按键压力标志:(字节)0;
返回键状态;
}
}
公共类KeyMappingWinApi
{
[DllImport(“user32.dll”)]
公共静态外部uint MapVirtualKeyx(uint uCode、uint uMapType、IntPtr dwhkl);
[DllImport(“user32.dll”)]
公共静态外部int ToUnicodeEx(uint wVirtKey,uint wScanCode,字节[]lpKeyState,
[Out,Marshallas(UnmanagedType.LPWStr)]StringBuilder pwszBuff、int cchBuff、uint wFlags、IntPtr dwhkl;
[DllImport(“user32.dll”)]
公共静态外部短VkKeyScanEx(字符ch、IntPtr dwhkl);
}

你可能想看看这些家伙:


也许仅仅购买它比开发它更便宜,你永远不知道;-)

这个OSK是用于一般用途还是专门用于给定的软件?(例如,你会将扫描代码发送到windows事件总线还是将字符代码发送到winforms应用程序?)差别很大。对于我们的软件,因此我想将字符代码发送到文本框。但是我想像windows中的默认osk一样使用键盘布局。我不确定,如果有任何进展,我会更新帖子。是的,但我想使用windows中的键盘布局。