2009-02-25 5 views
11

다른 컨트롤의 이벤트 내에서 마우스로 컨트롤을 찾아야합니다. GetTopLevel으로 시작하여 GetChildAtPoint을 사용하여 반복 할 수 있지만 더 빠른 방법이 있습니까? (... 그리고 아마도 느린)마우스 밑에있는 컨트롤을 빠르게 얻을 수 있습니까?

+0

가 왜 GetTopLevel에서 시작해야합니까를? –

+0

(a) 마우스 아래의 컨트롤은 이벤트가 발생하는 컨트롤의 자식 일 필요는 없으며 (b) 가장 안쪽의 컨트롤을 찾기 위해 계속 반복해야합니다. – Simon

답변

16

이 코드는 많은 이해가되지 않습니다하지만 컨트롤의 컬렉션을 통과하지 않도록 않습니다 당신은 단순히 직접 GetChildAtPoint에 갈 수

[System.Runtime.InteropServices.DllImport("user32.dll")] 
private static extern IntPtr WindowFromPoint(Point pnt); 

private void Form1_MouseMove(object sender, MouseEventArgs e) { 
    IntPtr hWnd = WindowFromPoint(Control.MousePosition); 
    if (hWnd != IntPtr.Zero) { 
    Control ctl = Control.FromHandle(hWnd); 
    if (ctl != null) label1.Text = ctl.Name; 
    } 
} 

private void button1_Click(object sender, EventArgs e) { 
    // Need to capture to see mouse move messages... 
    this.Capture = true; 
} 
+0

나에게 완전한 이해가된다. :-) WindowFromPoint는 포함 여부에 관계없이 화면의 마우스 위치 바로 아래에서 창 핸들을 가져옵니다. Control.FromHandle은 .Net 컨트롤로 변환합니다 (가능한 경우). 붐, 끝났어. 매우 매끄러운. –

+0

마우스 클릭을 시뮬레이션하는 것이 쉽지 않을까요? 당신은 링크를 찾을 수 있습니다 [여기] (http://stackoverflow.com/questions/2416748/how-to-simulate-mouse-click-in-c) – Pimenta

+0

다른 응용 프로그램 & –

2

테스트되지 않은 내 머리 위로 떨어져 :

Control GetControlUnderMouse() { 
    foreach (Control c in this.Controls) { 
     if (c.Bounds.Contains(this.PointToClient(MousePosition))) { 
      return c; 
     } 
    } 
} 

또는 LINQ와 공상이 될 :

return Controls.Where(c => c.Bounds.Contains(PointToClient(MousePosition))).FirstOrDefault(); 

어떻게 신뢰할이 확실하지 않다 그래도.

+0

방금 ​​사용 했으므로 마우스 위치 아래 모든 컨트롤을 가져 오는 것이 좋습니다. 그러나 c.Bounds.Contains (Point p)가 아닌 c.Bounds.IntersectsWith (Rectangle r)가 있어야합니다. – snicker

+0

D' oh! 감사. 나는 지금 그것을 단지 편집 할 것이다. .. –

+0

이것은 나로는 어울리지 않는다. 나는 항상 최고의 통제를 받는다. – SolidSnake

관련 문제