# Converting Virtual Keys to Scan Codes (for DirectInput)

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

## Recommended Posts

Well, I found the tutorial here that describes it, but I'm running into one problem: This function doesn't work with the arrow keys (I haven't tested many other keys though). I know it works with the letters, and the shift key, but when I use VK_UP or VK_DOWN, it always returns false. Here's the function:
BYTE Keys[256]; //Keys is a buffer for a LPDIRECTINPUTDEVICE8
bool keyboard_check(UINT key) {
return (Keys[ MapVirtualKeyEx(key,0,GetKeyboardLayout(0)) ] & 0x80);
}
I'm not sure what I did wrong. (Yes, I am looping)

##### Share on other sites
Why don't you use DIK_ constants as in http://msdn.microsoft.com/archive/default.asp?url=/archive/en-us/directx9_c_Summer_04/directx/input/tuts/tut1/step6retrievingfromkeyboard.asp ? Maybe that's the problem.

##### Share on other sites
Well, with my game I'm going to *attempt*, I am going to make key configuration. I already have the psuedo stuff worked out on Game Maker, but I need a way to retrieve the key code (virtual is my preference) of the current key being pressed, using a loop (0-255). Plus, I have an array of strings that name each key, and uses the virtual key system (i.e. key_name[32]="Space"). It's easier to loop through with virtual key codes that it is with scan codes (I suppose).

##### Share on other sites
Which is the tutorial you are referring to?

[no problem! There is no timeout! ;-)]

##### Share on other sites
The tutorial is at: http://www.gamedev.net/reference/articles/article842.asp
That is where I got the function names for converting Scan Code to Win32 Virtual Keys.

##### Share on other sites
I've read just now the tutorial... your function is totally different if compared to the tutorial one! [oh] I can't understand why you added 0x80 (maybe you're interested in only the first 128 scan codes). Anyway you will never detect the VK_UP/VK_DOWN and other keys (such as F1, F2,...) because theese have multybyte scan code. The tutorial says "In most cases, using char(result[0]) would provide the desired output"... not in all cases! [smile] So, to solve your problem, you have to use ToAsciiEx function (as you see in the tutorial [smile]).

Hope this helps.

##### Share on other sites
Ah, now I see why it's an UINT. Thanks for the help. (Rating+)

##### Share on other sites
Happy to be of help. [cool]

##### Share on other sites
For reference in case you need to manually check the numbers... I spent three hours adding a way to assign controls to keys in my old Stormrunner game (mostly with coordinate placing of the bitmap.. ugh).

Ignore blah, calc, and temp. blah & calc were the coordinates while temp was the width (normally 22).

HIGHLIGHTED, on the other hand, is what is returned by wParam when a WM_KEYDOWN event occurs.

Snippet!
		//now draw the keys..		temp=22;		if(HIGHLIGHTED==VK_BACK)		{			blah=348;	calc=345;	temp=46;		}		else if(HIGHLIGHTED==VK_TAB)		{			blah=24;	calc=369;	temp=46;		}		else if(HIGHLIGHTED==VK_RETURN)		{			blah=348;	calc=393;	temp=70;		}		else if(HIGHLIGHTED==VK_SHIFT)		{			blah=24;	calc=417;	temp=71;		}		else if(HIGHLIGHTED==VK_CONTROL)		{			blah=24;	calc=441;	temp=46;		}		else if(HIGHLIGHTED==VK_SPACE)		{			blah=148;	calc=441;	temp=94;		}		else if(HIGHLIGHTED==VK_PRIOR)//page up		{			blah=474;	calc=345;		}		else if(HIGHLIGHTED==VK_NEXT)//page down		{			blah=474;	calc=369;		}		else if(HIGHLIGHTED==VK_DELETE)		{			blah=424;	calc=369;		}		else if(HIGHLIGHTED==VK_END)		{			blah=449;	calc=369;		}		else if(HIGHLIGHTED==VK_HOME)		{			blah=449;	calc=345;		}		else if(HIGHLIGHTED==VK_LEFT)		{			blah=424;	calc=441;		}		else if(HIGHLIGHTED==VK_UP)		{			blah=449;	calc=417;		}		else if(HIGHLIGHTED==VK_RIGHT)		{			blah=474;	calc=441;		}		else if(HIGHLIGHTED==VK_DOWN)		{			blah=449;	calc=441;		}		else if(HIGHLIGHTED==VK_INSERT)		{			blah=424;	calc=345;		}		else if(HIGHLIGHTED>47 && HIGHLIGHTED <58)//0-9		{			if(HIGHLIGHTED==48)			{blah=273;	calc=345;}//0			else if(HIGHLIGHTED==49)	{blah=48;	calc=345;}//1			else if(HIGHLIGHTED==50)	{blah=73;	calc=345;}//2			else if(HIGHLIGHTED==51)	{blah=98;	calc=345;}//3			else if(HIGHLIGHTED==52)	{blah=123;	calc=345;}//4			else if(HIGHLIGHTED==53)	{blah=148;	calc=345;}//5			else if(HIGHLIGHTED==54)	{blah=173;	calc=345;}//6			else if(HIGHLIGHTED==55)	{blah=198;	calc=345;}//7			else if(HIGHLIGHTED==56)	{blah=223;	calc=345;}//8			else if(HIGHLIGHTED==57)	{blah=248;	calc=345;}//9		}		else if(HIGHLIGHTED>64 && HIGHLIGHTED <91)//a-z		{			if(HIGHLIGHTED==65)		{blah=73;  calc=393;}//a			else if(HIGHLIGHTED==66) {blah=198; calc=417;}//b			else if(HIGHLIGHTED==67) {blah=148; calc=417;}//c			else if(HIGHLIGHTED==68) {blah=123; calc=393;}//d			else if(HIGHLIGHTED==69) {blah=123; calc=369;}//e			else if(HIGHLIGHTED==70) {blah=148; calc=393;}//f			else if(HIGHLIGHTED==71) {blah=173; calc=393;}//g			else if(HIGHLIGHTED==72) {blah=198; calc=393;}//h			else if(HIGHLIGHTED==73) {blah=248; calc=369;}//i			else if(HIGHLIGHTED==74) {blah=223; calc=393;}//j			else if(HIGHLIGHTED==75) {blah=248; calc=393;}//k			else if(HIGHLIGHTED==76) {blah=273; calc=393;}//l			else if(HIGHLIGHTED==77) {blah=248; calc=417;}//m			else if(HIGHLIGHTED==78) {blah=223; calc=417;}//n			else if(HIGHLIGHTED==79) {blah=273; calc=369;}//o			else if(HIGHLIGHTED==80) {blah=298; calc=369;}//p			else if(HIGHLIGHTED==81) {blah=73;  calc=369;}//q			else if(HIGHLIGHTED==82) {blah=148; calc=369;}//r			else if(HIGHLIGHTED==83) {blah=98;  calc=393;}//s			else if(HIGHLIGHTED==84) {blah=173; calc=369;}//t			else if(HIGHLIGHTED==85) {blah=223; calc=369;}//u			else if(HIGHLIGHTED==86) {blah=173; calc=417;}//v			else if(HIGHLIGHTED==87) {blah=98;  calc=369;}//w			else if(HIGHLIGHTED==88) {blah=123; calc=417;}//x			else if(HIGHLIGHTED==89) {blah=198; calc=369;}//y			else if(HIGHLIGHTED==90) {blah=98;  calc=417;}//z		}		else if(HIGHLIGHTED>95 && HIGHLIGHTED<106)//numeric keypad		{			if(HIGHLIGHTED==96)			{blah=509;	calc=441;}//0			else if(HIGHLIGHTED==97)	{blah=509;	calc=417;}//1			else if(HIGHLIGHTED==98)	{blah=534;	calc=417;}//2			else if(HIGHLIGHTED==99)	{blah=559;	calc=417;}//3			else if(HIGHLIGHTED==100)	{blah=509;	calc=393;}//4			else if(HIGHLIGHTED==101)	{blah=534;	calc=393;}//5			else if(HIGHLIGHTED==102)	{blah=559;	calc=393;}//6			else if(HIGHLIGHTED==103)	{blah=509;	calc=369;}//7			else if(HIGHLIGHTED==104)	{blah=534;	calc=369;}//8			else if(HIGHLIGHTED==105)	{blah=559;	calc=369;}//9		}		else if(HIGHLIGHTED==106)//num*		{			blah=559;	calc=345;		}		else if(HIGHLIGHTED==107)//num+		{			blah=584;	calc=369;		}		else if(HIGHLIGHTED==109)//num-		{			blah=584;	calc=345;		}		else if(HIGHLIGHTED==110)//num.		{			blah=559;	calc=441;		}		else if(HIGHLIGHTED==111)//numslash		{			blah=534;	calc=345;		}		else if(HIGHLIGHTED>111 && HIGHLIGHTED<124)//Function keys		{			if(HIGHLIGHTED==112)		{blah=62;	calc=321;}//f1			else if(HIGHLIGHTED==113)	{blah=87;	calc=321;}//f2			else if(HIGHLIGHTED==114)	{blah=112;	calc=321;}//f3			else if(HIGHLIGHTED==115)	{blah=137;	calc=321;}//f4			else if(HIGHLIGHTED==116)	{blah=175;	calc=321;}//f5			else if(HIGHLIGHTED==117)	{blah=200;	calc=321;}//f6			else if(HIGHLIGHTED==118)	{blah=225;	calc=321;}//f7			else if(HIGHLIGHTED==119)	{blah=250;	calc=321;}//f8			else if(HIGHLIGHTED==120)	{blah=288;	calc=321;}//f9			else if(HIGHLIGHTED==121)	{blah=313;	calc=321;}//f10			else if(HIGHLIGHTED==122)	{blah=338;	calc=321;}//f11			else if(HIGHLIGHTED==123)	{blah=363;	calc=321;}//f12		}		else if(HIGHLIGHTED==186)//;		{			blah=298;	calc=393;		}		else if(HIGHLIGHTED==187)//=		{			blah=323;	calc=345;		}		else if(HIGHLIGHTED==188)//,		{			blah=273;	calc=417;		}		else if(HIGHLIGHTED==189)//-		{			blah=298;	calc=345;		}		else if(HIGHLIGHTED==190)//.		{			blah=298;	calc=417;		}		else if(HIGHLIGHTED==191)//slash		{			blah=323;	calc=417;		}		else if(HIGHLIGHTED==192)//tilde key		{			blah=24;	calc=345;		}		else if(HIGHLIGHTED==219)//[		{			blah=323;	calc=369;		}		else if(HIGHLIGHTED==220)//backslash		{			blah=373;	calc=369;		}		else if(HIGHLIGHTED==221)//]		{			blah=348;	calc=369;		}		else if(HIGHLIGHTED==222)//'		{			blah=323;	calc=393;		}

-Greven

##### Share on other sites
if I were you I would give a look at http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winui/winui/WindowsUserInterface/UserInput/VirtualKeyCodes.asp instead of the code Evil_Greven posted. [smile]

@ Evil_Greven:
Instead of a so many lines of code [sick] you can make use of a switch statement with cases (instead of else if... else if ...). You can do yet better if you use an array:

struct {    int blah;    int calc;    int temp;} array[256];array[VK_BACK].blah=348;array[VK_BACK].calc=345;array[VK_BACK].temp=46;

an so on.

Instead of a switch you just need theese assignments:

int myblah=array[HIGHLIGHTED].blah;
int mycalc=array[HIGHLIGHTED].calc;
int mytemp=array[HIGHLIGHTED].temp;

P.S.- HIGHLIGHTED is a var so you should write it in lowercase, just to avoid confusion with constants (in uppercase) [smile]

##### Share on other sites
Wait, I'm still kind of confused... [Sorry]
How would I use the ToAsciiEx() function to convert scan codes to virtual keys?
For example, how would I take VK_UP and get DIK_UP?
To go further, here is the code that defines the key names (it was in Game Maker Language, so ignore sytax)
//Defining Key Names//NOTE://string[256] c;//BYTE a;//FUNCTION string string(x) { returns x as a string }//FUNCTION string chr(x) { returns the character of Ascii value x }c[0]="?Unknown?"for (a=1; a<=255; a+=1;) c[a] = "<"+string(a)+">?";//Long listc[8]="Backspace";c[13]="Enter";c[16]="Shift";c[17]="Control";c[18]="Alt";c[19]="Pause/Break?";c[20]="CAPS Lock";c[27]="Escape";c[32]="Space";c[33]="Page Up";c[34]="Page Down";c[35]="End Key";c[36]="Home Key";c[37]="Left";c[38]="Up";c[39]="Right";c[40]="Down";c[45]="Insert";c[46]="Delete";for (b=48; b<=57; b+=1;) c[b]="Number "+chr(b); //Number 0-9for (d=65; d<=90; d+=1;) c[d]=chr(d); //A-Zfor (e=96; e<=105; e+=1;) c[e]="Numpad "+string(e-96) //Numpad 0-9c[106]="Numpad Asterik '*'"c[107]="Numpad Plus '+'"c[109]="Numpad Dash '-'"c[110]="Numpad Period '.'"c[111]="Numpad Slash '/'"for (f=112; f<=123; f+=1;) c[f]="F"+string(f-111) //F1-11

About the '& 0x80', in other tutorials, it returns the highest bit in the byte.

##### Share on other sites
Quote:
 Original post by deadimpWell, I found the tutorial here that describes it, but I'm running into one problem: This function doesn't work with the arrow keys (I haven't tested many other keys though). I know it works with the letters, and the shift key, but when I use VK_UP or VK_DOWN, it always returns false. Here's the function:BYTE Keys[256]; //Keys is a buffer for a LPDIRECTINPUTDEVICE8bool keyboard_check(UINT key) { return (Keys[ MapVirtualKeyEx(key,0,GetKeyboardLayout(0)) ] & 0x80);}I'm not sure what I did wrong. (Yes, I am looping)

I have just written my input library and I came across the same problem. It so happens that certain keys, (VK_ UP,DOWN,LEFT,RIGHT,KeyPad Enter) do not translate correctly with any MapVirtualKey - here was my simple fix that I will eventuallly try and make better, but it works for now:

[CODE]
// Convert to ascii
BYTE ASCII = MapVirtualKeyEx( m_keyboardbuffer [ dwCurbuffer ].dwOfs, 1, m_layout );
if( ASCII == 0 )
{
int temp = m_keyboardbuffer [ dwCurbuffer ].dwOfs;
if( temp == DIK_LEFT )
ASCII = INPUT_LEFT;
else if( temp == DIK_RIGHT )
ASCII = INPUT_RIGHT;
else if( temp == DIK_UP )
ASCII = INPUT_UP;
else if( temp == DIK_DOWN
ASCII = INPUT_DOWN;
...
}
...
[/code]

Basically I am checking if the key I convert from DI is 0, than see if it is something that does not translate, such as those DIK_ arrow keys. The INPUT_ keys are my own defines that translate to VK_'s.

I hope this helps some.

##### Share on other sites
Quote:
 Original post by deadimpWell, I found the tutorial here that describes it, but I'm running into one problem: This function doesn't work with the arrow keys (I haven't tested many other keys though). I know it works with the letters, and the shift key, but when I use VK_UP or VK_DOWN, it always returns false. Here's the function:BYTE Keys[256]; //Keys is a buffer for a LPDIRECTINPUTDEVICE8bool keyboard_check(UINT key) { return (Keys[ MapVirtualKeyEx(key,0,GetKeyboardLayout(0)) ] & 0x80);}I'm not sure what I did wrong. (Yes, I am looping)

I have just written my input library and I came across the same problem. It so happens that certain keys, (VK_ UP,DOWN,LEFT,RIGHT,KeyPad Enter) do not translate correctly with any MapVirtualKey - here was my simple fix that I will eventuallly try and make better, but it works for now:

// Convert to ascii   BYTE ASCII = MapVirtualKeyEx( m_keyboardbuffer [ dwCurbuffer ].dwOfs, 1, m_layout );   if( ASCII == 0 )   {      int temp = m_keyboardbuffer [ dwCurbuffer ].dwOfs;      if( temp == DIK_LEFT )      ASCII = INPUT_LEFT;      else if( temp == DIK_RIGHT )            ASCII = INPUT_RIGHT;      else if( temp == DIK_UP )	    ASCII = INPUT_UP;      else if( temp == DIK_DOWN                   ASCII = INPUT_DOWN;       ...   }   ...

Basically I am checking if the key I convert from DI is 0, than see if it is something that does not translate, such as those DIK_ arrow keys. The INPUT_ keys are my own defines that translate to VK_'s.

I hope this helps some.

- Drew

##### Share on other sites
You don't even really need to do that. Just use the DIK constants. The snippet in that article is only useful if you're using DirectInput and you want the user to be able to type strings in your game (e.g. type in their name). The DIK constants don't map easily to ASCII characters so you'd either need a massive switch statement or you'd use the function that the article presents. But for general keyboard use (i.e. movement, firing, etc) you can just use the DIK constants.

cheers
sam.

##### Share on other sites

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

## Create an account

Register a new account

• ### Forum Statistics

• Total Topics
628642
• Total Posts
2983998

• 9
• 9
• 10
• 21
• 20