I have been attempting to write a cpp autoclicker using header <windows.h> but it isn't working the best. The code works fine and all, but its extremely annoying to turn off as it requires a millisecond click, nothing longer, if I hold that shortcut for too long, it turns back on again. Any suggestions for improvements?
#include <iostream>
#include <Windows.h>
#include <random>
using namespace std;
int counti;
void menu()
{
cout << "Press 'Ctrl + Tab' to enable and Press 'Ctrl + Tab' to disable randomised autoclicker\n";
}
void clicker()
{
bool click = false; //sets click to false
int n;
while (true)
{
while (1) {
n = rand() % 125;
if (n > 75)break;
}
if (GetAsyncKeyState(VK_CONTROL) && GetAsyncKeyState(VK_TAB)) //if Ctrl + Tab is pressed
{
counti++;
if (counti % 2 == 1)click = true; //Shortcut pressed once and it activates
else if (counti % 2 == 0)click = false; //Shortcut pressed again and it deactivates
}
if (click == true) // if click = true it will press the mouse button down and up really fast
{
mouse_event(MOUSEEVENTF_RIGHTDOWN, 0, 0, 0, 0);
mouse_event(MOUSEEVENTF_RIGHTUP, 0, 0, 0, 0);
cout << n << endl;
Sleep(n); //random speed here
}
}
}
int main()
{
menu();
clicker();
return 0;
}
Thank you!!
Don't use the same hotkey to turn on and off. Use a different key.
Related
I've been implementing a dirty hack for a "panic" keyboard shortcut in a RHEL 8.4 environment to kill our application in the event that it hangs because we use a Mutter environment which prevents the user from being able to interact with the OS and only shows our application.
At first I looked into Gnome keyboard shortcuts, but it appears those get overridden or blocked entirely by Mutter, because that didn't work. So I repurposed some old driver code I wrote to write a standalone process that runs in the background and monitors the /dev/input/event file for keyboard events and responds to the Ctrl+Alt+Delete key sequence. When pressed, I use Qt to spawn a QMessageBox that when "Yes" is selected, it calls the script that kills and relaunches our application, and "No" just closes the dialog.
However, there's an issue where regardless of what you click, the dialog reappears. Through some testing, it appears this happens if you press Ctrl+Alt+Delete again while the dialog is visible, but I don't understand how that can happen, because the QMessageBox is modal and calling exec() on it should block the main thread, since the code immediately after reads the dialog result. So I also tried zeroing out the event data at the start of each loop to make sure a previous event isn't being read repeatedly while no events are taking place, but that had no effect either.
Can anyone tell what's going on here?
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <linux/input.h>
#include <string.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <unistd.h>
#include <stdlib.h>
#include <QApplication>
#include <QMessageBox>
using namespace std;
#define BITS_PER_LONG (sizeof(long) * 8)
#define NBITS(x) (((x - 1) / BITS_PER_LONG) + 1)
#define OFF(x) (x % BITS_PER_LONG)
#define LONG(x) (x / BITS_PER_LONG)
#define test_bit(bit, array) ((array[LONG(bit)] >> OFF(bit)) & 1)
string detect();
void poll(string handler);
int main(int argc, char ** argv) {
QApplication app(argc, argv);
bool found = false;
string handler = detect();
poll(handler);
return app.exec();
}
string detect() {
int eventX = 0;
string handler = "";
bool found = false;
while(!found) {
ostringstream oss;
oss << "/dev/input/event" << eventX;
handler = oss.str();
int fd = open(handler.c_str(), O_RDONLY);
if(fd < 0) {
if((errno == EACCES) && (getuid() != 0)) {
cout << "You must run as root to detect the keyboard." << endl;
exit(1);
} else {
// No more event handler files.
break;
}
}
// Read event code bits from event handler file descriptor.
unsigned long bit[EV_MAX][NBITS(KEY_MAX)];
memset(bit, 0, sizeof(bit));
ioctl(fd, EVIOCGBIT(0, EV_MAX), bit[0]);
// Read key events from file descriptor.
ioctl(fd, EVIOCGBIT(EV_KEY, KEY_MAX), bit[EV_KEY]);
// Test to make sure the event file defines the Ctrl, Alt, and Delete key events.
if(
( test_bit( KEY_LEFTCTRL, bit[EV_KEY] ) || test_bit( KEY_RIGHTCTRL, bit[EV_KEY] ) ) &&
( test_bit( KEY_LEFTALT, bit[EV_KEY] ) || test_bit( KEY_RIGHTALT, bit[EV_KEY] ) ) &&
test_bit(KEY_DELETE, bit[EV_KEY])
) {
cout << "Keyboard Found # " << handler << endl;
found = true;
}
close(fd);
eventX++;
}
if(!found) {
cout << "No keyboard event file found." << endl;
exit(2);
}
return handler;
}
void poll(string handler) {
ifstream keyboard(handler.c_str(), ios::in | ios::binary);
struct input_event event;
char data[sizeof(event)];
int states[2] = { 0, 0 };
bool dialogBlocked = false;
bool done = false;
while(!done) {
if(keyboard.is_open() && keyboard.good()) {
memset(data, 0, sizeof(event));
keyboard.read(data, sizeof(event));
memcpy(&event, data, sizeof(event));
if((event.code == KEY_LEFTCTRL) || (event.code == KEY_RIGHTCTRL)) {
if(event.value > 0) {
states[0] = 1;
} else {
states[0] = 0;
}
}
if((event.code == KEY_LEFTALT) || (event.code == KEY_RIGHTALT)) {
if(event.value > 0) {
states[1] = 1;
} else {
states[1] = 0;
}
}
if((event.code == KEY_DELETE) && (event.value > 0)) {
if((states[0] > 0) && (states[1] > 0) && !dialogBlocked) {
// Ctrl+Alt+Delete detected. Call killX.
dialogBlocked = true;
QMessageBox msgBox;
msgBox.setModal(true);
msgBox.setText("Do you want to reset?");
msgBox.setWindowTitle("Reset");
msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
msgBox.setDefaultButton(QMessageBox::No);
msgBox.setStyleSheet(
"QMessageBox {"
" background: rgb(220, 220, 220);"
" color: rgb(0, 0, 0);"
"}"
"QPushButton {"
" border: 1px solid rgb(20, 20, 20);"
" border-radius: 5px;"
" padding: 2px;"
"}"
"QPushButton:enabled {"
" background: rgb(240, 240, 240);"
" color: rgb(20, 20, 20);"
"}"
"QPushButton:!enabled {"
" background: rgb(200, 200, 200);"
" color: rgb(250, 250, 250);"
"}"
);
int ret = msgBox.exec();
if(ret == QMessageBox::Yes) {
system("sudo /opt/eds/bin/killX");
}
}
}
if(dialogBlocked) {
// Wait until Ctrl+Alt keys are released to let operator open dialog again.
if((states[0] == 0) && (states[1] == 0)) {
dialogBlocked = false;
}
}
} else {
cout << "Lost connection to keyboard. Attempting to re-establish..." << endl;
bool detected = false;
if(keyboard.is_open()) keyboard.close();
while(!detected) {
string redetectedHandler = detect();
if(!redetectedHandler.empty()) {
keyboard.open(redetectedHandler.c_str(), ios::in | ios::binary);
if(keyboard.is_open()) {
cout << "Connection to keyboard re-established." << endl;
detected = true;
}
}
}
}
}
if(keyboard.is_open()) keyboard.close();
}
You are never setting done to true, and by this you have a infinite loop which reopens the dialog regardless if you clicked on the yes option.
Also your I am not sure what system("sudo /opt/eds/bin/killX"); is intended to do. If you intend to kill the current process then it does not do the job. For simplicity sake you can call std::terminate then indeed, you would not have to set done to true, since you are exiting the loop abnormally.
So you have 2 options:
if(ret == QMessageBox::Yes) {
system("sudo /opt/eds/bin/killX");
done = true;
}
or
#include <exception>
....
if(ret == QMessageBox::Yes) {
std::terminate();
}
In my game right now I am trying to make a menu you can access when you press 'q', but currently I am having some issues. I think it switches to the CompScreen view and then back to the currentroom view quickly, I may be wrong. I am getting the cout CompMenu, HELP, and hello readings so I know it is running through the programs, but when I press q I remain in the same spot, nothing happening.
EventManager.h
#ifndef EventManager_h
#define EventManager_h
#endif /* EventManager_h */
int windowWidth = 5000;//width of window
int windowHeight = 5000;//height of window
sf::View leveltwo(sf::FloatRect(x, y, 5000, 5000));
sf::View start(sf::FloatRect(0, 0, 2500, 1500));
sf::View ComputerScreen(sf::FloatRect(50000, 50000, 5000, 5000));
sf::RenderWindow window(sf::VideoMode(windowWidth, windowHeight ), "Awesome Game" );
Character player("/Users/danielrailic/Desktop/Xcode /NewGame/ExternalLibs/Sprites/Player.png");
bool InMenu = false;
enum Levels{
StartRoom, LevelTwo
};
Levels room = StartRoom;
int currentroom;
void WhatRoom(int TheLevel){
switch (room){
case StartRoom:
currentroom = 1;
window.setView(start);
if (TheLevel == 2){
room = LevelTwo;
}
break;
case LevelTwo:
currentroom = 2;
window.setView(leveltwo);
break;
}
};
enum States{
compmenu, mainmenu, NoMenu
};
States menu = NoMenu;
void CompMenu(){
window.setView(ComputerScreen);
cout << "HELP";
InMenu = true;
}
void WhatMenu(int TheMenu){
switch (menu){
case compmenu:
cout << "CompMenu";
CompMenu();
break;
case mainmenu:
break;
case NoMenu:
if (TheMenu == 2){
menu = compmenu;
}
break;
if (TheMenu == 3){
menu = mainmenu;
}
break;
}
}
main.cpp (inside int main)
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Q) and InMenu == false){
WhatMenu(2);
}
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Q) and InMenu == true){
InMenu = false;
WhatRoom(currentroom);
cout << "hello";
}
If you have any questions or need to see more of the code let me know. Thanks.
I think you've missed else after first if block so it may be executed immediately because InMenu may be changed to true at that point:
else if (sf::Keyboard::isKeyPressed(sf::Keyboard::Q) and InMenu == true){
Also you should handle the situation when key is pressed for a long time (to react only when it enters pressed state) and get rid of all the global variables because they are already creating quite a mess.
I have this C++ Function that receives Virtual Key and Press/Release the key:
void SendKey (WORD wVk, bool press) {
keybd_event(wVk, 0, press? 0 : KEYEVENTF_KEYUP, 0);
}
But it does just press the key 1 time, not constantly as I expected.
I am constructing a JoyPad simulation, so, I need to configure KeyDown and KeyUp respectively, this is a little C++ process that reads by cmd the key and the type (Down, Press or Release):
#define WINVER 0x0500
#include <windows.h>
#include <iostream>
using namespace std;
void SendKey (WORD wVk, bool press) {
keybd_event(wVk, 0, press? 0 : KEYEVENTF_KEYUP, 0);
}
void PressKey (WORD wVk) {
SendKey(wVk, true);
Sleep(30);
SendKey(wVk, false);
}
int main() {
int key;
char type;
while(true) {
cin >> key;
cin >> type;
if(key == 0) break;
if(type == 'd') SendKey((WORD) key, true);
if(type == 'r') SendKey((WORD) key, false);
if(type == 'p') PressKey((WORD) key);
}
return 0;
}
Thanks a lot, if anyone has built something similar, please tell me.
You are going to have to send a key event for each key repeat you want, this is not going to happen auto-magically. Just like the real keyboard driver sends repeated key events after the initial delay.
I am trying to make a fun program where it display random numbers, but I need to remove the scrollbar so it looks more convincing. I managed to make the program full screen but I can't remove the vertical scrollbar. Screenshot
Code:
#include <iostream>
#include <Windows.h>
using namespace std;
int main() {
SetConsoleDisplayMode(GetStdHandle(STD_OUTPUT_HANDLE), CONSOLE_FULLSCREEN_MODE, 0);
int output;
bool done = false;
system("color a");
while (!done) {
output = 1 + (rand() % (int)(1000 - 1 + 1));
cout << output;
}
}
There are many ways, one of them is manipulating the size of the internal buffer of the console to have the same size of the window and then using ShowScrollBar function to remove the scrolls.
#include <iostream>
#include <Windows.h>
#include <WinUser.h>
using namespace std;
int main() {
SetConsoleDisplayMode(GetStdHandle(STD_OUTPUT_HANDLE), CONSOLE_FULLSCREEN_MODE, 0);
HANDLE hstdout = GetStdHandle(STD_OUTPUT_HANDLE);
CONSOLE_SCREEN_BUFFER_INFO csbi;
GetConsoleScreenBufferInfo(hstdout, &csbi);
csbi.dwSize.X = csbi.dwMaximumWindowSize.X;
csbi.dwSize.Y = csbi.dwMaximumWindowSize.Y;
SetConsoleScreenBufferSize(hstdout, csbi.dwSize);
HWND x = GetConsoleWindow();
ShowScrollBar(x, SB_BOTH, FALSE);
int output;
bool done = false;
system("color a");
while (!done) {
output = 1 + (rand() % (int)(1000 - 1 + 1));
cout << output;
}
}
Another way is to rely on conio.h or another C/C++ header/library which implements user interface functions.
I am using FLTK with C++ to write a program to scroll through a folder of images. I have a next button with the thumbnail for the next image, and the same for the previous button. I want to be able to go through the images by clicking the previous and next buttons as well as using the left and right arrows on the keyboard.
I succeeded in doing this, however not at the same time. When I only write a callback function like so:
void buttonCallback(Fl_Widget* widget, void* viewerPtr) {
Viewer* viewer = static_cast<Viewer*>(viewerPtr);
viewer->navPressed(widget);
viewer->redraw();
}
I can click the respective buttons to go forward and backwards, however when I overload the handle function to handle the keyboard arrows like so:
int Viewer::handle(int e) {
switch(e) {
case FL_FOCUS:
case FL_UNFOCUS:
return 1;
case FL_KEYBOARD:
if ( Fl::event_key() == FL_Left) {
prev->do_callback();
return(1);
} else if (Fl::event_key() == FL_Right) {
next->do_callback();
return(1);
}
return 1;
case FL_RELEASE:
do_callback();
return 1;
}
return Fl_Widget::handle(e);
}
I can use the arrows, however I cannot figure out how to use both arrows and clicking on the buttons. I have tried passing the Fl_Widget *w through to the handle function and back up to the callback, and I was able to click on the buttons, but could no longer use the arrows.
Here is the Viewer.cpp file:
#include <iostream>
#include "Viewer.h"
using namespace std;
void buttonCallback(Fl_Widget* widget, void* viewerPtr) {
//cout << "Callback called" << endl;
Viewer* viewer = static_cast<Viewer*>(viewerPtr);
viewer->navPressed(widget);
viewer->redraw();
}
Viewer::Viewer(string imageFolder, vector<string> imageFilenames, int width = 800, int height = 600) :
Fl_Window(width, height, "Image Viewer"), imageFolder(imageFolder), imageFilenames(imageFilenames), currentIndex(0), nextIndex(1), prevIndex(imageFilenames.size()-1),
prev(nullptr), next(nullptr), imageBox(nullptr), pic(nullptr) {
prev = new NavButton(getPathFilename(imageFilenames.at(prevIndex), true), "Previous Button", borderSize, this->h() - borderSize - thumbnailSize - borderSize, thumbnailSize, imageFilenames.size() - 1);
next = new NavButton(getPathFilename(imageFilenames.at(nextIndex), true), "Next Button",
this->w() - borderSize - thumbnailSize - borderSize, this->h() - borderSize - thumbnailSize - borderSize, thumbnailSize, imageFilenames.size()-1);
imageBox = new Fl_Box(borderSize, borderSize, this->w() - (2*borderSize), this->h() - (2*borderSize) - thumbnailSize - 2*borderSize);
//imageBox->box(FL_BORDER_BOX); // useful to see where the full size of the widget holding the images
pic = new Fl_JPEG_Image(getPathFilename(imageFilenames.at(currentIndex)).c_str());
imageBox->image(pic);
this->end();
prev->callback(buttonCallback, static_cast<void*>(this));
next->callback(buttonCallback, static_cast<void*>(this));
}
string Viewer::getPathFilename(string filename, bool thumb) {
string thumbPart = "";
if (thumb) thumbPart = "t_";
return imageFolder + "/" + thumbPart+ filename;
}
void Viewer::navPressed(Fl_Widget *widget) {
NavButton* b = dynamic_cast<NavButton*>(widget);
// adds to the click counts to keep track of them
b->addClickCount(); b->addTotalClicks();
cout << b->getLabel() << " has been pressed " << b->getClickCount() << " times." << endl;
cout << "All buttons have been pressed " << b->getTotClicks() << " times." << endl;
// determines which button is pressed
if (b->getLabel() == "Next Button") {
changeAllInds(true);
// check to see if at end of list
if ((nextIndex) > imageFilenames.size()-1) {
nextIndex = 0;
} else if (currentIndex > imageFilenames.size()-1) {
currentIndex = 0;
} else if (prevIndex > imageFilenames.size()-1) {
prevIndex = 0;
}
// changes main image
pic = new Fl_JPEG_Image(getPathFilename(imageFilenames.at(currentIndex)).c_str());
imageBox->image(pic);
// changes thumbnails
prev->setImage(getPathFilename(imageFilenames.at(prevIndex), true).c_str());
next->setImage(getPathFilename(imageFilenames.at(nextIndex), true).c_str());
} else {
changeAllInds(false);
// check to see if at end of list
if ((nextIndex) < 0) {
nextIndex = imageFilenames.size()-1;
} else if (currentIndex < 0) {
currentIndex = imageFilenames.size()-1;
} else if (prevIndex < 0) {
prevIndex = imageFilenames.size()-1;
}
// changes main image
pic = new Fl_JPEG_Image(getPathFilename(imageFilenames.at(currentIndex)).c_str());
imageBox->image(pic);
// changes thumbnails
prev->setImage(getPathFilename(imageFilenames.at(prevIndex), true).c_str());
next->setImage(getPathFilename(imageFilenames.at(nextIndex), true).c_str());
}
//cout << currentIndex << endl;
cout << endl;
}
void Viewer::changeAllInds(bool increase) {
if (increase) {
currentIndex++; nextIndex++; prevIndex++;
} else {
currentIndex--; nextIndex--; prevIndex--;
}
}
int Viewer::handle(int e) {
switch(e) {
case FL_FOCUS:
case FL_UNFOCUS:
return 1;
case FL_KEYBOARD:
if ( Fl::event_key() == FL_Left) {
prev->do_callback();
return(1);
} else if (Fl::event_key() == FL_Right) {
next->do_callback();
return(1);
}
return 1;
case FL_RELEASE:
do_callback();
return 1;
}
return Fl_Widget::handle(e);
}
And here is Viewer.h:
#ifndef VIEWER_H
#define VIEWER_H
#include <vector>
#include <string>
#include <FL/Fl_Window.H>
#include <FL/Fl_Box.H>
#include "NavButton.h"
class Viewer : public Fl_Window {
std::vector<std::string> imageFilenames;
Fl_Box *imageBox; // Holds image being shown
Fl_JPEG_Image *pic; // Image being shown
NavButton* prev; // Button to go to previous item
// Image is thumbnail of previous image
NavButton* next; // Button to go to next item
// Image is thumbnail of next image
int currentIndex; // Index of the image currently shown
int nextIndex; // Index of next image
int prevIndex; // Index of previous image
// private helper functions
std::string imageFolder;
std::string getPathFilename(std::string filename, bool thumb=false);
public:
static const int thumbnailSize = 50; // size of NavButton
static const int borderSize = 10; // size of border between window edge and widgets
void navPressed(Fl_Widget* widget);
// constructor
Viewer(std::string, std::vector<std::string>, int, int);
virtual int handle(int e);
//int key_handle(int e, int key);
//int mouse_handle(int e);
void changeAllInds(bool increase);
};
#endif
Please let me know if you need any more info to assist me, and thank you in advance!
This may achieve what you want. Add a third routine to do the navigation
int Navigate(int key)
{
if ( key == FL_Left) {
prev->do_callback();
return(1);
} else if (key == FL_Right) {
next->do_callback();
return(1);
}
return 1;
}
Then change the other two to call it. In your handler
int Viewer::handle(int e) {
switch(e) {
...
case FL_KEYBOARD:
return Navigate(Fl::event_key());
case FL_RELEASE:
...
}
...
In navpressed,
...
if (b->getLabel() == "Next Button") {
...
Navigate(FL_Right);
}
else {
...
Navigate(FL_Left);
}