views:

516

answers:

1

I've got one Form, custom drawing, no controls.

When I need to get the input from the user I go to OnKeyDown event and then map event's KeyData to a string** - so that I can recognize that user has pressed "ctrl X", etc, so everything is almost ok... the problem is with different keyboard settings and language specific letters - so for today my users get

ã -> a

ó -> o

So I need the KeyPress event right? But how do I know that user typed in for example 'ł' and not alt+L? I can't get my head around that for a while now...

** - I need to do it like that since I let users to configure shortcuts and using .ToString() produces not so user friendly text like "OemPeriod, Control" or even better: "ControlKey, Control"

+1  A: 

Yes, you'll need the KeyPress event. Or rather, override OnKeyPress. Mapping virtual key codes in the KeyDown event to key strokes is quite difficult, you'd have to be aware of the current keyboard layout. Take a look at the MSDN docs for ToUnicodeEx() to see what you are up against.

You don't have to worry about keystroke combinations like Alt+L. They don't generate a KeyPress event.

Here's an example. Start a new Windows Forms project and make the code look like this:

using System;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace WindowsFormsApplication1 {
  public partial class Form1 : Form {
    public Form1() {
      InitializeComponent();
    }
    StringBuilder mText = new StringBuilder();

    protected override void OnKeyPress(KeyPressEventArgs e) {
      if (e.KeyChar == '\b') {
        if (mText.Length > 0) mText.Remove(mText.Length - 1, 1);
      }
      else mText.Append(e.KeyChar);
      Invalidate();
    }

    protected override void OnPaint(PaintEventArgs e) {
      TextFormatFlags fmt = TextFormatFlags.Left;
      TextRenderer.DrawText(e.Graphics, mText.ToString(), this.Font, this.ClientRectangle, Color.Black, fmt);
    }
  }
}
Hans Passant
Hmm, correct me if I'm wrong, but KeyDown is before the KeyPress event, so... In KeyDown I need to know if the pressed keys are going to be handled by KeyPress... so I'll use ToUnicodeEx, right? But if I'm using ToUnicodeEx then I won't need the KeyPress event, correct?
argh
No, you don't need to know. KeyPress will let you know. Don't use ToUnicodeEx().
Hans Passant
Hmm I'm maybe doing it the 'wrong way' but I handle everything in KeyDown and everything seems to work fine :) But can you 'show' me in few lines of pseudo-code what your solution looks like?
argh
I updated my answer
Hans Passant
I'll check the "proper" version when I'll have the time, for now I'll stick with ToUnicodeEx(), thx!
argh