2009-02-25 17 views
11

別のコントロールのイベント内で、マウスの下でコントロールを見つける必要があります。私はGetTopLevelで始まり、GetChildAtPointを使って反復することができますが、より速い方法がありますか?マウスの下にあるコントロールを簡単に取得する方法はありますか?

テストされていないと、私の頭の上から
+0

は、なぜあなたは単に直接GetChildAtPointに行くことができなかった、GetTopLevelで起動する必要がありますか? –

+0

(a)マウスの下のコントロールは、必ずしもイベントが発生しているコントロールの子である必要はありません。(b)さらに、最も内側のコントロールを見つけるためには、反復処理を行う必要があります。 – Simon

答えて

16

このコードは、多くの意味がありませんが、それはコントロールのコレクションを横断避けるん:

[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.Conters(Point p)ではなく、c.Bounds.IntersectsWith(Rectangle r)でなければなりません。 – snicker

+0

D'oh!ありがとう。私はちょうど今それを編集します... –

+0

これは私と動作しません..私はいつもトップコントロールを得る – SolidSnake

関連する問題