I would like to take over how keys repeat in my program, which means disabling how SDL2 does it automatically.
It's possible to ignore SDL_KEYDOWN repeat events since the Event union member key has a repeat boolean you can filter with (this question explores that solution: How to disable key repeat in SDL2?). But SDL_TEXTINPUT events do not have the same info available in them, and so it's impossible to filter out characters that have repeated.
Is there any way to outright disable key repeating?
It seems there is currently no simple way to do this, and because I need this as well I made a ticket: https://bugzilla.libsdl.org/show_bug.cgi?id=4598
If you have another additional use case why you want this, feel free to add a comment on the bug ticket so the developers get an idea what sort of uses this is important for. (Mine is providing an emergency disable option for people with keys-getting-stuck bluetooth keyboards on android who want to still be able to type texts without major accidents)
Well in SDL lib might be a solution, but you can also add some simple c++ code to resolve your problem. For example if you don't want to play with SDL_KEYUP you can just do something like this:
//before loop
int keypress_control = 0;
//much Code, loop etc.
//
swich(event.type)
case SDL_KEYDOWN :
/*if or switch again as you want */if (keypress_control ==
2)
{
/*Code here*/
keypress_control = 0;
}
else
{
keypress_control = 0;
}
}
//after switch but Still in program loop
Keypress_control++;
//
//
Related
In my Qt (6.3.1) application, for a model I developed, I noticed the submit() method being called all the time.
After some debugging, I noticed, in void QTableView::setSelectionModel/QTreeView::setSelectionModel, this:
if (d->selectionModel) {
// support row editing
connect(d->selectionModel, SIGNAL(currentRowChanged(QModelIndex,QModelIndex)),
d->model, SLOT(submit()));
}
The documentation for QAbstractItemModel::submit() mentions "this function is typically used for row editing", which means this is done on purpose.
I have got more than 1 problem with this way of doing things, compared to the alternative of letting/requiring application developers to create the connection themselves:
Views do not seem to have a property to stop this connection from being created, hence the behavior is more than just a default, it is mandatory.
I do not see any way to know what to do except looking through Qt's source code. I had rather have to create the connection myself if I want it.
Only QSqlTableModel seems to have a mechanism to handle this (editStrategy()) but I could find nothing in neither QAbstractItemModel nor QAbstractTableModel.
-> what would be a good reason to want this connection above to be always created? Or am I perhaps wrong thinking this design is a bad one?
Answering my own question after 4 weeks without another answer nor any comment.
Despite having found a solution that seems to work in every case (see below), I still think this very design choice made by Qt as well as other special case they implemented are bad choices, would be interested to read other opinions in the comments.
Better than disconnecting signals, the solution I ended up implementing was to subclass QIdentityProxyModel and create an attribute to block the calls to submit (+ optionally revert).
void MyModel::revert() {
if (forwardRevertCalls)
QIdentityProxyModel::revert();
}
bool MyModel::submit() {
if (forwardSubmitCalls)
return QIdentityProxyModel::submit();
else
return false;
}
The reason for this choice is because of another special case in QStyledItemDelegate::eventFilter. Found in the documentation:
If the editor's type is QTextEdit or QPlainTextEdit then Enter and Return keys are not handled.
And I suppose things like QSpinBox do not behave this way.
This was causing submit to be called whenever I pressed Enter to validate an input in my model and change the selected row in 1 input; more precisely, it would execute case QAbstractItemDelegate::SubmitModelCache in QAbstractItemView::closeEditor.
I've started using SFML as my base graphics framework for a code editor I'm working on, the only thing I can't seem get completely right is keyboard input.
What I'm used to in QB64 (a language similar to Visual Basic), is to get keypresses using either the _keyhit command (which returns a virtual keycode), or the inkey$ command (which directly returns the current keypress's character). I'm looking for a similar solution in C++ (not necessarily cross-platform, possibly easily implementable along with SFML)
What I've tried as of now is to use _getch, which doesn't seem to work with the Windows framework, nor SFML, perhaps I should use some of the Windows.h routines for this purpose, but judging from what I've seen, those check for specific keypresses, not exactly what I need. The SFML framework provides "sf::Keyboard::isKeyPressed", but that one also checks for a specific keypress, but not for the whole keyboard, I also tried creating an array that serves as a map from the "sf::Keyboard::Key" enum to ASCII characters, but its not convincing, furthermore, the keys seem to "stick" and the pressed key's character keeps getting read even after it has been released.
If you are using SFML, it is actually quite simple. You need to use the sf::Event::KeyEvent class (or in this case, the struct).
https://www.sfml-dev.org/documentation/2.5.0/structsf_1_1Event_1_1KeyEvent.php
Though the catch is you have to get the event from something. Generally this is used from an SFML window.
//assuming your code is already set up for these items...
sf::Event Event;
while (window.GetEvent(Event))
{
if (Event.Type == sf::Event::KeyPressed)
{
//to get the key code, use Event.Key.Code
//your code
//for example
switch(Event.KeyEvent.Code)
{
case(sf::Keyboard::Key::Y):
//do stuff
break;
}
}
}
Heads up, it has been a while since I have worked with SFML so I am not 100% sure if the it will work with switch statements. Comparing with == will work too, in an if-else if-else statement.
There may also be other ways to get the sf::Event defined without a window.
Otherwise, it is fairly simple.
If you are looking just to detect a keypress kbhit() is the fuction.(Borland family of compilers , conio.h , but not a part of C++ standards when I googled it ).
https://www.cprogramming.com/fod/kbhit.html
Alternative : Under Unix-like operating system you can use ncurses to emulate most conio behavior( see if it works for you)
https://www.quora.com/With-which-function-can-I-replace-kbhit-in-C++-because-the-header-conio-h-doesnt-exist-in-linux
If you are looking for a code that can detect which key was pressed (ie Numpad 1 and 1 above the alphabets or Something like Esc or arrow keys).This code worked for me on a borland compiler. When you fetch the scan code ( not ascii ) it is different for every key in keyboard ( even the non ascii ones have a value)
void getkey()
{
union REGS ii,oo;
while(!kbhit());
ii.h.ah=0;//service no for ascii and scan code
int86(22,&ii,&oo);
ascii=oo.h.al;
scan=oo.h.ah;
}
I used the above code in my school project, so I don't remember the exact source where I found it .But I think it was Let us C by Yashwant Kanetkar under the GUI part ( It was removed later so you are looking for a publication pre 2008).
Hope it helps.
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
Hello everybody reading this. Thanks in advance for your time.
One thing before question: I DO NOT use neither MFC nor Windows Forms, just WinApi in C++.
Well, I am making a polynomial calculator in Visual C++. I added a Dialog to it, which was created in resources (.rc file) using drag'n'drop method. I suppose there would be no such a problem if i created my Dialog with CreateWindowEx (but I don't want to).
My Dialog has a few of Edit Controls. Everything is fine except that when the Dialog is launched, one of Edit controls takes focus to be ready to take keyboard input.
I have included management of EN_KILLFOCUS (Edit sends it to parent when loses focus due to selecting another control).
Here I read from control to wstring (string of wide characters - _UNICODE is defined), use some kind of parser to verify this wstring and remove bad characters, and then put correct string into the same edit control. It works fine, but here is the source of my problem:
When there was no input, parser returns string "0" (not the NULL, string is just set to "0"), as if control had focus and then lost it even before I clicked anything in Dialog.
Due to that, and something else (this is what I have to figure out), at the Dialog launch parser puts this string "0" to edit.
I want to make my edit not be able to take input from keyboard until i click one of the Edits (including this one).
If it is not possible, I want to clear the whole text at the beginning of dialog (being able to take input is not a problem, I just want to prevent parser from entering string "0" at the beginning)
My code:
In DlgProc I have:
//up here is switch to manage all controls
case MyEditID: // here is ID of one of my edits from resources
switch (HIWORD(wParam))
{
case EN_KILLFOCUS: // edit lost focus - another control selected
if (LOWORD(wParam)==MyEditID) //necessary to determine if
// one of allowed Edits sent this message
// because I have also other Edits
{
GetDlgItemText(hPanel, LOWORD(wParam), MyTempWcharArray, 100);
MyTempString.assign(MyTempWcharArray);
w1 = polynomial(MyTempWcharArray); // parser takes the string
// and removes bad chars in constructor
// polynomial is my class - you don't have to care of it
// w1 is declared before as object of polynomial class
MyTempString = w1.ConversionToString();
SetDlgItemText(hDialog, LOWORD(wParam), sw1);
}
break;
}
break;
does it matter what integer number is set to Edit's ID?
I know SetFocus(), and WM_SETFOCUS message. In this case I just can't get this working.
If i haven't included something important to make you see my point please let me know. I'm sorry I'm just a newbie in WinAPI world.
EDIT:
For those with a similar problem: Do not do this:
I made an workaround with global variable ProcessKillFocus set to false indicating that instructions in message management should not be processed, except that at the end (just before break;) I am changing it to true, so next time and later it will be processed:
case EN_KILLFOCUS:
if (ProcessKillFocus && LOWORD(wParam)==MyEditID)
{
// first time global ProcessKillFocus is false so all this is skipped
// 2nd time and later do all the stuff
}
ProcessKillFocus = true;
break;
Huge thanx to Sheyros Adikari for making my question easy to understand!!!
Huge thanx to patriiice for simple answer on a huge messing question!!!
ANSWER:
BTW: patriiice, I tried this:
case WM_INITDIALOG:
SetFocus(GetDlgItem(hDialog, Desired_Control_ID));
return (INT_PTR)FALSE;
break;
IT JUST WORKS!!!
You have to return FALSE to WM_INITDIALOG message and set the correct focus by yourself.
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?