Jump to content
  • Advertisement
Sign in to follow this  
sipickles

Using Virtual Key codes as input

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

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hello, Heres my so-far basic EditBox text input function:
bool cEditBox::HandleKeyDown( WPARAM wParam, LPARAM lParam )
{
	// check for character first
	if ( wParam >= 0x30 && wParam <= 0x5A )
	{
		m_text.insert( m_caretIndex, 1, wParam );
		// update cursor position
		m_caretIndex++;
		CalculateCaretXPosition();
		return true;
	}

	switch ( wParam )
	{
	case VK_LEFT: 
		return HandleLArrow();
		break;
	case VK_RIGHT:
		return HandleRArrow();
		break;
	default:
		return false;
		break;
	}
}

This works, surprisingly, except my cowboy way of inserting the pressed key only inputs capital letters. To be honest I didnt think I could use the VK code as a parameter for std::string::insert, but there you go. Can anyone suggest a nicer way to do this, so I can add SHIFT, CAPS LOCK and symbols support? Thank you Simon

Share this post


Link to post
Share on other sites
Advertisement
Maybe I am missing something, but that example doesnt seem to work for me!

Can anyone recommend how to produce the WCHAR character I am trying to insert, in the correct case etc?

Thanks

Simon

Share this post


Link to post
Share on other sites
If you still want to use WM_KEYDOWN, you might find this old msvc++6 code useful:

char getAllowedAscii(char c)
{
if( 0x20 <= c )
{
if( c <= 0x7e )
{
return c;
}
}

if( c == 0x08 ) return c; // backspace

return 0;
}

/**
MsVC++ gave some compiler errors and warnings on this piece of code I got from gamedev.net, probably since
the code was written for DirectInput which gets scancodes. I on the other hand get virtual key codes.
I fixed them, but I wonder if it a nice fix or a hack fix. I hope it's the first.
In case anyone wonder here's the url where I got the :
http://www.gamedev.net/reference/programming/features/scan2asc/
**/

static int scan2ascii(DWORD scancode, USHORT* result)
{
WPARAM vk;
static unsigned char State[256];
HKL layout=GetKeyboardLayout(0);


if (GetKeyboardState(State)==FALSE)
return 0;
vk=MapVirtualKeyEx(scancode,1,layout);
return ToAsciiEx(vk,scancode,State,result,0,layout);
}

char VK2char(WPARAM vk)
{
int r;
unsigned short c[2];

if( vk == VK_RETURN ) return '\n';// return key is pressed

vk = MapVirtualKey(vk, 0);
if( vk == 0 ) return 0;

r = scan2ascii( vk, c);

if( r )
{
if( c[0] > 255 ) return 0; // we don't want to use characters outside of the char range
return getAllowedAscii( (char) c[0] );
}
return 0;
}


WM_CHAR, as MrEvil said, is your best bet, though

Share this post


Link to post
Share on other sites
I have one small problem.

All my keys are inputting correctly now, thanks!

I've even got BACKSPACE working, despite there not being an opposite of std::string::insert!

However DELETE doesnt trigger WM_CHAR. I thought it might , having an ascii code of 127.

Anyone know how to catch the DELETE?

Thanks

Simon

Share this post


Link to post
Share on other sites
You need to catch both messages. The rule is pretty simple - use WM_CHAR for characters and WM_KEYxxx for keys.

'A', 'a', '<random chinese character>', etc. are characters. You catch those with WM_CHAR. DELETE is not a character, you catch it with WM_KEYDOWN. The fact that a few non-characters come through as WM_CHAR is mostly historical accident and it's probably best that you don't rely on it.

Trying to use just WM_CHAR doesn't work as you've discovered - many things that you want to catch that aren't characters don't come through. Using just WM_KEYxxx is possible but extremely problematic - be ready for your whole input system to break down if somebody is using a dvorak keyboard for instance. And you have no hope at all if somebody is using an IME or some sort of accessibility app.

Hiding all the complexity of converting keys to characters is actually the whole reason for the existance of the TranslateMessage API which you are (presumably) calling in your message loop.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!