النظر في إنشاء لحظة من لعبة الورق سريعة. يتم عرض جميع الرسومات ، دعنا نقول ، في TPainBox. يتعذر على TPaintBox تلقي تركيز الإدخال - لا يتم تشغيل أي أحداث عندما يضغط المستخدم على المفتاح ؛ لا يمكننا اعتراض مفاتيح المؤشر لتحريك سفينة حربية لدينا. دلفي مساعدة!
اعتراض إدخال لوحة المفاتيح
تعالج معظم تطبيقات دلفي عادةً مدخلات المستخدم من خلال معالجات أحداث معينة ، تلك التي تمكننا من التقاط المستخدم ضربات المفاتيح و العملية حركة الماوس.
نحن نعلم أن التركيز هو القدرة على تلقي إدخال المستخدم من خلال الماوس أو لوحة المفاتيح. فقط الكائن الذي يحتوي على التركيز يمكنه تلقي حدث لوحة المفاتيح. بعض عناصر التحكم ، مثل TImage و TPaintBox و TPanel و TLabel لا يمكنها تلقي التركيز. الغرض الأساسي من معظم عناصر التحكم الرسومية هو عرض النص أو الرسومات.
إذا كنا نرغب في اعتراض إدخال لوحة المفاتيح لعناصر التحكم التي لا يمكنها تلقي التركيز على الإدخال ، فسيتعين علينا التعامل مع واجهة برمجة تطبيقات Windows وخطافات الاسترجاعات و الرسائل.
السنانير ويندوز
من الناحية الفنية ، فإن وظيفة "الخطاف" هي وظيفة رد اتصال يمكن إدراجها في رسالة Windows النظام بحيث يمكن للتطبيق الوصول إلى دفق الرسائل قبل أن تأخذ معالجة أخرى للرسالة مكان. من بين العديد من أنواع ربط النوافذ ، يتم استدعاء ربط لوحة المفاتيح عندما يستدعي التطبيق دالة GetMessage () أو PeekMessage () وهناك رسالة لوحة مفاتيح WM_KEYUP أو WM_KEYDOWN إلى معالجة.
لإنشاء ربط لوحة المفاتيح الذي يعترض كل إدخال لوحة المفاتيح الموجهة إلى موضوع معين ، نحن بحاجة إلى الاتصال SetWindowsHookEx وظيفة API. إجراءات الروتينية التي تتلقى أحداث لوحة المفاتيح هي وظائف رد الاتصال المعرفة من قبل التطبيق تسمى وظائف ربط (KeyboardHookProc). يقوم Windows باستدعاء وظيفة الخطاف الخاصة بك لكل رسالة ضغط مفتاح (المفتاح لأعلى ولأسفل) قبل وضع الرسالة في قائمة انتظار الرسائل للتطبيق. تستطيع وظيفة الخطاف معالجة أو تغيير أو تجاهل ضغطات المفاتيح. السنانير يمكن أن تكون محلية أو عالمية.
ال قيمة الإرجاع من SetWindowsHookEx هو مؤشر إلى ربط تثبيت فقط. قبل الإنهاء ، يجب على التطبيق الاتصال بـ UnhookWindowsHookEx وظيفة لتحرير موارد النظام المرتبطة هوك.
مثال لوحة المفاتيح هوك
كإظهار لخطافات لوحة المفاتيح ، سنقوم بإنشاء مشروع مع تحكم بياني يمكنه تلقي مكابس المفاتيح. يتم اشتقاق TImage من TGraphicControl ، ويمكن استخدامه كسطح رسم لمباراة المعركة الافتراضية لدينا. نظرًا لأن TImage غير قادر على تلقي مكابس لوحة المفاتيح من خلال أحداث لوحة المفاتيح القياسية ، فإننا سننشئ وظيفة ربط تعترض جميع مدخلات لوحة المفاتيح الموجهة إلى سطح الرسم لدينا.
TImage معالجة أحداث لوحة المفاتيح
ابدا من جديد مشروع دلفي ووضع مكون صورة واحد في نموذج. قم بتعيين الخاصية Image1.Align إلى alClient. هذا كل شيء بالنسبة للجزء المرئي ، والآن يتعين علينا القيام ببعض الترميز. أولاً ، سنحتاج إلى بعض المتغيرات العالمية:
فار
Form1: TForm1 ؛
KBHook: HHook ؛ {هذا يعترض إدخال لوحة المفاتيح}
cx، cy: integer؛ {موقف سفينة معركة المسار}
{إعلان رد الاتصال}
وظيفة 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: = Point (cx، cy)؛
النهاية؛
لتحرير موارد النظام المرتبطة بالربط ، يجب علينا استدعاء دالة UnhookWindowsHookEx في الحدث OnDestroy:
الإجراء TForm1.FormDestroy (Sender: TObject)؛
ابدأ
{فك ربط اعتراض لوحة المفاتيح}
UnHookWindowsHookEx (KBHook) ؛
النهاية؛
الجزء الأكثر أهمية من هذا المشروع هو إجراء رد الاتصال KeyboardHookProc تستخدم لمعالجة ضربات المفاتيح.
وظيفة KeyboardHookProc (الرمز: عدد صحيح ؛ WordParam: Word؛ LongParam: LongInt): LongInt؛
ابدأ
حالة WordParam من
vk_Space: {erase battle ship's path}
ابدأ
مع Form1.Image1.Canvas تفعل
ابدأ
فرشاة. اللون: = clWhite ؛
فرشاة. نمط: = bsSolid ؛
Fillrect (Form1.Image1.ClientRect) ؛
النهاية؛
النهاية؛
vk_Right: cx: = cx + 1 ؛
vk_Left: cx: = cx-1 ؛
vk_Up: cy: = cy-1 ؛
vk_Down: cy: = cy + 1 ؛
النهاية؛ {قضية}
إذا كانت cx <2 ، فإن cx: = Form1.Image1.ClientWidth-2؛
إذا cx> Form1.Image1.ClientWidth -2 ثم cx: = 2؛
إذا كان <إذا كان cy> Form1.Image1.ClientHeight-2 ، ثم cy: = 2؛
مع Form1.Image1.Canvas تفعل
ابدأ
قلم جاف. اللون: = clRed ؛
فرشاة. اللون: = الزميل ؛
TextOut (0،0 ، التنسيق ('٪ d ،٪ d' ، [cx ، cy])) ؛
مستطيل (cx-2 ، cy-2 ، cx + 2 ، cy + 2) ؛
النهاية؛
النتيجة: = 0 ؛
{لمنع Windows من تمرير ضغطات المفاتيح إلى الإطار الهدف ، يجب أن تكون قيمة النتيجة قيمة غير صفرية.}
النهاية؛
هذا هو. لدينا الآن رمز معالجة لوحة المفاتيح النهائي.
لاحظ شيئًا واحدًا فقط: هذا الرمز مقيد بأي حال من الأحوال لاستخدامه فقط مع TImage.
تخدم وظيفة KeyboardHookProc كآلية KeyPreview و KeyProcess عامة.