You could use the WinAPI function WindowFromPoint
. Its C# signature is:
[DllImport("user32.dll")]
static extern IntPtr WindowFromPoint(POINT Point);
Note that POINT
here is not the same as System.Drawing.Point
, but PInvoke provides a declaration for POINT
that includes an implicit conversion between the two.
If you don’t already know the mouse cursor position, GetCursorPos
finds it:
[DllImport("user32.dll")]
static extern bool GetCursorPos(out POINT lpPoint);
However, the WinAPI calls lots of things “windows”: controls inside a window are also “windows”. Therefore, you might not get a top-level window in the intuitive sense (you might get a radio button, panel, or something else). You could iteratively apply the GetParent
function to walk up the GUI hierarchy:
[DllImport("user32.dll", ExactSpelling=true, CharSet=CharSet.Auto)]
public static extern IntPtr GetParent(IntPtr hWnd);
Once you find a window with no parent, that window will be a top-level window. Since the point you originally passed in belongs to a control that is not covered by another window, the top-level window is necessarily the one the point belongs to.