دلفي هي أداة تطوير برمجة WINDOWS جديدة تمامًا مقدمة من بورلاند لأنها تستخدم لغة باسكال (باسكال موجهة للكائنات) المرنة والقابلة لإعادة الاستخدام ولديها محرك قاعدة بيانات قوي (BDE) ورمز سريع يوفر المترجم أيضًا العديد من الميزات الممتازة. وهي مفضلة لدى غالبية المبرمجين وهي تبرز بين العديد من لغات البرمجة (مثل VB وPowerBuilder وPowerpoint وما إلى ذلك).
من مميزات DELPHI عن لغات البرمجة الأخرى (مثل VB4.0) أنه يمكن تخصيص الرسائل في DELPHI ومعالجتها مباشرة، وذلك لمن يريد كتابة مكوناته الخاصة (Component)، أو الذين يريدون اعتراض الرسائل وتصفيتها، وهو أمر ضروري للمستخدمين لأن كتابة المكونات تتطلب عمومًا معالجة الرسائل المقابلة. فيما يلي مقدمة لآلية معالجة الرسائل في دلفي.
1. تسليم الرسائل في DELPHI VCL
يحتوي كل مكون VCL (مكتبة المكونات المرئية) (مثل Tbutton وTedit وما إلى ذلك) في دلفي على آلية معالجة رسائل متأصلة. النقطة الأساسية هي أن فئة المكون تتلقى رسائل معينة وترسلها إلى طريقة المعالجة المناسبة إذا كانت موجودة لا توجد طريقة معالجة محددة، يتم استدعاء مقبض معالجة الرسائل الافتراضي. من بينها، mainwndPRoc هي طريقة ثابتة محددة في فئة Twincontrol ولا يمكن تحميلها بشكل زائد (تجاوز). لا يقوم بمعالجة الرسالة مباشرة، ولكنه يتركها للأسلوب wndproc للمعالجة، ويوفر وحدة معالجة الاستثناءات للأسلوب wndproc. يتم تعريف طريقة Mainwndproc على النحو التالي:
الإجراء MainWndProc(var الرسالة: TMessage);
Wndproc هي طريقة افتراضية محددة في فئة Tcontrol، والتي تستدعي طريقة الإرسال لتوزيع الرسائل.
الإجراء WndProc(var الرسالة: TMessage);
يتم تعريف طريقة الإرسال في فئة جذر Tobject ويتم الإعلان عنها على النحو التالي:
الإجراء Tobject.dispatch(var message); يجب أن تكون معلمة الرسالة التي تم تمريرها للإرسال من نوع السجل، ويجب أن تكون نقطة الإدخال الأولى في هذا السجل عبارة عن حقل من النوع الأساسي (حقل)، والذي يحتوي على رقم الرسالة المراد توزيعها. . على سبيل المثال:
يكتب
Tmessage=سجل
رسالة:الكاردينال;
wparam:Word;
lparam:longint;
النتيجة:لونجينت؛
نهاية؛
سوف يقوم أسلوب الإرسال باستدعاء أسلوب المقبض لفئة الجيل الأخير من المكون الذي يعالج هذه الرسالة بناءً على رقم الرسالة. إذا لم يكن هناك معالج مطابق لهذه الرسالة في هذا المكون وفئة الأصل الخاصة به، فسوف يقوم أسلوب الإرسال باستدعاء المعالج الافتراضي. الطريقة الافتراضية هي الطريقة الافتراضية المحددة في Tobject كما يلي:
الإجراء الافتراضي (رسالة فار)؛
تنفذ طريقة Defaulthandler في فئة Tobject إرجاعًا بسيطًا فقط دون أي معالجة للرسالة. يمكننا تنفيذ المعالجة الافتراضية للرسالة في الفئة الفرعية عن طريق التحميل الزائد لهذه الطريقة الافتراضية، بالنسبة للمكونات الموجودة في VCL، ستبدأ طريقة Defaulthandler في تشغيل النوافذ وظيفة API Defwindowproc لمعالجة الرسالة.
2. مقبض معالجة الرسائل في DELPHI
في DELPHI، يمكن للمستخدمين تخصيص الرسائل ومقابض معالجة الرسائل. يتضمن تعريف مقابض معالجة الرسائل المبادئ التالية:
يجب أن تكون طريقة معالجة الرسائل إجراءً، ويمكنها فقط تمرير معلمة متغيرة واحدة من نوع Tmessage.
يجب أن يتبع إعلان الطريقة أمر رسالة، متبوعًا بتسمية الرسالة (عدد صحيح ثابت) بين 0 و32767.
لا تحتاج طريقة معالج الرسائل إلى استخدام أمر التجاوز للإشارة بشكل صريح إلى تجاوز معالج الرسائل الخاص بالسلف. بالإضافة إلى ذلك، يتم الإعلان عنها بشكل عام في المنطقة المحمية أو الخاصة للمكون.
في مقبض معالجة الرسائل، يقوم المستخدم عمومًا بمعالجة الرسالة أولاً، ثم يستخدم أخيرًا الأمر الموروث لاستدعاء مقبض المعالجة المطابق لهذه الرسالة في فئة السلف (في بعض الحالات، قد يكون العكس بسبب مقبض المعالجة). قد تكون هذه الرسالة في فئة السلف غير واضحة، ويمكن أن يؤدي استدعاء الأمر الموروث إلى تجنب هذه المشكلة. وبالمثل، إذا لم يكن هناك معالج مطابق لهذه الرسالة في فئة السلف، فسوف يستدعي الأمر الموروث تلقائيًا طريقة Defaulthandler. (بالطبع، إذا كنت تريد حظر هذه الرسالة، ليست هناك حاجة لاستخدام الأمر الموروث).
يتم تعريف طريقة معالج الرسالة على النحو التالي:
الإجراء Mymsgmethod(var message:Tmessage message Msgtype);
وبالمثل، يمكن للمستخدمين أيضًا تحديد الرسائل الخاصة بهم، ويجب أن تبدأ بـ WM_USER.
فيما يلي أمثلة على الرسائل المخصصة ومقابض معالجة الرسائل:
const my_paint=Wm_user+1;
يكتب
Tmypaint=record
msgstr:الكاردينال;
msize:كلمة;
م اللون: لونجينت؛
msgresult:longint;
نهاية؛
يكتب
Tmycontrol=class(TCustomControl)
محمي
تغيير الإجراء (رسالة فار: Tmypaint)؛
.....
نهاية؛
...
الإجراء Tmycontrol.change(var message:Tmypaint);
يبدأ
الحجم:=message.msize {تعيين سمة حجم الزر}
اللون:=message.mcolor {تعيين سمة لون Tmybutton}
{افعل شيئًا آخر}
موروث {تم تسليمه إلى التحكم المخصص}
نهاية؛
3. تصفية الرسائل
تسمى تصفية الرسائل أيضًا مصيدة الرسائل. في ظل ظروف معينة، قد يحتاج المستخدمون إلى حظر رسائل معينة أو اعتراض رسائل معينة لمعالجتها. من المقدمة أعلاه، يمكننا أن نرى أن هناك ثلاث طرق بشكل عام لتصفية الرسائل: (1) التحميل الزائد للطريقة الافتراضية التي ورثها المكون (2). قم بتحميل الطريقة الافتراضية Defhandler الموروثة من المكون حيث تتم معالجة الرسائل. الطريقة الأكثر استخدامًا هي الطريقة (2)، والتي تم تقديمها في القسم السابق، الطريقة (1) مشابهة للطريقة (3) ونقدم هنا الطريقة (1) بإيجاز فقط.
العملية العامة للتحميل الزائد للطريقة الافتراضية wndproc هي كما يلي:
الإجراء Tmyobject.wndproc(var message:Tmessage);
يبدأ
{... تحديد ما إذا كان يجب معالجة هذه الرسالة..}
ورثت wndproc(message);
{تتم معالجة الرسائل غير المعالجة بواسطة طريقة wndproc الأصلية}
نهاية؛
يمكن أن نرى من هذا أن ميزة معالجة الرسائل في طريقة wndproc هي أنه يمكنها تصفية نطاق الرسائل بالكامل دون الحاجة إلى تحديد مقبض معالجة لكل رسالة. في الواقع، يتم استخدامه في مكون Tcontrol للتصفية والتصفية معالجة كافة رسائل الماوس (من WM_mousefirst إلى WM_mouselast، كما هو موضح في الكود التالي).
الإجراء TControl.WndProc(var الرسالة: TMessage);
يبدأ
إذا (Message.Msg>=WM_MOUSEFIRST) و
(Message.Msg <= WM_MOUSELAST)
ثم
إذا كان السحب ثم {التعامل مع حدث السحب}
DragMouseMsg(TWMMouse(رسالة))
آخر
... {تعامل مع رسائل الماوس الأخرى}
نهاية؛
إرسال(رسالة);
{وإلا أرسل الرسالة بشكل عادي}
نهاية؛
المثال التالي هو مثال بسيط للمكون المخصص:
فئة Tmyedit هي فئة جديدة مشتقة من فئة Tedit، وتتمثل خصائصها في أنها لا تستطيع الحصول على التركيز أثناء التشغيل ولا يمكن إدخالها بواسطة لوحة المفاتيح (تشبه إلى حد ما مكون Tlabel). يمكننا تصفية رسائل WM_setfocus وWM_mousemove في ملفاتها طريقة wndproc وتنفيذها لتحقيق المتطلبات المذكورة أعلاه، يكون البرنامج المصدر كما يلي:
وحدة تحرير؛
واجهة
الاستخدامات
ويندوز، الرسائل، SysUtils، الطبقات، الرسومات،
الضوابط والنماذج ومربعات الحوار،
StdCtrls;
يكتب
تميديت = فئة(تيديت)
خاص
{تصريحات خاصة}
محمي
{ التصريحات المحمية }
{المجالات والأساليب الأخرى}
الإجراء wndproc(var message:Tmessage);override;
عام
{التصريحات العامة}
نشرت
{ التصريحات المنشورة }
نهاية؛
سجل الإجراء؛
تطبيق
سجل الإجراء؛
يبدأ
RegisterComponents('Samples', [Tmyedit]);
نهاية؛
الإجراء Tmyedit.wndproc(var message:tmessage);
يبدأ
إذا message.msg=wm_mousemove بعد ذلك
يبدأ
المؤشر:= الغراب؛
{اضبط المؤشر على crarrow بدلاً من مؤشر crBeam الافتراضي}
مخرج؛
نهاية؛
إذا message.msg=wm_SetFocus ثم قم بالخروج؛
{قم بحماية رسالة WM_setfocus ومنع عنصر التحكم Tmyedit من الحصول على تركيز الإدخال}
ورثت wndproc(message);
{يتم تسليم الرسائل الأخرى إلى wndproc الأصل للمعالجة}
نهاية؛
نهاية.
يمكنك إضافة Tmyedit إلى لوحة المكونات لاختبار أدائها.
كما يتبين من المقدمة أعلاه، لا يمكن تحقيق ذلك إلا من خلال فهم آلية معالجة الرسائل في دلفي VCL، وإتقان أساليب وتوقيت معالجة الرسائل المختلفة (باستخدام أدوات مختلفة إذا لزم الأمر، مثل Winsight32، وSpy، وما إلى ذلك)، والجمع بين الخصائص. بالنسبة للغة OOP، يمكننا تجميع مكونات عالية الجودة. وهذا، بطبيعة الحال، يتطلب من القراء أن يستكشفوا باستمرار ويتراكموا الخبرة في الممارسة العملية.