Advice on Buffering keyboard input (C++) - c++

I am trying to use the space bar to pause my game, but don't know how to just toggle my pause bool.
I have a BYTE key[] that I use to check my key state (& 0x80).
I can't seem to find the right way to toggle the key though, ending up in some wonky behavior on my pause (it is a pong clone, so the ball either slows down, pauses, or does nothing).
I would greatly appreciate someone pointing me in the right direction.
EDIT:
I am writing a Win 32 app, using Direct2D.

Key presses are platform specific. You'll need to use platform specific functions to determine when a key is pressed or receive notification that a key was pressed.
In order for StackOverflow users to help you further, you will have to add the platform and compiler version (tools) to your post.
Console programs will have a different process for detecting key presses than windowing programs.

Related

How to detect whether tying is enabled in the currently selected/active interface in C++

In Windows 7(I am not sure about other OS) when you are on a webpage, pressing the space-bar scrolls a few pixels down the page. But when you are in an interface where typing can be done(like an input element, textarea, word editor, code editor, search bar, etc), pressing the space-bar obviously types a space.
Similarly, when all the open windows or menus are minimized, and you are viewing the desktop, and you press a letter key, instead of the letter being typed somewhere, a beep sound is produced.
This shows that the availability of a typing functionality can be "detected". And if it can be detected, it can most likely be done so using C++.
I don't know what to call this. I tried to find out using google but everything I got seemed unrelated to this. I was probably not using the correct keywords.
Whatever this is, I am creating a C++ program where I need to be able to detect it(in an if condition). Something like this
if (/*typing can be done*/) {
//Do something..........
}
Or this
if (/*typing can NOT be done*/) {
if( GetKeyState(VK_SPACE) & 0x8000 ) {
//Do something..........
}
}
And I need to be able to do so natively. Not specific to a particular console window or UI.
If you can help me in any way in figuring this out than please do so. And please feel free to make or suggest relevant edits to improve this question and make it less vague and more detailed and to-the-point.
The functionality you describe belongs to the program running the window with focus, not to the operating system (although the operating system will, at least in part, ultimately power that functionality). It shouldn't come as a surprise that programs can detect keystrokes, because otherwise you wouldn't be able to use your keyboard to input any characters into your computer.
However, you cannot just "detect" a random event with an if statement. "if" is not "when". Your computer will not repeatedly check all if statements in your program and jump to that location in the code whenever one matches. Imagine the chaos!
A program sufficiently complex to have a graphical interface almost certainly has an "event loop", be this in its own code or buried within an API call (as in the case of native Windows applications); such an event loop typically polls for keys being sent to the window(s) managed by the program. If you do not have an event loop (and if your operating system cannot generate a "signal" when a keystroke otherwise goes unhandled), you will have to make one.
Exact specifics are beyond the scope of a Stack Overflow answer, but by pointing you in the direction of a textbook about how to create graphical programs, I am enabling you to discover how input and output is handled in those cases.

How to detect if a user pressed Ctrl-Alt-Del or Alt-Tab so that I may minimize my program?

I'm writing a program in C++ using DirectX 11, and I would like to have it so that my program minimizes whenever a user presses Ctrl-Alt-Del or Alt-Tab.
Getting the window itself to minimize is the easy part, as all I have to do is call this function:
ShowWindow(hWnd, SW_MINIMIZE);
The part I'm stuck on is getting it to detect when either of those two particular keystrokes are inputted, so that I may call that function when one of those events occur.
Any assistance would be appreciated, and if you need me to clarify on something please let me know.
Someone far more well-versed in the Kernel of Windows can stomp in with heavy boots here and correct me, but as far as I know, Ctrl-Alt-Delete is so system, it's "mega system". The reason is that if programs could latch in to it, you'd end up with a dead desktop the moment some idiot decided it was a great idea to pop up an "Are you sure?" message box when the user realised his computer had gone to hell.
There are guidelines that we should follow as software developers, and trying to change the behaviour of the operating system (however good our intent), will always end in tears.
I suggest you don't try and do this (if it is indeed possible, I've never tried - to be frank), and start thinking about the more important things you can be doing. If memory serves and the user does hit Ctrl-Alt-Delete when you're running a DirectX application, you'll lose the surface/device context (assuming you're full screen).
Exit gracefully, or if you can recover - do so.

(C++) Disabling Alt commands in Windows

I'm making a program that needs to block all input during a short critical section. I used BlockInput, but it still allows the user to use hotkeys like Ctrl+Alt+F1 or Ctrl+Alt+F2 (switching taskbar in both displays). It is crucial that the user is not able to use these two hotkeys.
I read some things about a hook, but I'm not sure where to start with this solution. Any help would be greatly appreciated.
Thanks!
A keyboard hook could do the trick - check out SetWindowsHookEx. Note that it gets tricky on 64-bit systems.
But may I suggest simply setting your process/thread priority to some ludicrously high value? Windows will really favor your process then, and at the highest settings even keyboard and mouse stopped working - I found that out the hard way. :)

Grabbing events on specific keys with X11 on Linux

I'm writing a program in C++ to implement the keyboard backlight feature from OS X on MacBook Pro's running a Linux distro. So far, it turns the backlight on, on boot and if no keyboard and mouse events are registered for 20 seconds, it will turn it back off, and of course turn it on yet again when an event is registered. Next thing I need the program to do, is to capture keypresses on the keyboard-backlight-up/down keys, but I'm not sure how to approach this.
I am currently using XScreenSaverQueryInfo to get the idle time of keyboard and mouse events, so a method using X11 API would be okay. I have done a lot of googling but havent found a way that I felt sure about going with. The problem I'm seeing with lots of the methods I found, is that they use keycode to identify the key, but I dont think that would be a viable solution since the program should work for any keyboard-layout available.
Any idea of a method and API I should go with? What would work the best?
Regards,
The normal way to do this is with XGrabKey(). It uses keycodes, but you wouldn't hardcode the keycode, you'd get it with XKeysymToKeycode(). To be more correct you'd also want to redo the grab when you get a MappingNotify (XMappingEvent). (Note, MappingNotify, not MapNotify.) If there isn't a keysym for these keys - there probably isn't on old X versions, but hopefully newer X.org versions have one - then you just have to hardwire the keycode. Which won't be very robust or portable but probably works for everyone on Linux with the same hardware model.
Be prepared that key grabs are global, so if you try to XGrabKey() and something else has already grabbed that key, you'll get an X error - by default that exits the program. Another quirk of XGrabKey() is that it grabs the key with a precise modifier set. For example, to handle both with and without NumLock, you need to grab twice. See Global Hotkey with X11/Xlib
In a normal Linux setup (if you wanted to get a feature like this into upstream projects), the desktop environments don't want lots of separate apps fighting over the key grabs and getting errors. So there will be some central coordination points, such as the window manager or a special daemon might do all the keybindings and forward commands to other processes as needed. So you would probably want to look at patching the same upstream code that handles other special keys like this, if you were trying to get your feature integrated into distributions by default.
Another thing to be aware of is the Xkb API, which is a lot more complicated. There is some brain-bending way to grab keys with Xkb but I don't know of any advantage to going that route.
If you haven't done that yet, familiarize yourself with xev. Start it, give it the focus, and press the keys, to see what's happening.

Make a 'press any key' routine that is compatible with redirected standard input

I've got a C/C++ program that runs in a console window, and prompts the user to press any key to continue, or 'q' to quit. It currently uses _kbhit() to detect if a key has been pressed, and then uses _getch() to determine what character it was.
Now I want to be able to automate this program (from a C# app using a Process with RedirectStandardInput and CreateNoWindow set). Obviously I can no longer rely on _kbhit() as it uses ReadConsoleInput(), which fails when launched using my C# app. In my C# app I use process.StandardInput.Write("A") to push something onto the stream in an attempt to get my console app to continue.
In the console app I have used SetConsoleMode() to clear the ENABLE_LINE_INPUT flag so that I can use getchar() to return as soon as a character is pressed, and this works reasonably well (when I press a character key in the console window as well as when the call is made from the c# app). However, it has flaws in that it now only accepts characters keys (i.e. no F, Alt, Shift keys etc.) which isn't too big a problem, but moreso I seem to have to press return twice (and this is a key that lots of people will likely choose to press in the 'any key' situation).
Does anyone know how I can make the console app respond to a key (any a bonus, charcters and return only is acceptable) pressed ONCE, whilst still responding to a single character pushed onto the stream from my C# app?
Something I did notice, calling system("PAUSE") gives the exact behaviour I want, other than knowing what key was pressed so that I can quit on 'q'. I don't know how PAUSE does it though, and it doesn't let me use my custom message either :(.
I'm sure there's a really obvious solution, but it has been driving me mad. Any thoughts are much appreciated!
There are two issues with the resolutions:
Neither the C or C++ languages have
portable functions for waiting for a
keyboard key to be hit. It's an
operating system (platform) issue.*
C and C++ have different methods for
resolving I/O. Choose your
language, C or C++.
In my C++ console applications, I ask the user to "Press Enter to Continue" and use the ignore method of cin:
void Pause(void)
{
std::cout << "Press ENTER to continue.\n";
std::cout.flush(); // Insurance, make sure the text is displayed.
std::cin.ignore(100000, '\n'); // Ignore characters until an ENTER (newline) is received.
return;
}
I suggest you create a single file with the Pause function. You can write different versions for different platforms and let the build system select the correct file.
Not all platforms that run C or C++ are required to have keyboards. Many embedded systems don't have keyboards. Also, many windowing systems receive messages, events or signals when a key is pressed. Again, something different and not standard.
Here is a very good implementation for C++. Be sure to read over the entire tutorial, as I it may initially appear that it doesn't help you.
http://www.daniweb.com/forums/thread90228.html
Use cin.get(). This returns the appropriate key.
Thank you for all your responses, I've learned a lot about handling input!
However, I couldn't get anything to work exactly how I wanted, so I had to abandon the unified approach and put in a check to see if it was running in a window. If it is, I stick with _kbhit(), and if not I use PeekNamedPipe(), which gives me the number of characters sent from my C# app without transfering them into the stdin buffer. There's still a few issues that I have to work out to do with clearing any data that I don't want from the pipe, but it's solved my initial problem.
Thanks again for all the suggestions, they will undoubtably come in handy next time I have an input nightmare :)