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

发布于 2024-08-18 03:24:44 字数 1395 浏览 13 评论 0原文

我找到了这个键盘挂钩代码,我试图根据我的目的对其进行稍微修改: 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);
    }

控制台正确地将其输出为:

E
Z
T
Z
G
Z
etc.

但是,焦点应用程序仍然键入“E”而不是“Z”。为什么?我将挂钩键盘输入更改为包含“Z”而不是“E”,并且控制台行显示它已正确更改!

据我了解,调用 return CallNextHookEx(_hookID, nCode, wParam, lParam); 是将“立即打印”命令发送到打开的应用程序。难道不是这样的吗?有什么东西阻止我输入我想要的字符吗?我知道像 AutoHotkey 这样的应用程序会接受一个输入键,检查它,然后返回一个不同的字符。我在这里如何做同样的事情?

谢谢!

I found this keyboard hook code, which I'm trying to slightly modify for my purposes: http://blogs.msdn.com/toub/archive/2006/05/03/589423.aspx

As an overview, I want to have the user press a key, say 'E', and have the keyboard return a different character, 'Z', to whatever app is in focus.

The relevant method I changed now looks like:

    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);
    }

The console correctly outputs this as:

E
Z
T
Z
G
Z
etc.

HOWEVER, the in focus app still types 'E' instead of 'Z'. Why? I changed the hooked keyboard input to contain 'Z' instead of 'E', and the console lines show that it was changed correctly!

As I understand it, calling the return CallNextHookEx(_hookID, nCode, wParam, lParam); is what sends the "print this now" command to the open app. Is that not how it works? Is there something that's preventing me from typing the character I want? I know apps like AutoHotkey take an input key, check it, and return a different character. How do I do the same here?

Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

明月夜 2024-08-25 03:24:44

我以前做过这个,但有点不同。
我没有尝试更改发送到 CallNextHookEx 的参数,而是“吞掉”了按键(您可以通过从挂钩过程返回非零值来防止调用后续过程来做到这一点)。

然后我使用 SendInput 发送新密钥我想“注射”。

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

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

注意循环重定向,即“a”重定向到“b”重定向到“a”,它很容易爆炸;)

I've done this before but a little different.
Instead of trying to change the parameters sent to CallNextHookEx, I 'swallowed' the key press (you can do this by returning a nonzero value from the hook procedure to prevent subsequent procedures from being called).

Then I used SendInput to send the new key that I wanted to 'inject'.

So basically it works like this:

  • Hook procedure identifies a target key is pressed
  • Call to SendInput, with the new key
  • Return 1 from the hook procedure to ignore the original key

Be careful of cyclic redirects, i.e. 'a' redirected to 'b' redirected to 'a', it can easily blow up ;)

合久必婚 2024-08-25 03:24:44

您很可能在“线程范围”而不是“系统范围”安装了钩子,这意味着仅在安装钩子的线程中才会发生键转换。

为了在“系统范围内”安装它,您将需要两部分:一个具有“钩子提供程序”的 dll 和一个管理它的 exe。
这是一个很好的教程
http://www.codeproject.com/KB/system/hooksys.aspx
这里有一个例子:
http://www.codeguru.com/cpp/com -tech/shell/article.php/c4509/

但是:
1. 安装系统范围的挂钩可能会严重破坏您的系统(请确保转发未翻译的密钥)。
2. 请...不要创建另一个键盘记录器

You have, most likely, installed the hook "thread wide" and not "system wide", which means that the key translation will occur only for the thread installing the hook.

In order to install it "system wide" you will need two pieces: one dll having the "hook provider" and an exe managing it.
Here is a good tutorial
http://www.codeproject.com/KB/system/hooksys.aspx
and here an example:
http://www.codeguru.com/cpp/com-tech/shell/article.php/c4509/

But:
1. Installing system wide hooks can seriously screw up you system (make sure that you forward the keys that you don't translate).
2. Please... don't create another keylogger

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文