GetAsyncKeyState constantly active - c++

I am trying to make an autoclicker to mess around with getkeystate and key pressing functions in VS and c++, for some odd reason it will never stop clicking once it is initially clicked. I looked over my code and couldn't find anything wrong with it, i know the issue is gonna be something stupidly small. Heres my code:
#include <iostream>
#include <Windows.h>
using namespace std;
bool click = false;
int x = 0, y = 0, cps;
void gui()
{
cout << "Enter desired clicks per second: ";
cin >> cps;
}
void clicked()
{
while (1)
{
if (GetAsyncKeyState(VK_LBUTTON)) // Left mbutton
{
click = true;
}
else
{
click = false;
}
if (click == true)
{
mouse_event(MOUSEEVENTF_LEFTDOWN, x, y, 0, 0);
mouse_event(MOUSEEVENTF_LEFTUP, x, y, 0, 0);
Sleep(1000 / cps);
}
if (click == false)
{
continue;
}
}
}
int main()
{
gui();
clicked();
}```

You maybe missed to read the documentation about return value of GetAsyncKeyState.
The return value of GetAsyncKeyState is zero for the following cases:
The current desktop is not the active desktop
The foreground thread belongs to another process and the desktop does not allow the hook or the journal record.
And,if the most significant bit is set , the key is down.
So, for checking up, you need to check, if the most significant bit is reset.
[Sorry, I am writing the answer on mobile. So, could not provide source code.]

Related

Multiple key presses detected on SFML, can't solve it in any other way and works differently on different machines

this is my first post here.
I am trying to solve a problem I am having with my SFML project where I am using multiple clients, that communicate through texts that can be typed in the rendered window and then sent to the other sockets using a selector.
My problem is that everytime i press one button of the keyboard, the window detects like 3 or 4, and if I try it on another machine, the behaviour changes.
I tried almost every solution, including the setKeyRepeatEnabled(false);
This is the update function
void Client::Update(Input* input,sf::Event& Ev, sf::Font& font, sf::RenderWindow& window)
{
if (input->isKeyDown(sf::Keyboard::Return))
{
sf::Packet packet;
packet << id + ": " + text;
socket.send(packet);
sf::Text displayText(text, font, 20);
displayText.setFillColor(sf::Color::Red);
chat.push_back(displayText);
text = "";
input->setKeyUp(sf::Keyboard::Return);
}
else if (input->isKeyDown(sf::Keyboard::Backspace))
{
if (text.size() > 0)
text.pop_back();
}
else if (input->isKeyDown(sf::Keyboard::Space))
{
text += ' ';
}
else if (Ev.type == sf::Event::TextEntered)
{
text += Ev.text.unicode;
return;
}
//sf::Event::TextEntered
//text += Ev.text.unicode;
}
This is the render one.
void Client::Render(sf::Font& font, sf::RenderWindow& window)
{
sf::Packet packet;
socket.receive(packet);
std::string temptext;
if (packet >> temptext)
{
sf::Text displayText(temptext, font, 20);
displayText.setFillColor(sf::Color::Blue);
chat.push_back(displayText);
}
int i = 0;
for (i; i < chat.size(); i++)
{
chat[i].setPosition(0, i * 20);
window.draw(chat[i]);
}
sf::Text drawText(text, font, 20);
drawText.setFillColor(sf::Color::Red);
drawText.setPosition(0, i * 20);
window.draw(drawText);
}
I don't recognize the isKeyDown function as part of SFML, so I assume you either is something you implemented or is part of a previous version of SFML (being the current 2.5.1).
There are three ways to detect input from keyboard in SFML.
sf::Keyboard::isKeyPressed: looks like this is the one you are using. It will be true every cycle that the key is pressed. You definetly don't want this. The window.setKeyRepeatEnabled(false) will obviously not work because you don't get the input through the window, but directly from the keyboard.
sf::Event::KeyPressed and sf::Event::KeyReleased events: for this, window.setKeyRepeatEnabled(false) will work, but still it's not the recommended way to deal with text input, as it would require a lot of juggling by your side to handle key combinations (accents, uppa.
sf::Event::TextEntered event: now, this is the best and recommended way to handle typing. Check the tutorial to see how to use it.

c++ sfml apply only when button pressed

I have a probleme my character stay running when i release the LShift button
How can i reset the speed when the button is released ?
Actually i have this :
int speed(4);
int speedSprinte(20);
if(sf::Keyboard::isKeyPressed(sf::Keyboard::LShift))
{
keyCount++;
speed=speedSprinte;
std::cout<<speed<<std::endl;
}
i can add that but i think it possible to do that easier :
if(!sf::Keyboard::isKeyPressed(sf::Keyboard::LShift))
{
keyCount++;
speed=4;
std::cout<<speed<<std::endl;
}
Either use SFML events and listen to sf::Events::KeyReleased (https://www.sfml-dev.org/tutorials/2.5/window-events.php) or do it manually by storing the last state.
int speed(4);
int speedSprinte(20);
bool pressedLastTime{false};
if(sf::Keyboard::isKeyPressed(sf::Keyboard::LShift))
{
keyCount++;
speed=speedSprinte;
std::cout<<speed<<std::endl;
pressedLastTime = true;
}
else
{
if (pressedLastTime)
{
speed = 4;
pressedLastTime = false;
}
}

Global alt+space hotkey grabbing - weird keyboard focus behaviour

I'm grabbing Alt+Space global hotkey using xcb_grab_key, as follows:
xcb_key_symbols_t *keysyms = xcb_key_symbols_alloc(c);
xcb_keycode_t *keycodes = xcb_key_symbols_get_keycode(keysyms, XK_space), keycode;
// add bindings for all screens
xcb_screen_iterator_t iter;
iter = xcb_setup_roots_iterator (xcb_get_setup (c));
for (; iter.rem; xcb_screen_next (&iter)) {
int i = 0;
while(keycodes[i] != XCB_NO_SYMBOL) {
keycode = keycodes[i];
xcb_grab_key(c, true, iter.data->root, XCB_MOD_MASK_ANY, keycode, XCB_GRAB_MODE_SYNC, XCB_GRAB_MODE_SYNC);
i += 1;
}
}
Then in Qt's QAbstractNativeEventFilter subclass I process it and emit a Qt signal if key matches Alt+Space:
xcb_keycode_t *keycodes = xcb_key_symbols_get_keycode(keysyms, XK_space);
int i = 0;
bool found = false;
while(keycodes[i] != XCB_NO_SYMBOL) {
if(event->detail == keycodes[i]) {
if(event->state & GetModifier(c, keysyms, XK_Alt_L) || event->state & GetModifier(c, keysyms, XK_Alt_R)) {
xcb_allow_events(c, XCB_ALLOW_ASYNC_KEYBOARD, event->time);
emit gotHotKey();
found = true;
} else {
xcb_allow_events(c, XCB_ALLOW_REPLAY_KEYBOARD, event->time);
}
break;
}
i += 1;
}
if(found) return true;
(GetModifier is copied from VLC but I think this part doesn't matter since Alt-key is matched correctly)
The problem I'm having is that after show()ing main window when the hotkey is pressed, keyboard is most of the times1 not focused properly. I can type, but the cursor is not visible, input's border is not highlighted, and the shortcut Ctrl+Q for quitting desn't work. It can be worked around by moving the window, or pressing space - then focus is restored - cursor+border reappears and Ctrl+Q works. What might be causing this behaviour?
I'm using Qt 5.0.0 and xcb 1.8.1. Complete application can be downloaded for compiling from github.
1 it means sometimes the issue is not reproducible - focus is set correctly even for repeated window hide/shows, but then other times it happens multiple times in a row of hide/shows. It occurs more often than not overall.
(Edit: I've implemented a (very ugly...) workaround, so to reproduce the issue for the github project, the following code needs to be removed)
#ifndef WIN32
// Very ugly workaround for the problem described at http://stackoverflow.com/questions/14553810/
// (just show and hide a modal dialog box, which for some reason restores proper keyboard focus)
hackDialog.setGeometry(0, 0, 0, 0);
hackDialog.setModal(true);
hackDialog.show();
QTimer::singleShot(100, &hackDialog, SLOT(reject()));
#endif

Exiting glutFullScreen()

I don't understand why when I press 'f' it enters into fullscreen but does not exit out of full screen. In the beginning of this method I have set bool fullscreen = false;
Here is the code for my toggle:
case 'f': //toggle screenmode
if(!fullscreen){
glutFullScreen();
fullscreen = true;
} else if(fullscreen){
glutReshapeWindow(1200, 900);
glutPositionWindow(0,0);
fullscreen = false;
}
break;
at the top of this method I have set bool fullscreen = false;
Every time you press a key, GLUT will call your keyboard handler. And at the top of your keyboard handler, you create a bool variable named fullscreen and set its value to false. This happens regardless of whether you're in full-screen mode or not. Every time you press a key, this will happen.
If you want to retain a boolean variable that actually tracks whether you're currently fullscreen, then you need to use a global. And you need to not set it at the start of the function. You set it once when you create the window, and you only set it again when you change the fullscreen status of the window.
To restore the original window size
... switch the calling order of ReshapeWindow and PositionWindow to
glutPositionWindow(0,0);
glutReshapeWindow(1200, 900);
Otherwise it will go back to windowed mode, but not adapt to the window size you specified!
The problem is not in the code you posted above as according to glutFullScreen specification the window should exit fullscreen mode once glutReshapeWindow or glutPositionWindow is being called.
at the top of this method I have set bool fullscreen = false;
I bet you set this inside the same function (not as a global variable) rendering the variable always being false when you press f
Instead of defining the bool at the beginning of the method, you have to define a global variable. Otherwise each time that method is called, it will set the fullscreen bool to 0, and think that it's not in fullscreen mode. Also, you may want to take not of euphrat's answer, he makes a valid point about the method organization.
Try this:
case 'f': //toggle screenmode
fullScreen = !fullScreen;
if (fullScreen) {
glutFullScreen();
} else {
glutReshapeWindow(1200, 900);
glutPositionWindow(0,0);
}
break;
While it might not answer the question directly, I found it an excellent place to post a go-to full-screen and exit source code.
Switch and restore full screen with <GL/glut.h>
myGame.c
...
glutSpecialFunc(handleSpecial);
void handleSpecial(int key, int x, int y) {
oglHandleFullScreen(key, x, y);
}
...
If you are looking forward to responding to a keyboard event instead (glutKeyboardFunc), make sure to change the signature of the below oglHandleFullScreen to (unsigned char key, int x, int y).
fullscreen.h
void oglHandleFullScreen(int key, int x, int y);
void oglWindowed(int positionX, int positionY, int width, int height);
void oglFullScreen();
fullscreen.c
#include <GL/glut.h>
#include "fullscreen.h"
int isFullScreen = 0;
int previousPosition[2] = { 0, 0 };
int previousSize[2] = { 100, 100 };
void oglHandleFullScreen(int key, int x, int y) {
if (key != GLUT_KEY_F11) { // Respond to F11 key (glutSpecialFunc).
return;
}
if (isFullScreen) {
oglWindowed(previousPosition[0], previousPosition[1],
previousSize[0], previousSize[1]);
} else {
previousPosition[0] = glutGet(GLUT_WINDOW_X);
previousPosition[1] = glutGet(GLUT_WINDOW_Y);
previousSize[0] = glutGet(GLUT_WINDOW_WIDTH);
previousSize[1] = glutGet(GLUT_WINDOW_HEIGHT);
oglFullScreen();
}
isFullScreen = !isFullScreen;
}
void oglWindowed(int positionX, int positionY, int width, int height) {
glutReshapeWindow(width, height);
glutPositionWindow(positionX, positionY);
}
void oglFullScreen() {
glutFullScreen();
}
In this case, you may want to add a static keyword before the bool to make this variable initialized only once.
A safer approach would be to make fullscreen global, since static local variables may be implemented differently across compilers and c++ standards.
Edit to add code snippet:
static bool fullscreen = false;
This should fix the problem of initializing the variable every call to the function, and by c++11 standard should be thread-safe
(Many compilers may say otherwise. Visual Studio only supported this feature of c++11 in VS2015 according to another question's accepted answer: Is static init thread-safe with VC2010?)
Better option may be using a global variable (Wrapping into a class is not good for this purpose).
Edit: Also, despite being simple in syntax, this c++11 feature is costly when called frequently.(See Cost of thread-safe local static variable initialization in C++11?)
(A key down is not that frequent as drawing vertices at high FPS, though... Do NOT use this when performance-critical...)

C++: GetKeyState() has to run once

I need to listen keyboard key states for my tiny application.
#include <windows.h>
#include <fstream>
#include <iostream>
using namespace std;
int main()
{
while(1)
{
if(GetKeyState(VK_SPACE) & 0x80)
{
cout << "Space pressed.\r\n";
DoSpaceKeyTask();
}
if(GetKeyState(OTHER_KEY) & 0x80)
{
cout << "Other key pressed.\r\n";
DoOtherKeyTask();
}
}
return 0;
}
Once I click some keys from my keyboard, these functions has to run once. They're just some tiny tasks for my applications, which is not related in this topic.
My problem is, when I press a key, it executes the functions few times, due to while(1) looping few times during key press. I cannot use Sleep() in this case, because it still won't be effective.
I'm looking for a solution like this.
I press SPACE key.
DoSpaceKeyTask() executes "once."
I press OTHER key.
DoOtherKeyTask() executes "once."
I have like 5 keys that I will be using. Could anyone help me on this case?
Ps. If GetKeyState() function isn't useful on this task, feel free to suggest yours. My function knowledge is pretty limited on C++.
Your functions are called multiple times because of the duration time the button stays pressed. The system is very sensitive. So this is a workaround.
You could do something like this (set a flag that will assign a value when the key is down, and then reasign it when the key is up).
int k=0;//Flag
while(1){
//check if the key was pressed (key_down)
if((GetAsyncKeyState('0') & 0x8000) && (k == 0)){k=1; cout<<"'0' PRESSED."<<k<<endl;}//do your stuff here
//check if the key was released (key up)
else if(GetAsyncKeyState('0') == 0) k = 0;//reset the flag
}
I think that you will prefer to execute your functions "once" only when you have released up your keys, not when you have depressed (pressed) them down.
You don't need any additional flags and helper variables to define, allocate, assign to 0, and set each one to 1 and reset to 0 and so on, in order to achieve this goal. All what you need is just: First you have to use GetKeyState function inside the scope of while(1) to check when you have depressed a key. When the expression returns true, the executor pointer (the arrow that carry out a code line and then proceeds forward to the next code line when you either step into or step over) will enter into the if statement's scope. Then immediately trap it inside a loop and keep it trapped in there while the key you have depressed is still down and stop it before it is going to execute the function and free it when you have released that key up and then let it to execute the function.
For example, to execute the DoSpaceKeyTask function only "once" when you have depressed and released the space bar, then do the following code that should work:
while (1)
{
if (GetKeyState(VK_SPACE) & 0x80)
{
//The code here executes ONCE at the moment the space bar was pressed
cout << "Space pressed.\r\n";
while (GetKeyState(VK_SPACE) & 0x80) //You can write there ';' instead '{' and '}' below
{
//The executor pointer is trapped here while space bar is depressed and it will be free once space bar is released
}
//The code here executes ONCE at the moment the space bar was released
cout << "Space released.\r\n";
DoSpaceKeyTask();
}
}
Just the same with DoOtherKeyTask function:
while (1)
{
if (GetKeyState(OTHER_KEY) & 0x80)
{
//The code here executes ONCE at the moment the other key was pressed
cout << "Other key pressed.\r\n";
while (GetKeyState(OTHER_KEY) & 0x80) //You can write there ';' instead '{' and '}' below
{
//The executor pointer is trapped here while other key is depressed and it will be free once other key is released
}
//The code here executes ONCE at the moment the other key was released
cout << "Other key released.\r\n";
DoOtherKeyTask();
}
}
If you have already used either BT_'s idea or Pawel Zubrycki's idea, and now you want to use my idea, then you can delete all flags and variables that they suggested, because you don't need them anymore.
By the way, I have already tried the code that Pawel Zubrycki posted, but it doesn't work for me. The output that says that I have pressed either space bar or other key was not displayed when I have really pressed the space bar or other key that I chose.
Try this approach:
#include <windows.h>
#include <fstream>
#include <iostream>
using namespace std;
int main()
{
char lastSpaceState = 0, lastOtherKeyState = 0, spaceState, otherKeyState;
while(1)
{
spaceState = (GetKeyState(VK_SPACE & 0x80) != 0);
lastSpaceState = (spaceState && !lastSpaceState);
if(lastSpaceState)
{
cout << "Space pressed.\r\n";
DoSpaceKeyTask();
}
otherKeyState = (GetKeyState(OTHER_KEY) & 0x80 != 0);
lastOtherKeyState = (otherKeyState && !lastOtherKeyState);
if(lastOtherKeyState)
{
cout << "Other key pressed.\r\n";
DoOtherKeyTask();
}
}
return 0;
}
or as Chris suggest in OP comment more "modern" async approach.
You want a windows hook to hook the game and react to the keyboard input that game gets. Now I haven't really done this specific type of hook, but I can give you a good idea of the flow. I'll leave it up to you to cut down the space by looping through a map of keys you need rather than a huge, repetitive switch, and also to work out any small kinks I put in.
int main()
{
//I imagine the last argument here is the thread
//containing the game's message loop
HHOOK hook = SetWindowsHookEx (WH_CALLWNDPROC, hookProc, NULL, NULL);
//main loop
UnhookWindowsHookEx (hook);
}
LRESULT CALLBACK hookProc (int code, WPARAM wParam, LPARAM lParam)
{
if (code == HC_ACTION)
{
CWPSTRUCT details = *((LPCWPSTRUCT)lParam);
if (details.message == WM_KEYDOWN)
{
switch (details.wParam)
{
case KEY_ONE:
if (last [KEY_ONE] == UP)
{
DoKeyOneStuff();
last [KEY_ONE] = DOWN;
}
break;
}
}
else if (details.message == WM_KEYUP)
{
switch (details.wParam)
{
case KEY_ONE:
last [KEY_ONE] = UP;
break;
}
}
}
return CallNextHookEx (NULL, code, wParam, lParam);
}
Note how I use last [KEY_ONE]. I would recommend using an std::map to store keys you need by their vk code. Then you can just loop through the map and cut down a lot of space that a switch would take.
I was having the same issue. I have several keys that act like toggle buttons and only want to register the key events once per press. My solution was to make a simple object to handle the logic. This keeps the main code clean:
class KeyToggle {
public:
KeyToggle(int key):mKey(key),mActive(false){}
operator bool() {
if(GetAsyncKeyState(mKey)){
if (!mActive){
mActive = true;
return true;
}
}
else
mActive = false;
return false;
}
private:
int mKey;
bool mActive;
};
And here is the usage:
#include <windows.h>
KeyToggle toggleT(0x54); // T key toggle
KeyToggle toggleF(0x46); // F key toggle
void main(void)
{
while(true){
if(toggleT) {;} // do something
if(toggleF) {;} // do something
}
}
I know that this is pretty old thread but I still want to share my solution. I think that creating some kind of "flags" or "switches" is really not needed. Here is my code of looping all keycodes:
while (true)
{
for (int i = 0x01; i < 0xFE; i++)
{
if (GetKeyState(i) & 0x8000)
{
std::cout << (char)i << "\n";
while (GetKeyState(i) & 0x8000) {}
}
}
}
As you can see, you can easily just use while and the same GetKeyState function to wait for the key unpress. Much simpler solution.
Try sth. like this;
while (!GetKeyState(VK_SPACE) && !GetKeyState('A') == 1) {
//std::cout << "Key not pressed... \n";
Sleep(40);
}
if (GetKeyState('A')) {
std::cout << "\"A \" key pressed... \n";
}
else if (GetKeyState(VK_SPACE)) {
std::cout << "Space key pressed... \n";
}