问题
I'm creating a custom keyboard layout. As the beginning step, I want to have the user press a key, have my keyboard hook intercept it, and output a different key of my choosing.
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
I've changed the relevant method to this:
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);
}
I want it to declare a new KBD structure object, copy the KBD structure supplied by the keyboard hook into it, modify my object's vkCode to use a different character, and then overwrite the supplied object with my modified version. This should hopefully keep everything the same except for the fact that it writes a different character.
Unfortunately, it's not working. The original keyboard character is typed. The Visual Studio output pane also gets a A first chance exception of type 'System.ArgumentException' occurred in MirrorBoard.exe
error.
What can I do here to intercept the keyboard hook and replace it with a character of my choosing?
Thanks!
回答1:
The second parameter for Marshal.PtrToStructure
must be a class not a struct and KBDLLHOOKSTRUCT
is probably a struct.
Instead you should use it like this:
KBDLLHOOKSTRUCT replacementKey = (KBDLLHOOKSTRUCT)Marshal.PtrToStructure(lParam, typeof(KBDLLHOOKSTRUCT));
replacementKey.vkCode = 90; // char 'Z'
Marshal.StructureToPtr(replacementKey, lParam, false);
来源:https://stackoverflow.com/questions/2062748/using-a-low-level-keyboard-hook-to-change-keyboard-characters