2009-02-25 9 views
11

Devo trovare il controllo sotto il mouse, all'interno di un evento di un altro controllo. Potrei iniziare con GetTopLevel e scorrere verso il basso usando GetChildAtPoint, ma c'è un modo più veloce?C'è un modo rapido per ottenere il controllo che è sotto il mouse?

+0

Perché è necessario iniziare a GetTopLevel, non poteva semplicemente andare a GetChildAtPoint direttamente? –

+0

(a) Il controllo sotto il mouse non è necessariamente figlio del controllo il cui evento è attivo, e (b) dovrei ancora scorrere iterare per trovare il controllo più interno. – Simon

risposta

16

Questo codice non ha molto senso, ma non evita l'attraversamento delle collezioni Controlli:

[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

ha perfettamente senso per me. :-) WindowFromPoint afferra la maniglia della finestra direttamente sotto la posizione dei mouse sullo schermo, indipendentemente dal contenimento. Control.FromHandle lo traduce in un controllo .Net (se possibile). Boom, fatto. Molto lucido –

+0

Non sarebbe più semplice simulare il clic del mouse? Puoi trovare un link [qui] (http://stackoverflow.com/questions/2416748/how-to-simulate-mouse-click-in-c) – Pimenta

+0

Cosa succede se voglio ottenere il controllo di un'altra applicazione e –

2

testato e la parte superiore della mia testa (e forse lento ...):

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

o da fantasia con LINQ:

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

Non sono sicuro di quanto è affidabile questo sarebbe, però.

+0

L'ho appena usato, è bello avere * ogni * controllo sotto la posizione del mouse. Tuttavia, dovrebbe essere c.Bounds.Contains (Punto p) non c.Bounds.IntersectsWith (Rectangle r). – snicker

+0

D'oh! Grazie. Mi limiterò a modificarlo ora ... –

+0

questo non funziona con me .. ottengo sempre il controllo superiore – SolidSnake

Problemi correlati