我可以更改用户的键盘输入吗?

cks*_*ubs 8 c# keyboard-hook keyboard-layout low-level

我找到了这个键盘钩子代码,我试图为我的目的略微修改:http://blogs.msdn.com/toub/archive/2006/05/03/589423.aspx

作为概述,我想让用户按一个键,说'E',并让键盘返回一个不同的字符'Z',对任何焦点的应用程序.

我改变的相关方法现在看起来像:

    private static IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam)
    {
        if (nCode >= 0 && wParam == (IntPtr)WM_KEYDOWN)
        {
            //The truely typed character:
            int vkCode = Marshal.ReadInt32(lParam);
            Console.WriteLine((Keys)vkCode);

            KBDLLHOOKSTRUCT replacementKey = (KBDLLHOOKSTRUCT)Marshal.PtrToStructure(lParam, typeof(KBDLLHOOKSTRUCT));
            replacementKey.vkCode = 90; // char 'Z'
            Marshal.StructureToPtr(replacementKey, lParam, false);

            //Now changed to my set character
            vkCode = Marshal.ReadInt32(lParam);
            Console.WriteLine((Keys)vkCode);
        }
        return CallNextHookEx(_hookID, nCode, wParam, lParam);
    }
Run Code Online (Sandbox Code Playgroud)

控制台正确输出为:

E
Z
T
Z
G
Z
etc.
Run Code Online (Sandbox Code Playgroud)

但是,焦点应用程序仍然键入"E"而不是"Z".为什么?我更改了钩子键盘输入以包含'Z'而不是'E',并且控制台线显示它已正确更改!

据我了解,调用return CallNextHookEx(_hookID, nCode, wParam, lParam);是将"立即打印"命令发送到打开的应用程序.这不是它的工作原理吗?是否有什么东西阻止我输入我想要的角色?我知道像AutoHotkey这样的应用程序会输入一个输入键,检查它并返回一个不同的字符.我怎么在这里做同样的事情?

谢谢!

Ida*_*n K 5

我以前做过这件事,但有点不同.
我没有尝试更改发送到的参数CallNextHookEx,而是"按下"按键(您可以通过从挂钩过程返回非零值来防止后续过程被调用).

然后我使用SendInput发送我想要'注入'的新密钥.

所以基本上它的工作原理如下:

  • 挂钩程序识别按下目标键
  • 使用新密钥调用SendInput
  • 从钩子过程返回1以忽略原始键

小心循环重定向,即'a'重定向到'b'重定向到'a',它很容易爆炸;)