اسحب نموذج دلفي بدون شريط التسمية التوضيحية

اسحب نموذج دلفي بدون شريط التسمية التوضيحية

الطريقة الأكثر شيوعًا لنقل النافذة هي سحبها من شريط العنوان. تابع القراءة لمعرفة كيف يمكنك توفير قدرات السحب لنماذج دلفي دون شريط العنوان ، بحيث يمكن للمستخدم نقل نموذج من خلال النقر في أي مكان على منطقة العميل.

على سبيل المثال ، ضع في اعتبارك حالة تطبيق Windows الذي لا يحتوي على شريط عنوان ، كيف يمكننا نقل هذه النافذة؟ في الواقع ، من الممكن إنشاء نوافذ مع شريط عنوان غير قياسي وحتى أشكال غير مستطيلة. في هذه الحالة ، كيف يمكن لـ Windows معرفة أين تقع حدود وزوايا النافذة؟

WM_NCHitTest ويندوز رسالة

يعتمد نظام التشغيل Windows بشكل كبير على معالجة الرسائل. على سبيل المثال ، عند النقر فوق نافذة أو عنصر تحكم ، يرسل Windows رسالة wm_LButtonDown بها ، مع معلومات إضافية حول مكان مؤشر الماوس وأي مفاتيح التحكم مضغوطة حاليًا. يبدوا مألوفا؟ نعم ، هذا ليس أكثر من حدث OnMouseDown في دلفي.

وبالمثل ، يرسل Windows رسالة wm_NCHitTest كلما حدث حدث ماوس ، أي عندما يتحرك المؤشر ، أو عند الضغط على زر الماوس أو تحريره.

رمز الإدخال

إذا تمكنا من جعل Windows يعتقد أن المستخدم يقوم بسحب (النقر على) شريط العنوان بدلاً من منطقة العميل ، فيمكن للمستخدم سحب النافذة بالنقر فوق منطقة العميل. أسهل طريقة للقيام بذلك هي "خداع" Windows للاعتقاد بأنك تنقر فعليًا على شريط عنوان النموذج. إليك ما عليك القيام به:

1. أدخل السطر التالي في قسم "الإعلانات الخاصة" للنموذج (إعلان إجراء معالجة الرسائل):

إجراء WMNCHitTest (فار Msg: TWMNCHitTest) ؛ رسالة WM_NCHITTEST.

2. أضف الكود التالي في قسم "التنفيذ" بوحدة النموذج الخاص بك (حيث Form1 هو اسم النموذج المفترض):

إجراء TForm1.WMNCHitTest (فار Msg: TWMNCHitTest) ؛

ابدأ

   وارث;
  

إذا Msg.Result = htClient ثم رسالة: = htCaption؛

النهاية;

يستدعي السطر الأول من التعليمات البرمجية في معالج الرسائل الطريقة الموروثة للحصول على المعالجة الافتراضية لرسالة wm_NCHitTest. يقوم جزء If في الإجراء باعتراض وتغيير سلوك النافذة. هذا ما يحدث فعليًا: عندما يرسل نظام التشغيل رسالة wm_NCHitTest إلى النافذة ، جنبًا إلى جنب مع إحداثيات الماوس ، تقوم النافذة بإرجاع رمز يوضح الجزء الذي تم ضربه. الجزء المهم من المعلومات ، لمهمتنا ، هو في قيمة الحقل Msg.Result. في هذه المرحلة ، لدينا فرصة لتعديل نتيجة الرسالة.

هذا ما نقوم به: إذا قام المستخدم بالنقر فوق منطقة العميل الخاصة بالنموذج ، فسنجعل Windows يفكر في أن المستخدم قد نقر على شريط العنوان. في "كلمات" كائن Pascal: إذا كانت قيمة إرجاع الرسالة هي HTCLIENT ، فإننا ببساطة نقوم بتغييرها إلى HTCAPTION.

لا مزيد من أحداث الماوس

من خلال تغيير السلوك الافتراضي لأشكالنا ، نزيل قدرة Windows على إخطارك عندما يكون الماوس فوق منطقة العميل. أحد الآثار الجانبية لهذه الخدعة هو أن النموذج الخاص بك لن ينشئ أحداثًا لرسائل الماوس.

نافذة توضيحية بلا حدود

إذا كنت تريد إطار بلا حدود توضيحية بلا حدود يشبه شريط أدوات عائم ، فاضبط تسمية توضيحية للنموذج على سلسلة فارغة ، وقم بتعطيل كل الحدود ، واضبط BorderStyle على bsNone.

يمكن تغيير النموذج بطرق مختلفة عن طريق تطبيق التعليمات البرمجية المخصصة في أسلوب CreateParams.

المزيد من الخدع WM_NCHitTest

إذا نظرت بمزيد من الدقة إلى رسالة wm_NCHitTest ، فسترى أن القيمة المرجعة للوظيفة تشير إلى موضع النقطة الساخنة للمؤشر. هذا يمكننا من لعب بعض أكثر مع الرسالة لخلق نتائج غريبة.

جزء التعليمات البرمجية التالي سيمنع المستخدمين من إغلاق النماذج بالنقر فوق الزر "إغلاق".

إذا Msg.Result = htClose ثم رسالة: = htNowhere؛

إذا كان المستخدم يحاول نقل النموذج من خلال النقر على شريط التسمية التوضيحية والسحب ، فإن الرمز يستبدل نتيجة الرسالة بنتيجة تشير إلى قيام المستخدم بالنقر فوق منطقة العميل. هذا يمنع المستخدم من تحريك النافذة بالماوس (عكس ما كنا نفعله في التسول من هذه المقالة).

إذا Msg.Result = htCaption ثم Msg.Result: = htClient؛

وجود مكونات على النموذج

في معظم الحالات ، سيكون لدينا بعض المكونات في نموذج. دعنا نقول ، على سبيل المثال ، أن كائن لوحة واحد موجود في نموذج. إذا تم تعيين خاصية محاذاة لوحة ما إلى alClient ، فإن اللوحة تملأ منطقة العميل بالكامل بحيث يكون من المستحيل تحديد النموذج الأصلي من خلال النقر عليه. الكود أعلاه لن يعمل - لماذا؟ السبب في ذلك هو أن الماوس يتحرك دائمًا عبر مكون اللوحة ، وليس النموذج.

لنقل النموذج عن طريق سحب لوحة في النموذج ، يتعين علينا إضافة سطور قليلة من التعليمات البرمجية في إجراء حدث OnMouseDown لمكون اللوحة:

إجراء TForm1.Panel1MouseDown
(المرسل: TObject ؛ زر: TMouseButton.
التحول: TShiftState. س ، ص: عدد صحيح) ؛

ابدأ

ReleaseCapture.

SendMessage (Form1.Handle، WM_SYSCOMMAND، 61458، 0)؛

النهاية;

ملحوظة: لن يعمل هذا الرمز مع عناصر تحكم غير نافذة مثل مكونات TLabel.


شاهد الفيديو: الاجزاء الاساسية لمضخة الحقن الموزعة The basic parts of the distributed injection pump