Eventos clave: ProcessCmdKey

Estoy intentando que algo de respuesta de teclado ocurra en una pequeña prueba de Windows Form Application, y tengo una solución aproximada, que es anular ProcessCmdKey. Sin embargo, hay varios problemas que estoy encontrando e incoherencias que estoy encontrando.

Diferentes eventos: ¿Hay alguna forma de saber, en los argumentos ref Message msg, Keys keyData , si el par es KeyDown, KeyUp o KeyPress?

KeyPress: en todas partes he visto que KeyPress, es decir, una entrada de teclado repetida, solo ocurre con las teclas de caracteres, que no son las teclas de flecha. Sin embargo, el controlador de eventos se llama con la misma frecuencia, y en el mismo orden / con el mismo comportamiento, para las teclas de flecha como teclas de caracteres. ¿Es esto un evento de KeyPress, o es algo más?

Idealmente me gustaría una forma de manejar, a nivel de formulario, todos los eventos de teclado sin permitir que pasen a los controles en el formulario. Sin embargo, toda la documentación me confundió lo suficiente y omití los puntos clave, por lo que no he podido completar esto.

La ayuda en cualquiera de estos temas es apreciada. ¡Gracias!

La estructura del mensaje pasada a ProcessCmdKey () contiene el número de mensaje WINAPI en su propiedad Msg :

  • WM_KEYDOWN es 0x100 (256),
  • WM_KEYUP es 0x101 (257),
  • WM_CHAR (más o menos equivalente a KeyPress ) es 0x102 (258),
  • WM_SYSKEYDOWN es 0x104 (260),
  • WM_SYSKEYUP es 0x105 (261).

En relación con su pregunta sobre KeyPress , es cierto que las claves que no son de carácter, como las teclas de flecha, no generan mensajes WM_CHAR interna, pero sí generan WM_KEYDOWN , y ese mensaje también se envía varias veces para la entrada repetida.

También tenga en cuenta que no estoy seguro de que ProcessCmdKey() sea ​​el método correcto para lograr lo que desea. La documentación describe que solo maneja main menu command keys and MDI accelerators , que pueden ser solo un subconjunto de las teclas que desea capturar. Es posible que desee sobrescribir ProcessKeyPreview () en su lugar, que maneja todos los mensajes de teclado recibidos por los controles secundarios.

La anulación de ProcessCmdKey en su formulario está explícitamente diseñada para permitirle implementar el manejo personalizado de teclas abreviadas más allá del manejo mnemotécnico incorporado en botones y elementos de menú.

Solo se recurre a un evento de reducción de teclas, antes de que el control con el foco obtenga el evento KeyDown e independientemente del control del cliente que tenga el foco. Por lo tanto, no está asociado con KeyUp y no con KeyPress. Devuelve verdadero desde su anulación cuando reconoce la clave, después de ejecutar la función de acceso directo. Esto evita que la clave se siga procesando, no generará ningún evento KeyDown / Press / Up.

Es muy raro usar el argumento msg del método, el valor msg.Msg solo será WM_KEYDOWN o WM_SYSKEYDOWN con el último mensaje generado cuando el usuario mantiene presionada la tecla Alt. Lo cual no te importa ya que siempre puedes obtenerlo del argumento keyData . Me gusta esto:

  protected override bool ProcessCmdKey(ref Message msg, Keys keyData) { if (keyData == (Keys.Alt | Keys.F)) { // Alt+F pressed doSomething(); return true; } return base.ProcessCmdKey(ref msg, keyData); } 

Los otros modificadores es posible que desee comprobar con el | operador como se usa aquí son Teclas.Shift y Keys.Control. Entonces (Keys.Shift | Keys.Control | Keys.F1) busca Ctrl + Shift + F1. Puede interpretar los datos del mensaje cuando quiere hacer algo inusual, como comprobar si se repiten las teclas. Compruebe los documentos de MSDN para la notificación WM_KEYDOWN. El valor msg.LParam contiene un montón de información sobre el trazo de la tecla.

Tenga en cuenta que solo obtiene claves virtuales en este método. Keys.F es la tecla F en el diseño del teclado en inglés, pero no necesariamente la misma letra para la tecla en la misma ubicación en el diseño del usuario. Favorece las teclas de función para evitar un dolor de cabeza de documentación.

La repetición de teclas es una función del controlador del teclado y no está limitada a las teclas de escritura. La flecha y las teclas de función ciertamente se repetirán cuando se mantengan presionadas. Desea ignorar KeyPress en este escenario. Pero si asigna una tecla de método abreviado para una tecla que también es una tecla de escritura (como Teclas.F), entonces siempre debe buscar una tecla modificadora para no romper controles como TextBox.

Por último, pero no por ello menos importante, no se olvide de la compatibilidad incorporada para mnemónicos en los controles de botones y elementos de menú. Escribir su propiedad Text como &OK produce un acceso directo autodocumentado sin necesidad de ningún código. Operado por el usuario, en este ejemplo, escribiendo Alt + O.