C# Detect if mouse is over any window in hierarchy

7 hours ago 1
ARTICLE AD BOX

How can I check if the mouse cursor is over any window in my window hierarchy.
I have this window structure:

Window 1 Window 2 (owned by Window 1) Window 3 (owned by Window 2) Window X (owned by ...)

I'm using a mouse hook to check if the mouse is over ANY of the currently opened windows when clicked, so I can close the whole hierarchy if it's not. But for some reason, even tho I'm clicking on any of the windows I always get false in my IsInHierarchy. Any idea why and how to fix this?

The code I use:

internal sealed class PopupMenuDismissHook : IDisposable { private readonly nint _rootHWnd; private readonly PInvoke.LowLevelMouseProc _hookProc; private readonly nint _hookHandle; public nint LeafHWnd { get; set; } public PopupMenuDismissHook(nint rootHWnd) { _rootHWnd = rootHWnd; _hookProc = new PInvoke.LowLevelMouseProc(LowLevelMouseProcFunc); _hookHandle = PInvoke.SetWindowsHookEx(PInvoke.WH_MOUSE_LL, Marshal.GetFunctionPointerForDelegate(_hookProc), nint.Zero, 0); } public void Dispose() { if (_hookHandle != nint.Zero) PInvoke.UnhookWindowsHookEx(_hookHandle); } private nint LowLevelMouseProcFunc(int nCode, nint wParam, nint lParam) { if (nCode >= 0) { if (wParam is PInvoke.WM_LBUTTONUP or PInvoke.WM_RBUTTONUP or PInvoke.WM_MBUTTONUP) { var mousePos = Marshal.PtrToStructure<MSLLHOOKSTRUCT>(lParam).pt; if (!IsInHierarchy(mousePos)) PInvoke.PostMessage(_rootHWnd, PInvoke.WM_CLOSE, nint.Zero, nint.Zero); } } return PInvoke.CallNextHookEx(_hookHandle, nCode, wParam, lParam); } private bool IsInHierarchy(POINT mousePos) { var current = LeafHWnd; Console.WriteLine(current); while (current != nint.Zero) { if (PInvoke.GetWindowRect(current, out var rect)) { //Debug Console.WriteLine($"Rect: {rect.Left},{rect.Top},{rect.Right},{rect.Bottom}"); Console.WriteLine($"Mouse: {mousePos.x},{mousePos.y}"); if (PInvoke.PtInRect(ref rect, mousePos)) return true; } current = PInvoke.GetWindow(current, PInvoke.GW_OWNER); } //Debug Console.WriteLine("FALSE"); return false; } }
Read Entire Article