Considere por um momento a criação de algum jogo rápido de arcade. Todos os gráficos são exibidos, digamos, em uma TPainBox. TPaintBox não pode receber o foco de entrada - nenhum evento é disparado quando o usuário pressiona uma tecla; não podemos interceptar as teclas do cursor para mover nosso navio de guerra. Delphi Socorro!
Interceptar entrada do teclado
A maioria das aplicações Delphi normalmente manipula a entrada do usuário através de manipuladores de eventos específicos, aqueles que nos permitem capturar o usuário pressionamentos de teclas e processo movimento do mouse.
Sabemos que o foco é a capacidade de receber informações do usuário por meio do mouse ou teclado. Apenas o objeto que tem o foco pode receber um evento de teclado. Alguns controles, como TImage, TPaintBox, TPanel e TLabel, não podem receber foco. O objetivo principal da maioria dos controles gráficos é exibir texto ou gráficos.
Se quisermos interceptar a entrada do teclado para controles que não podem receber o foco de entrada, teremos que lidar com a API do Windows, ganchos, retornos de chamada e mensagens.
Ganchos do Windows
Tecnicamente, uma função "gancho" é uma função de retorno de chamada que pode ser inserida na mensagem do Windows sistema para que um aplicativo possa acessar o fluxo de mensagens antes que outro processamento da mensagem ocorra Lugar, colocar. Entre muitos tipos de ganchos para janelas, um gancho para teclado é chamado sempre que o aplicativo chama o GetMessage () ou PeekMessage () e há uma mensagem de teclado WM_KEYUP ou WM_KEYDOWN para processo.
Para criar um gancho de teclado que intercepte todas as entradas de teclado direcionadas a um determinado segmento, precisamos chamar SetWindowsHookEx Função API. As rotinas que recebem os eventos do teclado são funções de retorno de chamada definidas pelo aplicativo, chamadas de funções de gancho (KeyboardHookProc). O Windows chama sua função de gancho para cada mensagem de pressionamento de tecla (tecla acima e abaixo) antes que a mensagem seja colocada na fila de mensagens do aplicativo. A função de gancho pode processar, alterar ou descartar pressionamentos de tecla. Ganchos podem ser locais ou globais.
o valor de retorno SetWindowsHookEx é um identificador para o gancho recém-instalado. Antes de terminar, um aplicativo deve chamar o UnhookWindowsHookEx para liberar recursos do sistema associados ao gancho.
Exemplo de gancho do teclado
Como demonstração dos ganchos do teclado, criaremos um projeto com controle gráfico que pode receber pressionamentos de tecla. TImage é derivado do TGraphicControl, pode ser usado como uma superfície de desenho para o nosso hipotético jogo de batalha. Como o TImage não pode receber pressionamentos de teclado por meio de eventos de teclado padrão, criaremos uma função de gancho que intercepta todas as entradas de teclado direcionadas à nossa superfície de desenho.
Processamento de teclado do TImage
Comece novo Projeto Delphi e coloque um componente de imagem em um formulário. Defina a propriedade Image1.Align como alClient. É isso para a parte visual, agora temos que fazer algumas codificações. Primeiro, precisaremos de alguns variáveis globais:
var
Formulário1: TForm1;
KBHook: HHook; {isso intercepta a entrada do teclado}
cx, cy: inteiro; {rastrear a posição do navio de batalha}
{declaração de retorno de chamada}
função KeyboardHookProc (Código: Inteiro; WordParam: Word; LongParam: LongInt): LongInt; stdcall;
implementação
...
Para instalar um gancho, chamamos SetWindowsHookEx no evento OnCreate de um formulário.
procedimento TForm1.FormCreate (Sender: TObject);
início
{Ajuste o gancho do teclado para que possamos interceptar a entrada do teclado}
KBHook: = SetWindowsHookEx (WH_KEYBOARD,
{callback>} @KeyboardHookProc,
HInstance,
GetCurrentThreadId ());
{coloque o navio de batalha no meio da tela}
cx: = Image1.ClientWidth div 2;
cy: = Image1.ClientHeight div 2;
Image1.Canvas. PenPos: = Ponto (cx, cy);
fim;
Para liberar recursos do sistema associados ao gancho, devemos chamar a função UnhookWindowsHookEx no evento OnDestroy:
procedimento TForm1.FormDestroy (Sender: TObject);
início
{solte a interceptação do teclado}
UnHookWindowsHookEx (KBHook);
fim;
A parte mais importante deste projeto é a Procedimento de retorno de chamada KeyboardHookProc usado para processar pressionamentos de tecla.
função KeyboardHookProc (Código: Inteiro; WordParam: Word; LongParam: LongInt): LongInt;
início
caso WordParam de
vk_Space: {apague o caminho do navio de batalha}
início
com Form1.Image1.Canvas do
início
Escova. Cor: = clBranco;
Escova. Estilo: = bsSolid;
Fillrect (Form1.Image1.ClientRect);
fim;
fim;
vk_Right: cx: = cx + 1;
vk_Left: cx: = cx-1;
vk_Up: cy: = cy-1;
vk_Down: cy: = cy + 1;
fim; {caso}
Se cx <2, então cx: = Form1.Image1.ClientWidth-2;
Se cx> Form1.Image1.ClientWidth -2, cx: = 2;
Se cy <2, então cy: = Form1.Image1.ClientHeight -2;
Se cy> Form1.Image1.ClientHeight-2, então cy: = 2;
com Form1.Image1.Canvas do
início
Caneta. Cor: = clRed;
Escova. Cor: = clYellow;
TextOut (0,0, Formato ('% d,% d', [cx, cy]));
Retângulo (cx-2, cy-2, cx + 2, cy + 2);
fim;
Resultado: = 0;
{Para impedir que o Windows passe as teclas pressionadas para a janela de destino, o valor do Resultado deve ser um valor diferente de zero.}
fim;
É isso aí. Agora temos o melhor código de processamento de teclado.
Observe apenas uma coisa: esse código não é restrito a ser usado apenas com TImage.
A função KeyboardHookProc serve como um mecanismo geral KeyPreview & KeyProcess.