C#中的MouseKeyHook无法检测到鼠标左键单击的形式

时间:2018-10-30 15:42:41

标签: c#

首先抱歉,如果我的英语不好,这是我在这里的第一篇文章,我正在开发C#Windows窗体应用程序,并且我想检测来自窗体外部的单击(在台式机或其他设备上)。我正在尝试使用MouseKeyHook,因为我认为这是解决我的问题的方法,但是我无法使其工作..这是我的代码(我从https://github.com/gmamaladze/globalmousekeyhook那里获得了它,我也试图将globalevents替换为Hook.AppEvents。任何人都可以帮助我完成这项工作吗?:

private IKeyboardMouseEvents m_GlobalHook;

public void Subscribe()
{
    // Note: for the application hook, use the Hook.AppEvents() instead
    m_GlobalHook = Hook.GlobalEvents();

    m_GlobalHook.MouseDownExt += GlobalHookMouseDownExt;
    m_GlobalHook.KeyPress += GlobalHookKeyPress;
}

private void GlobalHookKeyPress(object sender, KeyPressEventArgs e)
{
    Console.WriteLine("KeyPress: \t{0}", e.KeyChar);
}

private void GlobalHookMouseDownExt(object sender, MouseEventExtArgs e)
{
    Console.WriteLine("MouseDown: \t{0}; \t System Timestamp: \t{1}", e.Button, e.Timestamp);

    // uncommenting the following line will suppress the middle mouse button click
    // if (e.Buttons == MouseButtons.Middle) { e.Handled = true; }
}

public void Unsubscribe()
{
    m_GlobalHook.MouseDownExt -= GlobalHookMouseDownExt;
    m_GlobalHook.KeyPress -= GlobalHookKeyPress;

    //It is recommened to dispose it
    m_GlobalHook.Dispose();
}

1 个答案:

答案 0 :(得分:0)

我正在使用与程序类型无关的类(winform,WPF等)

举个例子:

using System;
using System.Runtime.InteropServices;
using HookInput.API;
namespace HookInput.Mouse
{

    public class MouseInput
    {
        private const Int32 WM_MOUSEMOVE = 0x0200;

        private const Int32 WM_LBUTTONDOWN = 0x0201;
        private const Int32 WM_LBUTTONUP = 0x0202;
        private const Int32 WM_LBUTTONDBLCLK = 0x0203;
        private const Int32 WM_RBUTTONDOWN = 0x0204;
        private const Int32 WM_RBUTTONUP = 0x0205;
        private const Int32 WM_RBUTTONDBLCLK = 0x0206;
        private const Int32 WM_MBUTTONDOWN = 0x0207;
        private const Int32 WM_MBUTTONUP = 0x0208;
        private const Int32 WM_MBUTTONDBLCLK = 0x0209;

        private const Int32 WM_MOUSEWHEEL = 0x020A;

        private const Int32 WM_XBUTTONDOWN = 0x020B;
        private const Int32 WM_XBUTTONUP = 0x020C;
        private const Int32 WM_XBUTTONDBLCLK = 0x020D;


        private bool hooked = false;

        private WindowsHookAPI.HookDelegate mouseDelegate;
        private IntPtr mouseHandle;


        private const Int32 WH_MOUSE_LL = 14;


        public MouseInput()
        {
            mouseDelegate = MouseHookDelegate;
        }


        public void setHook(bool on)
        {
            if (hooked == on) return;
            if (on)
            {
                mouseHandle = WindowsHookAPI.SetWindowsHookEx(WH_MOUSE_LL, mouseDelegate, IntPtr.Zero, 0);
                if (mouseHandle != IntPtr.Zero) hooked = true;
            }
            else
            {
                WindowsHookAPI.UnhookWindowsHookEx(mouseHandle);
                hooked = false;
            }
        }

        private IntPtr MouseHookDelegate(Int32 Code, IntPtr wParam, IntPtr lParam)
        {
            //VK_LBUTTON    0x01 Left mouse button
            //VK_RBUTTON    0x02 Right mouse button
            //VK_MBUTTON    0x04 Middle mouse button
            //VK_XBUTTON1   0x05 X1 mouse button
            //VK_XBUTTON2   0x06 X2 mouse button
            // see https://msdn.microsoft.com/en-us/library/windows/desktop/ms644970(v=vs.85).aspx

            //mouseData:
            //If the message is WM_MOUSEWHEEL, the high-order word of this member is the wheel delta.The low-order word is reserved.
            //    A positive value indicates that the wheel was rotated forward, away from the user;
            //    a negative value indicates that the wheel was rotated backward, toward the user. 
            //    One wheel click is defined as WHEEL_DELTA, which is 120.(0x78 or 0xFF88)
            //If the message is WM_XBUTTONDOWN, WM_XBUTTONUP, WM_XBUTTONDBLCLK, WM_NCXBUTTONDOWN, WM_NCXBUTTONUP, or WM_NCXBUTTONDBLCLK, 
            //    the high - order word specifies which X button was pressed or released, 
            //    and the low - order word is reserved.This value can be one or more of the following values.Otherwise, mouseData is not used.
            //XBUTTON1  = 0x0001 The first X button was pressed or released.
            //XBUTTON2  = 0x0002  The second X button was pressed or released.

            MSLLHOOKSTRUCT lparam = (MSLLHOOKSTRUCT)Marshal.PtrToStructure(lParam, typeof(MSLLHOOKSTRUCT));
            int command = (int)wParam;
            if (Code < 0 || command == WM_LBUTTONDBLCLK || command == WM_RBUTTONDBLCLK)
                return WindowsHookAPI.CallNextHookEx(mouseHandle, Code, wParam, lParam);


            if (command == WM_MOUSEMOVE)
            {
                Console.WriteLine($"x:{lparam.pt.x} y:{lparam.pt.y}");
            }
             else if (command == WM_LBUTTONDOWN || command == WM_LBUTTONUP)
            {
                                if (command == WM_LBUTTONDOWN)
                                {
                                    //do something
                                }
                                else
                                {
                                    //do something
                                }
            }
            else if (command == WM_RBUTTONDOWN || command == WM_RBUTTONUP)
            {
                                if (command == WM_RBUTTONDOWN)
                                {
                                    //do something
                                }
                                else
                                {
                                    //do something
                                }
            }
            else if (command == WM_MBUTTONDOWN || command == WM_MBUTTONUP)
            {
                                if (command == WM_MBUTTONDOWN)
                                {
                                    //do something
                                }
                                else
                                {
                                    //do something
                                }
            }
            else if (command == WM_MOUSEWHEEL)
            {
                int wheelvalue = (Int16)(lparam.mouseData >> 16) < 0 ? -120 : 120; // Forward = 120, Backward = -120
            }


            return WindowsHookAPI.CallNextHookEx(mouseHandle, Code, wParam, lParam);
        }


        ~MouseInput()
        {

        }

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

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

文件API:

using System;
using System.Runtime.InteropServices;

namespace HookInput.API
{
    public class WindowsHookAPI
    {
        //public delegate IntPtr HookDelegate(
        //    Int32 Code, IntPtr wParam, IntPtr lParam);
        public delegate IntPtr HookDelegate(Int32 Code, IntPtr wParam, IntPtr lParam);

        [DllImport("User32.dll")]
        public static extern IntPtr CallNextHookEx(IntPtr hHook, Int32 nCode, IntPtr wParam, IntPtr lParam);

        [DllImport("User32.dll")]
        public static extern IntPtr UnhookWindowsHookEx(IntPtr hHook);


        [DllImport("User32.dll")]
        public static extern IntPtr SetWindowsHookEx(Int32 idHook, HookDelegate lpfn, IntPtr hmod, Int32 dwThreadId);

    }
}    

您可以实例化该类

    private MouseInput mouseInputHook = null;
    mouseInputHook = new MouseInput();
    mouseInputHook.setHook(true); // to activate the mousehook
    :
    :
    mouseInputHook.setHook(false); // to desactivate the mousehook