0

KeyDown イベントでは、呼び出しとイベントSuppressKeyPressを避けていました。ただし、イベントは停止されましたが、イベントは引き続き発生します。どうしてこれなの?KeyPressKeyUpKeyPressKeyUp

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);
    }
}
4

2 に答える 2

1

SuppressHeyPress が Control クラスでどのように処理されるかを見てみましょう。

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でリセットすることですが、徹底的に確認して、ユーザーが誤動作した場合(2つのキーを押すなど)に何が起こるかを確認する必要があります。

于 2012-05-29T11:20:58.820 に答える
0

うん、入れてみて

e.Handled = true;

の後e.Suppress... = true;

于 2012-05-29T08:59:21.023 に答える