我想将拉丁语键盘翻译成另一个键盘,如维吾尔语等。有一个维吾尔语键盘,但键的编码是如此复杂,以至于普通PC用户不能轻易键入维吾尔语。
所以我的目标是为这个问题创建一个软件解决方案,例如中文输入系统。在该系统中,您可以从各种键盘输入中文字符。这是一种聪明的解决方案,所以每个人都可以毫无问题地使用它。
所以我的目标是我想编写一个Windows服务应用程序,它捕获每个KeyDown-Strike(仅字母表)并将按下的键转换为目标(Unicode)字母并再次使用此翻译的字母模拟键击。结果,目标字母表将显示在光标点中。在结束时,我的应用程序从KEYDOWN按下
中丢弃/停止原始密钥这样就不会再显示了。
例如:
0xFEBD
,然后发送回光标点。到目前为止,第1步和第2步工作正常。我的问题是,在我捕获按键事件后,我无法丢弃/取消/停止此次击键的最后一次按键事件。
我不确定我的想法是否良好/有效,足以实现我的想法。现在我只是在尝试。也许你有更好的想法,你可以建议我。这是我的代码:
public class Simulate
{
[DllImport("USER32.DLL", CharSet = CharSet.Unicode)]
static extern UInt32 SendInput(UInt32 numberOfInputs, INPUT[] input, Int32 sizeOfInputStructure);
[StructLayout(LayoutKind.Sequential, Size = 24)]
struct KEYBDINPUT
{
public UInt16 Vk;
public UInt16 Scan;
public UInt32 Flags;
public UInt32 Time;
public UInt32 ExtraInfo;
}
[StructLayout(LayoutKind.Explicit)]
private struct INPUT
{
[FieldOffset(0)]
public int Type;
[FieldOffset(4)]
public KEYBDINPUT ki;
}
public static void UnicodeInput(UInt16 unicode)
{
INPUT down = new INPUT();
down.Type = 1; //INPUT_KEYBOARD
down.ki.Vk = 0;
down.ki.Scan = unicode;
down.ki.Time = 0;
down.ki.Flags = 0x0004; //KEYEVENTF_UNICODE
down.ki.ExtraInfo = 0;
INPUT up = new INPUT();
up.Type = 1; //INPUT_KEYBOARD
up.ki.Vk = 0;
up.ki.Scan = unicode;
up.ki.Time = 0;
up.ki.Flags = 0x0004; //KEYEVENTF_UNICODE
up.ki.ExtraInfo = 0;
INPUT[] input = new INPUT[2];
input[0] = down;
input[1] = up;
SendInput(1, input, Marshal.SizeOf(typeof(INPUT)));
}
}
/// Capture any window key
///
public static class WinKeyCapture
{
private const int WH_KEYBOARD_LL = 13;
private const int WH_CALLWNDPROC = 4;
private const int WM_KEYDOWN = 0x0100;
private const int WM_CHAR = 0x0102;
const int VK_A = 0x08;// 0x41; //up key
const int VK_DOWN = 0x28; //down key
const int VK_LEFT = 0x25;
const int VK_RIGHT = 0x27;
const uint KEYEVENTF_KEYUP = 0x0002;
const uint KEYEVENTF_EXTENDEDKEY = 0x0001;
const uint KEYEVENTF_CTRL = 0x11;
const uint KEYEVENTF_ADD = 0x6B;
const uint VK_LWIN = 0x5b;
private static LowLevelKeyboardProc _proc = WinKeyCapture.HookCallback;
[DllImport("user32.dll")]
public static extern void keybd_event(byte bVk, byte bScan, uint dwFlags, uint dwExtraInfo);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr SetWindowsHookEx(int idHook,
LowLevelKeyboardProc lpfn, IntPtr hMod, uint dwThreadId);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool UnhookWindowsHookEx(IntPtr hhk);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode,
IntPtr wParam, IntPtr lParam);
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr GetModuleHandle(string lpModuleName);
[DllImport("user32.dll", SetLastError = true)]
private static extern uint SendInput(uint numberOfInputs, INPUT[] inputs, int sizeOfInputStructure);
public static void SetHook()
{
SetHook(_proc);
}
public static void UnHook()
{
UnhookWindowsHookEx(_hookID);
}
private static IntPtr SetHook(LowLevelKeyboardProc proc)
{
using (Process curProcess = Process.GetCurrentProcess())
using (ProcessModule curModule = curProcess.MainModule)
{
return SetWindowsHookEx(WH_KEYBOARD_LL, proc, GetModuleHandle(curModule.ModuleName), 0);
}
}
private static IntPtr _hookID = IntPtr.Zero;
public static IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam)
{
int vkCode = Marshal.ReadInt32(lParam);
if (nCode >= 0 && wParam == (IntPtr)WM_KEYDOWN)
{
// TODO: identify only Alphabets then fire
VKcode(vkCode);
}
//wParam |= 0x4000;
return CallNextHookEx(_hookID, nCode, wParam, lParam);
}
private static void VKcode(int code)
{
switch (code) // TODO: Complete all other Alphabet-Tranylations
{
case 0x4B:
Simulate.UnicodeInput(0xFEDB);
break;
case 0x54:
Simulate.UnicodeInput(0xFEAD);
break;
case 0x55:
Simulate.UnicodeInput(0xFBE7);
break;
case 0x56:
Simulate.UnicodeInput(0xFEE9);
break;
case 0x59:
Simulate.UnicodeInput(0xFEE1);
break;
case 0x5a:
break;
}
}
/// <summary>
/// simulate key press
/// </summary>
/// <param name="keyCode"></param>
public static void SendKeyPress(KeyCode keyCode)
{
INPUT input = new INPUT {
Type = 1
};
input.Data.Keyboard = new KEYBDINPUT() {
Vk = (ushort)keyCode,
Scan = 0,
Flags = 0,
Time = 0,
ExtraInfo = IntPtr.Zero,
};
INPUT input2 = new INPUT {
Type = 1
};
input2.Data.Keyboard = new KEYBDINPUT() {
Vk = (ushort)keyCode,
Scan = 0,
Flags = 2,
Time = 0,
ExtraInfo = IntPtr.Zero
};
INPUT[] inputs = new INPUT[] { input, input2 };
if (SendInput(2, inputs, Marshal.SizeOf(typeof(INPUT))) == 0)
throw new Exception();
}
/// <summary>
/// simulate key press
/// </summary>
/// <param name="keyCode"></param>
public static void SendUnicodePress(KeyCode keyCode)
{
INPUT input = new INPUT {
Type = 1
};
input.Data.Keyboard = new KEYBDINPUT() {
Vk = (ushort)keyCode,
Scan = 0,
Flags = 0,
Time = 0,
ExtraInfo = IntPtr.Zero,
};
INPUT input2 = new INPUT {
Type = 1
};
input2.Data.Keyboard = new KEYBDINPUT() {
Vk = (ushort)keyCode,
Scan = 0,
Flags = 2,
Time = 0,
ExtraInfo = IntPtr.Zero
};
INPUT[] inputs = new INPUT[] { input, input2 };
if (SendInput(2, inputs, Marshal.SizeOf(typeof(INPUT))) == 0)
throw new Exception();
}
[StructLayout(LayoutKind.Sequential)]
internal struct INPUT
{
public uint Type;
public MOUSEKEYBDHARDWAREINPUT Data;
}
[StructLayout(LayoutKind.Explicit)]
internal struct MOUSEKEYBDHARDWAREINPUT
{
[FieldOffset(0)]
public HARDWAREINPUT Hardware;
[FieldOffset(0)]
public KEYBDINPUT Keyboard;
[FieldOffset(0)]
public MOUSEINPUT Mouse;
}
[StructLayout(LayoutKind.Sequential)]
internal struct HARDWAREINPUT
{
public uint Msg;
public ushort ParamL;
public ushort ParamH;
}
[StructLayout(LayoutKind.Sequential)]
internal struct KEYBDINPUT
{
public ushort Vk;
public ushort Scan;
public uint Flags;
public uint Time;
public IntPtr ExtraInfo;
}
[StructLayout(LayoutKind.Sequential)]
internal struct MOUSEINPUT
{
public int X;
public int Y;
public uint MouseData;
public uint Flags;
public uint Time;
public IntPtr ExtraInfo;
}
}