Reputation: 60001
update: I've modified the code below to reveal some additional information regarding the key that was pressed.
update #2: I've discovered the root cause of the issue: we have an HTML control (Gecko rendering engine) on our form. When that Gecko rendering engine navigates to some Flash control, suddenly ~2% of our key presses don't get through, even after we've removed the Gecko HTML control. Wahoo, I get to blame this on Flash! Now the question is, how do I fix this?
update #3: Nope, it's not Flash. It's the Gecko rendering engine. Navigating even to Google causes some keys to not come through to our app right. Hrmmm.
We have a strange case in our WinForms app where the user presses a key combination (in this case, Alt + S), and WinForms tells us some other key combo (value 262162) is pressed:
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
if(keyData == (Keys.S | Keys.Alt))
{
Console.WriteLine("You pressed Alt+S");
}
else if(keyData == (Keys.Menu | Keys.Alt))
{
Console.WriteLine("What the hell?"); // This sometimes gets hit when I press Alt+S
}
}
90% of the time, You pressed Alt+S
will be shown. But on rare occurrances, we press Alt + S and it says, What the hell?
.
Any idea what's wrong?
Upvotes: 4
Views: 4214
Reputation: 60001
EDIT I've discovered the root cause of the issue! See below.
After more experimenting, I've found that if do the following, it works as expected:
this.KeyPreview = true;
this.KeyDown += KeyDownHandler;
...
private void KeyDownHandler(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.S && e.Alt)
{
// This always works.
}
}
I can't explain why the ProcessCmdKey didn't work. I wish I knew. Until then, this is an acceptable workaround.
I've discovered the issue. We have an HTML control (Gecko rendering engine) on our form. When that gecko rendering engine is shown on a form, it must be installing a hook or something that changes some key presses, causing us to receive WM_Char instead of WM_KeyDown in certain cases.
Upvotes: 4
Reputation: 849
Just out of curiosity could you try this:
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
if (keyData == (Keys.S | Keys.Alt))
{
MessageBox.Show("You pressed Alt+S");
}
else if (keyData == (Keys.Menu | Keys.Alt))
{
return false;
}
return true;
}
returning false indicates that this is not a command key.
Upvotes: 0
Reputation: 849
Could it be that you are waiting too long to press the S key and an Alt key repeat is getting fired off?
EDIT2:I tried you posted code and I receive "What the Hell" the second I touch the ALT key, however if I disable this check the Alt-S always comes through. On my system this seems to be the default key code for the Alt key. I am able to ignore it and the Alt-S Will come through afterwards.
EDIT: According to the METADATA for the Keys enumeration Keys.Menu is 18. To see this hit F12 while the cursor is on the Keys Enumeration.
The documentation states that Keys.Menu is the Alt key.
http://msdn.microsoft.com/en-us/library/system.windows.forms.keys.aspx
This tells me that it is reporting the Alt key was pressed(18) with the Alt key modifier(262144) crazy stuff.
Upvotes: 1
Reputation: 8098
From my testing, it would appear that 262162 would be the "Alt" key.
Edit: I overrode the ProcessCmdKey and put in a break point on the "X = 1;" statement:
protected override bool ProcessCmdKey(ref System.Windows.Forms.Message msg, System.Windows.Forms.Keys keyData)
{
int x = (int)keyData;
if (x == 262162)
x = 1;
return true;
}
It hits that breakpoint whenever I hit the Alt key.
Upvotes: 1