How to simulate holding down a keyboard button in C++ - c++

I am trying to make a program that would simulate holding down a keyboard button.
This program is supposed to work in games, where holding down buttons such as W,A,S,D is required. I tested the program both in Grand Theft Auto V and Garry's Mod, but it didn't work in either of them.
I tried using SendInput and keybd_event functions for emulating the input with no luck.
#include <windows.h>
#define VK_W 0x57
using namespace std;
int main(){
while(1){
keybd_event(VK_W, 0, 0, 0);
Sleep(3000); //should hold W for 3 seconds
keybd_event(VK_W, 0, KEYEVENTF_KEYUP, 0);
Sleep(1000);
}
return 0;
}
I've created macros using Razer's keyboard software, which work perfectly, so there must be a way to simulate the key hold input.
I also tried creating an AutoHotkey script, which does work in Garry's Mod, but not in Grand Theft Auto V:
w::
SendInput {w down}
Sleep 3000
SendInput {w up}
This script holds W for 3 seconds when W is pressed.
I tried searching the web, but didn't find any working implementation.
EDIT: I searched around some more and found this: https://stackoverflow.com/a/3647975/1587051
It turns out I was using Unicode instead of keyboard scan codes combined with KEYEVENTF_SCANCODE flag. DirectInput games are now receiving the keystrokes correctly.

For reference sake, as it has already been answered in the comments, you have to use SendInput rather than SendMessage, when filling the INPUT structure required for the SendInput function make sure you combine your Flags with KEYEVENTF_SCANCODE to send hardware signals instead of virtual ones. These will be handled by DirectInput.
Source : Simulating Keyboard with SendInput API in DirectInput applications

Related

How do I get char directly from keyboard not through buffer?

I am making a game which has a character moves in 4 directions: up, down, left, right corresponding to W,S,A,D on the keyboard. The problem is when using getch() to get input from buffer, it always has a pause time after the first single keypress. For instance, when I hold 'A' button, it acts like: A(a short period of time)AAAAAAAAA.
How do I get rid of that delay time?
Any help would be appreciated.
(Answers in either C or C++ are all acceptable, since I am using graphics.h for this program, which requires C++ to run, but I mainly code in C).
I am using windows 10 64 bits.
For a non-blocking getch method I personally use this piece of code (in C):
#include <conio.h>
int getch_noblock(){
return _kbhit() ? _getch() : -1;
}
the _kbhit() method returns 0 if no key are pressed, otherwise returns a number if the keyboard input buffer is not empty.
the _getch() method read a char from the keyboard buffer.
It works only for Windows.
Documentation:
_khbit(): https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/kbhit?view=msvc-170
_getch(): https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/getch-getwch?view=msvc-170
By the way, surfing on the web I found an interesting method, but I've never tried or seen it:
https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/getch-nolock-getwch-nolock?view=msvc-170
getch() already bypasses buffer:
Prototype
int _getch(void);
Description
_getch obtains a character from stdin. Input is unbuffered, and this
routine will return as soon as a character is available without
waiting for a carriage return. The character is not echoed to stdout.
_getch bypasses the normal buffering done by getchar and getc.
And for your problem, as someone already said, you can use the kbhit() method

keybd_event not working for some applications

The keybd_event function as well as mouse input function are not functioning for a particular application.
I used the following code:
keybd_event(VK_LMENU, 0, KEYEVENTF_EXTENDEDKEY, 0);
keybd_event(VK_LMENU, 0, KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP, 0);
This is not working in 1 application out of many i tried,but that application is able to take input from the keyboard.
I also tried replacing the 2nd parameter with MapVirtualKey(VK_LMENU,MAPVK_VK_TO_VSC).
So, how is the application differentiating between simulated input and real input, and how do i send simulated strokes to the application(Some other c++ library function or some parameter twisting).
Thank You

Sending Keystrokes to a X Window

I am currently experimenting with xdotool to send keys to a process (I understand that it may not work for all processes that does not set _NET_WM_PID). I have trouble sending keystrokes to windows other from the focus. It does work if you are sending keystrokes to the CURRENTWINDOW. Below is the snippet that I used to test xdotool's functionality.
extern "C"{
#include <xdo.h>
}
//extern "C" xdo_window_search
#include <iostream>
#include <string.h>
using namespace std;
int main(){
xdo_t* p_xdo = xdo_new(NULL);
// Allocate memory for search query.
xdo_search_t s;
// Clear the allocated memory.
memset(&s, 0, sizeof(xdo_search_t));
// Set the search query.
s.pid = 1916;
s.max_depth = -1;
s.searchmask = SEARCH_PID;
s.require = xdo_search::SEARCH_ANY;
// Allocate memory for output
Window* windows;
int no_windows;
xdo_window_search(p_xdo,&s,&windows,&no_windows);
cout << no_windows << endl;
// Prints all windows' names with matching criteria
for( int i=0;i<no_windows;i++ ){
unsigned char * name;
int size;
int type;
xdo_get_window_name(p_xdo,windows[i],&name,&size,&type);
cout << i << ":" << name << endl;
}
for( int i=0;i<no_windows;i++ ){
xdo_type(p_xdo,windows[i],"Hello World",0);
}
//xdo_type(p_xdo,CURRENTWINDOW,"Hello World",0); // This does work.
return 0;
}
In additional to testing xdotool's functionality, I've looked into xdotool's source code. Interestingly, I found that they are using Xtest to send keystrokes to the focused window (CURRENTWINDOW) and X11's XSendEvent for other windows. I turned to xdotool because I couldn't get XSendEvent to work and Xtest cannot send keys to any other windows than the focused window.
Am I not using the xdotool correctly? Does xdotool not work with all *nix OS with X11?
[I am running this on Ubuntu 13.04.]
EDIT
So, it looks like that does work but not for all windows that it finds. For example, it works for firefox but not gedit and gnome-terminal although it found gedit and gnome-terminal by its pid. It behaves differently if I used CURRENTWINDOW.
So, it would be great if someone can explain why is this so. Like, is it related the force send flag in an XEvent?
Directly from the xdotool manual:
SENDEVENT NOTES
If you are trying to send key input to a specific window, and it does
not appear to be working, then it's likely your application is ignoring
the events xdotool is generating. This is fairly common.
Sending keystrokes to a specific window uses a different API than
simply typing to the active window. If you specify 'xdotool type
--window 12345 hello' xdotool will generate key events and send them
directly to window 12345. However, X11 servers will set a special flag
on all events generated in this way (see XEvent.xany.send_event in
X11's manual). Many programs observe this flag and reject these events.
It is important to note that for key and mouse events, we only use
XSendEvent when a specific window is targeted. Otherwise, we use XTEST.
Some programs can be configured to accept events even if they are
generated by xdotool. Seek the documentation of your application for
help.
Specific application notes (from the author's testing): * Firefox 3
seems to ignore all input when it does not have focus. * xterm can be
configured while running with ctrl+leftclick, 'Allow SendEvents' *
gnome-terminal appears to accept generated input by default.

SendInput not working for hold key 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().

Keyboard / Mouse input in C++

I'm wondering how to accept keyboard and mouse input in C++, using Visual Studio 2010, for Windows 7 32-bit.
--EDIT: I forgot to mention that I need keyboard / mouse input without interrupting the flow of the program. Something like a listener. I don't want to have to pause the program and ask for input, and then have the user type it out and press enter. What I'm looking for is more like:
If user presses W, S, A, D -> something happens.
Or: If user presses leftmousebutton in -> something happens.
I have to mention that I'm still very new to programming as a whole. I know basic OOP programming but that's about it. I'm definitely sure that this will involve things I don't know about yet, and I don't mind, I just ask that you explain it thoroughly, and possibly give an example so I know how to use it.
Thanks.
keyboard / mouse input without interrupting the flow
#include <windows.h>
#include <iostream>
using namespace std;
int main()
{
HANDLE hIn;
HANDLE hOut;
COORD KeyWhere;
COORD MouseWhere;
COORD EndWhere;
bool Continue = TRUE;
int KeyEvents = 0;
int MouseEvents = 0;
INPUT_RECORD InRec;
DWORD NumRead;
hIn = GetStdHandle(STD_INPUT_HANDLE);
hOut = GetStdHandle(STD_OUTPUT_HANDLE);
cout << "Key Events : " << endl;
cout << "Mouse Events : " << flush;
KeyWhere.X = 15;
KeyWhere.Y = 0;
MouseWhere.X = 15;
MouseWhere.Y = 1;
EndWhere.X = 0;
EndWhere.Y = 3;
while (Continue)
{
ReadConsoleInput(hIn,
&InRec,
1,
&NumRead);
switch (InRec.EventType)
{
case KEY_EVENT:
++KeyEvents;
SetConsoleCursorPosition(hOut,
KeyWhere);
cout << KeyEvents << flush;
if (InRec.Event.KeyEvent.uChar.AsciiChar == 'x')
{
SetConsoleCursorPosition(hOut,
EndWhere);
cout << "Exiting..." << endl;
Continue = FALSE;
}
break;
case MOUSE_EVENT:
++MouseEvents;
SetConsoleCursorPosition(hOut,
MouseWhere);
cout << MouseEvents << flush;
break;
}
}
return 0;
}
There are a number of related concepts behind this.
At the very low level, the keyboard and the mouse are hardware devices that generates some "interrupts" (in the form of electric signals) to the CPU.
The operating system provides some drivers that handle such interrupts by decoding the device communication specific protocol, and "standardizing" (at OS level) those signals in the form of events.
With "console applications", the operating system handles those events (the keyboard in particular) by filling up an input buffer (essentially a char[]) that is made accessible as a "virtually infinite sequence of characters" (complicated name for "file") named "CON", thus mimicking the "infinite teletype model" of the early days computers.
In a C++ program, the standard library -at program startup- associates to that "file" the std::cin and std::cout stream objects, so you can read the input character sequence using the std::istream functions and operators.
With "graphical applications", unfortunately, there is no "early days model" to mimic, and "events" are left available as the operating system native structure.
Different operating system differs in the way such events are represented and handled, but certain similitude can be seen.
For Windows (since your question is about), a typical program retrieves those events in sequence with a "message loop" in which calling certain OS APIs.
In that loop, the typical program will also give call another OS API to dispatch those event to appropriate "call-back" procedure, associated to a previously created "window".
That callback procedure has to detect the event code, cast the parameter as appropriate and manage them doing the action required.
A more precise detail can be seen with a WIN32 programming tutorial like http://www.winprog.org/tutorial/.
The most of the code is essentially C, since C is the language the API are formalized.
For C++, a number of libraries have then been written to represent OS objects is the form of C++ classes, and mapping the OS APIs to those classes members.
These libraries can be either OS specific (like MFC, WTL ...) or "multi-platform" (they exist in different version, mapping the API of various OSs into a same C++ interface) like WxWidget, Qt, Gtk, Fltk ...
Hope this can give you more hints to think about.
If you're writing a console application, you can use scanf or cin to get keyboard input. Console applications don't have any support for the mouse.
If you're writing a GUI application, you'll build the app out of standard windows controls that have built-in behaviors for mouse and keyboard input. You can use these re-usable controls as is, or you can augment them to make them behave exactly how you want for your application.
For example, in a GUI application, there's a standard edit control you can use that the user can type into. Your program receives messages when the user enters text into it, and based on those messages, or on other events, you can retrieve the text and do things with it as required by your program.
Windows or Console?
If console, use:
std::cin >> myVar;