Lessons Learned About Capturing Keystrokes in Windows 8

It would appear I’m going to start pumping out little “lessons learned” articles over the next few weeks, as I’ve learned an absolute TON from building my King Poker app.  Today’s lesson is about capturing keystrokes.

Many of you have probably done this before: you want to recognize a specific key that has been pressed when a user is entering something into a TextBox.  Maybe you want to take action when they press the Enter key, for example.  This is generally simple enough, you just set up a KeyDown (or KeyUp, depending on your needs) event on the TextBox in question, and then just check every time the event fires until you find the key you’re looking for.

That’s not what I wanted to do.

To give you some context, here’s a screenshot of my app:

screenshot_03162013_184638

For the cards in question, I want to hold the three Queens, and then re-deal, hoping to get the 4th Queen, or maybe one of the Wild Deuces.  (If I’m very lucky, BOTH!)

As the game currently stands, it is designed for use on a touch screen or with a mouse.  Clicking/tapping on a card will mark it as “HELD,” and won’t replace it when you click the “DEAL” button.  But you have to actually move your fingers or mouse to each card to mark them.  For speed players, they’d prefer physical buttons that can be pressed over having to touch a screen.

This is where my key capture needs come in.

I don’t have a control that I can just drop a KeyDown event on.  I want to be able to monitor keystrokes at all times.  For this, we can simply wire up an event in the code-behind file, and capture it there.  Here’s what it looks like:

protected override void OnNavigatedTo(NavigationEventArgs e)
{
    Window.Current.CoreWindow.KeyDown += CoreWindow_KeyDown;
}

void CoreWindow_KeyDown(Windows.UI.Core.CoreWindow sender, Windows.UI.Core.KeyEventArgs args)
{
    switch (args.VirtualKey)
    {
        case Windows.System.VirtualKey.Number1:
            if (HoldRound) HoldCard(Card0);
            else SetBet(1);
            break;
        case Windows.System.VirtualKey.Number2:
            HoldCard(Card1);
            break;
        case Windows.System.VirtualKey.Number3:
            HoldCard(Card2);
            break;
        case Windows.System.VirtualKey.Number4:
            HoldCard(Card3);
            break;
        case Windows.System.VirtualKey.Number5:
            if (HoldRound) HoldCard(Card4);
            else SetBet(5);
            break;
        case Windows.System.VirtualKey.Space:
            Deal();
            break;
    }
}

protected override void OnNavigatingFrom(NavigatingCancelEventArgs e)
{
    Window.Current.CoreWindow.KeyDown -= CoreWindow_KeyDown;
}

 

As you can see above, I subscribe to the Window.Current.CoreWindow.KeyDown event, which fires before anything else gets access to the key event.  This is also a great way to capture keystrokes before they get to your TextBox controls, etc.

Once I’ve got this event rigged up (and un-rigged it with my OnNavigatingFrom event), I can now easily provide physical keys for my power users by enabling the #1 – #5 keys to hold the cards rather than having to move their mouse all over the screen.  In addition, I’ve also set the Spacebar up to provide “Deal” functionality, which means they never need the mouse once they start playing the game.  Here’s a look at the cards held:

screenshot_03162013_190355

And finally, in case you were wondering, here’s what I drew (I got that wild 2) to get my four of a kind!

screenshot_03162013_190451

Summary

So there you have it.  A simple way to capture keystrokes in C# and XAML applications for Windows 8/Windows RT applications.  Many apps have a need for this in some way (even if it’s to provide a shortcut or even an Easter Egg), so consider this in your applications as well.

clip_image002

9 thoughts on “Lessons Learned About Capturing Keystrokes in Windows 8

  1. 1. string key = args.VirtualKey.ToString();
    key is assigned but never used.
    2. switch (args.VirtualKey.ToString()); case “Number1″:
    it’s inefficient to convert enum to string in a switch/case block

    • You are absolutely right. Not sure why I did it that way. Code has been updated. Must have been a late night of coding!

  2. Sorry dude… But your GUI Design ist totally bad!! It makes me puke…

  3. Nice work, good info – thanks.

  4. Good concise article! Enjoyed it on my train ride home

  5. Last update caused issues on Surface RT. Money counter is messed up
    D

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s