Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Issue with WinAPI SendInput code

Tags:

c++

winapi

I am writing a program, and it is going well so far, however I have an issue with the following code:

void Send(string content) {
    unsigned int size = content.size();
    INPUT *inputs = new INPUT[size];

    for (unsigned int i = 0; i < size; i++) {
        inputs[i].type = 1;
        inputs[i].ki.wVk          = 0;//LOWORD(VkKeyScan(content.at(i)));
        inputs[i].ki.wScan        = content.at(i);
        inputs[i].ki.dwFlags      = KEYEVENTF_UNICODE | KEYEVENTF_SCANCODE;
        inputs[i].ki.time         = 0;
        inputs[i].ki.dwExtraInfo  = ::GetMessageExtraInfo();
    }

    SendInput(size, inputs, sizeof(*inputs)*size);

    for (unsigned int i = 0; i < size; i++) {
        inputs[i].ki.dwFlags &= KEYEVENTF_KEYUP;
    }

    SendInput(size, inputs, sizeof(*inputs)*size);
}

What I am trying to achieve is being able to send input like this:

Send(string("Hello World!"));

However, it does everything it should not, such as moving the cursor even though the type is set to the keyboard. At most, it outputs one character. As you see on line 2, I have an INPUT array. However, when I view this in the debugger, it appears simply as a single INPUT structure, rather than an array of structures.

I am using g++ with gdb debugger + Code::Blocks IDE.

Thanks guys.

EDIT

NEW CODE:

void Send(string content) {
    unsigned int size = content.size();
    INPUT *inputs = new INPUT[size];
    INPUT curr[1];

    ZeroMemory(inputs, sizeof(*inputs)*size);

    for (unsigned int i = 0; i < size; i++) {
        inputs[i].type = 1;
        inputs[i].ki.wVk          = 0;//LOWORD(VkKeyScan(content.at(i)));
        inputs[i].ki.wScan        = content.at(i);
        inputs[i].ki.dwFlags      = KEYEVENTF_UNICODE | KEYEVENTF_SCANCODE;
        inputs[i].ki.time         = 0;
        inputs[i].ki.dwExtraInfo  = ::GetMessageExtraInfo();
    }

    for (unsigned int i = 0; i < size; i++) {
        curr[0] = inputs[i];            // Current input
        int a = ::SendInput(1, (INPUT*)&curr, sizeof(curr));

        inputs[i].ki.dwFlags &= KEYEVENTF_KEYUP;

        curr[0] = inputs[i];
        int b = ::SendInput(1, (INPUT*)&curr, sizeof(curr));

        TCHAR *buff = new TCHAR[3];

        wsprintf(buff, "%i %i", a, b);

        MessageBox(NULL, buff, "SendInput return vals", 0);
    }
}

This still sends nothing.

like image 620
Shane Avatar asked Mar 03 '26 06:03

Shane


1 Answers

sizeof(*inputs)*size

This is wrong, the cbSize parameter is the size of one INPUT structure, not the total size of the array.

You would have discovered this if you hadn't thrown away the SendInput return value. checking return values is the most basic troubleshooting possible when things go wrong.

You also have a memory leak. And you should use ZeroMemory on the array before filling it in.

Finally, you're pressing all the keys before releasing any of them. If you want to type text, you should press and release each key in sequence, so that no more than one key is pressed at a time.

like image 183
Ben Voigt Avatar answered Mar 05 '26 21:03

Ben Voigt



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!