Sending Key Presses with Interception

4k views Asked by At

I have tried all the normal methods of faking keyboard actions (SendInput/SendKeys/etc) but none of them seemed to work for games that used DirectInput. After a lot of reading and searching I stumbled across Interception, which is a C++ Library that allows you to hook into your devices.

It has been a very long time since I worked with C++ (Nothing existed for C#) so I am having some trouble with this. I have pasted in the sample code below.

Does it look like there would be anyway to initiate key actions from the code using this? The samples all just hook into the devices and rewrite actions (x key prints y, inverts mouse axis, etc).

enum ScanCode
{
    SCANCODE_X   = 0x2D,
    SCANCODE_Y   = 0x15,
    SCANCODE_ESC = 0x01
};

int main()
{
    InterceptionContext context;
    InterceptionDevice device;
    InterceptionKeyStroke stroke;

    raise_process_priority();

    context = interception_create_context();

    interception_set_filter(context, interception_is_keyboard, INTERCEPTION_FILTER_KEY_DOWN | INTERCEPTION_FILTER_KEY_UP);

    /*
    for (int i = 0; i < 10; i++)
    {
        Sleep(1000);
        stroke.code = SCANCODE_Y;
        interception_send(context, device, (const InterceptionStroke *)&stroke, 1);
    }
    */

    while(interception_receive(context, device = interception_wait(context), (InterceptionStroke *)&stroke, 1) > 0)
    {
        if(stroke.code == SCANCODE_X) stroke.code = SCANCODE_Y;

        interception_send(context, device, (const InterceptionStroke *)&stroke, 1);

        if(stroke.code == SCANCODE_ESC) break;
    }

The code I commented out was something I tried that didn't work.

2

There are 2 answers

2
oblitum On BEST ANSWER

You need to tweak key states for UP and DOWN states to get key presses. Pay attention at the while loop that the variable device is returned by interception_wait, your commented out code would send events to what?? device is not initialized! Forget your code and try some more basic. Look at the line inside the loop with the interception_send call, make more two calls after it, but don't forget to change stroke.state before each call using INTERCEPTION_KEY_DOWN and INTERCEPTION_KEY_UP so that you fake down and up events. You'll get extra keys at each keyboard event.

Also, you may try use INTERCEPTION_FILTER_KEY_ALL instead of INTERCEPTION_FILTER_KEY_DOWN | INTERCEPTION_FILTER_KEY_UP. The arrow keys may be special ones as mentioned at the website.

1
박찬영 On
void ThreadMethod()
{
    while (true)
    {
        if (turn)
        {
            for (int i = 0; i < 10; i++)
            {
                Sleep(1000);
                InterceptionKeyStroke stroke;
                stroke.code = SCANCODE_Y;
                stroke.state = 0;
                interception_send(context, device, (const InterceptionStroke *)&stroke, 1);
                Sleep(1);
                stroke.state = 1;
                interception_send(context, device, (const InterceptionStroke *)&stroke, 1);
                turn = false;
            }
        }
        else Sleep(1);
    }
}
            
CreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE)ThreadMethod, NULL, NULL, NULL);
            
while (interception_receive(context, device = interception_wait(context), (InterceptionStroke*)&stroke, 1) > 0)
{
    if (stroke.code == SCANCODE_F5) turn = true;
            
    interception_send(context, device, (InterceptionStroke*)&stroke, 1);
            
    if (stroke.code == SCANCODE_ESC) break;
}