دلفي هي أداة تطوير برمجيات مرئية موجهة للكائنات من شركة بورلاند. تجمع دلفي بين مزايا كل من Visual C++ وVisual Basic: سهلة الاستخدام وقوية ولها مزايا فريدة خاصة في تصميم الواجهة وبرمجة قواعد البيانات وبرمجة الشبكات.
الرسائل في دلفي
الرسالة عبارة عن إشعار يتم إرساله بواسطة Windows لإخبار التطبيق بوقوع حدث ما. في دلفي، يتم تغليف رسائل Windows في معظم الحالات في أحداث VCL، نحتاج فقط إلى التعامل مع أحداث VCL المقابلة، ومع ذلك، إذا كنا بحاجة إلى كتابة عناصر التحكم الخاصة بنا، أو اعتراض الرسائل أو تصفيتها، فيجب علينا التعمق في آلية معالجة الرسائل.
في دلفي، يتم تعريف الرسائل في شكل سجلات TMessage. افتح ملف message.pas، يمكننا أن نرى أن Tmessage تم تعريفه على النحو التالي:
يكتب
TMessage = سجل معبأ
الرسالة: الكاردينال؛
حالة عدد صحيح من
0: (WParam: لونجينت؛
LParam: لونجينت؛
النتيجة: لونجينت)؛
1: (WParamLo: كلمة؛
WParamHi: كلمة؛
LParamLo: كلمة؛
LParamHi: كلمة؛
النتيجة لو: كلمة؛
ResultHi: Word);
نهاية؛
من بينها، Msg هي قيمة ثابتة تختلف عن الرسائل الأخرى. يمكن أن تكون هذه القيم الثابتة ثوابت محددة مسبقًا في وحدات Windows أو ثوابت محددة من قبل المستخدم. عادةً ما تكون Wparam قيمة ثابتة مرتبطة برسالة، أو يمكن أن تكون مؤشرًا لنافذة أو عنصر تحكم. عادةً ما يكون LParam مؤشرًا للبيانات الموجودة في الذاكرة.
النتيجة هي القيمة المرجعة لمعالجة الرسائل. Wparam وLparam وResult كلها 32 بت. إذا كنت تريد الوصول إلى الـ 16 بت السفلية أو الـ 16 بت العليا، فيمكنك استخدام WparamLo وWparamHi وLParamLo وLparamHi وResultLo وResultHi على التوالي.
بالإضافة إلى Tmessage العام، يتم تعريف سجل رسائل خاص لكل Windows في دلفي. يمكننا تصفح ملف message.pas، وهنا سجل رسالة لوحة المفاتيح:
TWMKey = سجل معبأ
الرسالة: الكاردينال؛
كود CharCode: كلمة؛
غير مستخدم: كلمة؛
البيانات الرئيسية: لونجينت؛
النتيجة: لونجينت؛
يتم أيضًا تعريف الرسائل المتعلقة بلوحة المفاتيح مثل: سجلات WM_KEYDOWN وWM_KEYUP وWM_CHAR وWM_SYSKEYDOWN وWM_SYSKEYUP وWM_SYSCHAR على أنها TWMkey. يوجد البيان التالي في ملف message.pas:
TWMChar=TWMkey;
TWMkeyUp=TWMkey;
-KeyDown=TWMkey;
TWMkey;TWMSysChar=TWMkey;
إرسال الرسائل
تهدف معالجة الرسائل إلى تحديد كيفية استجابة التطبيق لرسائل Windows. في دلفي، كل رسالة لها عملية معالجة خاصة بها، ويجب أن تكون طريقة في كائن، ويمكنها تمرير رسالة Tmessage واحدة فقط أو أي سجل رسالة خاص آخر، ويجب أن يكون هناك أمر رسالة بعد إعلان الطريقة، متبوعًا برسالة تتراوح من 0 إلى ثابت بين 32767.
الرسائل التي ذكرناها سابقًا هي جميعها رسائل Windows القياسية (WM_X)، بالإضافة إلى ذلك، هناك رسائل VCL الداخلية ورسائل الإعلام والرسائل المحددة من قبل المستخدم.
تبدأ رسائل VCL الداخلية عادةً بـ "CM_" وتستخدم لإدارة الأشياء داخل VCL. إذا قمت بتغيير قيمة خاصية أو بعض الخصائص الأخرى لأحد المكونات، فستحتاج إلى إخطار المكونات الأخرى بالتغيير من خلال الرسائل الداخلية. على سبيل المثال، يتم إرسال رسالة تنشيط تركيز الإدخال إلى مكون نشط أو معطل لقبول تركيز الإدخال أو التخلي عنه.
هناك أيضًا رسائل إعلام. يحدث شيء ما لعنصر تحكم الطفل في النافذة ويجب إعلام النافذة الرئيسية بذلك من خلال رسائل الإعلام. إنه يعمل فقط مع عناصر التحكم القياسية في النوافذ، مثل الأزرار ومربعات القائمة ومربعات التحرير وما إلى ذلك. افتح ملف message.pas بعد Windows القياسي هو إعلان رسالة الإعلام:
ثابت
{$EXTERNALSYM BN_CLICKED}
BN_CLICKED = 0؛
{$EXTERNALSYM BN_PAINT}
BN_PAINT = 1;
{$EXTERNALSYM BN_HILITE}
BN_HILITE = 2؛
ما ورد أعلاه عبارة عن رسائل الإعلام الخاصة بالزر، والتي تشير على التوالي إلى أن المستخدم قام بالنقر فوق الزر، وأنه يجب إعادة رسم الزر، وأن المستخدم قام بتمييز الزر.
يمكن للمستخدمين أيضًا تحديد رسائلهم الخاصة وإرسال الرسائل لأنفسهم وكتابة إجراءات معالجة الرسائل. القيمة الثابتة للرسالة هي WM_USER+100 إلى $7FFF هذا النطاق محجوز بواسطة Windows للرسائل المعرفة من قبل المستخدم.
هناك ثلاث طرق لإرسال رسائل دلفي:
1. تنفيذ طريقة الكائن لفئة Tcontrol. يمكنك إرسال رسائل إلى أي نموذج أو عنصر تحكم، ما عليك سوى معرفة مثيل النموذج أو عنصر التحكم. وبيانها هو كما يلي:
وظيفة Tcontrol.Perform(Msg:Cardinal;Wparam,Lparam:Longint):Longint
2. وظائف Windows API SendMessage () وPostmessage (). وبيانها هو كما يلي:
وظيفة SendMessage (hWnd: HWND؛ Msg: UINT؛ wParam: WPARAM؛ lParam: LPARAM): LRESULT؛
وظيفة SendMessage(hWnd: HWND; Msg: UINT; wParam: WPARAM; lParam: LPARAM): LRESULT;
تقوم وظيفة PostMessage بإضافة رسالة إلى قائمة انتظار الرسائل الخاصة بالتطبيق. ستقوم حلقة رسائل التطبيق باستخراج الرسالة المسجلة من قائمة انتظار الرسائل ثم إرسالها إلى النافذة المقابلة.
يمكن لوظيفة SendMessage إرسال الرسائل مباشرة إلى إجراء النافذة عبر قائمة انتظار الرسائل. لذلك يتم استخدام SendMessage عندما يحتاج Windows إلى إرجاع قيمة على الفور، ويتم استخدام PostMessage عندما تحتاج تطبيقات مختلفة إلى معالجة الرسائل بالتسلسل. التنفيذ يشبه بشكل أساسي SendMessage، حيث يتم إرسالها مباشرة إلى إجراء النافذة. تحتاج وظائف SendMessage وPostmessage فقط إلى معرفة مقبض النافذة لإرسال الرسائل، حتى يتمكنوا من إرسال رسالة إلى نموذج غير دلفي، ولكن يجب أن يعرف الأداء مثيل النموذج أو عنصر التحكم.
آلية معالجة رسائل VCL
يوجد البيان application.Run في الكود المصدري لتطبيق Delphi، وتتمثل وظيفته في بدء حلقة الرسائل ثم استدعاء Application.PRocessMessage. ستجد هذه الوظيفة رسالة في قائمة انتظار رسائل التطبيق. عند استرداد رسالة من قائمة انتظار الرسائل، يتم تشغيل الحدث Application.OnMessage. بهذه الطريقة، قبل أن يقوم Windows نفسه بمعالجة الرسالة، فإنه يستجيب لمعالجة حدث OnMessage وهو متفوق على أي معالجة للرسائل ويستقبل فقط الرسائل المسجلة، أي الرسائل المرسلة بواسطة PostMessage كما هو مذكور أعلاه. يجب أن تكون عملية المعالجة التي تستجيب للحدث Application.OnMessage من النوع TmessageEvent، والذي يتم تعريفه على النحو التالي:
اكتب TMessageEvent = الإجراء (var Msg: TMsg؛ var Handled: Boolean) للكائن؛
حيث أن TMsg هو سجل الرسائل المحدد في نظام التشغيل Windows، فيمكننا الإعلان عنه على النحو التالي:
الإجراء OnMyMessage(var Msg:TMsg;var Handled:Boolean);
ثم قم بتعيين هذه الطريقة للحدث Application.OnMessage:
Application.OnMessage :=OnMyMessage;
سيقوم حدث OnMessage بالتقاط جميع الرسائل المرسلة إلى التطبيق، وهو حدث مزدحم للغاية، لذلك ليس من الحكمة تعيين نقاط توقف أثناء معالجة حدث OnMessage لمعالجة الرسائل.
الطريقة التي يستخدمها كائن VCL لتلقي الرسائل تسمى MainWndProc. إنها طريقة ثابتة محددة في فئة Twincontrol ولا يمكن تحميلها بشكل زائد. ولا يقوم بمعالجة الرسالة مباشرة. عندما تغادر الرسالة MainWndProc، يتم تمرير الرسالة إلى أسلوب WndProc الخاص بالكائن. أسلوب WndProc هو أسلوب ظاهري محدد في فئة Tcontrol، والذي يستدعي أسلوب Dispatch. يبحث Dispatch عن طريقة المعالجة المقابلة بناءً على الرسالة الواردة، وإذا لم يتمكن من العثور عليها في النهاية، فإنه يستمر في البحث عن طريقة معالجة الرسالة في الفئة الأصل حتى يتم العثور عليها، وإذا لم يتمكن من العثور عليها، فإنه يستدعي Defaulthandler. يقوم الأسلوب Defaulthandler بإجراء المعالجة النهائية للرسالة ثم يقوم بتمرير الرسالة إلى وظيفة Windows DefWindowProc أو إجراءات النافذة الافتراضية الأخرى.