So, I'm going to cut straight to it, I'm trying to make a chat system in an XNA game I'm making. I can easily figure out what keys are being pressed BUT I have no way of knowing what is actually being typed. To me, it looks like they are saying: OemShifthello billOemPeriod OemShifthow are youOemQuestion
which should look like Hello bill. How are you?
(or something along those lines).
Whats the best way to handle all of this?
For the PC there's nothing built in to the XNA framework making that easy (it's a different story for WP7 and the Xbox).
This post here summarizes pretty much all of your options fairly well.
http://dream-forever.net/Blog/2011/08/29/getting-true-keyboard-input-into-your-xna-games/
Basically
- Build a large dictionary with character to KeyPress mappings
- Hook into the XNA Game Forms KeyDown, KeyUp, KeyPress events
- Use the IMessageFilter interface
- Use SetWindowsHookEx to grab the Key Events
Each of those methods have their pros and cons and the author of the post provided a sample you can download.
In doing some research I also came across a library from the guys at Nuclex. They typically create fairly robust solutions so it would definitely be worth checking that out as well.
http://www.nuclex.org/blog/announcements/105-new-component-nuclex-input
The important thing to remember is that you're on the PC and that really ANY library will work that is out there (with some modificaton/tweakings). So don't limit yourself to looking at just XNA related samples. Samples for DirectInput, SlimDX, SharpDX etc would also be options, they may just take a little extra work to drop into your project.
So the simple solution I used was to get a hook to Win32 keyboard, and let windows translate whatever is being typed. It's on my other computer, but its basically using this solution on Gamedev.net. (post number #10)
Awesome thing is, if you use [DllImport("user32.dll", CharSet=CharSet.Unicode)]
(the CharSet part on all the .dll imports), you can get localized input from your keyboard!
So place this somewhere, register the events in Initialize, and that's it! Hope it works for you.
Edit
This whole Win32 business may seem intimidating, but don't let that stop you from using this - it's just a matter of copy-paste, and you can get it running perfectly in literally 2 minutes.
I guess you are querying the keyboard input via keyState.GetPressedKeys()
?
You will have to use a switch
statement somewhere in your code to map the members of the Keys
enum to actual characters. The ToString()
method works fine with letters, but not with the symbols, as they are specified by name.
switch (keyPressed)
{
case Keys.OemPeriod :
character = '.';
break;
case Keys.OemQuestion :
character = '?';
break;
// More cases
}
Watch out, though, as keyboards are different. As you correctly stated: Key != Symbol. Some keys on other hardware are maybe associated with a completely different symbol.