• 13
• 18
• 19
• 27
• 10

# WM_Keydown help

This topic is 2812 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

Hi, I am making a custom edit box. The edit box works fine, except that if I hold down a key, the letter will not be added multiple times no matter how long I hold the key.

I am wondering how I can make it exactly like a normal text box (I have used timers, e.g. adding another letter for each 100ms the key is held down, but it is annoying when it is not like normal text boxes). So what do I need to add to this to make it so I don't have to push a key multiple times to have multiple letters

case WM_KEYDOWN:		{			if(_wParam == VK_7)			{ 				MessageBox(NULL, "7 pressed.","7 pressed.", MB_OK);				break;			}		}

thanks,
r_bewick

##### Share on other sites
MessageBox probably isn't the best way to test it...

Try testing by showing something on the console (printf, cout, whatever), see if you get the repeat behaviour. Also, I believe you're looking for WM_KEYPRESS, not WM_KEYDOWN.

EDIT: <tt> works in posts but <code> doesn't? WTF?

##### Share on other sites
Quote:
 Original post by Sik_the_hedgehogMessageBox probably isn't the best way to test it...Try testing by showing something on the console (printf, cout, whatever), see if you get the repeat behaviour. Also, I believe you're looking for WM_KEYPRESS, not WM_KEYDOWN.

Wrong. WM_KEYDOWN is fine. WM_CHAR is better: since it has the "formatted" character: shifted/alted/caps-locked whatever.

So use WM_KEYDOWN for altering the caret position, and use WM_CHAR to read the character and put it into the string.
But it's right: it's not good to use MessageBox, since it steals the focus from the main application.

##### Share on other sites
Thanks guys, your right that Messagebox was not a good way to do it.

                case WM_CHAR:		{			if(_wParam == '7')			{ 				string str = "7 Pressed! \n";				OutputDebugString(str.c_str());				break;			}			break;		}

but this sends a message every frame, I would like it to happen like it would in a message box when you hold a key, e.g. it creates 1, then a little while later creates lots, like 7-77777777777777777777777. Instead of doing 100 7's in half a second.
by the way, WM_KEYPRESS is undefined

##### Share on other sites
Quote:
 Original post by r_bewickThanks guys, your right that Messagebox was not a good way to do it.*** Source Snippet Removed ***but this sends a message every frame, I would like it to happen like it would in a message box when you hold a key, e.g. it creates 1, then a little while later creates lots, like 7-77777777777777777777777. Instead of doing 100 7's in half a second.by the way, WM_KEYPRESS is undefined

Not sure if there is a "correct" way to do this, but you could write a delay function like you would for sprite animation:

int time_to_delay=5;int last_time;int current_delay;case WM_CHAR:		{                        //not sure if this is the real function                        current_delay=GetSystemTime()-last_time;			if(_wParam == '7' && current_delay >= time_to_delay)			{ 				string str = "7 Pressed! \n";				OutputDebugString(str.c_str());                                                                last_time=GetSystemTime();				break;			}                        			break;		}

##### Share on other sites
Wrong.

You don't have to use timing or timers.

OP: Post code. Do you handle the stuff in your WindProc or somewhere else?

And post your main loop too.

WM_KEYDOWN is sent repeatedly by the keyboard (or the OS, I'm not sure, but doesn't matter). And it is sent just like in the console. A longer delay after the first press, then repeated with the short delay.
The same as WM_CHAR. If WM_KEYDOWN is translated.

##### Share on other sites
thanks ChurchSkiz.

I was hoping that there was a "correct" way to do this. As I said above, I have done this sort of thing with timers before, but its never been perfect.

Does anyone have a better way?
If not, I guess I will have to use a timer.

##### Share on other sites

Sorry to say that, but ChurchSkiz"s solution is an unnecessary hack, that doesn't even behave perfectly (there's no long delay after the first message)

##### Share on other sites
sorry, got the above message while writing reply to previous.

Quote:
 Wrong.You don't have to use timers.

Could you give an example on how to do this?

Quote:
 Post code. Do you handle the stuff in your WindProc or somewhere else?And post your main loop too.

in Windproc I don't really handle anything except a check for window resize, focus, window close etc.
All the other code goes elsewhere (eg somewhere in main loop)
Normally I use GetAsyncKeyState() for my keyboard/mouse input but I know that I would have to use some sort of timing for that to simulate typing, whereas I thought there might be a way with one of the WM_ messages to get key typed messages like in a normal edit box.

Sorry, I can't post my main loop, it's huge...

##### Share on other sites
You should handle messages in the WindProc.

Because the code would be the code, you already posted. Read back a bit.
there's no need to use timers, because messages sent perfectly timed.

Anyway, if you really don't want to do that, look at these:
SystemParametersInfo with SPI_GETKEYBOARDDELAY and SPI_GETKEYBOARDSPEED to at least replicate the perfect behaviour (but again: you should go on the WinProc way).

It's a bit tricky to use, according to MSDN:
int setting = 0;SystemParametersInfo(SPI_GETKEYBOARDDELAY, 0, &setting, 0);int time_to_delay = (setting+1)*250; // ms//////////////int setting = 0;SystemParametersInfo(SPI_GETKEYBOARDSPEED, 0, &setting, 0);int time_to_delay = 400 - (setting * 12); // ms