使用低级键盘钩子更改键盘字符

cks*_*ubs 3 c# keyboard keyboard-hook low-level

我正在创建自定义键盘布局。作为开始步骤,我想让用户按下一个键,让我的键盘钩子拦截它,并输出我选择的不同键。

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

我已将相关方法更改为:

private static IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam)
{
    if (nCode >= 0 && wParam == (IntPtr)WM_KEYDOWN)
    {
        KBDLLHOOKSTRUCT replacementKey = new KBDLLHOOKSTRUCT();
        Marshal.PtrToStructure(lParam, replacementKey);
        replacementKey.vkCode = 90; // char 'Z'
        Marshal.StructureToPtr(replacementKey, lParam, true);
    }
    return CallNextHookEx(_hookID, nCode, wParam, lParam);
}
Run Code Online (Sandbox Code Playgroud)

我希望它声明一个新的 KBD 结构对象,将键盘钩子提供的 KBD 结构复制到其中,修改对象的 vkCode 以使用不同的字符,然后用修改后的版本覆盖提供的对象。这应该有希望保持所有内容相同,除了它写入不同的字符这一事实。

不幸的是,它不起作用。键入原始键盘字符。Visual Studio 输出窗格也会A first chance exception of type 'System.ArgumentException' occurred in MirrorBoard.exe出错。

我可以在这里做什么来拦截键盘钩子并用我选择的字符替换它?

谢谢!

Pen*_*puu 5

for 的第二个参数Marshal.PtrToStructure必须是一个类而不是一个结构体,KBDLLHOOKSTRUCT并且可能是一个结构体。

相反,您应该像这样使用它:

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