Search code examples
c++winapivectorinputsendinput

Array of INPUT / vector doesn't work with SendInput


So I'm trying to use SendInput in order to send multiple key presses / key releases at the same time. The array and vector have the correct information but for some reason it's just not pressing anything. Why?

I have tried picking one element from the array and vector and using SendInput to press / release the key and it works fine.

#include <iostream>
#include <Windows.h>
#include <vector>

class movement
{
public:
    std::vector<INPUT> inputs;

    void Key(std::vector<INPUT> INPUTkeys)
    {
        INPUT * inputs = new INPUT[INPUTkeys.size()];

        for (int i = 0; i < INPUTkeys.size(); i++)
            inputs[i] = INPUTkeys.at(i);

        SendInput(INPUTkeys.size(), inputs, sizeof(inputs));

        delete[] inputs;
    }

    void prepareInput(INPUT &input, int key, bool down)
    {
        input.type = INPUT_KEYBOARD;
        input.ki.dwExtraInfo = NULL;
        input.ki.time = NULL;
        input.ki.wScan = NULL;
        input.ki.wVk = key;

        if (down)
            input.ki.dwFlags = 0;
        else
            input.ki.dwFlags = KEYEVENTF_KEYUP;
    }
};

movement oMovement;

void main()
{
    while (!GetAsyncKeyState(VK_SPACE))
        Sleep(1);

    std::vector<INPUT> inputs;

    INPUT input;

    oMovement.prepareInput(input, 'U', true);
    inputs.push_back(input);
    oMovement.prepareInput(input, 'S', true);
    inputs.push_back(input);
    oMovement.prepareInput(input, 'X', true);
    inputs.push_back(input);

    oMovement.Key(inputs);
    inputs.clear();

    oMovement.prepareInput(input, 'U', false);
    inputs.push_back(input);
    oMovement.prepareInput(input, 'S', false);
    inputs.push_back(input);
    oMovement.prepareInput(input, 'X', false);
    inputs.push_back(input);

    oMovement.Key(inputs);
    inputs.clear();

    system("pause");
}

Solution

  • You are passing size of pointer as third parameter to SendInput while it should be size of INPUT struct. You also should check the result (at least in debug mode):

    void Key(std::vector<INPUT> & INPUTkeys) // pass by reference to prevent copying
    {
       ::UINT const sent_events_count
       {
           SendInput
           (
               static_cast<::UINT>(INPUTkeys.size())
           ,   INPUTkeys.data()
           ,   sizeof ::INTPUT
           )
       };
       assert(INPUTkeys.size() == sent_events_count);
    }