Sendinput() Not Equal to Pressing Key Manually on Keyboard in C++

C++ - Simulating keystrokes using SendInput method, failure to distinguish rightctrl key

This Code successfully stuffs RControl+ScrollLock+ScrollLock into the ScanCode app, however, sorry, the computer does not reboot like when it does when these keys are manually typed.

#define WINVER 0x0500
#include <windows.h>

int main()
{
// Must specify INPUT_KEYBOARD for all INPUT structs
INPUT ip[6] = {
{ INPUT_KEYBOARD },
{ INPUT_KEYBOARD },
{ INPUT_KEYBOARD },
{ INPUT_KEYBOARD },
{ INPUT_KEYBOARD },
{ INPUT_KEYBOARD },
};

Sleep(3000);

// Specify keys by scancode. For the VK_SCROLL, it was necessary
// to instead specify the wVK, otherwise VK==3 was received by ScanCode, instead
// of VK_SCROLL == 145!
//ip[0].ki.wVk = VK_CONTROL;
ip[0].ki.wScan = MapVirtualKey(VK_RCONTROL, MAPVK_VK_TO_VSC);
ip[0].ki.dwFlags = KEYEVENTF_SCANCODE | KEYEVENTF_EXTENDEDKEY;

ip[1].ki.wVk = VK_SCROLL;
ip[1].ki.wScan = MapVirtualKey(VK_SCROLL, MAPVK_VK_TO_VSC);
ip[1].ki.dwFlags = /*KEYEVENTF_SCANCODE*/ 0;

ip[2].ki.wVk = VK_SCROLL;
ip[2].ki.wScan = MapVirtualKey(VK_SCROLL, MAPVK_VK_TO_VSC);
ip[2].ki.dwFlags = /*KEYEVENTF_SCANCODE |*/ KEYEVENTF_KEYUP;

ip[3].ki.wVk = VK_SCROLL;
ip[3].ki.wScan = MapVirtualKey(VK_SCROLL, MAPVK_VK_TO_VSC);
ip[3].ki.dwFlags = /*KEYEVENTF_SCANCODE*/ 0;

ip[4].ki.wVk = VK_SCROLL;
ip[4].ki.wScan = MapVirtualKey(VK_SCROLL, MAPVK_VK_TO_VSC);
ip[4].ki.dwFlags = /*KEYEVENTF_SCANCODE |*/ KEYEVENTF_KEYUP;

//ip[5].ki.wVk = VK_CONTROL;
ip[5].ki.wScan = MapVirtualKey(VK_RCONTROL, MAPVK_VK_TO_VSC);
ip[5].ki.dwFlags = KEYEVENTF_SCANCODE | KEYEVENTF_KEYUP | KEYEVENTF_EXTENDEDKEY;

int i = _countof(ip);
int numSuccessful = SendInput(i, ip, sizeof(INPUT));
if (numSuccessful == i)
printf("Stuffed successful.\n");
else
{
printf("Succeeded with %d of %d; error %d\n", numSuccessful, i, GetLastError());
}

return 0;
}

I believe the reason is that SendInput() injects the keys into the layer above the keyboard driver, and it is the keyboard driver that is monitored for these keystrokes to initiate the BSOD.

Could not send backspace key using ::SendInput() to wordpad application

You are mixing up the virtual key and the scan code. The wVk member is the important one, the scan code will only be used it the virtual key is ambiguous. Fix:

kb.wVk   = vk;
kb.wScan = 0; // TODO: look at VkKeyScanEx()

Win32: SendInput Alt+Click not working in some programs

It works in most programs, it needs a small delay for some, but doesn't work at all in one of them.

"Most programs" check the Alt key state from inside the mouse message handler with correct synchronization. There are two correct ways:

  • Look at the modifier flags in the message parameters (only applicable to Control and Shift, NOT Alt)
  • GetKeyState()

"Needs a small delay for some" -- these programs check the Alt key state unsynchronized with the message delivery, probably with

  • GetAsyncKeyState()

but it could also mean the mouse message handler sets a flag and then some later code calls GetKeyState()


"doesn't work at all in one of them"

This program doesn't use the OS input queue (and its abstraction of keyboard state) at all for the behavior you are after, it reads the Alt key from the true keyboard, for example using Raw Input, DirectInput or the HID API. Usually you only see these techniques in games.

To make this "reads the true keyboard" program behave as if the Alt key is pressed, you'll need a USB keyboard simulator/driver sending real HID profile USB events, where the Raw Input portion of the OS will see them. And the program will still be able to detect a difference between "Alt key on keyboard #1" vs "Alt key on keyboard #2"



Related Topics



Leave a reply



Submit