Considere por un momento la creación de un juego de arcade rápido. Todos los gráficos se muestran, digamos, en un TPainBox. TPaintBox no puede recibir el foco de entrada: no se activan eventos cuando el usuario presiona una tecla; No podemos interceptar las teclas del cursor para mover nuestro acorazado. Ayuda Delphi!
La mayoría de las aplicaciones de Delphi generalmente manejan la entrada del usuario a través de controladores de eventos específicos, aquellos que nos permiten capturar las pulsaciones de teclas del usuario y procesar el movimiento del mouse.
Sabemos que el enfoque es la capacidad de recibir información del usuario a través del mouse o el teclado. Solo el el objeto que tiene el foco puede recibir un evento de teclado. Algunos controles, como TImage, TPaintBox, TPanel y TLabel no pueden recibir el foco. El propósito principal de la mayoría de los controles gráficos es mostrar texto o gráficos..
Si queremos interceptar la entrada del teclado para los controles que no pueden recibir el foco de entrada, tendremos que lidiar con la API de Windows, enlaces, devoluciones de llamada y mensajes.
Técnicamente, una función de "enganche" es una función de devolución de llamada que se puede insertar en el sistema de mensajes de Windows para que una aplicación pueda acceder a la secuencia de mensajes antes de que tenga lugar otro procesamiento del mensaje. Entre muchos tipos de enlaces de Windows, se llama un enlace de teclado cada vez que la aplicación llama a la función GetMessage () o PeekMessage () y hay un mensaje de teclado WM_KEYUP o WM_KEYDOWN para procesar.
Para crear un enlace de teclado que intercepte todas las entradas de teclado dirigidas a un hilo dado, debemos llamar SetWindowsHookEx Función API Las rutinas que reciben los eventos del teclado son funciones de devolución de llamada definidas por la aplicación llamadas funciones de enlace (KeyboardHookProc). Windows llama a su función de enlace para cada mensaje de pulsación de tecla (tecla arriba y tecla abajo) antes de que el mensaje se coloque en la cola de mensajes de la aplicación. La función de enlace puede procesar, cambiar o descartar pulsaciones de teclas. Los ganchos pueden ser locales o globales.
El valor de retorno de SetWindowsHookEx es un identificador para el enlace recién instalado. Antes de finalizar, una aplicación debe llamar al DesengancharWindowsHookEx función para liberar recursos del sistema asociados con el gancho.
Como demostración de los ganchos del teclado, crearemos un proyecto con control gráfico que pueda recibir pulsaciones de teclas. TImage se deriva de TGraphicControl, se puede utilizar como superficie de dibujo para nuestro hipotético juego de batalla. Dado que TImage no puede recibir las pulsaciones del teclado a través de eventos de teclado estándar, crearemos una función de enganche que intercepta todas las entradas del teclado dirigidas a nuestra superficie de dibujo.
Inicie un nuevo proyecto de Delphi y coloque un componente de imagen en un formulario. Establezca la propiedad Image1.Align en alClient. Eso es todo por la parte visual, ahora tenemos que hacer algo de codificación. Primero, necesitaremos algunas variables globales:
var
Form1: TForm1;
KBHook: HHook; esto intercepta la entrada del teclado
cx, cy: entero; rastrear la posición del barco de batalla
declaración de devolución de llamada
función KeyboardHookProc (Código: entero; WordParam: Word; LongParam: LongInt): LongInt; stdcall;
implementación
...
Para instalar un enlace, llamamos a SetWindowsHookEx en el evento OnCreate de un formulario.
procedimiento TForm1.FormCreate (remitente: TObject);
empezar
Configure el enlace del teclado para que podamos interceptar la entrada del teclado
KBHook: = SetWindowsHookEx (WH_KEYBOARD,
devolución de llamada> @KeyboardHookProc,
HInstance,
GetCurrentThreadId ());
coloca el barco de batalla en el medio de la pantalla
cx: = Image1.ClientWidth div 2;
cy: = Image1.ClientHeight div 2;
Image1.Canvas.PenPos: = Point (cx, cy);
final;
Para liberar recursos del sistema asociados con el enlace, debemos llamar a la función UnhookWindowsHookEx en el evento OnDestroy:
procedimiento TForm1.FormDestroy (remitente: TObject);
empezar
desenganchar la intercepción del teclado
UnHookWindowsHookEx (KBHook);
final;
La parte más importante de este proyecto es el Procedimiento de devolución de llamada KeyboardHookProc utilizado para procesar pulsaciones de teclas.
función KeyboardHookProc (Código: entero; WordParam: Word; LongParam: LongInt): LongInt;
empezar
caso WordParam de
vk_Space: borrar el camino del barco de batalla
empezar
con Form1.Image1.Canvas do
empezar
Brush.Color: = clWhite;
Brush.Style: = bsSolid;
Fillrect (Form1.Image1.ClientRect);
final;
final;
vk_Right: cx: = cx + 1;
vk_Left: cx: = cx-1;
vk_Up: cy: = cy-1;
vk_Down: cy: = cy + 1;
final; caso
Si cx < 2 then cx := Form1.Image1.ClientWidth-2;
Si cx> Form1.Image1.ClientWidth -2 entonces cx: = 2;
Si cy < 2 then cy := Form1.Image1.ClientHeight -2 ;
Si cy> Form1.Image1.ClientHeight-2 entonces cy: = 2;
con Form1.Image1.Canvas do
empezar
Color de la pluma: = clRed;
Brush.Color: = clYellow;
TextOut (0,0, Formato ('% d,% d', [cx, cy]));
Rectángulo (cx-2, cy-2, cx + 2, cy + 2);
final;
Resultado: = 0;
Para evitar que Windows pase las teclas presionadas a la ventana de destino, el valor del resultado debe ser un valor distinto de cero.
final;
Eso es. Ahora tenemos el último código de procesamiento de teclado.
Tenga en cuenta solo una cosa: este código no está restringido de ninguna manera para usarse solo con TImage.
La función KeyboardHookProc sirve como mecanismo general de KeyPreview y KeyProcess.