2012-05-29 2 views
0

В событии KeyDown я использовал SuppressKeyPress, чтобы избежать вызовов KeyPress и KeyUp событий. Однако, хотя событие KeyPress было остановлено, событие KeyUp все еще срабатывает. Почему это?Использование события SuppressKeyPress для блокировки события 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

Вы пытались использовать 'e.Handled = true' после' e.SuppressKeyPress = true'. – MoonKnight

+2

Ваш фрагмент кода не воспроизводит проблему. Вы столкнетесь с проблемой, когда вы вставляете свой код в таком виде. –

+1

Как сказал Ханс Пассант, отпечатай свой 'if's, я отредактировал ваш код. –

ответ

0

Да, попробуйте положить

e.Handled = true; 

после e.Suppress... = true;.

+1

Настройка SuppressKeyPress уже автоматически устанавливает Handled. –

1

Взглянув на то, как 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 и проверить его и сбросить его в KeyUp, но вы будете иметь тщательно проверить его и посмотреть, что происходит, когда пользователь ошибается (например, нажатие двух клавиш).

Смежные вопросы