2010-07-21 18 views
6

Básicamente, tengo un formulario con un control personalizado (y nada más). El control personalizado está completamente vacío y el formulario tiene KeyPreview establecido en verdadero.Eventos de tecla de flecha que no llegan

Con esta configuración, no estoy recibiendo ningún evento KeyDown para ninguna tecla de flecha o pestaña. Cada otra clave que tengo en mi teclado funciona. Tengo controladores de eventos KeyDown conectados a todo lo que tiene tales eventos, así que estoy seguro de que no me falta nada.

También es de destacar que si elimino el control personalizado (completamente vacío), SI recibo los eventos de la tecla de flecha.

¿Qué diablos está pasando aquí?

EDIT:

he añadido esto a la forma y el control, pero todavía no recibo teclas de flecha:

protected override void WndProc(ref Message m) { 
    switch (m.Msg) { 
     case 0x100: //WM_KEYDOWN 
      //this is the control's version. In the form, it's this.Text 
      ParentForm.Text = ((Keys)m.WParam).ToString(); 
      break; 
    } 
    base.WndProc(ref m); 
} 

También he comprobado con Spy ++, y determinó que el propio formulario no recibe ningún mensaje WM_KEYDOWN, todos van al control. Sin embargo, dicho esto, el control recibe los mensajes de la tecla de flecha WM_KEYDOWN. Suspiro.

Editar 2: También actualicé el archivo ZIP con esta versión. Por favor, mire, si usted quiere ayudar ...

Datos 3:

He cuenta de esto, más o menos. La forma es comer las teclas de flecha, probablemente en un intento de mantener el foco entre sus hijos. Esto se demuestra por el hecho de que SI obtengo los eventos si el formulario está vacío.

De todos modos, si añado este código a la forma, que comienza a recibir los eventos de nuevo:

public override bool PreProcessMessage(ref Message msg) { 
    switch (msg.Msg) { 
     case 0x100: //WM_KEYDOWN 
      return false; 
    } 
    return base.PreProcessMessage(ref msg); 
} 

Cuando puedo reemplazar esto, la forma no consigue la oportunidad de hacer su trabajo sucio, y así Obtengo mis eventos KeyDown como espero. Supongo que un efecto secundario de esto es que ya no puedo usar mi teclado para navegar por el formulario (no es un gran problema en este caso, ya que es un juego, ¡y el propósito de este ejercicio es implementar la navegación por teclado!)

La pregunta sigue siendo acerca de cómo deshabilitar esta "correctamente", si hay una manera ...

+0

Parece que la forma en la que está el control de usuario es capturar el evento y configurarlo para que lo maneje antes de que UserControl lo reciba. ¿Está asegurando que su control de usuario se enfoque cuando se presiona la tecla? –

Respuesta

10

He hecho algunas pruebas exhaustivas, y he descubierto todo.I wrote a blog post detailing the solution.

En resumen, que desea reemplazar el método ProcessDialogKey en la forma:

protected override bool ProcessDialogKey(Keys keyData) { 
    return false; 
} 

Esto hará que las teclas de flecha (y pestaña) que se suministren como eventos normales KeyDown. ¡SIN EMBARGO! Esto también hará que falle la funcionalidad normal de la tecla de diálogo (usando la tecla Tab para navegar controles, etc.). Si desea conservar eso, pero aún así obtener el evento KeyDown, utilizar esto en su lugar:

protected override bool ProcessDialogKey(Keys keyData) { 
    OnKeyDown(new KeyEventArgs(keyData)); 
    return base.ProcessDialogKey(keyData); 
} 

Esto entregar un mensaje KeyDown, sin dejar de hacer la navegación diálogo normal.

+0

Funciona a las mil maravillas. – Carra

+0

¡Gracias! ¡Funciona perfectamente! –

+0

¿Tu enlace de blog está muerto?!? –

0

Si el foco es el problema, y ​​no se puede conseguir el control de usuario a tomar un enfoque y mantenerlo , una solución sencilla sería repetir el evento a su control de usuario en el evento clave que le preocupa. Suscríbase a los eventos de pulsación de tecla o de tecla y luego haga que ese evento genere un evento para su control de usuario.

Así que esencialmente, Form1_KeyPress llamaría a UserControl1_KeyPress con el remitente y los argumentos del evento desde Form1_KeyPress, p.

protected void Form1_KeyPress(object sender, KeyEventArgs e) 
{ 
    UserControl1_KeyPress(sender, e); 
} 

De lo contrario, puede que tenga que tomar la ruta larga y anular sus eventos WndProc para obtener la funcionalidad que usted desea.

+0

UserControl está vacío y no puede recibir el enfoque (AFAIK). Entonces, el Formulario en sí debería recibir los eventos KeyDown. Sin embargo, no lo es. Como dije en la pregunta, tengo controladores de eventos conectados a todo lo que tiene el evento, pero nada está recibiendo el evento. Puedo intentar anular WndProc, pero realmente no debería tener que ... –

+0

He actualizado el OP con los resultados de mi reemplazo WndProc –

Cuestiones relacionadas