Huddled Masses
The internet home of Joel "Jaykul" Bennett...
Browse: Home / How to get the Char(acter) and VirtualKey from a WPF KeyDown event

How to get the Char(acter) and VirtualKey from a WPF KeyDown event

By Joel 'Jaykul' Bennett on 22-Sep-2008

While working on my WPF PowerShell console, I’m working on implementing PSRawUserInterface, and had to implement a method called ReadKey which returns a KeyInfo object. KeyInfo is a pretty simple struct class with four properties:

  • VirtualKeyCode
  • Character
  • ControlKeyState
  • KeyDown

So it doesn’t seem like it would be a real problem … just handle the KeyDown event or PreviewKeyDown event on the WPF control, right? Well, no. Because all of these just use a KeyEventArgs parameter which has a Key property which doesn’t map to a virtual key code (why isn’t the WPF Key enumeration in the right order? It’s ridiculous), and there’s no character information at all.

Thankfully, it is possible to get this information using PInvoke, but I wouldn’t want to try to do this in Silverlight. ;)

Here’s how it goes:

First, you need to get the VirtualKey code. Thankfully, there’s a simple class called KeyInterop, which exposes a static method VirtualKeyFromKey that gets us this information.

Then, we need to get the character. This is much trickier. First we have to get the keyboard state and then we have to map that VirtualKey we got in the first step to a ScanCode, and finally, convert all of that to Unicode, because .Net doesn’t really speak ASCII ;)

The rest of the code is pretty clear, I hope… you can find the current version of Keyboard.cs on CodePlex in the PoshCode source repository, but to make this complete, here’s the version as it stands now:


using System.Management.Automation.Host;
using System.Runtime.InteropServices;
using System.Text;
using System.Windows.Input;

namespace Huddled.Interop
{
   public static class Keyboard
   {

      /// <summary>The set of valid MapTypes used in MapVirtualKey
      /// </summary>
      /// <remarks></remarks>
      public enum MapType : uint
      {
         /// <summary>uCode is a virtual-key code and is translated into a scan code.
         /// If it is a virtual-key code that does not distinguish between left- and
         /// right-hand keys, the left-hand scan code is returned.
         /// If there is no translation, the function returns 0.
         /// </summary>
         /// <remarks></remarks>
         MAPVK_VK_TO_VSC = 0x0,

         /// <summary>uCode is a scan code and is translated into a virtual-key code that
         /// does not distinguish between left- and right-hand keys. If there is no
         /// translation, the function returns 0.
         /// </summary>
         /// <remarks></remarks>
         MAPVK_VSC_TO_VK = 0x1,

         /// <summary>uCode is a virtual-key code and is translated into an unshifted
         /// character value in the low-order word of the return value. Dead keys (diacritics)
         /// are indicated by setting the top bit of the return value. If there is no
         /// translation, the function returns 0.
         /// </summary>
         /// <remarks></remarks>
         MAPVK_VK_TO_CHAR = 0x2,

         /// <summary>Windows NT/2000/XP: uCode is a scan code and is translated into a
         /// virtual-key code that distinguishes between left- and right-hand keys. If
         /// there is no translation, the function returns 0.
         /// </summary>
         /// <remarks></remarks>
         MAPVK_VSC_TO_VK_EX = 0x3,

         /// <summary>Not currently documented
         /// </summary>
         /// <remarks></remarks>
         MAPVK_VK_TO_VSC_EX = 0x4,
      }

      /// <summary>
      /// The ToUnicode function translates the specified virtual-key code and keyboard state
      /// to the corresponding Unicode character or characters. To specify a handle to the keyboard layout
      /// to use to translate the specified code, use the ToUnicodeEx function.
      /// </summary>
      ///

Reblog this post [with Zemanta]

Similar Posts:

  • WPF Window “Native” Behavior: Metro Window
  • Creating WPF UIs for PowerShell with PowerBoots and Visual Studio WPF Designer
  • The Obligatory ShowUI Clock
  • PowerBoots 0.3 – The Faster Edition
  • Using alternate credentials with the FileSystem in PowerShell

Posted in Huddled | Tagged .Net Framework, Char, EventHandler, Interop, KeyDown, PInvoke, ScanCode, VirtualKey, WPF

« Previous Next »

Lijit Search

Tags

.Net .Net 2008 Scripting Games Automation Bugs Design Development Funny Gadgets GeoShell GUI Huddled Masses Internet licensing Microsoft Modules My Software News Personal PInvoke Pipeline Politics PoshCode PoshConsole PowerBoots PowerShell PowerShell Functions PowerTips Rants Recommender Repository Scripting ShowUI Software Solutions Textile Tips User Group UserInterface WalkThrough WebHosting Windows 7 WordPress WPF Xml

About Huddled Masses

This is web site is dedicated to the musings of Joel Bennett (aka Jaykul) about technology, software, software development, the web, and the world.

Any resemblance of the views expressed and the views of my employer, my terminal, or the view out my window are purely coincidental. The resemblance between them and my own views is non-deterministic. The question of the existence of views in the absence of anyone to hold them is left as an exercise for the reader.

P.S.: I occasionally link to things I think are great. When I do, I occasionally find a "referral code" so I can make a little cash. I promise that I don't link to anything just because of that cash (I wouldn't cross the street for the amount of cash those links bring in, never mind write a whole blog post) ... but I do not promise that things I link to will stay great as time passes, nor that you will agree with me about their greatness!

Archives

  • January 2012
  • October 2011
  • August 2011
  • July 2011
  • June 2011
  • March 2011
  • February 2011
  • January 2011
  • November 2010
  • August 2010

Copyright © 2012 Joel Bennett.

Powered by WordPress and Hybrid.