【问题标题】:Using a low-level keyboard hook to change keyboard characters使用低级键盘钩子更改键盘字符
【发布时间】:2011-01-04 23:40:23
【问题描述】:

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

我找到了这个键盘钩子代码,我正在尝试对其进行稍微修改以用于我的目的: 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);
}

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

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

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

谢谢!

【问题讨论】:

    标签: c# keyboard low-level keyboard-hook


    【解决方案1】:

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

    您应该像这样使用它:

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

    【讨论】:

    • Visual Studio 告诉我它是Marshal.PtrToStructure(IntPtr ptr, object structure); ...这与您所说的是否相符?它不会抛出错误或任何东西,编译得很好。
    • 它编译得很好,但在运行时会抛出一个ArgumentException
    • 如果不将 Ptr 保存到结构中,为什么要称为 PtrToStructure?但是如果我确实需要更改它,我应该在这里做什么?如果我不能使用 KBD 结构来保存指向 KBD 结构的指针,我该如何修改它?
    • PtrToStructure 无法将 ptr 保存到结构中,因为它已装箱(即它是副本)。我在答案中添加了正确的解决方案。
    • 您还可以查看msdn.microsoft.com/en-us/library/30ex8z62.aspx 的文档 - 它说:您不能将此重载方法与值类型一起使用。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多