2010-03-12 18 views
5

Tengo el siguiente problema en una aplicación WinForms. Estoy intentando implementar teclas rápidas y necesito procesar mensajes clave siempre que el control esté activo, sin importar si el foco está en un cuadro de texto dentro de ese control, etc.ProcessCmdKey - ¿Espera a KeyUp?

Rectificación de ProcessCmdKey funciona muy bien para esto y hace exactamente lo que Quiero con una excepción:

Si un usuario presiona una tecla y la mantiene presionada, ProcessCmdKey sigue activando eventos WM_KEYDOWN.

Sin embargo, lo que quiero lograr es que el usuario tenga que volver a soltar el botón antes de que se active otra tecla (por lo tanto, si alguien se sienta en el teclado no provocará eventos continuos de tecla de acceso directo).
Sin embargo, no puedo encontrar dónde atrapar eventos WM_KEYUP, por lo que puedo establecer un indicador si debe procesar mensajes ProcessCmdKey nuevamente?

¿Alguien puede ayudar aquí?

Gracias,

Tom

Respuesta

9

pensé que sería fácil, basta con ver número de repeticiones de la llave. No funcionó aunque si se usan modificadores. Tendrá que ver que la clave también suba, eso requiere implementar IMessageFilter. Esto funcionó:

public partial class Form1 : Form, IMessageFilter { 
    public Form1() { 
     InitializeComponent(); 
     Application.AddMessageFilter(this); 
     this.FormClosed += (s, e) => Application.RemoveMessageFilter(this); 
    } 
    bool mRepeating; 
    protected override bool ProcessCmdKey(ref Message msg, Keys keyData) { 
     if (keyData == (Keys.Control | Keys.F) && !mRepeating) { 
      mRepeating = true; 
      Console.WriteLine("What the Ctrl+F?"); 
      return true; 
     } 
     return base.ProcessCmdKey(ref msg, keyData); 
    } 
    public bool PreFilterMessage(ref Message m) { 
     if (m.Msg == 0x101) mRepeating = false; 
     return false; 
    } 
} 
+0

Hm, que no parece funcionar para mí, no parece PreProcessMessage para ser disparado. – TJF

+0

Arf, solo se ejecuta si el formulario tiene el foco. Necesitamos el plan B, déjalo pensar. –

+0

@Tom: está bien, IMessageFilter puede hacerlo. Actualicé mi publicación. –

3
const int WM_KEYDOWN = 0x100; 
const int WM_KEYUP = 0x101; 

protected override bool ProcessKeyPreview(ref Message m) 
{ 
    if (m.Msg == WM_KEYDOWN && (Keys)m.WParam == Keys.NumPad6) 
    { 
     //Do something 
    } 
    else if (m.Msg == WM_KEYUP && (Keys)m.WParam == Keys.NumPad6) 
    { 
     //Do something 
    } 

    return base.ProcessKeyPreview(ref m); 
} 
+1

WM_KEYUP no funciona aquí. – Paul

Cuestiones relacionadas