Set Arrow Keys As Input Keys - WinForms [duplicate] - c++

This question already has answers here:
Up, Down, Left and Right arrow keys do not trigger KeyDown event
(10 answers)
Closed 6 years ago.
I need to detect arrow keystrokes in the KeyDown event. I do understand that they need to be set as input keys but I'm not clear on how to accomplish it in C++ . Found good answers here, here and here. But that is C# and I need C++. Tried implementing like described here have this code in PreviewKeyDown but no luck.
switch (e->KeyCode)
{
case Keys::Down:
case Keys::Up:
case Keys::Right:
case Keys::Left:
case Keys::Space:
e->IsInputKey = true;
break;
}
and my KeyDown have :
if (e->KeyCode == Keys::Left)
{
///
}
Which is not working on pressing left.
What am I missing?

Here is a C++ example of how to capture Key presses:
C++ Detect when user presses arrow key
And here is the MSDN doc for the KeyDown event with some C++ code examples:
https://msdn.microsoft.com/en-us/library/system.windows.forms.control.keydown(v=vs.110).aspx?cs-save-lang=1&cs-lang=cpp#code-snippet-1
hope that helps.

I managed to solve it.
For anyone facing the same, it worked when I added events PreviewKeydown and KeyDown events with the same code, for each of the controls in the form, but not for the form.

Related

How to read key from keyboard in c++?

How to read key from keyboard in c++ ?
i used _getch() but this is not working always.
i heard about win32 keyboard api. i am targeting to windows so window specific technique is fine. can anyone give me simple example how to read key and check for arrow and function key.
i read article
How to simultaneous read keys on keyboard?
but this is not working in may case. here is my attempt inspired from above linked reference
char temp;
BYTE keys[256];
while(true)
{
temp = _getch();
if(GetKeyboardState(keys))
{
if(keys[VK_UP]&0xF0)
{
// Move Up : Case failing when i pressed up key
}
else if(keys[VK_DOWN]&0xF0 || keys[VK_RETURN]&0xF0)
{
// Move Down : Case failing when i pressed down or enter
}
else if(keys[VK_TAB]&0xF0)
{
// Move Next : Case failing when i pressed tab
}
else
{
// Print charecter which read using _getch()
cout<<temp;
}
}
}
i read MSDN article but do not understand what they are doing. i am doing such program first time so please make your example clear and illustrative so i can easly get it. thanks
I don't have a Windows machine at hand to test this out, but I am thinking that the fact that you are using temp = _getch(); before GetKeyboardState(keys) is eating your characters.
there are many library in C++ which handle this type of problem, if you are the choice, I advise you to use QKeySequence and other classes to let useful keyboard management.
If you want to see example, refer you to chromium project, here is an example used to test code of "keyboard driver".
you can either search many example with "filetype" syntax in google search engine (example : filetype:cc GetKeyboardState)...
you need to set correctly the layout before use GetKeyboardState...
Hope this help you.
Regards,
/Mohamed

SDL (And Others) Virtual Key Input

Today I set up the input in my application for all the different keys. This works fine except for virtual keys, for example, caret or ampersand. Keys that normally need shift to be got at. Using SDL these virtual keys don't work. As in they do not register an event.
if (event.type == SDL_KEYDOWN) {
switch (event.key.keysym.sym) {
case SDLK_CARET:
Keys[KeyCodes::Caret] = KeyState::Down;
break;
case SDLK_UP:
Keys[KeyCodes::Up] = KeyState::Down;
break;
default:
break;
}
I am absolutely sure my system works with physical keys like Up. The program queries a keystate like so:
if (Keys[KeyCode] == KeyState::Down) {
lua_pushboolean(L, true);
} else {
lua_pushboolean(L, false);
}
KeyCode is passed in as an argument.
So why are virtual keys, or keys that need shift to get at not working using SDL's KeyDown event type? Is more code needed to get to them? Or am I being stupid?
SDL only reports real key events.
The good news is you can enable Unicode translation to get symbols like '^' or '#'.
First put this in your initialization code:
SDL_EnableUNICODE(1);
Now SDL_KEYDOWN events will have the accompanying character in the unicode member of SDL_keysym. This factors in shift, caps lock, etc., when translating the key press into a character. Keys like SDLK_UP will have unicode == 0.
This actually makes using keysym.unicode ideal for text input, especially when used with SDL_EnableKeyRepeat.
Here's an example: on my keyboard, I hold shift-6 to generate ^. The program recieves an SDL_KEYDOWN event with keysym.sym == SDLK_6, and keysym.unicode == '^'.
The one caveat is that only key press events will be translated, not release events. But this should not be a big problem, since you shouldn't use text characters for game controls anyway, only real keys. And if you're doing text input with key repeating, it only matters when keys are pressed, not released.
You might have to mix-and-match using keysym.sym and keysym.unicode to fit your exact needs.
Ok I do apologise for getting slightly frustrated but I have finally got some code to tell when some one has pressed on the Caret key for example. I do hope others find this useful information.
case SDLK_6:
if (event.key.keysym.mod == KMOD_LSHIFT || event.key.keysym.mod == KMOD_RSHIFT) {
Keys[KeyCodes::Caret] = KeyState::Down;
} else {
Keys[KeyCodes::n6] = KeyState::Down;
}
break;
Basically when checking normal keys that have a shift click special key then check the key modifier. I understand the unicode value now but this idea seems simpler for now.
Again thanks for all the help!

Qt LEFT CTRL Key Code

In Qt's QKeyEvent I can check whether Ctrl was pressed by checking if ev->key() is Qt::Key_Control. But how can I distinguish between the left and right Ctrl keys?
I also need the same thing for Alt and Shift keys.
There is no way to do this using pure Qt methods, as far as I know.
Depending on your platform, however, you might be able to distinguish between the keys using the QKeyEvent::nativeScanCode() method instead of QKeyEvent::key().
For example, on Windows you should be able to test which Ctrl key was pressed as follows:
if (event->nativeScanCode() == VK_LCONTROL) {
// left control pressed
} else if (event->nativeScanCode() == VK_RCONTROL) {
// right control pressed
}
According to the Qt Namespace Reference, the enum Qt::Key has a different value for Qt::Key_Alt and Qt::Key_AltGr.
However, enum Qt::KeyboardModifier and enum Qt::Modifier don't see the pair of keys as different modifiers.
(note: I would have posted this as a comment but I don't have enough rep. yet)
Left and Right keys are part of virtual key code -> use nativeVirtualKey() to compare with windows VK_* enums instead of nativescancode().
If VK_RCONTROLdoes not work, check your nativeScanCode value of ctrl-right:
std::cout<<keyEvent->nativeScanCode(); and use this value:
int control_right = 285;
if(key->nativeScanCode() == control_right){...

Button held down by code

I am writing a game and am trying to make a person move with the arrow keys.
I have this code
if (Key_Down(DIK_DOWN))
{movedown(player)}
This works but as I want the player to take four steps every time the key is pressed I created and animation loop. so the player cannot input any more move commands until the animation is over and they have taken four steps I made the code this.
if(player.move == false)
{
if (Key_Down(DIK_DOWN))
{movedown(player)}
}
The problem is that now once a button is pressed the program acts like the button is held down and the player keeps moving until another direction is pressed.
Can anyone explain what the outer loop has done to the code and fix the problem ?
it is programmed in visual c++ 2005 and direct x 9.c
Edit:
If I remove the outer loop then the button press is only registered once so I don't think it is the movedown function.
Simply keep track of the keystate in a variable. So you can reset a move counter. Something like this, combining both:
int MovingDown = 0;
...
if (!Key_Down(DIK_DOWN)) MovingDown = 0;
else if (MovingDown < 4) {
MovingDown++;
movedown(player);
}
Hard to tell without seeing more of your codebase but I would guess that you're not re-setting player.move after you've moved the player. Have you tried sticking some break poins in there to see what is being called and why?
If you remove the if(player.move == false) line does it have the same issue? ..or have you changed something elsewhere? If you could post more of your codebase like the whole movedown function and anythnig else which interacts (e.g. the animation code) it would help us help you...
[Edit] Is movedown a macro? Maybe you've got some peculiar side effect eminating from that? If not, it ought to have a semi colon after the function call.
What does KEY_DOWN return? Is that an API call? Try testing against the exact value you expect it to return?

Keypress event in C++

I'm currently using GetAsyncKeyState() to detect Keydown events, but then the events will be repeated while you are holding down the key.
What would be an easy way to stop the event from repeating?
Example
If I hold down the key i on my keyboard for a while, I will get an output like this:
iiiiiiiiiiiiiiiiiiiiiiiii
Instead of this:
i
I want to force the user to press the key again to trigger the event.
Avoid using a keyboard related message like WM_KEYDOWN or WM_CHAR to detect a key, Windows repeats WM_KEYDOWN when the user holds it down. You simply need a your own bool flag that keeps track of the state of the key. Only change your game object state when you see a difference between the state as reported by GetAsyncKeyState() and this flag. Roughly:
bool movingLeft = false;
...
if ((GetAsyncKeyState(VK_LEFT) < 0) != movingLeft) {
movingLeft = !movingLeft;
gameObject->setVelocity(movingLeft ? -10 : 0);
}
Use KeyPress events (or KeyUp).
Btw according to MSDN SHORT WINAPI GetAsyncKeyState(__in int vKey);
Determines whether a key is up or down
at the time the function is called,
and whether the key was pressed after
a previous call to GetAsyncKeyState.
It doesn't say anything about detecting a keydown event.