Detecting simulated keyboard/mouse input
I might be wrong, but the on-screen keyboard (and other applications that simulate user input) most probably uses the SendInput API:
SendInput operates at the bottom level of the input stack. It is just a backdoor into the same input mechanism that the keyboard and mouse drivers use to tell the window manager that the user has generated input.
Source: http://blogs.msdn.com/b/oldnewthing/archive/2010/12/21/10107494.aspx
So there is probably no way to tell whether the input is coming from a "real" keyboard or not.
Detect if keyboard or mouse events are triggered by a software
The low-level keyboard/mouse hooks provided by SetWindowsHookEx()
report if input was generated by actual devices or injected by application code.
For a low-level keyboard hook, the hook provides a pointer to a KBDLLHOOKSTRUCT
structure, which has a flags
member that contains a LLKHF_INJECTED
flag for fake input.
For a low-level mouse hook, the hook provides a pointer to a MSLLHOOKSTRUCT
structure, which has a flags
member that contains either a LLMHF_INJECTED
or LLMHF_LOWER_IL_INJECTED
flag for fake input.
Either hook can return a non-zero value to block the input from being passed to the rest of the hook chain, and consequently to the target window.
Regarding the Raw Input API, according to (an older version of 1) the documentation for the GetRawInputDeviceInfo()
function:
hDevice [in, optional]
Type: HANDLEA handle to the raw input device. This comes from the lParam of the WM_INPUT message, from the hDevice member of RAWINPUTHEADER, or from GetRawInputDeviceList. It can also be NULL if an application inserts input data, for example, by using SendInput.
1: the highlighted note has been removed in the current version of the documentation, I do not know why.
So, the hDevice
that is reported by a WM_INPUT
message will be NULL for fake input.
however, it is not possible to block input with the Raw Input API. You still need a low-level hook for that.
How to tell real and virtual keypresses apart?
As it turns out the proper term for virtual key/mouse events is "injected" and the low level keyboard hook does provide a related flag in the KBDLLHOOKSTRUCT.
Now I modified the hook related event management so it lets through any events with the "LLKHF_INJECTED" flag, without suppressing or informing the main logic about it.
How to send hardware level keyboard input by program?
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.
Keyboard inputs in c without using a library that does everything for you
You will probably want to process the following two window messages in your message loop:
WM_KEYDOWN
WM_KEYUP
See the Microsoft documentation on Keyboard Input for further information.
Related Topics
Math Precision Requirements of C and C++ Standard
How to Overwrite Only Part of a File in C++
Why How to Call Base Template Class Method from Derived Class
When Do We Need to Pass the Size of Array as a Parameter
Write a Recursive Function That Reverses the Input String
How to Handle Key Press Events in C++
Is There Any C/C++ Library to Connect with a Remote Ntp Server
Inverse Fourier Transformation in Opencv
Program Is Generating Same Random Numbers on Each Run
Detecting Simulated Keyboard/Mouse Input
Why Do Reference Type Members Cause Implicitly-Declared Copy Assignment Operator to Be Deleted
Why Do Objects Returned from Bind Ignore Extra Arguments
Is Infinite Loop Still Undefined Behavior in C++ If It Calls Shared Library
Distinguish Between Single and Double Click Events in Qt
Get Sum of Values Stored in _M256D with Sse/Avx