MX-4
MX-4

Reputation: 73

How to send hardware level keyboard input by program?

I have been using keybd_event for keyboard input by command line. However, want something that can send hardware level input, just like real keyboard.

Is there anything that suits my purpose?

I am using Windows as operating system.

Upvotes: 2

Views: 2528

Answers (2)

Remy Lebeau
Remy Lebeau

Reputation: 596001

keybd_event() is deprecated, use SendInput() instead.

SendInput() posts its simulated events to the same queue that the hardware driver posts its events to, as shown in the below diagram from Raymond Chen's blog:

When something gets added to a queue, it takes time for it to come out the front of the queue

image

Upvotes: 1

unlut
unlut

Reputation: 3775

I once used SendInput to control a game character. Game (icy tower?) was using directx input system (I think?) and somehow it was ignoring keybd_event calls but this method worked. I do not know how close to hardware you need to be but did this the trick for me. I used virtual key codes but turned them into scancodes for this answer.

UINT PressKeyScan(WORD scanCode)
{
    INPUT input[1] = {0};
    input[0].type = INPUT_KEYBOARD;
    input[0].ki.wVk = NULL;
    input[0].ki.wScan = scanCode;
    input[0].ki.dwFlags = KEYEVENTF_SCANCODE;

    UINT ret = SendInput(1, input, sizeof(INPUT));

    return ret;
}

UINT ReleaseKeyScan(WORD scanCode)
{
    INPUT input[1] = {0};
    input[0].type = INPUT_KEYBOARD;
    input[0].ki.wVk = NULL;
    input[0].ki.wScan = scanCode;
    input[0].ki.dwFlags = KEYEVENTF_SCANCODE | KEYEVENTF_KEYUP;


    UINT ret = SendInput(1, input, sizeof(INPUT));

    return ret;
}

To simulate press and release you use them sequentially (or you may create a separate function for press and release that use same INPUT structure).

WORD scanCodeSpace = 0x39;
PressKeyScan(scanCodeSpace);
ReleaseKeyScan(scanCodeSpace)

You can use MapVirtualKeyA to get scan code from virtual key code.

Upvotes: 2

Related Questions