щелкнуло окно на mouseHook - PullRequest
       3

щелкнуло окно на mouseHook

0 голосов
/ 15 декабря 2018

У меня есть небольшое настольное приложение, в котором я использую мышиный крюк для отслеживания события щелчка мыши внутри и вне формы окна.Поэтому я хочу, чтобы пользовательский элемент управления вызывал событие при каждом щелчке мыши по этому элементу управления, но когда щелкнул сам элемент управления или щелкнули дочерние элементы управления в этом пользовательском элементе управления, я хочу игнорировать событие или действовать иначе.

Проблема в том, что все найденные мной крючки для мыши не имеют возможности узнать окно управления, которое вот-вот получит событие щелчка.

Мне нужно заранее знать, какое окно элемента управления должно получить событие click, чтобы я мог различить, является ли он дочерним элементом пользовательского элемента управления или любым другим элементом управления или вне формы.

Вот класс мышеловка, который я использую.Я нашел это онлайн.

using System;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Reflection;
using System.Threading;

using Microsoft;

namespace library
{

    /// <summary>
    /// Abstract base class for Mouse and Keyboard hooks
    /// </summary>
    public abstract class GlobalHook
    {
        /// <summary>
        /// 
        /// </summary>
        #region Windows API Code

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

        [StructLayout(LayoutKind.Sequential)]
        protected class MouseHookStruct
        {
            public POINT pt;
            public int hwnd;
            public int wHitTestCode;
            public int dwExtraInfo;
        }

        [StructLayout(LayoutKind.Sequential)]
        protected class MouseLLHookStruct
        {
            public POINT pt;
            public int mouseData;
            public int flags;
            public int time;
            public int dwExtraInfo;
        }

        [StructLayout(LayoutKind.Sequential)]
        protected class KeyboardHookStruct
        {
            public int vkCode;
            public int scanCode;
            public int flags;
            public int time;
            public int dwExtraInfo;
        }

        [DllImport("user32.dll", CharSet = CharSet.Auto,
           CallingConvention = CallingConvention.StdCall, SetLastError = true)]
        protected static extern int SetWindowsHookEx(
            int idHook,
            HookProc lpfn,
            IntPtr hMod,
            int dwThreadId);

        [DllImport("user32.dll", CharSet = CharSet.Auto,
            CallingConvention = CallingConvention.StdCall, SetLastError = true)]
        protected static extern int UnhookWindowsHookEx(int idHook);


        [DllImport("user32.dll", CharSet = CharSet.Auto,
             CallingConvention = CallingConvention.StdCall)]
        protected static extern int CallNextHookEx(
            int idHook,
            int nCode,
            IntPtr wParam,
            IntPtr lParam);

        [DllImport("user32")]
        protected static extern int ToAscii(
            int uVirtKey,
            int uScanCode,
            byte[] lpbKeyState,
            byte[] lpwTransKey,
            int fuState);

        [DllImport("user32")]
        protected static extern int GetKeyboardState(byte[] pbKeyState);

        [DllImport("user32.dll", CharSet = CharSet.Auto, 
            CallingConvention = CallingConvention.StdCall)]
        protected static extern short GetKeyState(int vKey);

        [DllImport("user32.dll", SetLastError = true)]
        static extern IntPtr GetThreadDesktop(uint dwThreadId);

        protected delegate int HookProc(int nCode, IntPtr wParam, IntPtr lParam);

        protected const int WH_MOUSE_LL = 14;
        protected const int WH_KEYBOARD_LL = 13;

        protected const int WH_MOUSE = 7;
        protected const int WH_KEYBOARD = 2;
        protected const int WM_MOUSEMOVE = 0x200;
        protected const int WM_LBUTTONDOWN = 0x201;
        protected const int WM_RBUTTONDOWN = 0x204;
        protected const int WM_MBUTTONDOWN = 0x207;
        protected const int WM_LBUTTONUP = 0x202;
        protected const int WM_RBUTTONUP = 0x205;
        protected const int WM_MBUTTONUP = 0x208;
        protected const int WM_LBUTTONDBLCLK = 0x203;
        protected const int WM_RBUTTONDBLCLK = 0x206;
        protected const int WM_MBUTTONDBLCLK = 0x209;
        protected const int WM_MOUSEWHEEL = 0x020A;
        protected const int WM_KEYDOWN = 0x100;
        protected const int WM_KEYUP = 0x101;
        protected const int WM_SYSKEYDOWN = 0x104;
        protected const int WM_SYSKEYUP = 0x105;

        protected const byte VK_SHIFT = 0x10;
        protected const byte VK_CAPITAL = 0x14;
        protected const byte VK_NUMLOCK = 0x90;

        protected const byte VK_LSHIFT = 0xA0;
        protected const byte VK_RSHIFT = 0xA1;
        protected const byte VK_LCONTROL = 0xA2;
        protected const byte VK_RCONTROL = 0x3;
        protected const byte VK_LALT = 0xA4;
        protected const byte VK_RALT = 0xA5;

        protected const byte LLKHF_ALTDOWN = 0x20;

        #endregion

        /// <summary>
        /// 
        /// </summary>
        #region Private Variables
        protected int _hookType;
        protected int _handleToHook;
        protected bool _isStarted;
        protected HookProc _hookCallback;
        #endregion

        /// <summary>
        /// 
        /// </summary>
        #region Properties
        public bool IsStarted
        {
            ///
            get
            {
                return _isStarted;
            }
        }
        #endregion

        /// <summary>
        /// 
        /// </summary>
        #region Constructor
        public GlobalHook()
        {
            ///
            Application.ApplicationExit += new EventHandler(Application_ApplicationExit);
        }
        #endregion

        /// <summary>
        /// 
        /// </summary>
        #region Methods
        public void Start()
        {
            ///
            if (!_isStarted && _hookType != 0)
            {

                // Make sure we keep a reference to this delegate!
                // If not, GC randomly collects it, and a NullReference exception is thrown
                _hookCallback = new HookProc(HookCallbackProcedure);

                //
                IntPtr pp = Marshal.GetHINSTANCE(Assembly.GetExecutingAssembly().GetModules()[0]);
                ///
                _handleToHook = SetWindowsHookEx(
                    _hookType,
                    _hookCallback,
                    (IntPtr)0/*Marshal.GetHINSTANCE(Assembly.GetExecutingAssembly().GetModules()[0])*/,
                    /*0*/(int)GetThreadDesktop((uint)Thread.CurrentThread.ManagedThreadId));

                /// Were we able to sucessfully start hook?
                if (_handleToHook != 0)
                {
                    ///
                    _isStarted = true;
                }

            }

        }
        public void Stop()
        {
            ///
            if (_isStarted)
            {
                ///
                UnhookWindowsHookEx(_handleToHook);

                ///
                _isStarted = false;
            }
        }
        protected virtual int HookCallbackProcedure(int nCode, IntPtr wParam, IntPtr lParam)
        {

            // This method must be overriden by each extending hook
            return 0;

        }
        protected void Application_ApplicationExit(object sender, EventArgs e)
        {
            ///
            if (_isStarted)
            {
                ///
                Stop();
            }
        }

        #endregion

    }


    /// <summary>
    /// Captures global mouse events
    /// </summary>
    public class MouseHook : GlobalHook
    {
        /// <summary>
        /// 
        /// </summary>
        #region MouseEventType Enum

        private enum MouseEventType
        {
            None,
            MouseDown,
            MouseUp,
            DoubleClick,
            MouseWheel,
            MouseMove
        }

        #endregion

        /// <summary>
        /// 
        /// </summary>
        #region Events

        public event MouseEventHandler MouseDown;
        public event MouseEventHandler MouseUp;
        public event MouseEventHandler MouseMove;
        public event MouseEventHandler MouseWheel;

        public event EventHandler Click;
        public event EventHandler DoubleClick;

        #endregion

        /// <summary>
        /// 
        /// </summary>
        #region Constructor

        public MouseHook()
        {

            _hookType = WH_MOUSE_LL;

        }

        #endregion

        /// <summary>
        /// 
        /// </summary>
        #region Methods
        protected override int HookCallbackProcedure(int nCode, IntPtr wParam, IntPtr lParam)
        {
            ///
            if (nCode > -1 && (MouseDown != null || MouseUp != null || MouseMove != null))
            {
                ///
                MouseLLHookStruct mouseHookStruct =
                    (MouseLLHookStruct)Marshal.PtrToStructure(lParam, typeof(MouseLLHookStruct));

                ///
                MouseButtons button = GetButton((Int32)wParam);
                MouseEventType eventType = GetEventType((Int32)wParam);

                ///
                MouseEventArgs e = new MouseEventArgs(
                    button,
                    (eventType == MouseEventType.DoubleClick ? 2 : 1),
                    mouseHookStruct.pt.x,
                    mouseHookStruct.pt.y,
                    (eventType == MouseEventType.MouseWheel ? 
                    (short)((mouseHookStruct.mouseData >> 16) & 0xffff) : 0));

                // Prevent multiple Right Click events (this probably happens for popup menus)
                if (button == MouseButtons.Right && mouseHookStruct.flags != 0)
                {
                    ///
                    eventType = MouseEventType.None;
                }

                ///
                switch (eventType)
                {
                    ///
                    //Control cont = Control.FromHandle(wParam);

                    ///
                    case MouseEventType.MouseDown:
                        ///
                        if (MouseDown != null)
                        {
                            ///
                            MouseDown(this, e);
                        }
                        break;
                    case MouseEventType.MouseUp:
                        if (Click != null)
                        {
                            ///
                            Click(this, new EventArgs());
                        }
                        if (MouseUp != null)
                        {
                            ///
                            MouseUp(this, e);
                        }
                        break;
                    case MouseEventType.DoubleClick:
                        if (DoubleClick != null)
                        {
                            ///
                            DoubleClick(this, new EventArgs());
                        }
                        break;
                    case MouseEventType.MouseWheel:
                        if (MouseWheel != null)
                        {
                            ///
                            MouseWheel(this, e);
                        }
                        break;
                    case MouseEventType.MouseMove:
                        if (MouseMove != null)
                        {
                            ///
                            MouseMove(this, e);
                        }
                        break;
                    default:
                        break;
                }
            }

            ///
            return CallNextHookEx(_handleToHook, nCode, wParam, lParam);
        }
        private MouseButtons GetButton(Int32 wParam)
        {
            ///
            switch (wParam)
            {
                ///
                case WM_LBUTTONDOWN:
                case WM_LBUTTONUP:
                case WM_LBUTTONDBLCLK:
                    return MouseButtons.Left;
                case WM_RBUTTONDOWN:
                case WM_RBUTTONUP:
                case WM_RBUTTONDBLCLK:
                    return MouseButtons.Right;
                case WM_MBUTTONDOWN:
                case WM_MBUTTONUP:
                case WM_MBUTTONDBLCLK:
                    return MouseButtons.Middle;
                default:
                    return MouseButtons.None;
            }
        }
        private MouseEventType GetEventType(Int32 wParam)
        {
            ///
            switch (wParam)
            {
                ///
                case WM_LBUTTONDOWN:
                case WM_RBUTTONDOWN:
                case WM_MBUTTONDOWN:
                    return MouseEventType.MouseDown;
                case WM_LBUTTONUP:
                case WM_RBUTTONUP:
                case WM_MBUTTONUP:
                    return MouseEventType.MouseUp;
                case WM_LBUTTONDBLCLK:
                case WM_RBUTTONDBLCLK:
                case WM_MBUTTONDBLCLK:
                    return MouseEventType.DoubleClick;
                case WM_MOUSEWHEEL:
                    return MouseEventType.MouseWheel;
                case WM_MOUSEMOVE:
                    return MouseEventType.MouseMove;
                default:
                    return MouseEventType.None;
            }
        }
        #endregion
    }

}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...