SendInput not working for hold key C++ - c++

I have this bit of code which uses SendInput to send a key press but it doesn't work for when I want to long hold a key (eg long hold 'a' would return 'aaaaaaaaa' in notepad).
Now I have looked all over google and the only way I can see to get around this is to keep sending the input if I want a long hold. I don't want to do that as this will just simulate 'a' being pressed over and over again.
keyboard.wVk = 0;
keyboard.wScan = MapVirtualKey(key, 0);
keyboard.dwFlags = KEYEVENTF_SCANCODE;
if (index_vector_no)
pressed[index_vector_no] = true;
keyboard.dwExtraInfo = 0;
input.type = INPUT_KEYBOARD;
input.ki = keyboard;
SendInput(1, &input, sizeof (input));
So I would like some answers to the following questions:
A) Am I right in thinking there is no way around this using SendInput and why doesn't it work for long hold?
B) What is an alternative method for successfully being able to send key down and key up signals. Preferably sending the keys to windows and not just to a particular application.
C) Is there a good lightweight C++ library I can use that handles global keyboard and mouse simulation?
Thanks in advance! =)
EDIT: Take a look at this post for more details of my problem: http://www.experts-exchange.com/Programming/Languages/Visual_Basic/Q_20833788.html

Repeating keystrokes is a feature of the keyboard controller, not of Windows or SendInput. You can certainly emulate it with a timer, repeatedly calling SendInput().

Related

How to use DeviceIOControl to send keyboard press to a video game?

I am trying to make a way of passing keyboard and mouse inputs over a LAN connection. While I have been successful at doing this using the SendInput() function for things like Notepad and Visual Studio, the inputs are not registered in many video games. After doing some research, it appears that I'll need to use DeviceIOControl to accomplish the task, however I have no idea how I am supposed to do this when the keycodes have to be determined at runtime.
I'm not sure if I can just arbitrarily set the hDevice parameter to the incoming keycode or not, or what the code would look like in the end.
If it helps, the below code is what is currently being used to input key presses. The server receives a string which is parsed out to determine the key press and the state of the key (whether it's a key up or key down event). This information is passed as the parameters to this function:
void keyPress(WORD k, int state)
{
INPUT Inputs;
std::cout<<"Key="<<k<<", state="<<state<<std::endl;
Inputs.type=INPUT_KEYBOARD;
Inputs.ki.wVk=k;
if(state==1)
{
Inputs.ki.dwFlags=0;
SendInput(1, &Inputs, sizeof(INPUT));
}
else
{
Inputs.ki.dwFlags=KEYEVENTF_KEYUP;
SendInput(1, &Inputs, sizeof(INPUT));
}
if((int)k!=0) //Keycode of 0 means that the last key pressed is being held down.
{
LastKey=k;
key[ 0]=LastKey;
}
}
Also, if I am going down the wrong rabbit hole and there is a better solution, please let me know!
Thank you,

Get any key from keyboard in C++ including keys like control

I'm programming in C++ and have run into a wall.
I need to get input from the keyboard. The problem is that I also need to get input from keys like control, scroll lock, windows key, etc. I also need to be able to differentiate between the numpad and regular numbers 0-9.
I tried using _getch(). While it can get keys like arrow keys and the numpad, I can't get keys like control, shift and scroll lock.
Does anyone have any suggestions?
There is no standard way to do this because C++ does not assume the system even has all those things.
A good solution for what you are trying to do is the SDL library. Look here:
https://www.libsdl.org/
I see the word "windows key" so I'm assuming you're programming for Windows
Use WinAPI ReadConsoleInput
HANDLE hInput = GetStdHandle(STD_INPUT_HANDLE);
INPUT_RECORD ir;
DWORD read;
if (!ReadConsoleInput(hInput, &ir, 1, &read) || read == 0) {
// Something went wrong
}
if (ir.EventType == KEY_EVENT) {
// Do stuff here
}
Refer to KEY_EVENT_RECORD for more information. You can get control keys states from
ir.Event.KeyEvent.dwControlKeyState
This is an example provided by Microsoft.

Activate windows "Alt Tab" switcher with SendInput

I need to show the windows switcher with SendInput. Another question I asked explains the reason of doing this. Shortly speaking, when I am holding Alt Tab to switch to other apps, my app may fire a key stroke using SendInput, which will interrupt current switcher, and this is why I need to refire a Alt Tab. Currently I am working on posting another tab key stroke (I am still holding alt when switching) or the entirely alt down + tab down & up. But with alt holding, a single tab stroke sent by SendInput will not trigger the switcher. And the entire combined key does not work neither. Here's some test code.
#include <windows.h>
#include <WinUser.h>
#include <iostream>
int main(void) {
Sleep(1000 * 3);
INPUT tabinput[2];
tabinput[0].type = INPUT_KEYBOARD;
tabinput[0].ki = {0x09, 0}; // KEY_TAB = 0x09
tabinput[1].type = INPUT_KEYBOARD;
tabinput[1].ki = {0x09, 0, KEYEVENTF_KEYUP};
SendInput(2, tabinput, sizeof(INPUT));
getchar();
}
I'm trying to fire a tab key stroke delayed 3s. I'am holding the alt key. This doesn't work. But the tab key is triggered, because When I run this code and switch to a text editor or something, there will be a tab event. My system is win8.1 64bit.
Windows 8 is blocking you.
In the Windows 8 security model, apps don’t have the privileges required to be a UI automation client. But you can write a desktop app that acts as an automation client with your app as the target. To do this, your desktop automation client app needs to be built with UIAccess permissions.
Change the manifest to UIAccess="true" and require administrator priviledge, created a certificate, sign the application with that certificate, put it in a location under Program Files, and run it. As explained here
https://msdn.microsoft.com/en-us/library/windows/desktop/dd979761.aspx?f=255&MSPPError=-2147217396
and here
https://social.msdn.microsoft.com/Forums/windowsdesktop/en-US/4b6dbc43-a026-4957-9178-91d2001e2d0d/windows-8-block-alttab-simulation#291eb5b4-f6d2-49b6-83db-658bd832f2c9
plus this
https://msdn.microsoft.com/en-us/library/ms742884.aspx?f=255&MSPPError=-2147217396
and this
https://translate.google.com/translate?sl=it&tl=en&js=y&prev=_t&hl=en&ie=UTF-8&u=http%3A%2F%2Fblogs.msdn.com%2Fb%2Fitasupport%2Farchive%2F2009%2F09%2F16%2Fsendsas-step-by-step.aspx&edit-text=&act=url
Arrays are 0-indexed, but you are populating the array using 1-based indexes. So you are not populating the first array element, and are trashing memory after the last array element. Use this instead:
int main(void) {
Sleep(1000 * 3);
INPUT tabinput[2];
tabinput[0].type = INPUT_KEYBOARD;
tabinput[0].ki = {VK_TAB, 0};
tabinput[1].type = INPUT_KEYBOARD;
tabinput[1].ki = {VK_TAB, 0, KEYEVENTF_KEYUP};
SendInput(2, tabinput, sizeof(INPUT));
getchar();
}

Detecting keyboard hotkeys when DirectInput DIK constants fail

I want to assign tasks and functions to the additional keys of my keyboard (e.g. Mute,VolumeChange, Browser,...). Now, I do know that DirectInput implements a full list of those keys like DIK_MUTE (msdn link). Unluckily, none of the keys are assigned to those values and obviously every key pressed is recognized as No. 128 by DirectInput.
But Windows seems to have no problem distincting between those keys as some of them are functional and for instance open applications. Is there a way to tweak this issues with or without DirectInput so that i can detect those keys also in fullscreen DX/OpenGL applications?
IDirectInputDevice8* device;
BYTE arrKey[256] = {0};
if FAILED(device->GetDeviceState(sizeof(BYTE)*256,arrKey))
return false;
BYTE byKey = ReportPressedKey(arrKey, sizeof(BYTE*)*256);
// byKey = 128 (DIK_MUTE, DIK_VOLUMEUP,DIK_NEXTTRACK,...)

How to repeat key strokes with SendInput?

I'm writing a little tool in VC++ to record key strokes to replay them later, a macro recorder. It works quite nice already, using a keyboard hook function that reads each and every key press and release event. The playback works with the SendInput() function and generally also works fine - except for repeating key strokes. Pressing a key several times after releasing it every time is no problem. But pressing it and holding it down, for the input character to be repeated, can be recorded but can only be replayed in some applications. Some accept and enter the character multiple times, some do it only once. (It is reproducible which does which.) The macro recorder itself also sees the held down key pressed just a single time during playback, through its monitoring hook.
So, how can I make SendInput send multiple subsequent key strokes of a single key without adding key release events on my own in between? Sending a sequence of [press] [press] [press] ... [release] doesn't always work.
You could send Multiple keys in one SendInput calls, but you will still need to set keyup flags on every char to get same results on every type of keystrokes.
if you need to send "aa", you can do like this.
INPUT input[4];
input[0].type = INPUT_KEYBOARD;
input[0].ki.wVk = 0;
input[0].ki.wScan = 'a';
input[0].ki.dwFlags = 0;
input[1].type = INPUT_KEYBOARD;
input[1].ki.wVk = 0;
input[1].ki.wScan = 'a';
input[1].ki.dwFlags = KEYEVENTF_KEYUP;
input[2].type = INPUT_KEYBOARD;
input[2].ki.wVk = 0;
input[2].ki.wScan = 'a';
input[2].ki.dwFlags = 0;
input[3].type = INPUT_KEYBOARD;
input[3].ki.wVk = 0;
input[3].ki.wScan = 'a';
input[3].ki.dwFlags = KEYEVENTF_KEYUP;
SendInput(4, input, sizeof(INPUT));
I'm not sure about your exact sequence of keystrokes, but I had a similar issue recently. I wrote a tiny Win32 tool [1] to send keys when a global shortcut key is pressed. When characters were repeated, e.g., "aaabc", the repeated characters were lost. I tried many combinations of KeyDown and KeyUp, but repeated characters were always lost.
Then I found this blog post: https://batchloaf.wordpress.com/2014/10/02/using-sendinput-to-type-unicode-characters/
While the author does not specifically discuss repeating characters, it inspired me to try SendInput() with only a single INPUT structure. This technique works very well for me.
In short:
Call SendInput() with only a single INPUT structure.
To simulate a single typed (regular) key, e.g., z, try this:
Send single KeyDown event: ki.dwFlags = KEYEVENTF_UNICODE
Send single KeyUp event: ki.dwFlags = KEYEVENTF_UNICODE | KEYEVENTF_KEYUP
[1] https://github.com/kevinarpe/win32/tree/master/send_input
Many people experience issues with the keyup and keydown calls being "dismissed" or "dropped", and alot of people have resolved their problems by placing a small buffer amount of time between the two, to assure that all commands are transfered:
sendinput alt keydown
sendinput 3 keydown
sleep 50
sendinput 3 keyup
sendinput alt keyup
There's also a SendInput.SendWait command....
Cheers
As far as I know, the way it works is if a key down event is received with no key up event for a certain period of time (the repeat delay), the key is considered "repeating" until a key up occurs.
Since sending press, press, press, release doesn't work always, have you tried recording the time between the key down and key up, then repeating the commands in that same time? It becomes real time, but it should trigger the same repeat actions that way.
I can't think of any other way to end up with the same amount of "key repeats" as the original since those aren't recorded as individual key presses.