Left Click - looping while detecting click - c++

Basically, the code below detects "U" is clicked, and if it's clicked then it checks for the left mouse button being clicked. It works up until that point, say you open it, gives it a click per second value, click 'u', and left-click. After you hold the left click it sends left clicks at the desired speed, but it doesn't stop until you click escape. I need it to stop once you let go of the left click button. I've tried a few different things all of which ending up with it either only sending 2 clicks or just not working. TLDR - need it to detect on key, then if the left click button is held down, sends the clicks at the desired cps, and when you let go of left click it stops clicking. I know it worded terribly, English isn't my first language. bool bClick = false;
while (true)
{
//toggles it on and off
if (GetAsyncKeyState('U') & 1)
bClick = !bClick;
if (bClick)
{
while (GetAsyncKeyState(VK_LBUTTON) < 0)
{
while (1)
{
INPUT input[2] = {};
input[0].type = INPUT_MOUSE;
input[0].mi.dx = x;
input[0].mi.dy = y;
input[0].mi.dwFlags = MOUSEEVENTF_LEFTDOWN;
input[1] = input[0];
input[1].mi.dwFlags = MOUSEEVENTF_LEFTUP;
SendInput(2, input, sizeof(INPUT));
std::cout << "Clicked ";
std::cout << clicks++;
std::cout << " times \n";
Sleep(1000 / cps);
if (GetAsyncKeyState(VK_ESCAPE))
{
break;
}
}
}
}
}

your program will continuously send click messages when running on my computer, and it will not stop by pressing the'U' or Esc key.
(I’m not sure if your problem is that the special button cannot be detected or the click is not issued)

Get rid of the inner-most while loop. It is an infinite loop that is broken only by pressing ESC. The middle while loop is all you need, it stops when the left mouse button is released.
while (true)
{
//toggles it on and off
if (GetAsyncKeyState('U') & 1)
bClick = !bClick;
if (bClick)
{
while (GetAsyncKeyState(VK_LBUTTON) < 0)
{
INPUT input[2] = {};
input[0].type = INPUT_MOUSE;
input[0].mi.dx = x;
input[0].mi.dy = y;
input[0].mi.dwFlags = MOUSEEVENTF_LEFTDOWN;
input[1] = input[0];
input[1].mi.dwFlags = MOUSEEVENTF_LEFTUP;
SendInput(2, input, sizeof(INPUT));
std::cout << "Clicked ";
std::cout << clicks++;
std::cout << " times \n";
Sleep(1000 / cps);
if (GetAsyncKeyState(VK_ESCAPE))
{
break;
}
}
}
}

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;
}

Randomized Autoclicker C++ using one key for on/off

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.

How do you make a typing macro in C++

I am trying to make a program that when you type "Alt+A" it will write type out a line like "Hello" for example. This is the closest I've gotten:
if (GetAsyncKeyState(65))
{
cout << "worked" << std::endl;
string bind = "Hello";
INPUT Input = { 0 };
Input.type = INPUT_KEYBOARD;
for (int i = 0; i < bind.length(); i++)
{
Input.ki.wVk = VkKeyScanA(bind[i]);
SendInput(1, &Input, sizeof(Input));
}
Sleep(500);
}
It works similar to how I want, but there are some problems that I encountered:
I can't get the Alt key to work. When I use GetAsyncKeyState(18), it runs the "worked" output but it doesn't type out any of the word.
Whenever I press the key bind (for example "A"), it will type that letter as well. Is there any way I can cancel out that key press? I was thinking that I could just make it so that it types the backspace button before the word, but I'm assuming there is a better to go about this.
I also have a problem that the program doesn't type exactly what is put in. It doesn't type capital letters, and it only types one letter if there are two in a row. In the code that I put, it will say "helo" instead of "Hello."
I have made some simple changes to your code, which can basically meet your needs.
But if you need higher functionality, you may need to use RegisterHotKey, and create your window to handle the WM_HOTKEY message.
#include <windows.h>
#include <iostream>
using namespace std;
int main()
{
HWND hwnd = (HWND)0x001E0BF2; //notepad window
SetForegroundWindow(hwnd);
while (1)
{
if (GetAsyncKeyState(18)&0x8000)
{
if (GetAsyncKeyState(65)&0x8000)
{
INPUT keyup_ALT = { 0 };
keyup_ALT.type = INPUT_KEYBOARD;
keyup_ALT.ki.wVk = 18;
keyup_ALT.ki.dwFlags = KEYEVENTF_KEYUP;
SendInput(1, &keyup_ALT, sizeof(INPUT));
cout << "worked" << std::endl;
string bind = "Hello";
INPUT Input[2] = { 0 };
Input[0].type = Input[1].type = INPUT_KEYBOARD;
Input[1].ki.dwFlags = KEYEVENTF_KEYUP;
for (int i = 0; i < bind.length(); i++)
{
short ch = VkKeyScanA(bind[i]);
Input[0].ki.wVk = Input[1].ki.wVk = ch;
if (((ch & 0xff00) >> 8) & 0x1)
{
INPUT shift = { 0 };
shift.type = INPUT_KEYBOARD;
shift.ki.wVk = VK_SHIFT;
SendInput(1, &shift, sizeof(INPUT));
}
SendInput(2, Input, sizeof(INPUT));
if (((ch & 0xff00) >> 8) & 0x1)
{
INPUT shift = { 0 };
shift.type = INPUT_KEYBOARD;
shift.ki.wVk = VK_SHIFT;
shift.ki.dwFlags = KEYEVENTF_KEYUP;
SendInput(1, &shift, sizeof(INPUT));
}
}
Sleep(500);
}
}
}
}
CHANGES:
Add status check of ALT key;
Make the return value of the GetAsyncKeyState and (&) 0x8000;
Make the ALT key up, to resolve "it runs the "worked" output but it
doesn't type out any of the word."
Check the return value of VkKeyScanA, the high-order byte contains
the shift state, which control the capital letters, then determine whether to send shift key.

Mouse events not read in C++ console

When I move my mouse or do any mouse related operations like clicking, it isn't picked up or read by ReadConsoleInput while keyboard events are picked up.
It used to work but now, I don't know what's causing problems which blocks the reading of mouse events.
This is the code i'm using, and I referred from This Website
DWORD numEvents = 0;
DWORD numEventsRead = 0;
while (appIsRunning)
{
reachedEnd = false;
GetNumberOfConsoleInputEvents(Input_Handle, &numEvents);
if (numEvents != 0)
{
INPUT_RECORD *eventBuffer = new INPUT_RECORD[numEvents];
ReadConsoleInput(Input_Handle, eventBuffer, numEvents, &numEventsRead);
for (DWORD i = 0; i < numEventsRead; ++i)
{
if (eventBuffer[i].EventType == KEY_EVENT) // this works
{
. // other
. // functions
if (eventBuffer[i].Event.KeyEvent.uChar.UnicodeChar == 'c' && eventBuffer[i].Event.KeyEvent.bKeyDown)
return true;
}
else if (eventBuffer[i].EventType == MOUSE_EVENT) // this doesnt work
{
cout << " E";
if (eventBuffer[i].Event.MouseEvent.dwButtonState == FROM_LEFT_1ST_BUTTON_PRESSED)
{
char x[50];
fstream file;
file.open("test.txt", ios::out);
cout << " YY";
SetConsoleCursorPosition(Output_Handle, { eventBuffer[i].Event.MouseEvent.dwMousePosition.X , eventBuffer[i].Event.MouseEvent.dwMousePosition.Y });
cin >> x;
file << "SetConsoleCursorPosition(out, { "
<< eventBuffer[i].Event.MouseEvent.dwMousePosition.X << " , "
<< eventBuffer[i].Event.MouseEvent.dwMousePosition.Y << "}); "
<< x;
}
}
}
delete[] eventBuffer;
}
if (reachedEnd)
return true;
}
I guess i should also post the code which sets the console mode and stuff
void initScr(COORD bufferSize, HANDLE& hOut, HANDLE& hIn, SMALL_RECT screen, SMALL_RECT side, Box& screenBox, Box& sideBox)
{
hOut = GetStdHandle(STD_OUTPUT_HANDLE);
hIn = GetStdHandle(STD_INPUT_HANDLE);
CONSOLE_CURSOR_INFO cursorInfo;
SMALL_RECT windowSize = { 0, 0, bufferSize.X - 1, bufferSize.Y - 1 };
SetWindowPos(GetConsoleWindow(), HWND_TOPMOST, 5, 5, 0, 0, SWP_NOREDRAW | SWP_SHOWWINDOW | SWP_NOSIZE);
SetConsoleWindowInfo(hOut, true, &windowSize);
SetConsoleScreenBufferSize(hOut, bufferSize);
SetConsoleMode(hOut, ENABLE_WINDOW_INPUT | ENABLE_INSERT_MODE | ENABLE_EXTENDED_FLAGS | ENABLE_MOUSE_INPUT);
cls(hOut); //Clears the whole screen
SetConsoleTitle(L"The Game");
GetConsoleCursorInfo(hOut, &cursorInfo);
cursorInfo.bVisible = false;
SetConsoleCursorInfo(hOut, &cursorInfo);
screenBox.drawBox(screen, hOut, COLOR(bRed | bGreen | bBright ));
sideBox.drawBox(side, hOut, COLOR(bRed | bGreen | bBright));
setcursorPos({ 91, 5 }, hOut);
cout << "Press \'C\' to re-create maze";
setcursorPos({ 91, 7 }, hOut);
cout << " Arrow keys for movement.";
setcursorPos({ 0,0 }, hOut);
}
I guess this part of my code is quite messy.
Your problem is enabled selection by mouse in console.
just open your console (Win + r) -> cmd, open properties and disable highlighting function
(I have russian language as my default, but checkbox that you need must be here (i highlighted it by red line))
You may need to pass the ENABLE_MOUSE_INPUT flag to SetConsoleMode().
Also notice that some functions will discard console mouse events. Read the notes at the linked SetConsoleMode documentation.

Scrolling menu in the console

There is the menu in the console navigating by arrows UP-DOWN. Problem: when I select "Enter number" and the result disappears, I can't select another menu item. How to fix it?
Here is my C++ code:
#include <iostream>
#include <string>
#include <windows.h>
using namespace std;
int main()
{
string Menu[2] = {"Enter number", "Exit"};
int pointer = 0;
while(true)
{
system("cls");
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 15);
cout << "Main Menu\n\n";
for (int i = 0; i < 2; ++i)
{
if (i == pointer)
{
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 11);
cout << Menu[i] << endl;
}
else
{
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 15);
cout << Menu[i] << endl;
}
}
while(true)
{
if (GetAsyncKeyState(VK_UP) != 0)
{
pointer -= 1;
if (pointer == -1)
{
pointer = 1;
}
break;
}
else if (GetAsyncKeyState(VK_DOWN) != 0)
{
pointer += 1;
if (pointer == 2)
{
pointer = 0;
}
break;
}
else if (GetAsyncKeyState(VK_RETURN) != 0)
{
switch (pointer)
{
case 0:
{
int number;
cout << "\nEnter number --> ";
cin >> number;
cout << "\nThe number is ";
cout << number;
Sleep(1000);
} break;
case 1:
{
return 0;
} break;
}
break;
}
}
Sleep(150);
}
return 0;
}
Maybe, it will be better to use Qt::Key instead of GetAsyncKeyState?
The problem is GetAsyncKeyState,
MSDN tells us:
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.
So in your case, you pressed Enter to get your number, so the enter key has been pressed since the last call, so (GetAsyncKeyState(VK_RETURN) != 0) is always true.
You should have look more precisely on the return of GetAsyncKeyState to see if the key is really pressed, or to do nothing if the key was already pressed in the call just before. Be careful with the last option, other apps or threads can also call GetAsyncKeyState.
The reason why your result disappears when you select "Enter Number" is because you reinitialize the output buffer with the new string every time you press the "Up Arrow". You can get around this by turning this into a FSM logic where you are in control of the states and your next state is dependent on the current and previous state. At the moment, your logic only cares about the current state.
To be sure to test if a key is pressed at a moment, use:
short result;
result = GetAsyncKeyState(VK_RETURN);
if (result & 0x8000) { ... }
or
if (GetAsyncKeyState(VK_RETURN) & 0x8000) { ... }
I tried this at home but it seems Javia1492 is right, you also have a buffer problem I didn't know. Try not to use "system("cls")", it's old C. try to write your own clearing function like the following found on MSDN:
void cls( HANDLE hConsole )
{
COORD coordScreen = { 0, 0 }; // home for the cursor
DWORD cCharsWritten;
CONSOLE_SCREEN_BUFFER_INFO csbi;
DWORD dwConSize;
// Get the number of character cells in the current buffer.
if( !GetConsoleScreenBufferInfo( hConsole, &csbi ))
{
return;
}
dwConSize = csbi.dwSize.X * csbi.dwSize.Y;
// Fill the entire screen with blanks.
if( !FillConsoleOutputCharacter( hConsole, // Handle to console screen buffer
(TCHAR) ' ', // Character to write to the buffer
dwConSize, // Number of cells to write
coordScreen, // Coordinates of first cell
&cCharsWritten ))// Receive number of characters written
{
return;
}
// Get the current text attribute.
if( !GetConsoleScreenBufferInfo( hConsole, &csbi ))
{
return;
}
// Set the buffer's attributes accordingly.
if( !FillConsoleOutputAttribute( hConsole, // Handle to console screen buffer
csbi.wAttributes, // Character attributes to use
dwConSize, // Number of cells to set attribute
coordScreen, // Coordinates of first cell
&cCharsWritten )) // Receive number of characters written
{
return;
}
// Put the cursor at its home coordinates.
SetConsoleCursorPosition( hConsole, coordScreen );
}