1

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 Answers2

2

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.

oblitum
  • 11,380
  • 6
  • 54
  • 120
  • Just to clarify, the way your explaining it, that is just to get more keypresses from when I press one key correct? I am looking for a way to actually make key presses without ever pushing a key. For example, if I click a button in my application, I could make it send a keypress for "control+a". –  Jan 12 '12 at 19:37
  • You can do it normally, you just need to identify the keyboard id you want to fake input, and save it in some variable, in this case the device id is being saved at the variable device. After knowing the id associated with a given device, you can send events anyway you want. Commonly, PS/2 devices get id equals to INTERCEPTION_KEYBOARD(0), USB devices get INTERCEPTION_KEYBOARD(1) or higher. – oblitum Jan 12 '12 at 23:46
0
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;
}
박찬영
  • 1
  • 1
  • While this code may solve the question, [including an explanation](//meta.stackexchange.com/q/114762) of how and why this solves the problem would really help to improve the quality of your post, and probably result in more up-votes. Remember that you are answering the question for readers in the future, not just the person asking now. Please [edit] your answer to add explanations and give an indication of what limitations and assumptions apply. – Adrian Mole Jul 09 '22 at 09:33