Я пытаюсь разработать программное обеспечение, которое будет принимать ввод с клавиатуры, потреблять ввод и возвращать некоторые другие символы, заменяющие типизированный ввод. Например, если я наберу: «abcd» и определю правило обмена как любой русский алфавит, то я буду ожидать вывода как: «ский».
Код, который я использую, выглядит следующим образом:
namespace hook_form
{
public partial class Form1 : Form
{
//Keyboard API constants
private const int WH_KEYBOARD_LL = 13;
private const int WM_KEYDOWN = 0x0100;
private const int WM_KEYUP = 0x0101;
private const int WM_SYSKEYUP = 0x0105;
private const int WM_SYSKEYDOWN = 0x0104;
private HookHandlerDelegate proc;
private IntPtr hookID = IntPtr.Zero;
private delegate IntPtr HookHandlerDelegate(int nCode, IntPtr wParam, ref KBDLLHOOKSTRUCT lParam);
private struct KBDLLHOOKSTRUCT
{
public int vkCode;
int scanCode;
public int flags;
int time;
int dwExtraInfo;
}
private IntPtr HookCallback(int nCode, IntPtr wParam, ref KBDLLHOOKSTRUCT lParam)
{
bool AllowKey = false;
switch (lParam.vkCode)
{
case (65|97|66|98): // key codes for "a/b/c/d" etc. goes here
//Alt+Tab, Alt+Esc, Ctrl+Esc, Windows Key
AllowKey = true;
SendKeys.Send("\u0997"); // code for russian letters here....
break;
}
MessageBox.Show(lParam.vkCode.ToString());
if (AllowKey == false)
return (System.IntPtr)1;
return CallNextHookEx(hookID, nCode, wParam, ref lParam);
}
#region DllImports
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr SetWindowsHookEx(int idHook,
HookHandlerDelegate 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, ref KBDLLHOOKSTRUCT lParam);
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr GetModuleHandle(string lpModuleName);
#endregion
private void buttonStart_Click(object sender, EventArgs e)
{
proc = new HookHandlerDelegate(HookCallback);
using (Process curProcess = Process.GetCurrentProcess())
using (ProcessModule curModule = curProcess.MainModule)
{
hookID = SetWindowsHookEx(WH_KEYBOARD_LL, proc,
GetModuleHandle(curModule.ModuleName), 0);
}
}
private void btnEnd_Click(object sender, EventArgs e)
{
UnhookWindowsHookEx(hookID);
}
}
}
Я получаю вывод как: "aсbкcиdй", я имею в виду, что напечатанные буквы (английские) не потребляются кодом (я имею в виду, что они не должны появляться в выводе), даже если я вернул (System.IntPtr)1
.
Я думаю, что это проблема отцепления. Может ли кто-нибудь помочь мне решить эту проблему?
Если это невозможно, может кто-нибудь посоветовать мне какое-нибудь программное обеспечение с открытым исходным кодом, использующее клавиатуру?