Обработка событий вне формы (глобальный перехват клавиш) - C#

Узнай цену своей работы

Формулировка задачи:

Здравствуйте! В процессе обучения у меня возникли 2 вопроса: 1. Можно ли написать приложение для обработки нажатия кнопок клавиатуры, которое будет работать вне формы? К примеру, мне нужно чтобы при нажатии какой-нибудь кнопки курсор перемещался в заданную точку рабочего стола. 2. Можно ли отдельно обработать событие перемещения курсора(мышь неподвижна) и перемещение мыши. В первом случае подразумевается, что курсор перемещается программным путем. К примеру:
Cursor.Position = new Point(150,150);

Решение задачи: «Обработка событий вне формы (глобальный перехват клавиш)»

textual
Листинг программы
    public static class MouseHook
    {
        #region Declarations
        public static event MouseEventHandler MouseDown;
        public static event MouseEventHandler MouseUp;
        public static event MouseEventHandler MouseMove;
 
        [StructLayout( LayoutKind.Sequential )]
        struct MOUSEHOOKSTRUCT
        {
            public POINT pt;
            public IntPtr hwnd;
            public int wHitTestCode;
            public IntPtr dwExtraInfo;
        }
 
        [StructLayout( LayoutKind.Sequential )]
        struct MSLLHOOKSTRUCT
        {
            public POINT pt;
            public int mouseData;
            public int flags;
            public int time;
            public IntPtr dwExtraInfo;
        }
 
        [StructLayout( LayoutKind.Sequential )]
        struct POINT
        {
            public int X;
            public int Y;
 
            public POINT ( int x, int y )
            {
                this.X = x;
                this.Y = y;
            }
 
            public static implicit operator Point ( POINT p )
            {
                return new Point( p.X, p.Y );
            }
 
            public static implicit operator POINT ( Point p )
            {
                return new POINT( p.X, p.Y );
            }
        }
 
        const int WM_LBUTTONDOWN = 0x201;
        const int WM_LBUTTONUP = 0x202;
        const int WM_MOUSEMOVE = 0x0200;
        const int WM_MOUSEWHEEL = 0x020A;
        const int WM_RBUTTONDOWN = 0x0204;
        const int WM_RBUTTONUP = 0x0205;
        const int WM_MBUTTONUP = 0x208;
        const int WM_MBUTTONDOWN = 0x207;
        const int WM_XBUTTONDOWN = 0x20B;
        const int WM_XBUTTONUP = 0x20C;
 
        static IntPtr hHook = IntPtr.Zero;
        static IntPtr hModule = IntPtr.Zero;
        static bool hookInstall = false;
        static bool localHook = true;
        static API.HookProc hookDel;
        #endregion
 
        /// <summary>
        /// Hook install method.
        /// </summary>
        public static void InstallHook ( )
        {
            if ( IsHookInstalled )
                return;
 
            hModule = Marshal.GetHINSTANCE( AppDomain.CurrentDomain.GetAssemblies()[0].GetModules()[0] );
            hookDel = new API.HookProc( HookProcFunction );
 
            if ( localHook )
                hHook = API.SetWindowsHookEx( API.HookType.WH_MOUSE,
                    hookDel, IntPtr.Zero, AppDomain.GetCurrentThreadId() ); // Если подчеркивает необращай внимание, так надо.
            else
                hHook = API.SetWindowsHookEx( API.HookType.WH_MOUSE_LL,
                    hookDel, hModule, 0 );
 
            if ( hHook != IntPtr.Zero )
                hookInstall = true;
            else
                throw new Win32Exception( "Can't install low level keyboard hook!" );
        }
        /// <summary>
        /// If hook installed return true, either false.
        /// </summary>
        public static bool IsHookInstalled
        {
            get { return hookInstall && hHook != IntPtr.Zero; }
        }
        /// <summary>
        /// Module handle in which hook was installed.
        /// </summary>
        public static IntPtr ModuleHandle
        {
            get { return hModule; }
        }
        /// <summary>
        /// If true local hook will installed, either global.
        /// </summary>
        public static bool LocalHook
        {
            get { return localHook; }
            set
            {
                if ( value != localHook )
                {
                    if ( IsHookInstalled )
                        throw new Win32Exception( "Can't change type of hook than it install!" );
                    localHook = value;
                }
            }
        }
        /// <summary>
        /// Uninstall hook method.
        /// </summary>
        public static void UnInstallHook ( )
        {
            if ( IsHookInstalled )
            {
                if ( !API.UnhookWindowsHookEx( hHook ) )
                    throw new Win32Exception( "Can't uninstall low level keyboard hook!" );
                hHook = IntPtr.Zero;
                hModule = IntPtr.Zero;
                hookInstall = false;
            }
        }
        /// <summary>
        /// Hook process messages.
        /// </summary>
        /// <param name="nCode"></param>
        /// <param name="wParam"></param>
        /// <param name="lParam"></param>
        /// <returns></returns>
        static IntPtr HookProcFunction ( int nCode, IntPtr wParam, [In] IntPtr lParam )
        {
            if ( nCode == 0 )
            {
                if ( localHook )
                {
                    MOUSEHOOKSTRUCT mhs = (MOUSEHOOKSTRUCT)Marshal.PtrToStructure( lParam, typeof( MOUSEHOOKSTRUCT ) );
                    #region switch
                    switch ( wParam.ToInt32() )
                    {
                    case WM_LBUTTONDOWN:
                        if ( MouseDown != null )
                            MouseDown( null,
                                new MouseEventArgs( MouseButtons.Left,
                                    1,
                                    mhs.pt.X,
                                    mhs.pt.Y,
                                    0 ) );
                        break;
                    case WM_LBUTTONUP:
                        if ( MouseUp != null )
                            MouseUp( null,
                                new MouseEventArgs( MouseButtons.Left,
                                    1,
                                    mhs.pt.X,
                                    mhs.pt.Y,
                                    0 ) );
                        break;
                    case WM_MBUTTONDOWN:
                        if ( MouseDown != null )
                            MouseDown( null,
                                new MouseEventArgs( MouseButtons.Middle,
                                    1,
                                    mhs.pt.X,
                                    mhs.pt.Y,
                                    0 ) );
                        break;
                    case WM_MBUTTONUP:
                        if ( MouseUp != null )
                            MouseUp( null,
                                new MouseEventArgs( MouseButtons.Middle,
                                    1,
                                    mhs.pt.X,
                                    mhs.pt.Y,
                                    0 ) );
                        break;
                    case WM_MOUSEMOVE:
                        if ( MouseMove != null )
                            MouseMove( null,
                                new MouseEventArgs( MouseButtons.None,
                                    1,
                                    mhs.pt.X,
                                    mhs.pt.Y,
                                    0 ) );
                        break;
                    case WM_MOUSEWHEEL:
                        // Данный хук не позволяет узнать куда вращается колесо мыши.
                        break;
                    case WM_RBUTTONDOWN:
                        if ( MouseDown != null )
                            MouseDown( null,
                                new MouseEventArgs( MouseButtons.Right,
                                    1,
                                    mhs.pt.X,
                                    mhs.pt.Y,
                                    0 ) );
                        break;
                    case WM_RBUTTONUP:
                        if ( MouseUp != null )
                            MouseUp( null,
                                new MouseEventArgs( MouseButtons.Right,
                                    1,
                                    mhs.pt.X,
                                    mhs.pt.Y,
                                    0 ) );
                        break;
                    default:
                        //Debug.WriteLine(string.Format("X:{0}; Y:{1}; Handle:{2}; HitTest:{3}; EI:{4}; wParam:{5}; lParam:{6}",
                        //    mhs.pt.X, mhs.pt.Y, mhs.hwnd, mhs.wHitTestCode, mhs.dwExtraInfo, wParam.ToString(), lParam.ToString()));
                        break;
                    }
                    #endregion
                }
                else
                {
                    MSLLHOOKSTRUCT mhs = (MSLLHOOKSTRUCT)Marshal.PtrToStructure( lParam, typeof( MSLLHOOKSTRUCT ) );
 
                    #region switch
                    switch ( wParam.ToInt32() )
                    {
                    case WM_LBUTTONDOWN:
                        if ( MouseDown != null )
                            MouseDown( null,
                                new MouseEventArgs( MouseButtons.Left,
                                    1,
                                    mhs.pt.X,
                                    mhs.pt.Y,
                                    0 ) );
                        break;
                    case WM_LBUTTONUP:
                        if ( MouseUp != null )
                            MouseUp( null,
                                new MouseEventArgs( MouseButtons.Left,
                                    1,
                                    mhs.pt.X,
                                    mhs.pt.Y,
                                    0 ) );
                        break;
                    case WM_MBUTTONDOWN:
                        if ( MouseDown != null )
                            MouseDown( null,
                                new MouseEventArgs( MouseButtons.Middle,
                                    1,
                                    mhs.pt.X,
                                    mhs.pt.Y,
                                    0 ) );
                        break;
                    case WM_MBUTTONUP:
                        if ( MouseUp != null )
                            MouseUp( null,
                                new MouseEventArgs( MouseButtons.Middle,
                                    1,
                                    mhs.pt.X,
                                    mhs.pt.Y,
                                    0 ) );
                        break;
                    case WM_MOUSEMOVE:
                        if ( MouseMove != null )
                            MouseMove( null,
                                new MouseEventArgs( MouseButtons.None,
                                    1,
                                    mhs.pt.X,
                                    mhs.pt.Y,
                                    0 ) );
                        break;
                    case WM_MOUSEWHEEL:
                        if ( MouseMove != null )
                            MouseMove( null,
                                new MouseEventArgs( MouseButtons.None, mhs.time,
                                    mhs.pt.X, mhs.pt.Y, mhs.mouseData >> 16 ) );
                        //Debug.WriteLine(string.Format("X:{0}; Y:{1}; MD:{2}; Time:{3}; EI:{4}; wParam:{5}; lParam:{6}",
                        //            mhs.pt.X, mhs.pt.Y, mhs.mouseData, mhs.time, mhs.dwExtraInfo, wParam.ToString(), lParam.ToString()));
                        break;
                    case WM_RBUTTONDOWN:
                        if ( MouseDown != null )
                            MouseDown( null,
                                new MouseEventArgs( MouseButtons.Right,
                                    1,
                                    mhs.pt.X,
                                    mhs.pt.Y,
                                    0 ) );
                        break;
                    case WM_RBUTTONUP:
                        if ( MouseUp != null )
                            MouseUp( null,
                                new MouseEventArgs( MouseButtons.Right,
                                    1,
                                    mhs.pt.X,
                                    mhs.pt.Y,
                                    0 ) );
                        break;
                    default:
 
                        break;
                    }
                    #endregion
                }
            }
 
            return API.CallNextHookEx( hHook, nCode, wParam, lParam );
        }
    }
 
    static class API
    {
        public delegate IntPtr HookProc ( int nCode, IntPtr wParam, [In] IntPtr lParam );
 
        [DllImport( "user32.dll" )]
        public static extern IntPtr CallNextHookEx ( IntPtr hhk, int nCode, IntPtr wParam, [In] IntPtr lParam );
 
        [DllImport( "user32.dll", SetLastError = true )]
        public static extern IntPtr SetWindowsHookEx ( HookType hookType, HookProc lpfn,
        IntPtr hMod, int dwThreadId );
 
        [DllImport( "user32.dll", SetLastError = true )]
        public static extern bool UnhookWindowsHookEx ( IntPtr hhk );
 
        [DllImport( "kernel32.dll", CharSet = CharSet.Auto, SetLastError = true )]
        public static extern IntPtr GetModuleHandle ( string lpModuleName );
 
        public enum HookType : int
        {
            WH_JOURNALRECORD = 0,
            WH_JOURNALPLAYBACK = 1,
            WH_KEYBOARD = 2,
            WH_GETMESSAGE = 3,
            WH_CALLWNDPROC = 4,
            WH_CBT = 5,
            WH_SYSMSGFILTER = 6,
            WH_MOUSE = 7,
            WH_HARDWARE = 8,
            WH_DEBUG = 9,
            WH_SHELL = 10,
            WH_FOREGROUNDIDLE = 11,
            WH_CALLWNDPROCRET = 12,
            WH_KEYBOARD_LL = 13,
            WH_MOUSE_LL = 14
        }
    }

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

11   голосов , оценка 3.636 из 5