Pressing right arrow causes up arrow to be set
I am ov开发者_开发技巧erriding ProcessCmdKey
in a control like this:
protected override bool ProcessCmdKey(ref Message msg, Keys keyData) {
if ((keyData & Keys.Up) == Keys.Up)
MessageBox.Show("Up arrow");
else if ((keyData & Keys.Right) == Keys.Right)
MessageBox.Show("Right arrow");
// it doesn't matter what I return, the glitch happens anyway
return base.ProcessCmdKey(ref msg, keyData);
}
And when I press the Up arrow key, the message Up arrow
appears, but it also appears when I press the Right arrow key. Why is this?
The answer is realy simple Keys.Right
has value 39 and Keys.Up
has value 38. Your first bit and operation is 38 or 39 & 38 which is always 38, then you're cheking if 38 is equal to 38 which is always true.
Read the comment above for a description of the problem.
protected override bool ProcessCmdKey(ref Message msg, Keys keyData) {
if (keyData == ((Keys)(Keys.Shift | Keys.Up)))
MessageBox.Show("Up arrow");
else if (keyData == Keys.Right)
MessageBox.Show("Right arrow");
// it doesn't matter what I return, the glitch happens anyway
return base.ProcessCmdKey(ref msg, keyData);
}
You don't even need to cast it, because the argument is passed in as a key. So you can compare the two enums just like you would two strings or integers.
indeed the problem is that the (int)key values are not powers of 2. As long as you only want to capture single keystrokes, you can just use (keys == Keys.Up) or whatever. When you want to catch control or shift keys as well, this is not possible via (keyData == ((Keys)(Keys.Shift | Keys.Up))) The solution i used is maybe not the most sophisticated, but I can't spoil a lot of time on this kind of items. This approach at least works:
const int WM_KEYDOWN = 0x100;
const int WM_SYSKEYDOWN = 0x104;
if ((msg.Msg == WM_KEYDOWN) || (msg.Msg == WM_SYSKEYDOWN))) // Only act on on keydown
{
// allkeys will contian something like "LEFT,SHIFT". Carefull in debugger:
// Tooltip and Watch value still assumes powers of 2 and will show wrong values
string allkeys = keys.ToString().ToUpper();
bool shift = allkeys.contains("SHIFT");
bool alt = allkeys.contains("ALT");
bool control = allkeys.contains("CONTROL");
if(allkeys.Contains("UP"))
{}
else if(allkeys.Contains("DOWN"))
{}
else if(allkeys.Contains("LEFT"))
{}
else (allkeys.Contains("RIGHT"))
{}
}
精彩评论