/// <summary> /// Returns the window from the given point (Except hidden / disabled windows). /// </summary> /// <param name="point">The point (x, y)</param> /// <returns>The handle to the window beneath the point</returns> public static IntPtr LowestLevelWindowFromPoint(WinApi.POINT point) { var hWnd = WinApi.WindowFromPoint(point); //WinApi.ScreenToClient(hWnd, ref cursorPosition); var child = WinApi.ChildWindowFromPoint(hWnd, point); // Is there any child window? if (child != IntPtr.Zero) { hWnd = child; } // No more child windows? Just return the current window handle if ((WinApi.GetWindowLong(hWnd, (WinConstants.GWL_STYLE)) & WinConstants.WS_POPUP) != 0) { return(hWnd); } hWnd = GetChildMost(point, hWnd); return(hWnd); }
/// <summary> /// Return the window handle to the "lowest" child window of a given window handle. /// This is necessary, for example, for group boxes or something. /// WindowFromPoint will just return a handle to the group box, /// instead of returning the handle to one of its child windows (a text box or something). /// </summary> /// <param name="point">The point (x, y)</param> /// <param name="hWnd">The window handle (top window)</param> /// <returns>The handle to the child window</returns> private static IntPtr GetChildMost(WinApi.POINT point, IntPtr hWnd) { // Max size of a window var dwWndArea = WinConstants.MAXDWORD; // size of the parent window var hWndParent = WinApi.GetParent(hWnd); // first child window handle var hWndChild = WinApi.GetWindow(hWndParent, WinConstants.GW_CHILD); // Iterate child windows while (hWndChild != IntPtr.Zero) { // ignore hidden windows if (WinApi.IsWindowVisible(hWndChild)) { // window beneath the point WinApi.RECT rect; WinApi.GetWindowRect(hWndChild, out rect); // Is the given point within the rectangle of the current child window? if (WinApi.PtInRect(ref rect, point)) { // find smallest var dwChildArea = (uint)(rect.Width * rect.Height); // Is the current child window size smaller than the one of the last child window? if (dwChildArea < dwWndArea) { dwWndArea = dwChildArea; hWnd = hWndChild; } } } // retrieving next child window handle hWndChild = WinApi.GetWindow(hWndChild, WinConstants.GW_HWNDNEXT); } return(hWnd); }