是否可以在C#中捕获键控事件并随后取消此事件?
我想把拉丁键盘翻译成另一种键盘,比如维语或类似的语言。有一个维语键盘,但按键的编码是如此复杂,以至于普通的PC用户无法轻松地键入维语 所以我的目标是为这个问题创建一个软件解决方案,比如中文输入系统。在这个系统中,你可以从各种键盘输入汉字。这是一种聪明的解决方案,这样每个人都可以少用它来解决问题 因此,我的目标是编写一个Windows服务应用程序,它捕获每个按键敲击(仅字母表)并将按下的键转换为目标(Unicode)字母表,然后使用此转换的字母表再次模拟按键敲击。因此,目标字母表将显示在光标点上。最后,我的应用程序会放弃/停止按下向下键的原始键 这样就不会再出现了 例如:是否可以在C#中捕获键控事件并随后取消此事件?,c#,winapi,keyboard-events,C#,Winapi,Keyboard Events,我想把拉丁键盘翻译成另一种键盘,比如维语或类似的语言。有一个维语键盘,但按键的编码是如此复杂,以至于普通的PC用户无法轻松地键入维语 所以我的目标是为这个问题创建一个软件解决方案,比如中文输入系统。在这个系统中,你可以从各种键盘输入汉字。这是一种聪明的解决方案,这样每个人都可以少用它来解决问题 因此,我的目标是编写一个Windows服务应用程序,它捕获每个按键敲击(仅字母表)并将按下的键转换为目标(Unicode)字母表,然后使用此转换的字母表再次模拟按键敲击。因此,目标字母表将显示在光标点上。
0xFEBD
,然后发送回光标点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;
}
}
公共类模拟
{
[DllImport(“USER32.DLL”,CharSet=CharSet.Unicode)]
静态外部UInt32 SendInput(UInt32 numberOfInputs,INPUT[]INPUT,Int32 SizeOfInput结构);
[StructLayout(LayoutKind.Sequential,Size=24)]
结构键输入
{
公共UInt16 Vk;
公共UInt16扫描;
32面国旗;
公共UInt32次;
公共UInt32外部信息;
}
[StructLayout(LayoutKind.Explicit)]
私有结构输入
{
[字段偏移量(0)]
公共int类型;
[现场偏移(4)]
公钥输入;
}
公共静态输入(UInt16 unicode)
{
输入向下=新输入();
down.Type=1;//输入键盘
down.ki.Vk=0;
down.ki.Scan=unicode;
down.ki.Time=0;
down.ki.Flags=0x0004;//KEYEVENTF\u UNICODE
down.ki.ExtraInfo=0;
向上输入=新输入();
up.Type=1;//输入键盘
up.ki.Vk=0;
up.ki.Scan=unicode;
up.ki.Time=0;
up.ki.Flags=0x0004;//KEYEVENTF\u UNICODE
up.ki.ExtraInfo=0;
输入[]输入=新输入[2];
输入[0]=向下;
输入[1]=向上;
SendInput(1,input,封送处理大小(typeof(input)));
}
}
///捕获任何窗口键
///
公共静态类WinKeyCapture
{
专用常量int WH_键盘LL=13;
私有常量int WH_CALLWNDPROC=4;
私有常量int WM_KEYDOWN=0x0100;
私有常量int WM_CHAR=0x0102;
常量int VK_A=0x08;//0x41;//向上键
const int VK_DOWN=0x28;//向下键
const int VK_LEFT=0x25;
常数int VK_RIGHT=0x27;
consuint keyevent fu KEYUP=0x0002;
const uint keyevent f_EXTENDEDKEY=0x0001;
consuint keyevent f_CTRL=0x11;
consuint keyevent f_ADD=0x6B;
常数VK_LWIN=0x5b;
私有静态低层KeyboardProc_proc=WinKeyCapture.HookCallback;
[DllImport(“user32.dll”)]
公共静态外部无效keybd_事件(字节bVk、字节bScan、uint dwFlags、uint dwExtraInfo);
[DllImport(“user32.dll”,CharSet=CharSet.Auto,SetLastError=true)]
私有静态外部IntPtr SetWindowsHookEx(int idHook,
低级键盘程序lpfn、IntPtr hMod、uint dwThreadId);
[DllImport(“user32.dll”,CharSet=CharSet.Auto,SetLastError=true)]
[返回:Marshallas(UnmanagedType.Bool)]
私有静态外部bool unhookwindowshookx(IntPtr hhk);
[DllImport(“user32.dll”,CharSet=CharSet.Auto,SetLastError=true)]
私有静态外部IntPtr CallNextHookEx(IntPtr hhk,intncode,
IntPtr wParam、IntPtr lParam);
[DllImport(“kernel32.dll”,CharSet=CharSet.Auto,SetLastError=true)]
私有静态外部IntPtr GetModuleHandle(字符串lpModuleName);
[DllImport(“user32.dll”,SetLastError=true)]
私有静态外部uint SendInput(uint numberOfInputs、INPUT[]inputs、int SIZEOFINPUT结构);
公共静态void SetHook()
{
SetHook(_proc);
}
公共静态void UnHook()
{
unhookwindowshookx(_hookID);
}
专用静态IntPtr SetHook(低级键盘程序)
{
使用(Process curProcess=Process.GetCurrentProcess())
使用(ProcessModule curModule=curProcess.MainModule)
{
返回SetWindowsHookEx(WH\u KEYBOARD\u LL,proc,GetModuleHandle(curModule.ModuleName),0);
}
}
私有静态IntPtr _hookID=IntPtr.Zero;
公共静态IntPtr HookCallback(intncode、IntPtr wParam、IntPtr lParam)
{
int vkCode=Marshal.ReadInt32(LPRAM);
如果(nCode>=0&&wParam==(IntPtr)WM\u KEYDOWN)
{
//待办事项:只识别字母,然后开火
VKcode(VKcode);
}
//wParam |=0x4000;
返回CallNextHookEx(_hookID,nCode,wParam,lParam);
}
私有静态void VKcode(int代码)
{
开关(代码)//TODO:完成所有其他字母转换
{
案例0x4B:
模拟输入(0xFEDB);
打破
案例0x54:
模拟单输入(0xFEAD);
打破
案例0x55:
模拟输入(0xFBE7);
布雷亚