SendInput to background window - c++

I want to send the mouse and keyboard input, which is recieved from android client, to games running on windows.
SendInput works for almost all games I have worked so far. But for SendInput to work the game must be a foreground window.
To solve that I used PostMessage(hwnd,...) with hwnd being handle to the game window. But this does not work if game is using DirectInput. That was solved by hooking GetDeviceState. Now another game I started working on is using WM_INPUT or raw input and I have to create raw input to make it work.
According to this MSDN Article
DirectInput is a set of API calls that abstracts input devices on the
system. Internally, DirectInput creates a second thread to read
WM_INPUT data, and using the DirectInput APIs will add more overhead
than simply reading WM_INPUT directly.
directInput works using WM_INPUT.
The SendInput function inserts the events in the INPUT structures
serially into the keyboard or mouse input stream. These events are not
interspersed with other keyboard or mouse input events inserted either
by the user (with the keyboard or mouse) or by calls to keybd_event,
mouse_event, or other calls to SendInput.
So SendInput is also providing abstraction.
All I want is to send the input to application independently even when its window is not in focus. That way I will be able to send input to multiple games at once. Is there any way to achieve this using one higher level API call like SendInput? Can this be done with SendInput? Is there any C/C++ library for that?

When registering your input device using the RAWINPUTDEVICE structure,
set dwFlags = RIDEV_EXINPUTSINK to receive input when the process is in the background.
Example:
RAWINPUTDEVICE rid;
rid.usUsagePage = 1;
rid.usUsage = 4; // Joystick
rid.dwFlags = RIDEV_EXINPUTSINK;
rid.hwndTarget = window;
if (!RegisterRawInputDevices(&rid, 1, sizeof(RAWINPUTDEVICE)))
return -1;

Related

How to retrieve key press/release event while GLFW window is in focus, but not process key event on the OS?

With the Win32 API you can hook keyboard events at different stages in this keyboard input model
If I was using the Win32 API, I could a create hook and retrieve the message from the system message queue, do "some stuff", then not send the message to the thread message queue. (I only want to cancel sending the message to the thread message queue if a a specific GLFW window is in focus)
But since I need my program to be cross platform, I'm just using a GLFW key callback to retrieve keyboard input when the GLFW window is in focus.
But if for example the user alt tabs (presses the Windows key on Windows, uses command + space on MacOS, etc.), I need to do "some stuff" with the keys they pressed without the user actually tabbing out of the GLFW window.
The only way the user should be able to drop focus of the GLFW window is if their cursor is out of the window's bounds and click out of it.
If the explanation of my problem is not so good, please let me know.

How to detect main keyboard connection and disconnection on Windows

I'm working on an application that uses Window's window and raw input APIs.
I can get input without too much difficulty and right now I'm trying to detect when devices are connected or disconnected from the application. To do so I'm listening to WM_INPUT_DEVICE_CHANGE and using GetRawInputDeviceInfo() to fetch device information.
My current issue is that, when having a mouse and keyboard connected, the OS detects three devices: two keyboards and a mouse. The mouse works fine but, due to having two different keyboards, I can't identify which one is actually the "main" one. When the mouse or keyboard are disconnected, one of the keyboard devices is removed. In order to have no keyboards, all devices must be disconnected.
Is there any simple way for detecting which keyboard is the "main" one? Or there isn't any concept of a "main" keyboard on this API?
Right now I have though the following "solutions":
First one would be to store the device handle when a key is pressed
and keep it as the main keyboard but this sounds a bit "hacky".
Second one would be to try to differentiate the "main" keyboard based on number of keys. Issue is that this also seems a bit hacky as keyboard
could vary in number of keys easily.
Although I don't deem it necessary, I'm providing a bit of code about how I'm checking connection and disconnection status for devices, just for completion.
// Read LPARAM from WM_INPUT_DEVICE_CHANGE and fetch the information.
HANDLE DeviceHandle = (HANDLE)LParam;
bool bIsConnected = WParam == GIDC_ARRIVAL;
if(!bIsConnected)
return;
// Get the device data.
RID_DEVICE_INFO DeviceInfoData;
UINT SizeData = sizeof(RID_DEVICE_INFO);
UINT DeviceResult = GetRawInputDeviceInfo((void*)LParam, RIDI_DEVICEINFO, &DeviceInfoData, &SizeData);
// Launch any callback based on device type read from dwType variable inside DeviceInfoData.
Many thanks :)
There is no such concept such as "main keyboard" in Windows API.
All keyboard button presses are posted to message queue as WM_KEYDOWN/WM_KEYUP and WM_INPUT.
With RawInput you can distinguish which keyboard sent particular input - but it is your decision which keyboard you want to hear (you can filter by keyboard handle for example).
Some mouse devices or USB mouse receivers can emulate HID keyboard for special things like macros or hotkey press etc. Thats probably why you're seeing second keyboard in a list.
Second one would be to try to differentiate the "main" keyboard based on number of keys. Issue is that this also seems a bit hacky as keyboard could vary in number of keys easily.
You cannot detect how many keys keyboard really have. RID_DEVICE_INFO_KEYBOARD has same fake info for any HID keyboard.
You can look at my test code here for example how to differentiate devices.
Also note that in some cases device handle is not provided with WM_INPUT. See details here.
UPDATE: If you're really want to detect number of keys that keyboard have - you can try to open keyboard device handle and use IOCTL_KEYBOARD_QUERY_EXTENDED_ATTRIBUTES IOCTL that may give you KEYBOARD_EXTENDED_ATTRIBUTES structure. Its PhysicalLayout field may have Keyboard Physical Layout (Usage ID: 0x2C3) value:
Value
Description
0x00
Unknown Layout
0x01
101 (e.g., US)
0x02
103 (Korea)
0x03
102 (e.g., German)
0x04
104 (e.g., ABNT Brazil)
0x05
106 (DOS/V Japan)
0x06
Vendor‐specific – If specified, VendorSpecificPhysicalLayout must also be specified.
This will work only with some newer keyboards that are supporting HID Usage Table Review Request 42: Consumer Page Keyboard Assist Controls extension (HID Features 0x2C1-0x2C6 under Generic Desktop(Keyboard) Top‐Level Application Collection).
Here is my example code:
KEYBOARD_EXTENDED_ATTRIBUTES extended_attributes{ KEYBOARD_EXTENDED_ATTRIBUTES_STRUCT_VERSION_1 };
DWORD len = 0;
if (!DeviceIoControl(interfaceHandle.get(), IOCTL_KEYBOARD_QUERY_EXTENDED_ATTRIBUTES, nullptr, 0, &extended_attributes, sizeof(extended_attributes), &len, nullptr))
return; // keyboard do not support 0x2C1-0x2C6 HID features
DCHECK_EQ(len, sizeof(extended_attributes));
// extended_attributes.PhysicalLayout - will have keyboard layout type

Are Windows Precision Touchpad click/tap events communicated through the WM_INPUT message? If not, how do I get them?

I'm in the middle of adding custom Windows Touchpad handling into my Windows C++ desktop application. From a high level, the app has its own cursor and objects that can be clicked. The cursor needs to be directly controlled by a Windows Precision Touchpad, and completely decoupled from the standard Windows mouse. I'm accomplishing this via processing raw input from WM_INPUT messages, and using low level mouse hooks to prevent controlling the normal mouse pointer.
I'm able to interpret single and multi-finger gestures just fine using the WM_INPUT data, but haven't figured out how to get "clicks" or "taps" from the touchpad. Legacy Mouse Input events will obviously not work for my use case since they:
Aren't global and require my app to be focused
Are generated by any connected mouse/pointing device, not just the touchpad I registered for.
Interact at the location of the Windows mouse pointer, which is not driving the cursor in my app.
Are clicks/taps contained in the WM_INPUT reports, and I'm just not able to find them, or is there another way I can capture raw clicks from only the touchpad in my application?
RAWMOUSE struct that comes with WM_INPUT mouse message contains usButtonFlags with mouse button up/down transition state.
You cannot get clicks/taps because AFAIK classic Win32 API is not suitable for touch input at all - it just emulating mouse in case of touchpad.
According to touchpad spec all compatible Windows Precision Touchpad's are HID devices that are sending touchpad data in their Input Reports. They should contain corresponding Top Level Collection Page 0x0D (Digitizers), Usage 0x05 (Touch Pad) - and this will be seen as separate HID device from Win32 user-mode. See sample HID Report Descriptor.
Knowing this you can register to receive touchpad data with RegisterRawInputDevices call. After that you'll receive WM_INPUT message with RAWHID struct for each tounchpad input report - this needs to be handled manually (according to device's Preparsed HID Report Descriptor Data etc).
It's not easy but doable.
See example code here.
Update: Also there are WM_TOUCH and WM_GESTURE messages available since Windows 7. Maybe its what you're looking for. Sample code.
you can use PostMessage(applicationWinhandle, WM_INPUT, wparam, mouseDeviceHandle) send WM_INPUT message to your application, and then hook GetRawInputData or GetRawInputBuffer to send data.

Log second keyboard events

I have my own keyboard and an USB barcode scanner that works like a second keyboard.
I would like to use the main keyboard to control the computer (as you usually do) and the second keyboard (that is actually the barcode scanner) to log all the input into a file.
Is this possible to do?
The point is, I could be on the internet, word, excel or whatever. I would use the main keyboard to write to that processes while in the background the second keyboard (barcode scanner) could be at the same time writing but to a log file. The program that I could be using in the moment would never know about the second keyboard input.
Thanks, all suggestions are very welcome.
You can use the Raw Input API to monitor keyboard events before the OS processes them. The API will tell you which device is sending each event, so you can log events from just the scanner.
However, the Raw Input API does not allow you to block input, so to block the scanner's events from being processed as normal keyboard events, you would need to use SetWindowsHookEx() to setup a keyboard hook that dismisses the events.
However, SetWindowsHookEx() does not report which device is sending each event, so you will have to coordinate the two APIs manually. When Raw Input detects a keyboard event, set a flag based on which device the event came from. When the hook detects the cooresponding event, check the flag and dismiss the event if the flag indicates the scanner device.
See Combining Raw Input and keyboard Hook to selectively block input from multiple keyboards on CodeProject.

How does 2 or more processes interact with the keyboard?

I have been thinking a lot over keyboard handling. How does it work? I can't seem to google me to a good explaining.
I know that a keyboard interrupt is made every time a key is pressed. The processor halts whatever it is processing and load the keyboard data from the keyboard buffer, storing it in a system level buffer.
But what happens next? Let's take a practical example. What happens when I run the following piece of code:
...
std::string s;
std::cin >> s;
....
Does the cin read from a user level representation of the system level keyboard buffer? That makes perfect sense in my head because then 2, or more processes can read from the same buffer, and by that way I don't loose any key presses. But does it work this way?
I know I'm talking in very general terms. The OS I'm using is OS X.
Except in rare situations, your keyboard and display are managed by a Window Manager: X11, Gnome, KDE, Carbon, Cocoa or Windows.
It works like this.
The keyboard driver is part of the OS.
The window manager is a privileged process, which acquires the device during startup. The window manager "owns" the device. Exclusively.
The interrupts go to OS.
The OS responds the interrupt by queueing. Eventually -- when there's nothing of a higher priority to do -- it captures the keyboard input from the interrupt and buffers it.
The owning process (the window manager) is reading this buffer. From this, it creates keyboard events.
Your application works through the window manager.
Example 1 -- You're running a command-line application. In a terminal window. When terminal window is front-most, the window manager directs events at the terminal window. Keyboard events become the stdin stream.
Example 2 -- you're running GUI application. In your own application's window. When your application's window is front-most, the window manager direct events at your application window. Keyboard events are available for your various GUI controls to process. Some keyboard events may cycle among the controls or active buttons.