If you ever used GetAsyncKeyState() or GetKeyState() or any other windows function using virtual keys, this post might be useful to you.
There are certain situations where you might want to print out a string representation of the virtual key you're dealing with, and from what I've researched, I don't think there's an API function call that will do this for us, so I made my own.
The following function will take as input a Virtual Key Code (e.g. VK_RETURN) and then return the string representation of the key (e.g. "VK_RETURN"). Of course it works for 'A' to 'Z' and digits as well (there are no VK_* macros for such virtual keys because they're the same as the ascii char representation).
Here's the function, Its a big one so I've hidden it by default.
Show Code
#define caseStringify(x) case x: return string(#x)
string vkToString(int vk) {
char c[2] = {0};
if (vk >= '0' && vk <= '9') { c[0]=(char)vk; return string(c); }
if (vk >= 'A' && vk <= 'Z') { c[0]=(char)vk; return string(c); }
switch(vk) {
// VK_0 - VK_9 are the same as ASCII '0' - '9' (0x30 - 0x39)
// 0x40 : unassigned
// VK_A - VK_Z are the same as ASCII 'A' - 'Z' (0x41 - 0x5A)
caseStringify(VK_LBUTTON);
caseStringify(VK_RBUTTON);
caseStringify(VK_CANCEL);
caseStringify(VK_MBUTTON); // NOT contiguous with L & RBUTTON
caseStringify(VK_XBUTTON1); // NOT contiguous with L & RBUTTON
caseStringify(VK_XBUTTON2); // NOT contiguous with L & RBUTTON
caseStringify(VK_BACK);
caseStringify(VK_TAB);
caseStringify(VK_CLEAR);
caseStringify(VK_RETURN);
caseStringify(VK_SHIFT);
caseStringify(VK_CONTROL);
caseStringify(VK_MENU);
caseStringify(VK_PAUSE);
caseStringify(VK_CAPITAL);
caseStringify(VK_KANA);
caseStringify(VK_JUNJA);
caseStringify(VK_FINAL);
caseStringify(VK_KANJI);
caseStringify(VK_ESCAPE);
caseStringify(VK_CONVERT);
caseStringify(VK_NONCONVERT);
caseStringify(VK_ACCEPT);
caseStringify(VK_MODECHANGE);
caseStringify(VK_SPACE);
caseStringify(VK_PRIOR);
caseStringify(VK_NEXT);
caseStringify(VK_END);
caseStringify(VK_HOME);
caseStringify(VK_LEFT);
caseStringify(VK_UP);
caseStringify(VK_RIGHT);
caseStringify(VK_DOWN);
caseStringify(VK_SELECT);
caseStringify(VK_PRINT);
caseStringify(VK_EXECUTE);
caseStringify(VK_SNAPSHOT);
caseStringify(VK_INSERT);
caseStringify(VK_DELETE);
caseStringify(VK_HELP);
caseStringify(VK_LWIN);
caseStringify(VK_RWIN);
caseStringify(VK_APPS);
caseStringify(VK_SLEEP);
caseStringify(VK_NUMPAD0);
caseStringify(VK_NUMPAD1);
caseStringify(VK_NUMPAD2);
caseStringify(VK_NUMPAD3);
caseStringify(VK_NUMPAD4);
caseStringify(VK_NUMPAD5);
caseStringify(VK_NUMPAD6);
caseStringify(VK_NUMPAD7);
caseStringify(VK_NUMPAD8);
caseStringify(VK_NUMPAD9);
caseStringify(VK_MULTIPLY);
caseStringify(VK_ADD);
caseStringify(VK_SEPARATOR);
caseStringify(VK_SUBTRACT);
caseStringify(VK_DECIMAL);
caseStringify(VK_DIVIDE);
caseStringify(VK_F1);
caseStringify(VK_F2);
caseStringify(VK_F3);
caseStringify(VK_F4);
caseStringify(VK_F5);
caseStringify(VK_F6);
caseStringify(VK_F7);
caseStringify(VK_F8);
caseStringify(VK_F9);
caseStringify(VK_F10);
caseStringify(VK_F11);
caseStringify(VK_F12);
caseStringify(VK_F13);
caseStringify(VK_F14);
caseStringify(VK_F15);
caseStringify(VK_F16);
caseStringify(VK_F17);
caseStringify(VK_F18);
caseStringify(VK_F19);
caseStringify(VK_F20);
caseStringify(VK_F21);
caseStringify(VK_F22);
caseStringify(VK_F23);
caseStringify(VK_F24);
caseStringify(VK_NUMLOCK);
caseStringify(VK_SCROLL);
caseStringify(VK_OEM_NEC_EQUAL); // '=' key on numpad
caseStringify(VK_OEM_FJ_MASSHOU); // 'Unregister word' key
caseStringify(VK_OEM_FJ_TOUROKU); // 'Register word' key
caseStringify(VK_OEM_FJ_LOYA); // 'Left OYAYUBI' key
caseStringify(VK_OEM_FJ_ROYA); // 'Right OYAYUBI' key
caseStringify(VK_LSHIFT);
caseStringify(VK_RSHIFT);
caseStringify(VK_LCONTROL);
caseStringify(VK_RCONTROL);
caseStringify(VK_LMENU);
caseStringify(VK_RMENU);
caseStringify(VK_BROWSER_BACK);
caseStringify(VK_BROWSER_FORWARD);
caseStringify(VK_BROWSER_REFRESH);
caseStringify(VK_BROWSER_STOP);
caseStringify(VK_BROWSER_SEARCH);
caseStringify(VK_BROWSER_FAVORITES);
caseStringify(VK_BROWSER_HOME);
caseStringify(VK_VOLUME_MUTE);
caseStringify(VK_VOLUME_DOWN);
caseStringify(VK_VOLUME_UP);
caseStringify(VK_MEDIA_NEXT_TRACK);
caseStringify(VK_MEDIA_PREV_TRACK);
caseStringify(VK_MEDIA_STOP);
caseStringify(VK_MEDIA_PLAY_PAUSE);
caseStringify(VK_LAUNCH_MAIL);
caseStringify(VK_LAUNCH_MEDIA_SELECT);
caseStringify(VK_LAUNCH_APP1);
caseStringify(VK_LAUNCH_APP2);
caseStringify(VK_OEM_1); // ';:' for US
caseStringify(VK_OEM_PLUS); // '+' any country
caseStringify(VK_OEM_COMMA); // ',' any country
caseStringify(VK_OEM_MINUS); // '-' any country
caseStringify(VK_OEM_PERIOD); // '.' any country
caseStringify(VK_OEM_2); // '/?' for US
caseStringify(VK_OEM_3); // '`~' for US
caseStringify(VK_OEM_4); // '[{' for US
caseStringify(VK_OEM_5); // '\|' for US
caseStringify(VK_OEM_6); // ']}' for US
caseStringify(VK_OEM_7); // ''"' for US
caseStringify(VK_OEM_8);
caseStringify(VK_OEM_AX); // 'AX' key on Japanese AX kbd
caseStringify(VK_OEM_102); // "<>" or "\|" on RT 102-key kbd.
caseStringify(VK_ICO_HELP); // Help key on ICO
caseStringify(VK_ICO_00); // 00 key on ICO
caseStringify(VK_PROCESSKEY);
caseStringify(VK_ICO_CLEAR);
caseStringify(VK_PACKET);
}
c[0]=(char)vk;
return string(c);
}
I ended up needing this on my NES emulator in order to display mapped-keyboard settings. That's probably where other people will need it too.
In case you've never seen something like this and you're wondering how it works, it uses a powerful and very useful feature of the C/C++ preprocessor called 'stringification'.
Essentially you take convert arguments to a macro into string representations.
Here's more info:
http://gcc.gnu.org/onlinedocs/cpp/Stringification.html
I took the winapi macros for the virtual keys and wrapped them in a macro that converts them to strings. Mostly was just copy-paste and regex replace work.
Anyways have fun :)
Wonderful, I like this post!
ReplyDeleteExtremely useful even a decade later, thank you.
ReplyDelete