2009-05-01 12 views
6

मैं सी # में एक कस्टम नियंत्रण लागू करने की कोशिश कर रहा हूं और माउस को घुमाए जाने पर मुझे ईवेंट प्राप्त करने की आवश्यकता है। मुझे पता है कि MouseHover घटना है लेकिन यह केवल एक बार आग लगती है। इसे फिर से आग लगाने के लिए मुझे नियंत्रण के माउस को लेने और फिर से दर्ज करने की आवश्यकता है।नियंत्रण में एकाधिक माउसहोवर घटनाएं

क्या कोई तरीका है कि मैं इसे पूरा कर सकता हूं?

+0

क्या आप स्पष्टीकरण दे सकते हैं? क्या आप हर बार x/y निर्देशांक बदलते समय एक ईवेंट चाहते हैं जब यह आपके नियंत्रण पर होवर हो रहा हो? –

+0

जब भी माउस चलना बंद कर देता है तो मैं एक ईवेंट प्राप्त करना चाहता हूं। मैं MouseMove ईवेंट को भी हुक करता हूं, लेकिन मुझे यह जानने की ज़रूरत है कि माउस कब चल रहा है। क्या MouseHover ईवेंट का उपयोग करने से ऐसा करने का कोई और तरीका है? –

उत्तर

8

चलिए परिभाषित करते हैं कि "चलने से रोकता है" जैसा कि n एमएस के लिए पिक्सेल त्रिज्या के भीतर रहता है "।

MouseMove ईवेंट की सदस्यता लें और अपना टाइमआउट सेट करने के लिए टाइमर (n एमएस पर सेट करें) का उपयोग करें। जब भी माउस चलता है, सहिष्णुता के खिलाफ जांचें। यदि यह आपकी सहिष्णुता के बाहर है, तो टाइमर रीसेट करें और एक नई उत्पत्ति रिकॉर्ड करें।

स्यूडोकोड:

Point lastPoint; 
const float tolerance = 5.0; 

//you might want to replace this with event subscribe/unsubscribe instead 
bool listening = false; 

void OnMouseOver() 
{ 
    lastpoint = Mouse.Location; 
    timer.Start(); 
    listening = true; //listen to MouseMove events 
} 

void OnMouseLeave() 
{ 
    timer.Stop(); 
    listening = false; //stop listening 
} 

void OnMouseMove() 
{ 
    if(listening) 
    { 
     if(Math.abs(Mouse.Location - lastPoint) > tolerance) 
     { 
      //mouse moved beyond tolerance - reset timer 
      timer.Reset(); 
      lastPoint = Mouse.Location; 
     } 
    } 
} 

void timer_Tick(object sender, EventArgs e) 
{ 
    //mouse "stopped moving" 
} 
+0

धन्यवाद, मैं कोशिश करूँगा। :) –

+0

मैं टाइमर का उपयोग करके कुछ अधिक सरल कर रहा हूं। यह "हैकिश" की तरह है लेकिन यह काम पूरा हो जाता है। सहायता के लिए धन्यवाद। –

+0

@ एलसी: मेरे पास एक समान कार्यान्वयन है, लेकिन इसे "सहनशीलता" का उपयोग करने के लिए आवश्यक नहीं मिला है। बस जांचें कि अंतिम माउस स्थान वर्तमान से अलग है या नहीं, ठीक है। –

2

क्यों MouseHover घटना में MouseMove ईवेंट की सदस्यता नहीं है, तो mouseleave घटना में सदस्यता समाप्त

संपादित करें:

एक तरीका यह निर्धारित करने के लिए माउस बंद कर दिया है एक टाइमर हर बार शुरू करने के लिए होगा आप एक माउस चाल घटना प्राप्त करें, जब टाइमर समाप्त हो गया है तो आप माउस को रोक सकते हैं। माउसलेव पर माउसमोव इवेंट को हटाने का कारण आपको माउस को अपने नियंत्रण में होने पर ही ईवेंट प्राप्त करने की अनुमति देगा।

+0

क्या आप इसका अर्थ स्पष्ट कर सकते हैं? मैं पहले से ही माउसमोव इवेंट को संभालता हूं और यह केवल तब मुझे बताता है जब माउस चल रहा है, जब इसे रोका नहीं जाता है। –

+0

हे। वही विचार +1 –

+0

मैंने टाइमर का उपयोग करने के बारे में सोचा था। मैं कल कोशिश कर रहा हूँ। और मैं दूसरे विकल्प का उपयोग नहीं कर सकता क्योंकि माउस नियंत्रण के बाहर होने पर भी मुझे माउस ईवेंट प्राप्त करने की आवश्यकता होती है। –

5

मुझे लगता है कि यह एक पुराने विषय है, लेकिन मैं एक तरह से मैं यह कर पाया साझा करना चाहते थे: कि घटना पकड़ता माउस की घटना कॉल ResetMouseEventArgs() नियंत्रण पर पर ।

+2

यह मेरे लिए काम नहीं किया। – snarf

1

यह सबसे स्पष्ट कार्यान्वयन था जिसके साथ मैं आ सकता था। यह काफी अच्छी तरह से काम करता है:

[DllImport("user32.dll")] 
    static extern IntPtr SendMessage 
    (
     IntPtr controlHandle, 
     uint message, 
     IntPtr param1, 
     IntPtr param2 
    ); 

    const uint WM_MOUSELEAVE = 0x02A3; 

    Point lastMousePoint = Point.Empty; 

    void richTextBox_MouseMove(object sender, MouseEventArgs e) 
    { 
     if (Math.Abs(e.Location.X - lastMousePoint.X) > 1 || Math.Abs(e.Location.Y - lastMousePoint.Y) > 1) 
     { 
      lastMousePoint = e.Location; 

      SendMessage((sender as RichTextBox).Handle, WM_MOUSELEAVE, IntPtr.Zero, IntPtr.Zero); 
     } 
    } 

    void richTextBox_MouseHover(object sender, EventArgs e) 
    { 
     foo(); 
    } 
0

यहां थोड़ा सा सरल संस्करण है जो टाइमर पर भरोसा नहीं करता है। जब भी आप यह जांचना चाहते हैं कि माउस घुमा रहा है या नहीं, तो वर्तमान समय की तुलना करने के लिए बस अंतिम माउस चाल का समय रिकॉर्ड करें।

private DateTime mouseMoveTime = DateTime.Now; 
    private Point mouseMoveLoc = new Point(); 

    private bool IsHovering() 
    { 
     return (mouseMoveTime.AddMilliseconds(SystemInformation.MouseHoverTime)).CompareTo(DateTime.Now) < 0; 
    } 

    private void myControl_MouseMove(object sender, MouseEventArgs e) 
    { 
     // update mouse position and time of last move 
     if (Math.Abs(e.X - mouseMoveLoc.X) > SystemInformation.MouseHoverSize.Width || 
      Math.Abs(e.Y - mouseMoveLoc.Y) > SystemInformation.MouseHoverSize.Height) 
     { 
      mouseMoveLoc = new Point(e.X, e.Y); 
      mouseMoveTime = DateTime.Now; 
     } 
    } 

या वास्तव में एक छोटा संस्करण जिसमें दूरी सहिष्णुता नहीं है।

private DateTime mouseMoveTime = DateTime.Now; 

    private bool IsHovering() 
    { 
     return (mouseMoveTime.AddMilliseconds(SystemInformation.MouseHoverTime)).CompareTo(DateTime.Now) < 0; 
    } 

    private void myControl_MouseMove(object sender, MouseEventArgs e) 
    { 
     mouseMoveTime = DateTime.Now; 
    } 

बस का उपयोग करते हैं (IsHovering()) ... जब तुम अगर माउस को ले जाता है की जाँच की जरूरत है।

एक बात मैंने देखी है हालांकि यह है कि जब आप खींच रहे हों तो माउसमोव को निकाल दिया नहीं जाता है। हालांकि आप इसे पाने के लिए अपने ड्रैग इवेंट में माउसमोवटाइम/लोक अपडेट कोड कॉपी कर सकते हैं।

संबंधित मुद्दे