Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I change a user's keyboard input?

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!

like image 981
ck_ Avatar asked Jan 14 '10 20:01

ck_


People also ask

Can you change keyboard input?

Switch between keyboard layouts or input methods On a hardware keyboard, press and hold the Windows logo key , and then press the Spacebar to cycle through your input methods.

How do I change the external keyboard settings?

Change how the keys respond on an external keyboardGo to Settings > Accessibility > Keyboards, then tap any of the following: Key Repeat: You can adjust the repeat interval and delay. Sticky Keys: Use Sticky Keys to press and hold modifier keys, such as Command and Option, as you press another key.

How do I change keyboard inputs in Windows 11?

Select the Start > Settings > Time & language > Language & region. Select the language that has the keyboard you want, then select Options. Select Add a keyboard and choose the keyboard you want to add. If you don't see the keyboard you want, you may have to add a new language to get additional options.


1 Answers

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:

  • Hook procedure identifies a target key is pressed
  • Call to SendInput, with the new key
  • Return 1 from the hook procedure to ignore the original key

Be careful of cyclic redirects, i.e. 'a' redirected to 'b' redirected to 'a', it can easily blow up ;)

like image 86
Idan K Avatar answered Sep 22 '22 00:09

Idan K