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.
Related
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.
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.
I am writing a very simple sample program that simply shows you "a key is pressed or not" only once, the key pressed event is triggered whenever i press any number of keys (either i press one key, two keys or more), while the key is released event is triggered when an SDL_KEYUP event is occurred while the number of keys pressed is only 1 key, this example works perfectly on arrow keys, however for the other keys whenever i press multiple keys and release only one of them a "Key is released" message is triggered followed by "a key is pressed", i failed to locate the problem with this.
my Code:
#include <iostream>
#include <SDL2/SDL.h>
using namespace std;
SDL_Event input;
int main(int argc, const char * argv[])
{
SDL_Init(SDL_INIT_EVERYTHING);
int y = 0;
int z = 0;
int w = 0;
bool key = false;
const Uint8 *state = SDL_GetKeyboardState(NULL);
while (1){
w = 0;
SDL_PollEvent(&input);
//check for events generated
switch (input.type) {
case SDL_KEYDOWN:
key = true;
break;
case SDL_KEYUP:
key = false;
break;
default:
break;
}
// Check for no. of keys pressed using ASCII code
for (y = 48;y<=127;y++)
if(state[y] == 1)
w++;
// Display the messages
if (key && z==0 )
{
cout << "Key is Pressed" << endl;
z = 1;
}
else if (!key && w < 1 && z==1)
{
cout << "Key is released" << endl;
z = 0;
}
}
return 0;
}
The problem was with the initialization of the for loop, SDL 2 does not use the same ASCII enumerations for characters thus my code tend to ignore the code enumerations outside the (48-127) range after changing the code to:
for (y = 0;y<=127;y++)
if(state[y] == 1)
w++;
the problem is solved
Is there any function that can wait for input until a certain time is reached? I'm making kind of Snake game.
My platform is Windows.
For terminal based games you should take a look at ncurses.
int ch;
nodelay(stdscr, TRUE);
for (;;) {
if ((ch = getch()) == ERR) {
/* user hasn't responded
...
*/
}
else {
/* user has pressed a key ch
...
*/
}
}
Edit:
See also Is ncurses available for windows?
I found a solution using kbhit() function of conio.h as follows :-
int waitSecond =10; /// number of second to wait for user input.
while(1)
{
if(kbhit())
{
char c=getch();
break;
}
sleep(1000); sleep for 1 sec ;
--waitSecond;
if(waitSecond==0) // wait complete.
break;
}
Try with bioskey(), this is an example for that:
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <bios.h>
#include <ctype.h>
#define F1_Key 0x3b00
#define F2_Key 0x3c00
int handle_keyevents(){
int key = bioskey(0);
if (isalnum(key & 0xFF)){
printf("'%c' key pressed\n", key);
return 0;
}
switch(key){
case F1_Key:
printf("F1 Key Pressed");
break;
case F2_Key:
printf("F2 Key Pressed");
break;
default:
printf("%#02x\n", key);
break;
}
printf("\n");
return 0;
}
void main(){
int key;
printf("Press F10 key to Quit\n");
while(1){
key = bioskey(1);
if(key > 0){
if(handle_keyevents() < 0)
break;
}
}
}
Based on #birubisht answer I made a function which is a bit cleaner and uses NON-deprecated versions of kbhit() and getch() - ISO C++'s _kbhit() and _getch().
Function takes: number of seconds to wait for user input
Function returns: _ when user does not put any char, otherwise it returns the inputed char.
/**
* Gets: number of seconds to wait for user input
* Returns: '_' if there was no input, otherwise returns the char inputed
**/
char waitForCharInput( int seconds ){
char c = '_'; //default return
while( seconds != 0 ) {
if( _kbhit() ) { //if there is a key in keyboard buffer
c = _getch(); //get the char
break; //we got char! No need to wait anymore...
}
Sleep(1000); //one second sleep
--seconds; //countdown a second
}
return c;
}
I have been looking for an equivalent to kbhit() and I have read several forums on this subject, and the majority seem to suggest using ncurses.
How should I go about checking if a key is pressed in C++ using ncurses?
The function getch() provided by ncurses reads a character from the window.
I would like to write a function that only checks if there is a key press and then I want to do getch().
You can use the nodelay() function to turn getch() into a non-blocking call, which returns ERR if no key-press is available. If a key-press is available, it is pulled from the input queue, but you can push it back onto the queue if you like with ungetch().
#include <ncurses.h>
#include <unistd.h> /* only for sleep() */
int kbhit(void)
{
int ch = getch();
if (ch != ERR) {
ungetch(ch);
return 1;
} else {
return 0;
}
}
int main(void)
{
initscr();
cbreak();
noecho();
nodelay(stdscr, TRUE);
scrollok(stdscr, TRUE);
while (1) {
if (kbhit()) {
printw("Key pressed! It was: %d\n", getch());
refresh();
} else {
printw("No key pressed yet...\n");
refresh();
sleep(1);
}
}
}