#### Archived

This topic is now archived and is closed to further replies.

# WM_KYEDOWN alternative?

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

## Recommended Posts

Once again i turn to you fellow programmers... What i want to do is; while the left arrow key is beeing pressed, my pixel should move to the left. Ok, that is not hard to achive, but there''s one problem. The first second, it moves with a nice frame rate, then it starts to move more jumpy... Then i release the key and press it again and it behaves the same again (smooth movement for a sec and then...). Im using gdi... I tried GetAsyncKeyState(...) but i get the same result. I increased the process priority to HIGH without any change. And i try to achive a constant framerate by using timeGetTime()and even at 50 fps it is really easy to see the jumpiness in the movement. The strange thing is that i dont get a fps drop when it starts to move more jumpy... Any ideas? // Peter

##### Share on other sites
Ummmm, I''m not exactly sure how, but this i''m pretty certain has something to do with how windows sends the messages. For example, if you go into a word processor, hold down an letter key. You''ll notice at first one appears, then a small time lapse where nothing happens, then they will continually repeat. Windows just wasn''t built for games. Look into using DirectInput. I don''t think there''s a workaround for this using win32.

##### Share on other sites
well with the winproc method i can see where the jumpiness comes
into play.. but with GetAsyncKeyState you shouldnt have those problems...

simple solution- direct input.

-eldee
;another space monkey;
[ Forced Evolution Studios ]

##### Share on other sites
quote:
Original post by MelvinElvin
Ummmm, I''m not exactly sure how, but this i''m pretty certain has something to do with how windows sends the messages. For example, if you go into a word processor, hold down an letter key. You''ll notice at first one appears, then a small time lapse where nothing happens, then they will continually repeat. Windows just wasn''t built for games. Look into using DirectInput. I don''t think there''s a workaround for this using win32.

you have no idea what you''re talking about do you.
heh

open your control panel and check out ''keyboard properties''

see the thing that says "repeat rate"?

move that up and down... wow! magically windows is now ''built
for games''

-eldee
;another space monkey;
[ Forced Evolution Studios ]

##### Share on other sites
eldee: Really it does have to do with the way Windows sends messages. Granted, you can adjust the repeat rate, and granted there IS a Win32 work-around, Melvin wasn''t too far off, and he admitted that his info was just as he recalled.

By the way, GetAsyncKeyState was made for stuff like this. I''ll believe it''s jumpy when I see the code and build it myself.

Later,
ZE.

//email me.//zealouselixir software.//msdn.//n00biez.//

##### Share on other sites
Instead, you could use WM_KEYDOWN and wait for a WM_KEYUP, while keeping track of the keypresses yourself.

Though I''d much rather use DInput or something.

Discharge

##### Share on other sites
Check out this article on why keyboards are evil. It has nothing to do with response/refresh rate per se; just a friendly heads-up.

##### Share on other sites
Oluseyi,

Strange, the keyboard test (holding keys) actually worked here. Was that an older article?

---
My Site-My Tetris Clone w/Source

##### Share on other sites
Maybe I'm a little late for this, but here's my 2 cents.
From what I read, you're checking the keystate inside the windows message processing function and checking for keystate messages when the key is pressed. You can still use GetAsyncKeyState(), but just check for the keystate inside the main loop where you perform game logic.

Here's what André did in TotWGPG:

        #define KEYDOWN(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 1 : 0)#define KEYUP(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 0 : 1)// Now inside the main game logic loopif (KEYDOWN(VK_SPACE)){    // Spacebar is pressed}

This is much better. Now you don't get a bunch of extra messages stored and waiting. It's also better for the reason that your input is in the main game loop and is included in every frame of animation, while Windows messages could be unpredictable.
---
Help points: 2 (Eh... I have to start somewhere)

[edited by - Weston on September 7, 2002 12:49:37 AM]

##### Share on other sites
It''s not that old. I suspect some of the newer keyboards - particularly the USB variants - are finally using designs that eliminate those issues.

##### Share on other sites
Here''s some code... i hope it will look nice with the tags... (never done that before)

Anyways, i appreciate your effort in this matter...

As i said before, i got the same result with GetAsyncKeyState... =( I think it has to be somthing with how windows deals with the WM_KEYDOWN messages. I think that windows instead of sending one message for each keydown-tick it bundels several messges into one and it has a counter that says how many messages this message represent.

Darkor - do you mean like this?
WM_KEYDOWN:
keyList[wParam] = true;
break;
WM_KEYUP:
keyList[wParam] = false;
break;

That is how i do it...
...and this is how the code looks at the moment.

  // The main loop in main =)	DWORD	time = timeGetTime();	bool	done = false;	while (!done)	{		if( PeekMessage( &msg, NULL, 0, 0, PM_NOREMOVE ) )		{			if( !GetMessage( &msg, NULL, 0, 0 ) )			{				if (msg.message == WM_QUIT)					done = true;			}			TranslateMessage(&msg);			DispatchMessage(&msg);		}						// Any key pressed?		if (keyList[0])		{//			if (GetAsyncKeyState(VK_RIGHT) & 0x8000) //				runner.Move( Point( 3, 0 ) );			switch (keyList[0])			{				case VK_LEFT:					path.Move( PathObject::LEFT, &runner );					break;				case VK_DOWN:					path.Move( PathObject::DOWN, &runner );					break;				case VK_RIGHT:					path.Move( PathObject::RIGHT, &runner );					break;				case VK_UP:					path.Move( PathObject::UP, &runner );					break;			}									Point pos = runner.Get();			rect.left	= pos.x-10;			rect.right	= pos.x+10;			rect.top	= pos.y-10;			rect.bottom = pos.y+10;						InvalidateRect( hWnd, &rect, TRUE );					}				while (time+30> timeGetTime());;		time = timeGetTime();			}// And in WinProc...case WM_KEYDOWN:			switch (wParam)			{				case VK_LEFT: 				case VK_RIGHT:				case VK_UP:				case VK_DOWN:					keyList[0] = wParam;					break;				case VK_SPACE:					break;			}			return 0;		case WM_KEYUP:			switch (wParam)			{				case VK_LEFT: 				case VK_RIGHT:				case VK_UP:				case VK_DOWN:						keyList[0] = 0;					break;				case VK_SPACE:					break;			}			break;

##### Share on other sites
This barely merits an answer, but here goes...

You''re setting keyList[0] to the wParam of the keypress, ONLY WHEN YOU RECEIVE A KEYDOWN MESSAGE, so of course GetAsyncKeyState is dependent on message rates and the way you process them! But that''s not how it''s supposed to be; trash your keyboard handlers in the WndProc altogether and just check each frame whether or not each key is down.

Later,
ZE.

//email me.//zealouselixir software.//msdn.//n00biez.//

• ### Forum Statistics

• Total Topics
628684
• Total Posts
2984223

• 12
• 13
• 13
• 10
• 10