Get key press info out of console - c

I am trying to create a C application (keylogger) that works on the background and gets notified when any key is pressed on windows 10. I have used this code sample so far:
while(37) {
for(int i=0; i<256; i++) {
if(GetAsyncKeyState(i) == -32767) DoTheJob();
}
}
The main problem I have here is that it uses too much power with this infinite loop and sometimes even when I press a button the 3rd line doesn't check for that buttons key state at the first moment of the press action and the code doesn't works. I have also tried kbhit(); but it works only when I input to console not on background.

Related

Refresh screen every 1 second with ncurses

I want to refresh the screen every one second. I'm implementing a chat with ncurses.
So far, I have the following function:
void print_chat(char *chat) {
mvprintw(1, 1, "RPC Chat");
move(2, 1);
for (int i=0; i<CHAT_WIDTH; i++) {
addch('_');
}
move(CHAT_HEIGHT + 3, 1);
for (int i=0; i<CHAT_WIDTH; i++) {
addch('_');
}
mvprintw(CHAT_HEIGHT + 5, 1, "Enter message: ");
}
Which prints the following screen:
In the main function I'd like to have a loop that refreshes the screen every 1 second, obtaining possible new messages from a server, and refreshes the screen in that interval so if any, new messages could be displayed. I also want to read users input while the refreshing goes on at the same time. Do I need threads?
My attempt so far in the main function:
while (1) {
print_chat(chat);
refresh();
sleep(1);
chat = read_chat_from_server();
/*char l = getch(); --> This would block the loop, waiting for input...
}
Do I need threads to achieve this? If so, would the thread be able to reprint the screen? Any other way to solve this problem?
The problem is that getch() is waiting for the user to press return.
You want to have a look at raw() and call it once before getting any input. By calling this function you can get characters from the user without him pressing return, pausing your program. Basically the console reads user input, prints each character as its being written, and when the user sends '\n', it returns that input to your program (See this answer).
You might want to look at noecho() too. Similar to raw(), lets you scan for user input (using getch()) without printing the characters on the screen. This is usually useful for letting your program handle how the characters are displayed.
Finally, it may be a good idea to call refresh() when something gets updated (e.g. check each second if you got a message, you sent one, etc.) and then call refresh(). If you still want to run it every second, maybe try nodelay(stdscr, 1), where stdscr is your default window:
The nodelay option causes getch to be a non-blocking call. If no input is ready, getch returns ERR. If disabled (bf is FALSE), getch waits until a key is pressed.
You need to call the timeout() function when you first initialize your program.
timeout(0) should cause getch() to not wait for user input.

AUTOHOTKEY: Problem with code which suspend script after clicking key and unsuspend it after clicking 2 another keys. Doing 2 things at the same time

In game chat start with t key and I want that after pressing t on keyboard my script will be suspend and I will can normally write on chat but if I press enter or esc my script will be unsuspended (esc - close chat, enter - send message on chat).
I have problem with this code:
t::
Suspend On
Loop
{
GetKeyState, state, Enter, P
GetKeyState, state2, Escape, P
if (state = Enter){
Suspend Off
break
}
else if (state2 = Escape){
Suspend Off
break
}
}
return
Main problem with this code is loop which not work, and I don't know how to repair it or replace it something more useful or better solution.
Another problem is t key which work but I must click it 2 times, why? First click suspends script, second click runs chat. I want after clicking 1 time t key chat will run and script will suspend. I want the same with enter and esc, to make 2 functions at the same time (enter - unsuspends script and send message on chat, esc - close chat and unsuspends script)
The problem is with the usage of the (deprecated legacy) GetKeyState command, but I must say, the whole solution could be implemented a lot better.
The output value of the command doesn't contain key names, it contains D for down, or U for up, as stated in the documentation. And also you'd need to "quote" your strings.
And the problem with your T key not working on the first press, is of course because you have a hotkey that is capturing the press of the T key.
To not consume the T key press when the hotkey runs, you want to use the ~ modifier(docs).
But anyway, I think a better implementation would be just that a press of the keys simply suspends/unsuspends.
Like so:
~t::Suspend, On
~Enter::
~Esc::Suspend, Off
As a bonus:
The usage of #IfWinActive(docs) might be desirable so the hotkeys only work when your game is active.
#IfWinActive, ahk_exe ExeOfMyGame.exe
~t::Suspend, On
~Enter::
~Esc::Suspend, Off
#IfWinActive
I change code to this:
~t::
Suspend On
Loop
if (GetKeyState("Enter", "P") || GetKeyState("Escape", "P"))
break
Suspend Off
return
Why? Because in #0x464e code was that problem when I suspended script manually and click enter / esc it unsuspended it, I needed after click T it suspend and only enter / esc will unsuspend it. When I manually suspend it in code which is above enter / esc do not unsuspend it.

TextField keyboard is lost when clearing text from within DataChangedListener

I have a TextField on which I listen key presses
TextField msgField = new TextField();
msgField.setSingleLineTextArea(false);
msgField.addDataChangedListener((i1, i2) -> { ... });
I want to clear() the field's text when a certain key is pressed (enter key)
msgField.addDataChangedListener((i1, i2) -> {
if(!msgField.getText().isEmpty())
{
String lastChar = msgField.getText().substring(msgField.getText().length()-1);
if(lastChar.equals("\n"))
{
msgField.clear();
}
}
});
When enter is pressed, the keyboard is closed on this field, which I am trying to prevent. How can I prevent this? setText("") (instead of clear()) produces a random number of further calls to DataChanged which messes things up (I tried wrapping with sync and control vars, no success there either). I have tested this on Android
DataChangedListener is verbose so you shouldn't rely on it's low level behavior too much. In other words I'm not sure why clear() doesn't send events but it's possible it should... You need to guard against that in your DataChangedListener .
If you want to re-open the virtual keyboard just use startEditingAsync on the text field which will re-launch the text field. Notice that clear explicitly stops editing as invoking setText while editing can produce an inconsistent result as the user might be typing something on the native UI thread and you're trying to override him from the EDT. Stopping to make a change is essential to synchronize the native/lightweight components.

How to use two keys of keyboard simultaneously in sdl

I'm writing a simple game in C with SDL and I have defined that player one controls it's_for example_tank with arrow key of the keyboard and player two controls it's tank with the keys "W","A","S","D" of the key board.
My problem is they can't press the keys simultaneously.
I have a function called "handle_events" that controls the events in the infinite while of the game and it's code is like below:
int handle_events(Tank* tank,Tank* tanker, Wall walls[]){
SDL_Event event;
while (SDL_PollEvent(&event)) {
if (event.type == SDL_QUIT)
return EXIT;
if (event.type == SDL_KEYDOWN){
if(event.key.keysym.sym==SDLK_UP){
move_tank_forward(tank,colliding(tank,walls));
}else if(event.key.keysym.sym==SDLK_DOWN){
move_tank_back(tank,colliding(tank,walls));
} else if(event.key.keysym.sym==SDLK_RIGHT || event.key.keysym.sym==SDLK_LEFT) {
turn_tank(event.key.keysym.sym, tank);
} else if(event.key.keysym.sym==SDLK_w){
move_tank_forward(tanker,colliding(tanker,walls));
} else if (event.key.keysym.sym==SDLK_s){
move_tank_back(tanker,colliding(tanker,walls));
} else if(event.key.keysym.sym==SDLK_d || event.key.keysym.sym==SDLK_a){
turn_tank(event.key.keysym.sym, tanker);
}
}
I'm looking for a way that two players can play simultaneously because right now if for example both players press the up key and the w key, none of them can move their tank.
It appears you rely on key repeat - feature of operating/windowing system to repeat last pressed key with fixed interval after some initial pause, e.g. when you keep key pressed in text editor it starts filling that symbol after some delay. Only last key is repeated though.
With SDL, you should know when key is repeated from repeat field of keyboard event. However, you almost never want to make prolonged movement based on keypress event. With your current scheme, I can press a key very quickly and tank will move faster, or I can modify my OS repeat interval. Movement, if supposed to be at constant speed, should rely on time, not how fast user can press a button. That is why you only need to take nothion of "ok, button A pressed, - as long as it pressed, I will attempt to rotate left at each fixed update interval", and when you get key-released event - you drop that intention.
As Danny_ds said, it is often much easier and robust to use key state array instead of events (mostly because of repeat) - with SDL, you can get that via SDL_GetKeyboardState. Make your update_movements or whatever function, and call it every N miliseconds.
On Windows you can use the GetAsyncKeyState() function.
For an equivalent on Linux see this question.

how to get Return key press event?

I'm coding a console editor in C. I'm using CodeLite Editor on Windows. I want to insert a newline ('\n') when the user presses Return (Enter) key. I want to accomplish this goal with getchar() function is that possible?
I need it because I want to increment the y axis variable.
Code I'm trying on :
int X = 0; // X-axis
int Y = 0; // Y-axis
char key = getchar();
if (key=='sth') // Here I want to perform my check
{
//Do Something
++Y;
}
Update :
If it has a code like : '\x45' for example post it in the comments plz!!!
If you are trying to implement an editor, you will quickly find that getchar() is not the way to interpret keyboard events. In this very simplistic example, where all you might do is wait for a single keystroke of input that either is or is not a newline, your program will work if you change 'sth' (an abbreviation for "something"?) to '\n'. However, as your editor becomes more complicated, you will want to have an actual event handler that can detect any sort of keyboard events and can asynchronously deal with them. getchar() is not the way to do that.
This answer from 7 years ago shows that (1) you can go a limited distance with getch() (and getchar()), but (2) a far larger number of people agree that it's no substitute for a real event handler: Detect Keyboard Event in C

Resources