أحداث الماوس تمر عبر السيطرة على الوالدين
-
23-08-2019 - |
سؤال
البيئة: .NET Framework 2.0، مقابل 2008.
أحاول إنشاء فئة فرعية من بعض عناصر تحكم .NET (الملصقات، لوحة) التي ستمر عبر أحداث الماوس معينة (MouseDown
, MouseMove
, MouseUp
) إلى عنصر تحكم الوالدين (أو بدلا من ذلك إلى نموذج المستوى الأعلى). يمكنني القيام بذلك عن طريق إنشاء معالجات لهذه الأحداث في مثيلات الضوابط القياسية، على سبيل المثال:
public class TheForm : Form
{
private Label theLabel;
private void InitializeComponent()
{
theLabel = new Label();
theLabel.MouseDown += new MouseEventHandler(theLabel_MouseDown);
}
private void theLabel_MouseDown(object sender, MouseEventArgs e)
{
int xTrans = e.X + this.Location.X;
int yTrans = e.Y + this.Location.Y;
MouseEventArgs eTrans = new MouseEventArgs(e.Button, e.Clicks, xTrans, yTrans, e.Delta);
this.OnMouseDown(eTrans);
}
}
لا يمكنني نقل معالج الأحداث في فئة فرعية من عنصر التحكم، لأن الأساليب التي ترفع الأحداث في عنصر تحكم الأصل محمي وليس لدي مؤهل للتحكم الرئيسي:
لا يمكن الوصول إلى العضو المحمي
System.Windows.Forms.Control.OnMouseDown(System.Windows.Forms.MouseEventArgs)
عبر تصفية من النوعSystem.Windows.Forms.Control
; ؛ يجب أن يكون التصفيات من النوعTheProject.NoCaptureLabel
(أو مشتقة منه).
أنا أبحث في تجاوز WndProc
طريقة التحكم في فئتي الفرعية، ولكن نأمل أن يعطيني شخص ما حلا نظيفا.
المحلول
نعم. بعد الكثير من البحث، وجدت المقال "الضوابط العائمة، نمط Tooltip", ، والتي تستخدم WndProc
لتغيير الرسالة من WM_NCHITTEST
ل HTTRANSPARENT
, ، جعل Control
شفافة لأحداث الماوس.
لتحقيق ذلك، قم بإنشاء عنصر تحكم موروث من Label
وبما هو إضافة التعليمات البرمجية التالية.
protected override void WndProc(ref Message m)
{
const int WM_NCHITTEST = 0x0084;
const int HTTRANSPARENT = (-1);
if (m.Msg == WM_NCHITTEST)
{
m.Result = (IntPtr)HTTRANSPARENT;
}
else
{
base.WndProc(ref m);
}
}
لقد اختبرت هذا في Visual Studio 2010 مع ملف تعريف .NET Framework 4.
نصائح أخرى
تحتاج إلى كتابة طريقة عامة / محمية في الفصل الأساسي الخاص بك والتي سترفع الحدث لك. ثم اتصل بهذه الطريقة من الفئة المشتقة.
أو
هل هذا ما تريد؟
public class MyLabel : Label
{
protected override void OnMouseDown(MouseEventArgs e)
{
base.OnMouseDown(e);
//Do derived class stuff here
}
}
ال WS_EX_TRANSPARENT
نمط النافذة الممتدة فعلا يفعل هذا (فهو استخدام Tooltips في مكان). قد ترغب في التفكير في تطبيق هذا النمط بدلا من الترميز الكثير من المعالجين للقيام بذلك من أجلك.
للقيام بذلك، تجاوز CreateParams
طريقة:
protected override CreateParams CreateParams
{
get
{
CreateParams cp=base.CreateParams;
cp.ExStyle|=0x00000020; //WS_EX_TRANSPARENT
return cp;
}
}
لمزيد من القراءة: