我必须为我们公司的程序编写屏幕键盘,该程序主要用于具有触控功能的行业PC。
我们无法使用Windows默认键盘,因为我们不需要键盘上的所有键。所以我被要求用C#写一个自定义的。
我已经找到this blog作为参考,但我不确定如何开始。
我创建了一个小型原型GUI,为每个键分配一个扫描码,并将这些扫描码转换为相关字符。并将它们发送到主动控件。但我不确定我应该使用哪种扫描码。
所以我的问题是,这是编写像这样的OSK的正确方法,如果是,我应该使用哪些扫描码?有链接吗?
我也不确定如何处理 shift 状态......
修改
好的,我做了一些研究,想出了一个osk,它读取当前的键盘布局,甚至处理简单的 shift 状态( Shift 和 Alt的Gr )。我写了一个继承自KeyButton
的{{1}}类,此Button
具有byte类型的KeyButton
属性,如果为其分配了有效的扫描码,{{1}将调用相关函数来获取正确的文本。我使用Michael Kaplan博客的功能进行了一些小改动。最后我发现我必须和他一样做。
所以问题的答案是:是的,您必须在按钮上使用扫描码,然后从键盘布局中获取虚拟键和unicode。 Use these scancodes.
现在我得到的角色唯一剩下的就是发送它们。
答案 0 :(得分:1)
我觉得这很简单,只需制作一系列按钮并为每个按钮分配一个字母,并在按钮内点击方法就可以做到简单。
SendKeys.Send("A");
根据按钮等更改密钥
答案 1 :(得分:1)
我编写了映射类,将键代码映射到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);
}
答案 2 :(得分:0)