Convert key code to corresponding display character

In a C # Windows.Forms project, I have a control that does not provide a KeyPressed event (its COM control is an ESRI card).

It contains only KeyUp and KeyDown events containing the KeyEventArgs structure .

How can I convert the information in KeyEventArgs to a displayed Unicode character, given the currently active keyboard layout, etc.?

+5
source share
3 answers

The trick is to use the user32.dll feature set: GetWindowThreadProcessId , GetKeyboardLayout , GetKeyboardState and ToUnicodeEx .

  • Use GetWindowThreadProcessId with your control handle to achieve the corresponding native thread identifier.
  • Pass this GetKeyboardLayout stream ID to get the current keyboard layout.
  • Call GetKeyboardState to get the current state of the keyboard. This helps the next method decide which character will be generated according to the state of the modifiers.
  • , ToUnicodeEx key code ( ), state, ( ), (0) .

, .

  public class KeyboardHelper
    {
        [DllImport("user32.dll", CharSet = CharSet.Unicode, ExactSpelling = true)]
        private static extern int ToUnicodeEx(
            uint wVirtKey,
            uint wScanCode,
            Keys[] lpKeyState,
            StringBuilder pwszBuff,
            int cchBuff,
            uint wFlags,
            IntPtr dwhkl);

        [DllImport("user32.dll", ExactSpelling = true)]
        internal static extern IntPtr GetKeyboardLayout(uint threadId);

        [DllImport("user32.dll", ExactSpelling = true)]
        internal static extern bool GetKeyboardState(Keys[] keyStates);

        [DllImport("user32.dll", ExactSpelling = true)]
        internal static extern uint GetWindowThreadProcessId(IntPtr hwindow, out uint processId);

        public static string CodeToString(int scanCode)
        {
            uint procId;
            uint thread = GetWindowThreadProcessId(Process.GetCurrentProcess().MainWindowHandle, out procId);
            IntPtr hkl = GetKeyboardLayout(thread);

            if (hkl == IntPtr.Zero)
            {
                Console.WriteLine("Sorry, that keyboard does not seem to be valid.");
                return string.Empty;
            }

            Keys[] keyStates = new Keys[256];
            if (!GetKeyboardState(keyStates))
                return string.Empty;

            StringBuilder sb = new StringBuilder(10);
            int rc = ToUnicodeEx((uint)scanCode, (uint)scanCode, keyStates, sb, sb.Capacity, 0, hkl);
            return sb.ToString();
        }
    }
+11

Itai Bar-Haim , .

CodeToString (int scanCode) ToUnicodeEx() -1, .

ToUnicodeEx() 2. , .

, ^ ( ), $. ^ (), ^ $azertyui.

, :

1) StringBuilder ToUnicodeEx(). , .

2) ToUnicodeEx() -1, char StringBuilder . : ToUnicodeEx() scancode Space.

, : , , ToUnicodeEx(), . , , - ToUnicodeEx() scancode Space .

!

+8

KeysConverter ConvertToString. , KeyDown KeyPress.

0

All Articles