Search code examples
c#mouse-hook

Mouse hook, respond only when clicked on Button


I developed C# application which responds to low level mouse clicks. I used mouse hook to do this. The application is working fine, whenever i click any window it responds and perform some task. But i want to do a modification here. I wanted to respond the mouse clicks whenever the click is performed on any buttons on the window. If i click on plain area of window it should not respond. Currently it responds wherever i click. I could not find how to identify whether i clicked on a button or not.

This is my code :

private IntPtr SetHook(MouseHookHandler proc)
    {
        using (ProcessModule module = Process.GetCurrentProcess().MainModule)
            return SetWindowsHookEx(WH_MOUSE_LL, proc, GetModuleHandle(module.ModuleName), 0);
    }
    private IntPtr HookFunc(int nCode, IntPtr wParam, IntPtr lParam)
    {
        if (nCode >= 0)
        {
            if (MouseMessages.WM_LBUTTONUP == (MouseMessages)wParam)
                if (LeftButtonUp != null)
                    LeftButtonUp((MSLLHOOKSTRUCT)Marshal.PtrToStructure(lParam, typeof(MSLLHOOKSTRUCT)));
            if (MouseMessages.WM_RBUTTONUP == (MouseMessages)wParam)
                if (RightButtonUp != null)
                    RightButtonUp((MSLLHOOKSTRUCT)Marshal.PtrToStructure(lParam, typeof(MSLLHOOKSTRUCT)));

        }
        return CallNextHookEx(hookID, nCode, wParam, lParam);
    }

[StructLayout(LayoutKind.Sequential)]
    public struct POINT
    {
        public int x;
        public int y;
    }

 [StructLayout(LayoutKind.Sequential)]
    public struct MSLLHOOKSTRUCT
    {
        public POINT pt;
        public uint mouseData;
        public uint flags;
        public uint time;
        public IntPtr dwExtraInfo;
    }

    [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    private static extern IntPtr SetWindowsHookEx(int idHook,
        MouseHookHandler lpfn, IntPtr hMod, uint dwThreadId);

    [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    [return: MarshalAs(UnmanagedType.Bool)]
    public static extern bool UnhookWindowsHookEx(IntPtr hhk);

    [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    private static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode, IntPtr wParam, IntPtr lParam);

    [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    private static extern IntPtr GetModuleHandle(string lpModuleName);

Please help me to solve this problem. Thank you.


Solution

  • It seems you are looking for something along the lines of WindowFromPoint.

    Call that to see what is under the mouse cursor, then you can query it for whatever properties you are interested in.