Interception de l'entrée du clavier avec Delphi

Considérons un instant la création d'un jeu d'arcade rapide. Tous les graphiques sont affichés, disons, dans une TPainBox. TPaintBox ne peut pas recevoir le focus d'entrée - aucun événement n'est déclenché lorsque l'utilisateur appuie sur une touche; nous ne pouvons pas intercepter les touches du curseur pour déplacer notre cuirassé. Delphes Aidez-moi!

Interception du clavier

La plupart des applications Delphi gèrent généralement les entrées utilisateur via des gestionnaires d'événements spécifiques, ceux qui nous permettent de capturer l'utilisateur frappes et processus mouvement de la souris.

Nous savons que l'accent est mis sur la capacité de recevoir les commentaires des utilisateurs via la souris ou le clavier. Seulement le l'objet qui a le focus peut recevoir un événement clavier. Certains contrôles, tels que TImage, TPaintBox, TPanel et TLabel ne peuvent pas recevoir le focus. Le but principal de la plupart des contrôles graphiques est d'afficher du texte ou des graphiques.

Si nous voulons intercepter l'entrée du clavier pour les contrôles qui ne peuvent pas recevoir le focus d'entrée, nous devrons traiter avec l'API Windows, les hooks, les rappels et

instagram viewer
messages.

Crochets Windows

Techniquement, une fonction "hook" est une fonction de rappel qui peut être insérée dans le message Windows système de sorte qu'une application puisse accéder au flux de messages avant que tout autre traitement du message ne prenne endroit. Parmi de nombreux types de crochets Windows, un crochet clavier est appelé chaque fois que l'application appelle GetMessage () ou PeekMessage () et il y a un message clavier WM_KEYUP ou WM_KEYDOWN à processus.

Pour créer un crochet clavier qui intercepte toutes les entrées clavier dirigées vers un thread donné, nous devons appeler SetWindowsHookEx Fonction API. Les routines qui reçoivent les événements clavier sont des fonctions de rappel définies par l'application appelées fonctions de raccordement (KeyboardHookProc). Windows appelle votre fonction de raccordement pour chaque message de frappe (touche haut et touche bas) avant que le message ne soit placé dans la file d'attente de messages de l'application. La fonction de raccordement peut traiter, modifier ou supprimer des frappes. Les crochets peuvent être locaux ou mondiaux.

le valeur de retour de SetWindowsHookEx est une poignée pour le crochet qui vient d'être installé. Avant de terminer, une application doit appeler le UnhookWindowsHookEx pour libérer les ressources système associées au hook.

Exemple de crochet de clavier

En guise de démonstration des crochets de clavier, nous allons créer un projet avec contrôle graphique pouvant recevoir des pressions de touches. TImage est dérivé de TGraphicControl, il peut être utilisé comme surface de dessin pour notre jeu de bataille hypothétique. Étant donné que TImage n'est pas en mesure de recevoir des pressions sur le clavier via des événements de clavier standard, nous allons créer une fonction de crochet qui intercepte toutes les entrées de clavier dirigées vers notre surface de dessin.

TImage Processing Keyboard Events

Recommencer Projet Delphi et placez un composant Image sur une fiche. Définissez la propriété Image1.Align sur alClient. C'est tout pour la partie visuelle, maintenant nous devons faire du codage. D'abord, nous aurons besoin de variables globales:

 var
Form1: TForm1;
KBHook: HHook; {ceci intercepte la saisie au clavier}
cx, cy: entier; {suivre la position du navire de bataille}
{déclaration de rappel}
function KeyboardHookProc (Code: Entier; WordParam: Word; LongParam: LongInt): LongInt; stdcall;
la mise en oeuvre
...

Pour installer un hook, nous appelons SetWindowsHookEx dans l'événement OnCreate d'un formulaire.

 procédure TForm1.FormCreate (Sender: TObject);
commencer
{Réglez le crochet du clavier afin que nous puissions intercepter la saisie au clavier}
KBHook: = SetWindowsHookEx (WH_KEYBOARD,
{rappel>} @KeyboardHookProc,
HInstance,
GetCurrentThreadId ());
{placez le vaisseau de bataille au milieu de l'écran}
cx: = Image1.ClientWidth div 2;
cy: = Image1.ClientHeight div 2;
Image1.Canvas. PenPos: = Point (cx, cy);
fin;

Pour libérer des ressources système associées au hook, nous devons appeler la fonction UnhookWindowsHookEx dans l'événement OnDestroy:

 procédure TForm1.FormDestroy (expéditeur: TObject);
commencer
{décrochez l'interception du clavier}
UnHookWindowsHookEx (KBHook);
fin;

La partie la plus importante de ce projet est la Procédure de rappel KeyboardHookProc utilisé pour traiter les frappes.

 function KeyboardHookProc (Code: Entier; WordParam: Word; LongParam: LongInt): LongInt;
commencer
cas WordParam de
vk_Space: {effacer le chemin du vaisseau de bataille}
commencer
avec Form1.Image1.Canvas do
commencer
Brosse. Couleur: = clWhite;
Brosse. Style: = bsSolid;
Fillrect (Form1.Image1.ClientRect);
fin;
fin;
vk_Right: cx: = cx + 1;
vk_Left: cx: = cx-1;
vk_Up: cy: = cy-1;
vk_Down: cy: = cy + 1;
fin; {Cas}
Si cx <2, alors cx: = Form1.Image1.ClientWidth-2;
Si cx> Form1.Image1.ClientWidth -2 alors cx: = 2;
Si cy <2, alors cy: = Form1.Image1.ClientHeight -2;
Si cy> Form1.Image1.ClientHeight-2 alors cy: = 2;
avec Form1.Image1.Canvas do
commencer
Stylo. Couleur: = clRed;
Brosse. Couleur: = clJaune;
TextOut (0,0, Format ('% d,% d', [cx, cy]));
Rectangle (cx-2, cy-2, cx + 2, cy + 2);
fin;
Résultat: = 0;
{Pour empêcher Windows de passer les frappes à la fenêtre cible, la valeur de résultat doit être une valeur différente de zéro.}
fin;

C'est ça. Nous avons maintenant le code de traitement clavier ultime.

Notez juste une chose: ce code n'est en aucun cas limité à être utilisé uniquement avec TImage.

La fonction KeyboardHookProc sert de mécanisme général de KeyPreview et KeyProcess.

instagram story viewer