Wednesday, April 20, 2011

C#: Is there a way to properly convert Keys.Oem? to proper string without doing string manipulation?

C#: Is there a method to convert Keys.Oem? to proper string without doing string manipulation?

When I do e.ToString() and if the key is a / or <, and so on, it converts as OemSlash, OemQuestion. Is there a way .net method properly convert Keys.OemSpace to "Space" without it including "OemSpace" and without string manipulation? And if there's not a built-in method to do such a thing, what would be the best way to go upon it then?

From stackoverflow
  • The only way I can think of to do this is to use regular expressions. I know this isn't the answer you probably wanted. Hopefully someone knows of a method to do this.

  • You probably want to use the ToAscii or ToUnicode function for this, which is part of the Win32 API. (I doubt you're going to get a simple pure BCL/cross-platform solution, if that's what you want.) They're relatively simple functions that convert virtual key codes to characters (either in ASCII or Unicode encoding, as the names suggest).

    Edit: I think you may actually be in luck with the KeysConverter class!

    Samuel : KeysConverter seems to be almost useless. Keys.D3 | Keys.Shift produces "Shift+3".
    Noldorin : Yeah, so that's not what is needed. I'll remove that and leave the original part of the post.
  • If you want to determine what character you will get from a given key with given modifiers, you should use the user32 ToAscii function. Or ToAsciiEx if you want to use a keyboard layout other then the current one.

    using System.Runtime.InteropServices;
    public static class User32Interop
    {
      public static char ToAscii(Keys key, Keys modifiers)
      {
        var outputBuilder = new StringBuilder(2);
        int result = ToAscii((uint)key, 0, GetKeyState(modifiers),
                             outputBuilder, 0);
        if (result == 1)
          return outputBuilder[0];
        else
          throw new Exception("Invalid key");
      }
    
      private const byte HighBit = 0x80;
      private static byte[] GetKeyState(Keys modifiers)
      {
        var keyState = new byte[256];
        foreach (Keys key in Enum.GetValues(typeof(Keys)))
        {
          if ((modifiers & key) == key)
          {
            keyState[(int)key] = HighBit;
          }
        }
        return keyState;
      }
    
      [DllImport("user32.dll")]
      private static extern int ToAscii(uint uVirtKey, uint uScanCode,
                                        byte[] lpKeyState,
                                        [Out] StringBuilder lpChar,
                                        uint uFlags);
    }
    

    You can now use it like this:

    char c = User32Interop.ToAscii(Keys.OemQuestion, Keys.ShiftKey); // = '?'
    

    If you need more than one modifier, just or them. Keys.ShiftKey | Keys.AltKey

    SealedSun : +1 for the code. Really useful, thanks ^^

0 comments:

Post a Comment