Principais events: ProcessCmdKey

Eu estou tentando obter alguma resposta de teclado acontecendo em um pequeno teste Windows Form Application e eu tenho uma solução aproximada, que é replace ProcessCmdKey. No entanto, existem vários problemas que estou encontrando e inconsistências que estou encontrando.

Eventos diferentes: Existe uma maneira de dizer, nos argumentos ref Message msg, Keys keyData , se o mesmo é um KeyDown, um KeyUp ou um KeyPress?

KeyPress: Em todos os lugares que eu olhei diz que KeyPress, ou seja, uma input de teclado repetida, só acontece para as teclas de caracteres, que as teclas de seta não são. No entanto, o manipulador de events está sendo chamado com freqüência e no mesmo mannor / com o mesmo comportamento, para as teclas de seta como teclas de caractere. Isso está em face de um evento KeyPress, ou é outra coisa?

Eu gostaria idealmente de uma maneira de manipular, em nível de formulário, todos os events de teclado sem deixá-los passar para os controles no formulário. No entanto, toda a documentação me confundiu o suficiente, e perdeu pontos-chave, de modo que eu não consegui completar isso.

Ajuda sobre qualquer um desses tópicos é bem-vinda. Obrigado!

A estrutura da mensagem passada para ProcessCmdKey () contém o número da mensagem WINAPI na sua propriedade Msg :

  • WM_KEYDOWN é 0x100 (256),
  • WM_KEYUP é 0x101 (257),
  • WM_CHAR (aproximadamente equivalente a KeyPress ) é 0x102 (258),
  • WM_SYSKEYDOWN é 0x104 (260),
  • WM_SYSKEYUP é 0x105 (261).

Com relação à sua pergunta sobre o KeyPress , é verdade que chaves sem caractere, como as teclas de seta, não geram mensagens WM_CHAR internamente, mas geram WM_KEYDOWN , e essa mensagem também é enviada várias vezes para input repetida.

Observe também que não tenho certeza se o ProcessCmdKey() é o método correto para obter o que você deseja. A documentação descreve-a como manipulando apenas as main menu command keys and MDI accelerators , que podem ser apenas um subconjunto das teclas que você deseja capturar. Você pode querer replace ProcessKeyPreview () , que manipula todas as mensagens de teclado recebidas pelos controles filho.

Substituir ProcessCmdKey em seu formulário é explicitamente destinado a permitir que você implemente o tratamento de pressionamento de tecla de atalho personalizado além do tratamento mnemônico interno em botões e itens de menu.

Só é chamado em um evento key down, antes que o controle com o foco receba o evento KeyDown e independentemente de qual controle de cliente tenha o foco. Portanto, não está associado ao KeyUp e não ao KeyPress. Você retorna true da sua substituição quando reconhece a chave, depois de executar a function de atalho. Isso impede que a chave seja processada, não gerará nenhum evento KeyDown / Press / Up.

É muito raro usar o argumento msg do método, o valor msg.Msg sempre será WM_KEYDOWN ou WM_SYSKEYDOWN com a última mensagem produzida quando o usuário pressionou a tecla Alt. Que você não se preocupa desde que você sempre pode obter se a partir do argumento keyData . Como isso:

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

Os outros modificadores que você pode querer verificar com o | operador como usado aqui são Keys.Shift e Keys.Control. Então (Keys.Shift | Keys.Control | Keys.F1) verifica Ctrl + Shift + F1. Você pode interpretar os dados da msg quando quiser fazer algo incomum, como verificar se há chaves repetitivas. Verifique os documentos MSDN para a notificação WM_KEYDOWN. O valor msg.LParam contém várias informações sobre o toque da tecla.

Observe que você só recebe chaves virtuais nesse método. Keys.F é a tecla F no layout do teclado em inglês, mas não necessariamente a mesma letra para a tecla no mesmo local no layout do usuário. Favorecer as teclas de function para evitar uma dor de cabeça de documentação.

A repetição de teclas é um recurso do controlador de teclado e não se limita a teclas de digitação. As teclas de seta e de function certamente serão repetidas quando pressionadas. Você deseja ignorar o KeyPress neste cenário. Mas se você atribuir uma tecla de atalho para uma chave que também é uma tecla de digitação (como Keys.F), então você também sempre deve procurar uma tecla modificadora para não quebrar controles como TextBox.

Por último, mas não menos importante, não se esqueça do suporte integrado para mnemônicos nos controles de botão e item de menu. Escrever sua propriedade Text como &OK produz um atalho de autodocumentação sem precisar de código. Operado pelo usuário, neste exemplo, digitando Alt + O.