سؤال

لدي مشكلة مع MouseEvents على WinForm C# التطبيق.

أريد الحصول على كل نقرات الماوس على طلبي ولكن لا تريد أن تضع المستمع في كل طفل عنصر لا تستخدم ويندوز ربط الماوس.

على فلاش يمكنني وضع المستمع في مرحلة الحصول على جميع MouseEvents على الفيلم.

هل هناك شيء من هذا القبيل على C# ؟ عالمي MouseListener?


تحرير:

أنا إنشاء هذه الفئة من IMessageFilter الجواب تستخدم التطبيق.AddMessageFilter.

public class GlobalMouseHandler : IMessageFilter{

    private const int WM_LBUTTONDOWN = 0x201;

    public bool PreFilterMessage(ref Message m){
        if (m.Msg == WM_LBUTTONDOWN) {
            // Do stuffs
        }
        return false;
    }
}

ووضع هذا الرمز على الضوابط التي تحتاج إلى الاستماع العالمية النقرات:

GlobalMouseHandler globalClick = new GlobalMouseHandler();
Application.AddMessageFilter(globalClick);
هل كانت مفيدة؟

المحلول

بسيط واحد طريقة للقيام بذلك هو أن تضيف رسالة حلقة التصفية عن طريق الاتصال Application.AddMessageFilter و كتابة الدرجة التي تطبق IMessageFilter واجهة.

عبر IMessageFilter.PreFilterMessage, ، صفك يحصل أن ترى أي مدخلات الرسائل التي تمر عبر التطبيق الخاص بك رسالة حلقة. PreFilterMessage يحصل أيضا أن تقرر ما إذا كنت تريد تمرير هذه الرسائل على التحكم المحددة التي كنت متجهة.

قطعة واحدة من التعقيد أن هذا النهج يدخل هو الاضطرار إلى التعامل مع ويندوز رسائل عبر رسالة البنية مرت بك PreFilterMessage الأسلوب.وهذا يعني مشيرا إلى Win32 documention على WM\_LBUTTONDOWN, WM\_MOUSEMOVE, WM\_LBUTTONUP الخ بدلا من التقليدية MouseDown, MouseMove و MouseUp أحداث.

نصائح أخرى

فئة عينة

class CaptureEvents : IMessageFilter
{
    #region IMessageFilter Members
    public delegate void Callback(int message);
    public event Callback MessageReceived;

    IntPtr ownerWindow;
    Hashtable interestedMessages = null;
    CaptureEvents(IntPtr handle, int[] messages)
    {
        ownerWindow = handle;
        for(int c = 0; c < messages.Length ; c++)
        {
            interestedMessages[messages[c]] = 0;
        }
    }
    public bool PreFilterMessage(ref Message m)
    {
        if (m.HWnd == ownerWindow && interestedMessages.ContainsKey(m.Msg))
        {
            MessageReceived(m.Msg);
        }
        return true;
    }

    #endregion
}

نلقي نظرة على هذه المادة.ذلك بشكل متكرر hoooks جميع السيطرة على الأحداث و تبث لهم.يمكنك أيضا تجاوز WndProc في النموذج الخاص بك.

إذا كنت لا تريد للتعامل مع الرسائل عن طريق تجاوز النموذج.PreProcessMessage أو شكل.WndProc ثم هل يمكن فرعية شكل ربط معالج الحدث إلى جميع MouseClick الأحداث من مختلف عناصر التحكم في النموذج.
تحرير:نسيت أن recurse الطفل من خلال ضوابط التحكم في النموذج.

    public class MousePreviewForm : Form
    {
      protected override void OnClosed(EventArgs e)
      {
         UnhookControl(this as Control);
         base.OnClosed(e);
      }

      protected override void OnLoad(EventArgs e)
      {
         base.OnLoad(e);

         HookControl(this as Control);
      }

      private void HookControl(Control controlToHook)
      {
         controlToHook.MouseClick += AllControlsMouseClick;
         foreach (Control ctl in controlToHook.Controls)
         {
            HookControl(ctl);
         }      
      }

      private void UnhookControl(Control controlToUnhook)
      {
         controlToUnhook.MouseClick -= AllControlsMouseClick;
         foreach (Control ctl in controlToUnhook.Controls)
         {
            UnhookControl(ctl);
         }
      }

      void AllControlsMouseClick(object sender, MouseEventArgs e)
      {
         //do clever stuff here...
         throw new NotImplementedException();
      }
   }

النماذج الخاصة بك سوف تحتاج بعد ذلك إلى اشتقاق من MousePreviewForm لا نظام.يقوم نظام ويندوز.أشكال.شكل.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top