2010-10-19 18 views
5

मेरे सी # (.NET 2) ऐप में है, मैं यह निर्धारित करना चाहता हूं कि माउस पर कौन सा नियंत्रण है।निर्धारित करें कि कौन सा नियंत्रण माउस पॉइंटर

मैं ऐसा करने के कुछ तरीकों के बारे में सोच सकता हूं जो सही काम नहीं करेगा। मैं Control.Location संपत्ति का उपयोग कर सकता हूं, लेकिन यह मुझे शीर्ष/बाएं देता है, और माउस नियंत्रण के दूसरी तरफ हो सकता है। मैं नियंत्रण के केंद्र बिंदु की गणना कर सकता था, लेकिन बड़े नियंत्रण इसे नियंत्रित करेंगे (नियंत्रण के किनारे के पास होने के नाते नियंत्रण के करीब होने के नाते)।

तो मूल रूप से मेरे पास कैनवास और एक बिंदु पर आयतों का एक गुच्छा है। मुझे बिंदु के नजदीक आयत को खोजने की ज़रूरत है।

(आदर्श रूप से मैं वास्तव में बिंदु और आयताकार के बीच की दूरी को भी जानना चाहता हूं)।

कोई विचार?

+0

क्या उनमें से एक उत्तर आपकी मदद करता है? –

उत्तर

3

आप निम्न खोजने की जरूरत है:
- निकटतम कोने से दूरी
- निकटतम किनारे से दूरी
- (वैकल्पिक) के केंद्र के लिए

मूल रूप से दूर है, तो आप इन तीन मूल्यों के छोटे से चाहते हैं। यह निर्धारित करने के लिए कि कौन सा करीब है, उसके नियंत्रण को दो नियंत्रणों में लें।

जब आप फ़ॉर्म पर सभी नियंत्रणों को पुन: स्थापित करके फॉर्म को लोड करते हैं और नीचे दिए गए वर्ग का संग्रह बनाते हैं तो शुरू करें।

किसी बिंदु पर सबसे नज़दीकी नियंत्रण ढूंढने के लिए, संग्रह को पुन: सक्रिय करें (नीचे कोड देखें)। अब तक की न्यूनतम दूरी के साथ नियंत्रण का ट्रैक रखें। यदि आप चाहते हैं तो आप ContainsPoint() के लिए परीक्षण कर सकते हैं ... यदि आपको नियंत्रण मिलता है जहां बिंदु नियंत्रण सीमाओं के भीतर आता है, तो आपको अपना नियंत्रण मिल जाता है (जब तक आपके पास ओवरलैपिंग नियंत्रण नहीं है)। अन्यथा, जब आप संग्रह के अंत तक पहुंच जाते हैं, तो केंद्र/किनारे की सबसे छोटी दूरी के साथ आपको जो नियंत्रण मिलता है वह आपका नियंत्रण होता है।

public class HitControl { 

    public Control ThisControl; 

    private Rectangle ControlBounds; 
    private Point Center; 

    public HitControl (Control FormControl) { 
     ControlBounds = FormControl.Bounds; 
     Center = new Point(ControlBounds.X + (ControlBounds.Width/2), ControlBounds.Y + (ControlBounds.Height/2)); 
    } 

    // Calculate the minimum distance from the left, right, and center 
    public double DistanceFrom(Point TestPoint) { 

     // Note: You don't need to consider control center points unless 
     // you plan to allow for controls placed over other controls... 
     // Then you need to test the distance to the centers, as well, 
     // and pick the shortest distance of to-edge, to-side, to-corner 

     bool withinWidth = TestPoint.X > ControlBounds.X && TestPoint.X < ControlBounds.X + ControlBounds.Width; 
     bool withinHeight = TestPoint.Y > ControlBounds.Y && TestPoint.Y < ControlBounds.Y + ControlBounds.Height; 

     int EdgeLeftXDistance = Math.Abs(ControlBounds.X - TestPoint.X); 
     int EdgeRightXDistance = Math.Abs(ControlBounds.X + ControlBounds.Width - TestPoint.X); 

     int EdgeTopYDistance = Math.Abs(ControlBounds.Y - TestPoint.Y); 
     int EdgeBottomYDistance = Math.Abs(ControlBounds.Y + ControlBounds.Height - TestPoint.Y); 

     int EdgeXDistance = Math.Min(EdgeLeftXDistance, EdgeRightXDistance); 
     int EdgeYDistance = Math.Min(EdgeTopYDistance, EdgeBottomYDistance); 


     // Some points to consider for rectangle (100, 100, 100, 100): 
     // - (140, 90): Distance to top edge 
     // - (105, 10): Distance to top edge 
     // - (50, 50): Distance to upper left corner 
     // - (250, 50): Distance to upper right corner 
     // - (10, 105): Distance to left edge 
     // - (140, 105): Distance to top edge 
     // - (105, 140): Distance to left edge 
     // - (290, 105): Distance to right edge 
     // - (205, 150): Distance to right edge 
     // ... and so forth 


     // You're within the control 
     if (withinWidth && withinHeight) { 
      return Math.Min(EdgeXDistance, EdgeYDistance); 
     } 

     // You're above or below the control 
     if (withinWidth) { 
      return EdgeYDistance; 
     } 

     // You're to the left or right of the control 
     if (withinHeight) { 
      return EdgeXDistance; 
     } 

     // You're in one of the four outside corners around the control. 
     // Find the distance to the closest corner 
     return Math.Sqrt(EdgeXDistance^2 + EdgeYDistance^2); 


    } 

    public bool ContainsPoint (Point TestPoint) { 
     return ControlBounds.Contains(TestPoint); 
    } 


} 



// Initialize and use this collection 
List<HitControl> hitControls = (from Control control in Controls 
           select new HitControl(control)).ToList(); 

Point testPoint = new Point(175, 619); 
double distance; 
double shortestDistance = 0; 
HitControl closestControl = null; 

foreach (HitControl hitControl in hitControls) { 

    // Optional... works so long as you don't have overlapping controls 
    // If you do, comment this block out 
    if (hitControl.ContainsPoint(testPoint)) { 
     closestControl = hitControl; 
     break; 
    } 

    distance = hitControl.DistanceFrom(testPoint); 
    if (shortestDistance == 0 || distance < shortestDistance) { 
     shortestDistance = distance; 
     closestControl = hitControl; 
    } 
} 

if (closestControl != null) { 
    Control foundControl = closestControl.ThisControl; 
} 
0

आप आयतों :)

  1. टेस्ट के आधार पर विचार करने के लिए है: नियंत्रण के भीतर माउस है?
  2. यदि नहीं: तो किसी भी किनारे से कितना दूर?

तो आप को पता है जो नियंत्रित करता है आप, रूप है, उदाहरण के लिए, एक नियंत्रण में रुचि रखते हैं है ..

0

शुरुआत के लिए, विधि है कि कुछ मनमाने ढंग से बात करने के लिए आयत किनारे से दूरी की गणना करेगा बनाने । इस विधि के लिए हस्ताक्षर किया जाना चाहिए:

double DistanceFrom(Rect r, Point p); 

फिर, सरल के लिए, कोशिश सभी नियंत्रण पुनरावृति दूरी की गणना, न्यूनतम दूरी और नियंत्रण है कि यह प्रदान की याद है,।

आयताकार दूरी के लिए, this देखें।

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

वास्तव में, आप नियंत्रण का एक क्रमबद्ध सूची ताकि आप हमेशा पहले एक है कि शीर्ष पर करीब है हो सकता है, और माउस चालें के रूप में है कि सूची बनाए रखने बनाए रख सकते हैं - यह अधिक कुशल होने का साबित हो सकता है गति की शर्तों में। दिलचस्प मुद्दा हालांकि :)

1

पहले चेक करें कि किसी भी rectangle में बिंदु है। यदि नहीं, तो आप this में एल्गोरिदम के साथ अपने बिंदु और प्रत्येक पंक्ति खंड के बीच की दूरी पा सकते हैं। आप अपने नियंत्रण के 4 सेगमेंट भी पा सकते हैं, इसलिए आपके पास चार सेगमेंट (नियंत्रण पक्ष निर्धारित करने) की एक सूची (पहली बार शुरू की गई) है और अब आप निकटतम सेगमेंट, निकटतम आयत पा सकते हैं।

0

मैं डैनियल से सहमत हूं कि हमें इसकी आवश्यकता है: डबल दूरी से (रेक्ट आर, प्वाइंट पी);

लेकिन इससे पहले, हमें इसकी आवश्यकता है: डबल दूरी से (लाइन आर, प्वाइंट पी); और डबल कोण BetweenPoints (प्वाइंट पी 1, प्वाइंट पी 2);

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