2010-01-14 212 views
2

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

我发现这个键盘钩子代码,我想稍微修改一下我的目的: 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错误。

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

谢谢!

回答

4

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

相反,你应该使用这样的:

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

Visual Studio中告诉我,它的'Marshal.PtrToStructure(IntPtr的PTR,对象结构);'...不跟你说什么花言巧语?它不会抛出错误或任何东西,编译得很好。 – cksubs 2010-01-14 07:39:02

+0

它编译得很好,但在运行时抛出'ArgumentException'。 – 2010-01-14 07:41:13

+0

如果它没有将Ptr保存到结构中,为什么它会被称为PtrToStructure?但是如果我确实需要改变它,我应该在这里做什么?如果我不能使用KBD结构来保存指向KBD结构的指针,我该如何修改它? – cksubs 2010-01-14 07:47:55