在KeyDown事件中,我使用SuppressKeyPress
来避免调用KeyPress
和KeyUp
事件。但是,虽然KeyPress
事件已停止,但KeyUp
事件仍会触发。这是为什么?
private void textBox1_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.H)
{
listBox1.Items.Add("key down" + e.KeyCode);
// e.SuppressKeyPress = true;
}
}
private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
{
if (e.KeyChar == 'h')
{
listBox1.Items.Add("key press" + e.KeyChar);
}
}
private void textBox1_KeyUp(object sender, KeyEventArgs e)
{
if(e.KeyCode==Keys.H)
{
listBox1.Items.Add("key up" + e.KeyCode);
}
}
答案 0 :(得分:1)
看看如何在Control类中处理SuppressHeyPress:
protected virtual bool ProcessKeyEventArgs(ref Message m)
{
// ...
if (e.SuppressKeyPress)
{
this.RemovePendingMessages(0x102, 0x102);
this.RemovePendingMessages(0x106, 0x106);
this.RemovePendingMessages(0x286, 0x286);
}
return e.Handled;
}
显然你不能做这样的事情来抑制WM_KEYUP消息(当你处理KeyDown事件时,KeyPress消息已经发送到你的控件,但是KeyUp消息在用户释放之前不会触发键)。
您可以使用以下代码对此进行测试:
[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern bool PeekMessage([In, Out] ref MSG msg, HandleRef hwnd, int msgMin, int msgMax, int remove);
[Serializable, StructLayout(LayoutKind.Sequential)]
public struct MSG
{
public IntPtr hwnd;
public int message;
public IntPtr wParam;
public IntPtr lParam;
public int time;
public int pt_x;
public int pt_y;
}
private void RemovePendingMessages(Control c, int msgMin, int msgMax)
{
if (!this.IsDisposed)
{
MSG msg = new MSG();
IntPtr handle = c.Handle;
while (PeekMessage(ref msg, new HandleRef(c, handle), msgMin, msgMax, 1))
{
}
}
}
private void SuppressKeyPress(Control c)
{
this.RemovePendingMessages(c, 0x102, 0x102);
this.RemovePendingMessages(c, 0x106, 0x106);
this.RemovePendingMessages(c, 0x286, 0x286);
}
private void SuppressKeyUp(Control c)
{
this.RemovePendingMessages(c, 0x101, 0x101);
this.RemovePendingMessages(c, 0x105, 0x105);
}
private void textBox2_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.H)
{
SuppressKeyPress(sender); // will work
SuppressKeyUp(sender); // won't work
}
}
一个解决方案是使用布尔标志suppressKeyUp,在KeyDown将其设置为true并检查它并在KeyUp中重置它,但你必须彻底检查它,看看当用户行为不当时会发生什么(比如按下两个)键)。
答案 1 :(得分:0)
是的,试试
e.Handled = true;
在e.Suppress... = true;
之后。