Υποκλοπή εισόδου πληκτρολογίου με Delphi

Σκεφτείτε για λίγο τη δημιουργία ενός γρήγορου παιχνιδιού arcade. Όλα τα γραφικά εμφανίζονται, ας πούμε, σε ένα TPainBox. Το TPaintBox δεν μπορεί να λάβει την εστίαση εισόδου - δεν εκπέμπουν συμβάντα όταν ο χρήστης πιέσει ένα πλήκτρο. δεν μπορούμε να παρακολουθήσουμε τα πλήκτρα δρομέα για να μετακινήσουμε το θωρηκτό μας. Δελφοί βοήθεια!

Εισαγωγή στο πληκτρολόγιο

Οι περισσότερες εφαρμογές Delphi χειρίζονται συνήθως την είσοδο χρήστη μέσω συγκεκριμένων χειριστών συμβάντων, εκείνων που μας επιτρέπουν να καταγράψουμε το χρήστη πληκτρολογήσεις και τη διαδικασία κίνηση του ποντικιού.

Γνωρίζουμε ότι η εστίαση είναι η δυνατότητα λήψης εισόδου χρήστη μέσω του ποντικιού ή του πληκτρολογίου. Μόνο το το αντικείμενο που έχει την εστίαση μπορεί να λάβει ένα συμβάν πληκτρολογίου. Ορισμένα στοιχεία ελέγχου, όπως TImage, TPaintBox, TPanel και TLabel, δεν μπορούν να λάβουν εστίαση. Ο πρωταρχικός σκοπός των περισσότερων γραφικών στοιχείων είναι η εμφάνιση κειμένου ή γραφικών.

Αν θέλουμε να παρεμποδίσουμε την είσοδο πληκτρολογίου για στοιχεία ελέγχου που δεν μπορούν να λάβουν την εστίαση εισόδου, θα πρέπει να ασχοληθούμε με τα Windows API, τα γάντζους, τις επανάκλησεις και

instagram viewer
μηνυμάτων.

Windows Αγκίστρια

Από τεχνική άποψη, μια λειτουργία "γάντζου" είναι μια λειτουργία επανάκλησης που μπορεί να εισαχθεί στο μήνυμα των Windows έτσι ώστε μια εφαρμογή να μπορεί να έχει πρόσβαση στη ροή μηνυμάτων πριν από τη λήψη άλλης επεξεργασίας του μηνύματος θέση. Ανάμεσα σε πολλούς τύπους αγκιστριών παραθύρων, ένα άγκιστρο πληκτρολογίου καλείται κάθε φορά που η εφαρμογή καλεί το GetMessage () ή PeekMessage () και υπάρχει ένα μήνυμα πληκτρολογίου WM_KEYUP ή WM_KEYDOWN για να επεξεργάζομαι, διαδικασία.

Για να δημιουργήσετε ένα γάντζο πληκτρολογίου που παρεμποδίζει την πληκτρολόγηση όλων των εισερχομένων πληκτρολογίων σε ένα δεδομένο νήμα, πρέπει να καλέσουμε SetWindowsHookEx API λειτουργία. Οι ρουτίνες που λαμβάνουν τα συμβάντα πληκτρολογίου είναι λειτουργίες επανάκλησης που ορίζονται ως εφαρμογές που ονομάζονται λειτουργίες αγκίστρου (KeyboardHookProc). Τα Windows καλούν τη λειτουργία του άγκιστρου για κάθε μήνυμα πληκτρολόγησης (πληκτρολογήστε επάνω και πληκτρολογήστε) πριν το μήνυμα τοποθετηθεί στην ουρά μηνυμάτων της εφαρμογής. Η λειτουργία αγκίστρου μπορεί να επεξεργαστεί, να αλλάξει ή να απορρίψει τις πληκτρολογήσεις. Οι γάντζοι μπορεί να είναι τοπικοί ή παγκόσμιοι.

ο αξία επιστροφής του SetWindowsHookEx είναι μια λαβή στο γάντζο που μόλις εγκαταστήσατε. Πριν από τον τερματισμό, μια εφαρμογή πρέπει να καλέσει το UnhookWindowsHookEx λειτουργούν με τους πόρους του συστήματος που σχετίζονται με το γάντζο.

Παράδειγμα γάντζου πληκτρολογίου

Ως επίδειξη των αγκιστριών πληκτρολογίου, θα δημιουργήσουμε ένα έργο με γραφικό έλεγχο που θα μπορεί να λαμβάνει πλήκτρα. Το TImage προέρχεται από το TGraphicControl, μπορεί να χρησιμοποιηθεί ως επιφάνεια σχεδίασης για το υποθετικό μας παιχνίδι μάχης. Δεδομένου ότι το TImage δεν μπορεί να δεχτεί πρεσαρίσματα πληκτρολογίων μέσω τυποποιημένων συμβάντων πληκτρολογίου, θα δημιουργήσουμε μια λειτουργία αγκίστρου που θα αναστέλλει κάθε είσοδο πληκτρολογίου που κατευθύνεται στην επιφάνεια σχεδίασής μας.

Εκδηλώσεις πληκτρολογίου επεξεργασίας TImage

Ξεκινήστε νέα Πρόγραμμα Δελφών και τοποθετήστε ένα στοιχείο εικόνας σε μια φόρμα. Ορίστε την ιδιότητα Image1.Align στο alClient. Αυτό είναι για το οπτικό μέρος, τώρα πρέπει να κάνουμε κάποια κωδικοποίηση. Πρώτον, χρειαζόμαστε κάποιες παγκόσμιες μεταβλητές:

 var
Μορφή1: TForm1;
KBHook: HHook; {αυτό παρακολουθεί την είσοδο του πληκτρολογίου}
cx, cy: ακέραιο; {θέση του σκάφους της μάχης}
{declaration of callback}
λειτουργία KeyboardHookProc (Κωδικός: Ακέραιος; WordParam: Word; LongParam: LongInt): LongInt. stdcall;
εκτέλεση
...

Για να εγκαταστήσετε ένα γάντζο, καλούμε SetWindowsHookEx στο συμβάν OnCreate μιας φόρμας.

 διαδικασία TForm1.FormCreate (αποστολέας: TObject);
ξεκινήσει
{Ρυθμίστε το άγκιστρο πληκτρολογίου έτσι ώστε να μπορούμε να παρεμποδίσουμε την εισαγωγή πληκτρολογίου}
KBHook: = SetWindowsHookEx (WH_KEYBOARD,
{callback>} @KeyboardHookProc,
HInstance,
GetCurrentThreadId ());
{τοποθετήστε το πολεμικό πλοίο στη μέση της οθόνης}
cx: = Image1.ClientWidth div 2;
cy: = Image1.ClientHeight div 2;
Image1.Canvas. PenPos: = Σημείο (cx, cy);
τέλος;

Για να ελευθερώσετε τους πόρους του συστήματος που σχετίζονται με το άγκιστρο, πρέπει να καλέσουμε τη λειτουργία UnhookWindowsHookEx στο συμβάν OnDestroy:

 διαδικασία TForm1.FormDestroy (αποστολέας: TObject);
ξεκινήσει
{ξεκλειδώστε την υποκλοπή του πληκτρολογίου}
UnHookWindowsHookEx (KBHook);
τέλος;

Το σημαντικότερο μέρος αυτού του έργου είναι το Διαδικασία επανάκλησης πληκτρολογίουHookProc χρησιμοποιείται για την επεξεργασία πληκτρολογίων.

 λειτουργία KeyboardHookProc (Κωδικός: Ακέραιος; WordParam: Word; LongParam: LongInt): LongInt.
ξεκινήσει
περίπτωση WordParam του
vk_Space: {διαγραφή του μονοπατιού του ποταμού}
ξεκινήσει
με το Form1.Image1.Canvas do
ξεκινήσει
Βούρτσα. Χρώμα: = clWhite;
Βούρτσα. Στυλ: = bsSolid;
Πλήρης (Form1.Image1.ClientRect);
τέλος;
τέλος;
vk_Right: cx: = cx + 1.
vk_Left: cx: = cx-1.
vk_Up: cy: = cy-1;
vk_Down: κύκλο: = cy + 1;
τέλος; {υπόθεση}
Αν cx <2 τότε cx: = Form1.Image1.ClientWidth-2;
Αν cx> Form1.Image1.ClientWidth -2 τότε cx: = 2;
Αν cy <2 τότε cy: = Form1.Image1.ClientHeight -2;
Αν cy> Form1.Image1.ClientHeight-2 τότε cy: = 2;
με το Form1.Image1.Canvas do
ξεκινήσει
Στυλό. Χρώμα: = clRed;
Βούρτσα. Χρώμα: = clYellow;
TextOut (0,0, Μορφή ('% d,% d', [cx, cy]));
Ορθογώνιο (cx-2, cy-2, cx + 2, cy + 2);
τέλος;
Αποτέλεσμα: = 0;
{Για να αποτρέψετε τα Windows να περάσουν τις πληκτρολογήσεις στο παράθυρο προορισμού, η τιμή του αποτελέσματος πρέπει να είναι μη μηδενική τιμή.}
τέλος;

Αυτό είναι. Τώρα έχουμε τον απόλυτο κωδικό επεξεργασίας πληκτρολογίου.

Σημειώστε μόνο ένα πράγμα: αυτός ο κώδικας δεν περιορίζεται σε καμία περίπτωση να χρησιμοποιείται μόνο με το TImage.

Η λειτουργία KeyboardHookProc χρησιμεύει ως γενικός μηχανισμός KeyPreview & KeyProcess.