My goal is to implement a custom Control + S key press handler to wire up to a custom save method in a winforms app.
There are several ways to accomplish this based on my R&D. First, I tried the obvious KeyPress event handler. This wasn't powerful enough to capture the key presses I need (it wasn't called on the Editor level, which is what I needed).
The second option which looks better is the protected override bool ProcessCmdKey(ref Message msg, Keys keyData) override. This works - it intercepts the CTRL key click, but apparently I need to write extra code to persist the fact the CTRL key is pressed and intercept the next key press (which would be S in my case) and then perform the custom action.
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
if (keyData == (Keys.S | Keys.Control))
{
// This is never called
}
else if (keyData == (Keys.Menu | Keys.Alt))
{
// this is called each time I hit CTRL
}
return true;
}
ProcessCmdKey seems to be called immediately after I hit the CTRL key.
This post suggests creating a KeyTracker class that will persist the keys pressed and do what it needs to do:
Capture Key Sequence via ProcessCmdKey
Which seems like a good option, but before I dig in an implement a memento tracking pattern, does anyone have input on how else to accomplish this seemingly common feature?
Another pattern uses the GetKeyboardState API function:
Capture multiple key downs in C#
This seems interesting, though I'm not sure it will suite my needs.
[DllImport ("user32.dll")]
public static extern int GetKeyboardState( byte[] keystate );
private void Form1_KeyDown( object sender, KeyEventArgs e )
{
byte[] keys = new byte[255];
GetKeyboardState (keys);
if( keys[(int)Keys.Up] == 129 && keys[(int)Keys.Right] == 129 )
{
Console.WriteLine ("Up Arrow key and Right Arrow key down.");
}
}
Thank you for taking a look at my problem.
UPDATE
I've added three events for key handling to my DataPanel. None of these events are being picked up by VS when I set breakpoints in the events, so this is what leads me to believe that ProcessCmdKey is my best option.
If I could get these Events to work, that would be good as well:
// Ctrl + S: Save Support
this.ParentForm.KeyPreview = true;
this.KeyPress += new KeyPressEventHandler(DataPanel_KeyPress);
this.KeyDown += new KeyEventHandler(DataPanel_KeyDown);
this.PreviewKeyDown += new PreviewKeyDownEventHandler(DataPanel_PreviewKeyDown);
None of these events seem to be caught when pressing any keys:
void DataPanel_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e)
{
if (e.KeyCode == (Keys.S | Keys.Control))
{
SessionManager.Trace.AddTrace("You Hit Save!!");
}
}
void DataPanel_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == (Keys.S | Keys.Control))
{
SessionManager.Trace.AddTrace("You Hit Save!!");
}
}
void DataPanel_KeyPress(object sender, KeyPressEventArgs e)
{
var key = e.KeyChar;
}
UPDATE
I've solved the problem by using a simple KeyUp event and the KeyPreview flag:
void ShipmentDataPanel_KeyUp(object sender, KeyEventArgs e)
{
if (e.Control && e.KeyCode == Keys.S)
{
MessageBox.Show("Control + S Key Hit!");
}
}
Thank you.