我在这样的控件中覆盖ProcessCmdKey
:
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);
}
当我按向上箭头键时,会出现Up arrow
消息,但是当我按向右箭头键时也会出现。这是为什么?
答案 0 :(得分:3)
答案非常简单Keys.Right
的值为39,Keys.Up
的值为38.您的第一位和操作是38或39& 38,这总是38,那么如果38等于38,那么你就是在等待,这总是正确的。
答案 1 :(得分:2)
阅读上面的评论,了解问题的描述。
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);
}
你甚至不需要强制转换它,因为参数是作为键传递的。所以你可以像两个字符串或整数一样比较两个枚举。
答案 2 :(得分:0)
确实问题是(int)键值不是2的幂。只要你只想捕获单击键,你就可以使用(keys == Keys.Up)或其他任何东西。 当你想要捕获控制键或移位键时,这是不可能的(keyData ==((Keys)(Keys.Shift | Keys.Up))) 我使用的解决方案可能不是最复杂的,但我不能在这类物品上浪费大量时间。这种方法至少有效:
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"))
{}
}