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!
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:
Be careful of cyclic redirects, i.e. 'a' redirected to 'b' redirected to 'a', it can easily blow up ;)