Program doesn't run functions repeatedly (C++) - c++

I am making an autoclicker. The "ClickLoop" function I found on another SO post works, but I am trying to add a key to toggle the autoclicker on and off.
This is my code so far:
#include <windows.h>
#include <iostream>
#include <chrono>
#include <thread>
#include <random>
bool on = false;
void tick () {
if(GetKeyState('x') & 0x8000) {
on = !on;
}
tick();
};
void WINAPI ClickLoop(int delay) {
std::cout << "test" << std::endl;
while ((GetAsyncKeyState(VK_LBUTTON) & 0x8000) == 0) {
Sleep(1);
}
int nCurrKeyState = GetKeyState(VK_LBUTTON);
int nPrevKeyState;
do {
if (on) {
INPUT Input;
ZeroMemory(&Input, sizeof(INPUT));
Input.type = INPUT_MOUSE;
Input.mi.dwFlags = MOUSEEVENTF_LEFTUP;
SendInput(1, &Input, sizeof(INPUT));
Input.mi.dwFlags = MOUSEEVENTF_LEFTDOWN;
SendInput(1, &Input, sizeof(INPUT));
// Delay in MS
Sleep(delay);
nPrevKeyState = nCurrKeyState;
nCurrKeyState = GetKeyState(VK_LBUTTON);
if ((GetAsyncKeyState(VK_LBUTTON) & 0x8000) == 0)
break;
} else {
break;
}
} while (nCurrKeyState != nPrevKeyState);
ClickLoop(delay);
}
int main() {
int delay;
std::cout << "Delay in milliseconds: ";
std::cin >> delay;
tick();
ClickLoop(delay);
return 0;
}
I then use G++ to compile the code:
g++ main.cpp -o main
After running the "main" executable, I find that it starts up, asks me for the delay and then stops after a couple of seconds.
Why does this happen?

void tick () {
...
tick();
}
This is an endless recursion loop. Once main() calls tick(), the program is stuck in this loop and never reaches ClickLoop().
void WINAPI ClickLoop(int delay) {
...
ClickLoop(delay);
}
This is also an endless recursion loop.
You need to get rid of these recursive loops.
Another problem I see is that you are using GetKeyState() in places, but GetKeyState() depends on the calling thread having a message loop to process WM_(L|M|R)BUTTON(DOWN|UP) window messages to update the thread's internal keyboard state. But there is no window or message loop in this code.
GetAsyncKeyState() does not depend on a window or a message loop.

Related

C++ Autoclicker not exitising loop

so I am trying to make an auto clicker that runs run you hold down the mouse button My current loop looks like However when I run this it just clicks for ever and ever and does not stop when I release the mouse button. Thanks in advance. ps pressed is defaulted as false.
while(GetAsyncKeyState(VK_LBUTTON)&&!pressed)
{
pressed = true;
INPUT Input = { 0 };
// left down
Input.type = INPUT_MOUSE;
Input.mi.dwFlags = MOUSEEVENTF_LEFTDOWN;
::SendInput(1, &Input, sizeof(INPUT
// left up
::ZeroMemory(&Input, sizeof(INPUT));
Input.type = INPUT_MOUSE;
Input.mi.dwFlags = MOUSEEVENTF_LEFTUP;
::SendInput(1, &Input, sizeof(INPUT
cout << "pressed"
sleep_for(milliseconds(100));
pressed = false;
}
First of all, the return value of GetAsyncKeyState has two bits, we only need its highest bit, so we use GetAsyncKeyState(VK_LBUTTON)&0x8000.
Secondly, the signal sent at the end of the loop simulates the operation of the mouse release, so the return value of GetAsyncKeyState() is 0, and you cannot continue to enter the loop to simulate the click operation of the mouse. Therefore, we should first simulate the mouse release operation, and then simulate the mouse click operation, so that the function can be realized normally.
Finally, SendInput() supports multiple operations at a time, we can build an array of INPUT, and then send the required signals at once, so that you can more easily achieve your needs.
Here is the code you can refer:
#include <windows.h>
#include <iostream>
using namespace std;
#define INPUT_COUNT 2
int main(int argc, char* argv[])
{
int pressed = false;
while (true)
{
while (GetAsyncKeyState(VK_LBUTTON) & 0x8000)
{
pressed = true;
INPUT Input[INPUT_COUNT] = { 0,0 };
Input[0].type = INPUT_MOUSE;
Input[0].mi.dwFlags = MOUSEEVENTF_LEFTUP;
Input[1].type = INPUT_MOUSE;
Input[1].mi.dwFlags = MOUSEEVENTF_LEFTDOWN;
::SendInput(INPUT_COUNT, Input, sizeof(INPUT));
cout << "pressed" << endl;
pressed = false;
Sleep(100);
}
}
return 0;
}

How do I program a parallel keyboard input

As written before, I would like to know how parallel keyboard input works.
This is my code so far:
cout << "Enter time for Key A: ";
cin >> timeA;
cout << "Enter time for Key B: ";
cin >> timeB;
while (1)
{
Sleep(timeA);
INPUT ip;
ip.type = INPUT_KEYBOARD;
ip.ki.time = 0;
ip.ki.dwFlags = KEYEVENTF_UNICODE; // Specify the key as a unicode character
ip.ki.wScan = 'A'; // Which keypress to simulate
ip.ki.wVk = 0;
ip.ki.dwExtraInfo = 0;
SendInput(1, &ip, sizeof(INPUT));
Sleep(timeB);
ip.type = INPUT_KEYBOARD;
ip.ki.time = 0;
ip.ki.dwFlags = KEYEVENTF_UNICODE; // Specify the key as a unicode character
ip.ki.wScan = 'B'; // Which keypress to simulate
ip.ki.wVk = 0;
ip.ki.dwExtraInfo = 0;
SendInput(1, &ip, sizeof(INPUT));
}
It works, but I would like to reach, that e.g. the Letter A is being pressed every 500ms and the Letter B is pressed every 1s. How would I do that?
This is a timer class. You can create an object and call it like:
timer timer_1(time_in_milliseconds, true_if_async, &function_name, argument_1, arg_2, ...);
This way you can run your functions after a certain amount of time has passed, you can run multiple functions together with async as well or just use sync and queue them. Your choice.
Threads is the best solution for your problem.
class timer
{
public:
template <class Callable, class... Arguments>
timer(int after, const bool async, Callable&& f, Arguments&&... args)
{
std::function<typename std::result_of<Callable(Arguments...)>::type()> task(bind(forward<Callable>(f), forward<Arguments>(args)...));
if (async)
{
thread([after, task]()
{
std::this_thread::sleep_for(std::chrono::milliseconds(after));
task();
}).detach();
}
else
{
std::this_thread::sleep_for(std::chrono::milliseconds(after));
task();
}
}
};
Here's a small example usage:
void say(const string& word)
{
cout << "Hello, " << word << "!\n";
}
int main(int argc, char* argv[])
{
while (true)
{
timer timer1(500, false, &say, "pyreN - A");
timer timer2(1000, false, &say, "pyreN - B");
}
}

C++ closing my process via hotkey [duplicate]

This question already has an answer here:
C++ Hotkey to run function
(1 answer)
Closed 5 years ago.
I'm trying to code a little "virus" (just a fun joke program which messes around with the cursor and makes some beep sounds). However, I want to close this process with my F9 key.
Here's what I have so far:
void executeApp()
{
while (true)
{
if (GetAsyncKeyState(VK_F9) & 0x8000)
{
exit(0);
}
Sleep(200);
}
}
I made a thread that runs this function. However, when I run my entire code and press F9, the process still runs. Only when I press it 2-3 times, it comes up with an Error: "Debug Error! abort() has been called."
It would be nice if someone knows how I can kill my process via a hotkey.
Here is the whole code of the program:
#include <iostream>
#include <stdio.h>
#include <windows.h>
#include <conio.h>
#include <ctime>
#include <thread>
#include <random>
using namespace std;
//random number gen for while loops in cursor/beep functions.
random_device rd;
mt19937 eng(rd());
uniform_int_distribution<> distr(1, 100);
//variables used for this program.
int random, Dur, X, Y, Freq;
HWND mywindow, Steam, CMD, TaskMngr;
char Notepad[MAX_PATH] = "notepad.exe";
char Website[MAX_PATH] = "http:\\www.google.de";
//functions
void RandomCursor(), Beeper(), OpenStuff(), executeApp();
//threads
thread cursor(RandomCursor);
thread beeps(Beeper);
thread openstuff(OpenStuff);
thread appexecute(executeApp);
int main()
{
srand(time(0));
random = rand() % 3;
system("title 1337app");
cursor.join();
beeps.join();
appexecute.join();
return 0;
}
//void SetUp()
//{
// mywindow = FindWindow(NULL, "1337app");
// cout << "oh whats that? let me see.\n";
// Sleep(1000);
// ShowWindow(mywindow, false);
//}
void Beeper()
{
while (true)
{
if (distr(eng) > 75)
{
Dur = rand() % 206;
Freq = rand() % 2124;
Beep(Dur, Freq);
}
Sleep(1500);
}
}
//void OpenStuff()
//{
// ShellExecute(NULL, "open", Notepad, NULL, NULL, SW_MAXIMIZE);
// ShellExecute(NULL, "open", Website, NULL, NULL, SW_MAXIMIZE);
//}
void RandomCursor()
{
while (true)
{
if (distr(eng) < 50)
{
X = rand() % 302;
Y = rand() % 202;
SetCursorPos(X, Y);
}
Sleep(500);
}
}
void executeApp()
{
while (true)
{
if (GetAsyncKeyState(VK_F9) & 0x8000)
{
exit(0);
}
Sleep(200);
}
}
GetAsyncKeyState() returns two pieces of information, but you are looking at only one of them and it is the one that is not very useful to your code.
Per the documentation:
If the function succeeds, the return value specifies whether the key was pressed since the last call to GetAsyncKeyState, and whether the key is currently up or down. If the most significant bit is set, the key is down, and if the least significant bit is set, the key was pressed after the previous call to GetAsyncKeyState.
When you AND the return value with 0x8000, you are testing only the most significant bit, which means you are testing only if the key is currently down at the exact moment that GetAsyncKeyState() is called. Which is why it usually takes several presses, or holding down the key for awhile, for your code to detect the key press. You have a race condition in your code.
You should also AND the return value with 0x0001 to check if the key has been pressed and released in between the times that you call GetAsyncKeyState():
if (GetAsyncKeyState(VK_F9) & 0x8001)
Or simply:
if (GetAsyncKeyState(VK_F9) != 0)
That being said, what you really should do instead is actually monitor the keyboard and let it tell you when the key is pressed. Either:
use RegisterHotKey(), handling WM_HOTKEY window messages.
use RegisterRawInputDevices(), handling WM_INPUT window messages.
use SetWindowsHookEx() to monitor key presses using a callback function instead of a window (but you still need a message loop).
Update: Since your code does not have an HWND of its own, try SetWindowsHookEx(), eg:
#include <iostream>
#include <stdio.h>
#include <windows.h>
#include <conio.h>
#include <ctime>
#include <thread>
#include <random>
using namespace std;
//random number gen for while loops in cursor/beep functions.
random_device rd;
mt19937 eng(rd());
uniform_int_distribution<> distr(1, 100);
//variables used for this program.
int random, Dur, X, Y, Freq;
HWND mywindow, Steam, CMD, TaskMngr;
char Notepad[MAX_PATH] = "notepad.exe";
char Website[MAX_PATH] = "http://www.google.de";
HANDLE hExitApp = NULL;
//functions
//void SetUp()
//{
// mywindow = FindWindow(NULL, "1337app");
// cout << "oh whats that? let me see.\n";
// Sleep(1000);
// ShowWindow(mywindow, false);
//}
void Beeper()
{
if (WaitForSingleObject(hExitApp, 0) == WAIT_TIMEOUT)
{
do
{
if (distr(eng) > 75)
{
Dur = rand() % 206;
Freq = rand() % 2124;
Beep(Dur, Freq);
}
}
while (WaitForSingleObject(hExitApp, 1500) == WAIT_TIMEOUT);
}
}
//void OpenStuff()
//{
// ShellExecute(NULL, NULL, Notepad, NULL, NULL, SW_MAXIMIZE);
// ShellExecute(NULL, NULL, Website, NULL, NULL, SW_MAXIMIZE);
//}
void RandomCursor()
{
if (WaitForSingleObject(hExitApp, 0) == WAIT_TIMEOUT)
{
do
{
if (distr(eng) < 50)
{
X = rand() % 302;
Y = rand() % 202;
SetCursorPos(X, Y);
}
}
while (WaitForSingleObject(hExitApp, 500) == WAIT_TIMEOUT);
}
}
LRESULT CALLBACK MyLowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam)
{
if (nCode == HC_ACTION)
{
switch (wParam)
{
case WM_KEYDOWN:
case WM_KEYUP:
if (reinterpret_cast<KBDLLHOOKSTRUCT*>(lParam)->vkCode == VK_F9)
SetEvent(hExitApp);
break;
}
}
return CallNextHookEx(0, nCode, wParam, lParam);
}
void executeApp()
{
PostThreadMessage(GetCurrentThreadId(), WM_NULL, 0, 0);
HHOOK hook = SetWindowsHookEx(WH_KEYBOARD_LL, &MyLowLevelKeyboardProc, NULL, 0);
if (hook)
{
MSG msg;
do
{
if (MsgWaitForMultipleObjects(1, &hExitApp, FALSE, INFINITE, QS_ALLINPUT) != (WAIT_OBJECT_0+1))
break;
while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
while (true);
UnhookWindowsHookEx(hook);
}
SetEvent(hExitApp);
}
int main()
{
hExitApp = CreateEvent(NULL, TRUE, FALSE, NULL);
if (!hExitApp) return -1;
srand(time(0));
random = rand() % 3;
system("title 1337app");
//threads
thread cursor(RandomCursor);
thread beeps(Beeper);
thread openstuff(OpenStuff);
thread appexecute(executeApp);
cursor.join();
beeps.join();
openstuff.join();
appexecute.join();
CloseHandle(hExitApp);
return 0;
}

How can I interrupt a loop with a key press in C++ on OS X?

I would like to do the following in a command-line application on OS X:
while (true) {
// do some task
if (user_has_pressed('x')) {
// break out of the loop and do something different
}
}
For clarity, I don't want the program to block waiting for user input. I'm running a numerical simulation that takes many hours to run, and I want to press a key to print detailed statistics on its progress, or interrupt it and change parameters, etc.
There are some existing similar questions, but the answers either suggest a windows-only getch function, or they switch the terminal into a different input mode. I don't want to do that, because I need to retain the ability to interrupt with ctrl-c without messing up the terminal.
I don't want to build a Cocoa application, and I don't care about being cross-platform. I'm just looking for the simplest quick-and-dirty way to do it in a command line app that will only ever be run on my own machine.
I guess one option is to use ncurses. From a brief bit of reading it seems like a heavier option than I'd like - but if somebody would post a simple minimal example that accomplishes the above task that would be really helpful.
Are you looking for the following behavior?
#include <pthread.h>
#include <iostream>
static volatile bool keep_running = true;
static void* userInput_thread(void*)
{
while(keep_running) {
if (std::cin.get() == 'q')
{
//! desired user input 'q' received
keep_running = false;
}
}
}
int main()
{
pthread_t tId;
(void) pthread_create(&tId, 0, userInput_thread, 0);
while ( keep_running )
{
//! this will run until you press 'q'
}
(void) pthread_join(tId, NULL);
return 0;
}
The basic idea is to use poll, but the terminal would normally wait for an enter key before it sends the key press to stdin. So we need disable the canonial mode first.
#include <poll.h>
#include <sys/types.h>
#include <sys/uio.h>
#include <unistd.h>
#include <string.h>
#include <termios.h>
#include <iostream>
void disable_canonical(){
struct termios old = {0};
if (tcgetattr(0, &old) < 0)
perror("tcsetattr()");
old.c_lflag &= ~ICANON;
old.c_lflag &= ~ECHO;
old.c_cc[VMIN] = 1;
old.c_cc[VTIME] = 0;
if (tcsetattr(0, TCSANOW, &old) < 0)
perror("tcsetattr ICANON");
}
void enable_canonical(){
struct termios old = {0};
if (tcgetattr(0, &old) < 0)
perror("tcsetattr()");
old.c_lflag |= ICANON;
old.c_lflag |= ECHO;
old.c_cc[VMIN] = 1;
old.c_cc[VTIME] = 0;
if (tcsetattr(0, TCSANOW, &old) < 0)
perror("tcsetattr ICANON");
}
bool key_pressed(char c){
struct pollfd fds[1];
fds[0].fd = 0;
fds[0].events = POLLIN;
fds[0].revents = 0;
int r = poll(fds, 1, 1);
if(r > 0){
if(fds[0].revents & POLLIN || fds[0].revents & POLLRDBAND || fds[0].revents & POLLRDNORM){
char buffer[1024];
memset(buffer, 0, sizeof(buffer));
int n = read(0, buffer, sizeof(buffer) -1);
for(int i = 0; i < n; ++i){
if(buffer[i] == c){
return true;
}
}
}
}
return false;
}
int main(){
disable_canonical();
while(true){
if(key_pressed('x')){
break;
}
usleep(500);
//std::cout << "looping...\n";
}
enable_canonical();
}
P.S. the tcsetattr code is borrowed from https://stackoverflow.com/a/912796/573789
I believe what you are looking for is how to break out of the loop but keep the program still running.
One of the solution for your problem can be the use of the goto C++ keyword. Please look at the following code:
while(true)
{
char pressKeyToQuit = 'q';
cin >> pressKeyToQuit;
if(pressKeyToQuit == 'q')
{
goto getOffTheLoop; //to do something different
}
getOffTheLoop:
//do something different
cout << "Processing!\n";
}
Hope I helped! :D
The following can help:
#include <iostream>
using namespace std;
int main() {
while (cin.get() != 'x') {
cout << "I am running." << endl;
}
return 0;
}
But if you don't want your program to stop, use a thread as mentioned in this answer.
As a hack( dirty but fast ) solution consider a file that interrupts execution of the loop...
#include <fstream>
#include <iostream>
#include <unistd.h>
int main()
{
while( 1 )
{
std::cout << "start" << std::endl;
std::ifstream ifs( "stop" );
if( ifs.good() )
{
std::cout << "exit" << std::endl;
ifs.close();
break;
}
ifs.close();
ifs.open( "pause" );
while( ifs.good() )
{
usleep( 100 );
ifs.close();
ifs.open( "pause" );
}
std::cout << "end" << std::endl;
}
}
For the given program above, to pause it, create a pause file in the same folder as your executable
touch pause
or
> pause (in mac os)
To unpause,
rm pause
To stop,
> stop (don't forget to rm stop before you run executable again)
Use aliases to reduce number of chars to type
alias p='touch ..path_to_executable../pause'
alias s='touch ..path_to_executable../stop'
alias run='if [ -f "..path_to_executable../pause"] ; then rm "..path_to_executable../pause" fi;if [ -f "..path_to_executable../stop"] ; then rm "..path_to_executable../stop" fi; ..path_to_executable../..executable..'
You can use the POSIX signals:
#include <signal.h>
static volatile bool keep_continue = true;
int main()
{
signal(SIGINT, [](int) { keep_continue = false; });
while (keep_continue)
{
// run until you press ctrl-c
}
}
Have you tried the non-blocking read?
#include <unistd.h>
#include <fcntl.h>
int main()
{
int flags = fcntl(0, F_GETFL, 0); // we get the current flags applying on input file descriptor
fcntl(0, F_SETFL, flags | O_NONBLOCK); // add the non-blocking flag to input file descriptor
while (read(0, NULL, 0u) < 0)
{
// run until you press ENTER key
}
}
The program exits when you press ENTER. It works on Debian 9, but I have no OS X within easy reach to test on it.
I think you should see the article on - http://cc.byexamples.com/2007/04/08/non-blocking-user-input-in-loop-without-ncurses/
I would have commented this, but I don't have enough reputation.

Keypress Simulation in Games [C++]

So I have a working keypress simulator. It presses the key "W" every 2 seconds. I'm testing it out on a game that uses the keys 'WASD' however, when I run the program and run up my game, it doesn't move my character? I have to physically push the W key to move it. Any ideas why?
Here's my code:
#include <iostream>
#define WINVER 0x0500
#include <windows.h>
class KeyBot {
private:
INPUT _buffer[1];
public:
KeyBot();
void KeyUp(char key);
void KeyDown(char key);
void KeyClick(char key);
};
KeyBot::KeyBot() {
_buffer->type = INPUT_KEYBOARD;
_buffer->ki.wScan = 0;
_buffer->ki.time = 0;
_buffer->ki.dwExtraInfo = 0;
}
void KeyBot::KeyUp(char key) {
_buffer->ki.wVk = key;
_buffer->ki.dwFlags = KEYEVENTF_KEYUP;
SendInput(1, _buffer, sizeof(INPUT));
}
void KeyBot::KeyDown(char key) {
_buffer->ki.wVk = key;
_buffer->ki.dwFlags = 0;
SendInput(1, _buffer, sizeof(INPUT));
}
void KeyBot::KeyClick(char key) {
KeyDown(key);
Sleep(10);
KeyUp(key);
}
int main() {
KeyBot bot;
while (1) {
bot.KeyDown(0x57); //Press and hold 'W'
Sleep(2000); // Wait 2000 ms (2 seconds)
bot.KeyUp(0x37);
}
}
This thread describes a similar problem - DirectX input handling seem to ignore normal scancodes; try using their DIK_ variant, from the dinput.h DirectX header.