Original Post
🔒 Locked
Win32 Keyboard Input Without Delay or Repeat?
Advertisement
What exactly do you mean by "smooth" keyboard input?
I use
when I don't want to bother with using DInput
if(GetAsyncKeyState(vkey_here) & 0x8000){ do_stuff}when I don't want to bother with using DInput
By smooth i mean't without a keyboard delay or repeat.
Thanks,
Thanks,
Quote:
Original post by Ximmer
I useif(GetAsyncKeyState(vkey_here) & 0x8000){ do_stuff}
when I don't want to bother with using DInput
Sounds like what i'm after, thanks.
Likewise. Not exactly the best way of doing things but it's very simple to setup. Just remember it ignores window focus, so you'll have to test for that separately (i.e. it just reads straight from the keyboard, regardless of whether any of your app windows would actually receive the input).
So how do we solve the problem of when our window doesn't have focus? Is GetAsyncKeyState() the correct way to do it and we just have to check for our focus?
Given that I still have no idea what you mean by delay, I have to ask what's wrong with just processing WM_KEYDOWN?
The keydown repeat delay occurs, ie the delay configurable via the keyboard settings in the control panel. This means you get intervals between WM_KEYDOWN events. Perfectly valid input for typing etc, but polling the state is really what i needed.
Im possibly completely misinterpreting the use of WM_KEYDOWN but i failed to see the answer on MSDN.
Im possibly completely misinterpreting the use of WM_KEYDOWN but i failed to see the answer on MSDN.
I recommend processing WM_KEYDOWN and WM_KEYUP messages. Works absolutely great for my software 3D renderer.
If you're seeing any kind of delay with this method then post your message pumping loop, as it is probably not written how it should be.
If you're seeing any kind of delay with this method then post your message pumping loop, as it is probably not written how it should be.
Quote:WM_KEYDOWN doesn't do repeats as per the keyboard control panel setting. You only get it when the key is initially pressed and then a WM_KEYUP when you let go, and you simply treat the key as down the whole time between the receiving of the WM_KEYDOWN and WM_KEYUP messages.
Original post by Dave
The keydown repeat delay occurs, ie the delay configurable via the keyboard settings in the control panel. This means you get intervals between WM_KEYDOWN events. Perfectly valid input for typing etc, but polling the state is really what i needed.
Im possibly completely misinterpreting the use of WM_KEYDOWN but i failed to see the answer on MSDN.
You must be processing WM_CHAR messages as well, as those do the keyboard setting repeats.
My message loop is as follows:
I am not handling WM_CHAR.
If i stick a hit count break point on the break line below WM_KEYDOWN and set it to break at 100 hits, it takes about 7 or 8 seconds to get there, when the application framerate is significantly higher than that.
while( WM_QUIT != msg.message ) { if( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) ) { TranslateMessage( &msg ); DispatchMessage( &msg ); } else { MyApplication.Frame(); } }I am not handling WM_CHAR.
LRESULT CALLBACK WndProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam ){ switch( message ) { case WM_DESTROY: PostQuitMessage( 0 ); break; case WM_KEYDOWN: break; default: return DefWindowProc( hWnd, message, wParam, lParam ); } return 0;}If i stick a hit count break point on the break line below WM_KEYDOWN and set it to break at 100 hits, it takes about 7 or 8 seconds to get there, when the application framerate is significantly higher than that.
Quote:Well that all looks fine, basically the same as mine in fact.
Original post by Dave
My message loop is as follows:while( WM_QUIT != msg.message ) { if( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) ) { TranslateMessage( &msg ); DispatchMessage( &msg ); } else { MyApplication.Frame(); } }
I am not handling WM_CHAR.LRESULT CALLBACK WndProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam ){ switch( message ) { case WM_DESTROY: PostQuitMessage( 0 ); break; case WM_KEYDOWN: break; default: return DefWindowProc( hWnd, message, wParam, lParam ); } return 0;}
If i stick a hit count break point on the break line below WM_KEYDOWN and set it to break at 100 hits, it takes about 7 or 8 seconds to get there, when the application framerate is significantly higher than that.
Sorry, I forgot to say that you should be checking if ((lParam & (1<<30)) == 0)
before handling the WM_KEYDOWN. I just put a when-hit breakpoint in my KeyDown handler and with that check in the message dispatching switch statement before calling the KeyDown handler, it works as I described.
Totally forgot that little if-statement was there.
Yeah that empty case statement was purely for demonstrative purposes. The application class has a wndproc that the events get passed through to, essentially no extra complexity. In regards to the hit count test, how long did it take your hitcount to reach 100?
Quote:I didn't use a hit counter. There's this really cool feature that not many people seem to know about called "When Hit" breakpoints. You right click on the breakpoint and select "When Hit..." then in the dialog that shows you check the "Print a message" checkbox.
Original post by Dave
Yeah that empty case statement was purely for demonstrative purposes. The application class has a wndproc that the events get passed through to, essentially no extra complexity. In regards to the hit count test, how long did it take your hitcount to reach 100?
Then have the output window visible while you run your program and you will get the specified output each time it goes through the breakpoint. You can even have it show the values of variables etc. A far better alternative to inserting print statements and rebuilding and running again to debug a problem.
Mine then only shows up the KeyDown handler being called as the key is pressed, which I'm sure you're will too once you add the check I mentioned before. So I would have to press a key 100 times to get to a 100 hitcount.
Just checked MSDN:
Quote:
Because of the autorepeat feature, more than one WM_KEYDOWN message may be posted before a WM_KEYUP message is posted. The previous key state (bit 30) can be used to determine whether the WM_KEYDOWN message indicates the first down transition or a repeated down transition.
LRESULT CALLBACK WndProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam ){ switch( message ) { case WM_DESTROY: PostQuitMessage( 0 ); break; case WM_KEYDOWN: if ((lParam & (1<<30)) == 0) OnKeyDown(wParam); // Put "When Hit" breakpoint on here break; default: return DefWindowProc( hWnd, message, wParam, lParam ); } return 0;}
Hmm, so as previously said, so long as you keep an app side mapping of the state of the keys (defaulting to up) and assume that when WM_KEYDOWN happens that a key is down until WM_KEYUP is recieved for that key, it should all work.
Quote:
Original post by Dave
The keydown repeat delay occurs, ie the delay configurable via the keyboard settings in the control panel.
That's the repeat part of the question, now WTF did you mean by "without delay and repeat"? What does keyboard delay mean by itself?
Quote:Basically, yeah.
Original post by Dave
Hmm, so as previously said, so long as you keep an app side mapping of the state of the keys (defaulting to up) and assume that when WM_KEYDOWN happens that a key is down until WM_KEYUP is recieved for that key, it should all work.
Quote:
Original post by SiCrane Quote:
Original post by Dave
The keydown repeat delay occurs, ie the delay configurable via the keyboard settings in the control panel.
That's the repeat part of the question, now WTF did you mean by "without delay and repeat"? What does keyboard delay mean by itself?
I think he means the fact that the messages keep being sent. And if there's a delay between the key press and the first message, then he probably isn't polling the window messages fast enough.
What I'd do is just keep track of the buttons you need. WM_KEYDOWN would be used to set the corresponding button into the pressed state, and WM_KEYUP would be used to set the button into the released state. Then you just check the button state. Repeated WM_KEYDOWN messages won't hurt because they'll just set the button into a state it was already.
A similar idea can be applied to WM_INPUT messages.
Quote:
Original post by SiCrane Quote:
Original post by Dave
The keydown repeat delay occurs, ie the delay configurable via the keyboard settings in the control panel.
That's the repeat part of the question, now WTF did you mean by "without delay and repeat"? What does keyboard delay mean by itself?
Go look in your control panel, change the settings and type and you'll see the difference.
Topic Locked
This topic has been locked by a moderator. New replies are not allowed.
Sign in to reply to this topic.
Advertisement