I know that you can set actions to trigger if the user presses a set key, in my case Escape, with something like this:
transitions.push_back(new KeyTransition("GameMode", OIS::KC_ESCAPE));
What I want to know is if I can have the program "think" the Escape key has been pressed, even if it has not. For example, when the user clicks a button, the program simulates that the escape key has been pressed and triggers the event attached to it.
One way to do this would be instead of tying it to a specific key press event, you had a more generic method.
So have a method like Cancel() or GoBackOneScreen() etc, whatever it is that ESC is doing. Then you could have the ESC keypress call GoBackOneScreen() and when you needed to simulate the ESC key press, you could do it by just calling the GoBackOneScreen() method.
See this: How do I send key strokes to a window without having to activate it using Windows API?
Summary: You can't reliably.
//To force user to press escape key
#include<iostream.h>
#include<conio.h>
void main
{
cout<<"press escape to exit\n";
loop:
if(getch()==27);
else
{
if (getch()==27);
goto loop;
}
}
Related
I am using C++ and ncurses to get key input for a game. I have a moveable object that the arrow keys control. The behavior that I want is to be able to constantly move right with an arrow key and jump with the up keyy without interrupting the moving right. However, currently with ncurses, when RIGHT is being held and UP is pressed, it stops registering that RIGHT is being held, and you have to release and press RIGHT again.
How can I fix this?
I have seen this post, which is how I'm getting the multiple key input (see below), however I don't think this is the problem.
while (gameRunning) {
int ch;
vector<int> keys;
while ((ch == getch()) != ERR) {
keys.push_back(ch);
// keys vector now has all pressed keys,
// however if you are holding right and up is pressed,
// holding right is not recognized until you release and
// right is pressed again
}
// loop through keys vector here, do things with pressed keys
}
To handle text input I've set up a char-event callback with glfwSetCharCallback, and to handle non-text keypresses (arrow keys & hotkeys) I've set up a key-event callback with glfwSetKeyCallback.
What happens in this situation is that for a key press of a character key, I get two calls, one in the key-event callback, and then one in the char-event callback. This can cause unwanted effects - for example let's suppose the user configured the key "a" to enter "Append Mode" of a text editor - after it enters the mode it will also enter the character "a".. Is there a good way to handle this?
So far I've relied on both events arriving together before glfwPollEvents returns, and have merged them. But I get reports that this scheme doesn't work well on some Ubuntu systems..
I've been having trouble with this one as well. After some rudimentary debugging I found that if you press, hold then release a 'typable' key (meaning a key which may fire both the glfwKeyCallback and glfwCharCallback), the output is as follows:
KeyCallback - pressed
CharCallback - typed
KeyCallback - repeated
CharCallback - typed
(3. and 4. repeat until key is released)
KeyCallback - released
With this, and judging from the fact that there is a 0ms delay between the two events firing, they're probably fired sequentially. The solution I came up with (is rather janky), and involves creating some sort of KeyEvent structure:
(examples are in C++)
enum KeyEventType
{
Pressed,
Repeated,
Released
}
struct KeyEvent
{
KeyEventType Type;
int Key;
unsigned char Codepoint;
bool IsTyped;
}
and store it along with an index variable, such as
[main/input class]
std::vector<KeyEvent> m_KeyEvents;
size_t m_LastKeyEventIndex;
in the main file.
Then, when the glfwKeyCallback fires, push a new KeyEvent into the vector:
[glfwKeyCallback]
KeyEventType type = (action == GLFW_PRESS ? KeyEventType::Pressed : (action == GLFW_REPEAT ? KeyEventType::Repeated : KeyEventType::Released));
KeyEvent event = KeyEvent(type, key);
m_KeyEvents.push_back(event);
m_LastKeyEventIndex = m_KeyEvents.size() - 1;
and if the glfwCharCallback fires, we know from the debugging that it should be (immediately) after the corresponding keyCallback event, so you can modify the last added entry in the vector to add the codepoint and mark it as a 'typed' event, after-the-fact. This also gives the added benefit of tying the actual key that was pressed to the generated codepoint, which could come in useful.
[glfwCharCallback]
m_KeyEvents.at(m_LastKeyEventIndex).Codepoint = codepoint;
m_KeyEvents.at(m_LastKeyEventIndex).IsTyped = true;
Finally, in the main loop when you go to call glfwPollEvents(), process all those pending KeyEvents and then clear the vector and reset the index.
I haven't fully tested this yet, but some very rudimentary debugging shows this as a promising solution, resulting in the following*:
*I'm using a custom Key enum in place of the int Key. You could probably use glfwGetKeyName() to get the printable key name, however this resulted in exceptions for me when pressing some keys.
I am writing an application with WxWidgets, and have run into an issue with a multiline text control (wxTextControl). It is the input field in a chat window, and it needs to be multi line in case the user types a longer message that needs to wrap. I want the send event, e.g. the action that is taken when the Send button is pressed, to be executed when the user presses enter in the control. I have this working using the wxEVT_COMMAND_TEXT_ENTER event, with the wxTE_PROCESS_ENTER style enabled. However, the problem is that while the send command does get executed, a new line character \n is also appended to the text (this happens after the send command and after I have cleared the text, resulting in an empty field except for a new line). I tried to avoid this by trapping both char and key down events, but for some reason they are not firing.
I simply want to avoid the new line being shown at all. Does anyone have any tips?
I am developing on Windows, but the application is meant to run on all platforms supported by WxWidgets.
You might track wxEVT_COMMAND_TEXT_UPDATED and clear the editor when a new-line is entered (it assumes you are also clearing the editor when Enter is pressed).
BEGIN_EVENT_TABLE(Test,wxFrame)
EVT_TEXT_ENTER(EditorID, Test::OnEnter)
EVT_TEXT(EditorId, Test::OnText)
END_EVENT_TABLE()
void Test::OnEnter(wxCommandEvent&)
{
Send(editor->GetValue());
editor->Clear();
}
void Test::OnText(wxCommandEvent& event)
{
if (event.GetString() == wxT("\n")) { //seems to work, not much info in documentation?
editor->Clear();
}
}
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.
How to make Esc key to minimize a dialog? By default it closes. Should I process KeyEvent or there is a better way?
I think you may use this:
void MyDialog::keyPressEvent(QKeyEvent *e) {
if(e->key() != Qt::Key_Escape)
QDialog::keyPressEvent(e);
else {/* minimize */}
}
Also have a look at Events and Event Filters docs.
Escape calls reject(). I override this function (in my case not to minimize the dialog but to prompt to save)
void MyDialog::reject() {if(cleanupIsOK()) done(0);}
Al_
Renaming the reject is correct. But be careful because if you want to close the dialog in other way you cannot call close.
MyDialog::reject(){
if(some_closing_condition)
{
QDialog::reject() //calls the default close.
}
else
{
//skip reject operation
}
}
I think that to do this, you would basically have to avoid inheriting from QDialog. The documentation for QDialog says:
Escape Key
If the user presses the Esc key in a
dialog, QDialog::reject() will be
called. This will cause the window to
close: The close event cannot be
ignored.
Interestingly Qt docs state ESC calls reject()
Escape Key
If the user presses the Esc key in a dialog, QDialog::reject() will be
called. This will cause the window to close: The close event cannot be
ignored
yet QDialog::reject() documentation says hides. i.e closeEvent() is not called, which I have confirmed to be the case.
void QDialog::reject()
Hides the modal dialog and sets the result code to Rejected