Reputation: 3720
I have an implementation which hooks into the keydown event, which suppresses the keypress event and does some magic. Now I want to show something more friendly than "ControlKey" etc, so there's a switch you can see in the code below. Except I've realised things like the number keys along the top end up as D1
, D2
, etc., and then there's things like Add
showing up for the numpad +. In addition, Print Screen doesn't seem to be recognised.
Is there something I'm missing?
This is a hard question for me to describe fluently, but hopefully you get what I mean. If not I guess I'll be replying to comments and improving this as I go.
private int numKeys = 0;
private List<int> shortcutKeys = new List<int>();
private void textBoxRegionKeys_Click(object sender, EventArgs e)
{
textBoxRegionKeys.SelectAll();
}
private void textBoxRegionKeys_KeyDown(object sender, KeyEventArgs e)
{
// There are certain keys we want to ignore...
if (e.KeyCode != Keys.Delete && e.KeyCode != Keys.Back)
{
// We can handle this ourselves, thanks
e.SuppressKeyPress = true;
// Shortern what we show
string ret = e.KeyCode.ToString();
switch (ret)
{
case "ControlKey": ret = "Ctrl"; break;
case "ShiftKey": ret = "Shift"; break;
case "Menu": ret = "Alt"; break;
}
// If we haven't selected anything, we should be appending
if (textBoxRegionKeys.SelectionLength == 0)
{
if (numKeys > 0)
{
// Does our key already exist in the list?
if (shortcutKeys.Exists(x => x == e.KeyValue))
{
return;
}
textBoxRegionKeys.Text += " + ";
}
textBoxRegionKeys.Text += ret;
shortcutKeys.Add(e.KeyValue);
numKeys++;
}
else
{
textBoxRegionKeys.Text = ret;
shortcutKeys.Clear();
shortcutKeys.Add(e.KeyValue);
numKeys = 1;
}
}
}
Upvotes: 0
Views: 330
Reputation: 16353
The TextBox KeyDown/KeyPress etc will only be raised for keys that may be accepted as input in to the text box (and associated modifiers). As such, you will not see keys handled such as Print Screen etc. The best option I can think of is not ideal, but you could override the ProcessKeyPreview or some other Form level Message interceptor to get notified of ANY key press. Something like...
protected override bool ProcessKeyPreview(ref Message m)
{
var keyCode = (Keys)Enum.ToObject(typeof (Keys), m.WParam);
//Insert some logic
return base.ProcessKeyPreview(ref m);
}
Of course, this method will be invoked whenever the FORM has focus, and a key is pressed, so you would have to filter down by doing some form of check (which again is not ideal)
if(ReferenceEquals(ActiveControl, textBoxRegionKeys)) {}
Which if your dealing with things like UserControls will be very unreliable.
As for formatting in to nice friendly messages, I think you basically you will need your own map of special characters... I am not aware of any Globalized lookup for Keys. I will dig a little and update the answer if I find something.
Edit
Did a little digging and couldn't find anything obvious for nice key mappings. I would just create a map of "friendly" key names:
private static readonly Dictionary<Keys, String> KeysMap = new Dictionary<Keys, String>
{
{ Keys.D1, "1"},
{ Keys.D9, "9"}
};
And do something like:
String friendlyKeyCode;
if (!KeysMap.TryGetValue(keyCode, out friendlyKeyCode))
friendlyKeyCode = keyCode.ToString();
Personally, I find this approach better than a massive switch... but that works too.
Upvotes: 1