Пользователь пока ничего не рассказал о себе

Наибольший вклад в теги

Все теги (4)

Лучшие ответы пользователя

Все ответы (2)
  • Как реализовать глобальный KeyPress в C#?

    @dark_Kelvin
    Если нужны горячие клавиши, то используйте RegisterHotKey / UnregisterHotKey
    Если надо отлавливать события KeyDown KeyPress KeyUp, то используйте SetWindowsHookEx с параметром WH_KEYBOARD_LL / UnhookWindowsHookEx
    private bool hooked = false;
    		private IntPtr hHook;
    		private HookProc managedDelegate = InternalCallback;
    		
    		public event KeyEventHandler KeyDown;
            public event KeyEventHandler KeyUp;
    		public event KeyPressEventHandler KeyPress;
    
    		public void StartHook()
            {
                IntPtr delegt = Marshal.GetFunctionPointerForDelegate(managedDelegate);
    			hHook = SetWindowsHookEx(HookType.WH_KEYBOARD_LL, delegt, getMainModuleHandle(), 0);
    			if (hHook == IntPtr.Zero) throw new Win32Exception(Marshal.GetLastWin32Error());
    		}
    		
    		public virtual void Unhook()
            {
    			if (!UnhookWindowsHookEx(hHook)) throw new Win32Exception(Marshal.GetLastWin32Error());
    		}
    		
    		protected int InternalCallback(int code, IntPtr wParam, IntPtr lParam)
            {
                if (code >= 0)
                {
                    bool handled = false;
                    KeyboardHookStruct keyboardHookStruct = (KeyboardHookStruct)Marshal.PtrToStructure(lParam, typeof(KeyboardHookStruct));
    				
    				if (KeyDown != null && ((int)wParam == WM_KEYDOWN || (int)wParam == WM_SYSKEYDOWN))
    				{
    					Keys keyData = (Keys)keyboardHookStruct.VirtualKeyCode;
    					KeyEventArgs e = new KeyEventArgs(keyData);
    					KeyDown.Invoke(null, e);
    					handled = e.Handled;
    				}
    				
    				if (KeyPress != null && (int)wParam == WM_KEYDOWN)
    				{
    					//Перекодирование сканкодов в Ascii
    				}
    				
    				if (KeyUp != null && ((int)wParam == WM_KEYUP || (int)wParam == WM_SYSKEYUP))
    				{
    					Keys keyData = (Keys)keyboardHookStruct.VirtualKeyCode;
    					KeyEventArgs e = new KeyEventArgs(keyData);
    					KeyUp.Invoke(null, e);
    					handled = handled || e.Handled;
    				}
    				
                    if (handled) return 1;
                }
                return CallNextHookEx(hHook, code, wParam, lParam);
            }
    		
    		
    		
    		private IntPtr getMainModuleHandle()
            {
                IntPtr hMod;
                using (Process process = Process.GetCurrentProcess())
                using (ProcessModule module = process.MainModule)
                {
                    hMod = GetModuleHandle(module.ModuleName);
                }
                return hMod;
            }
    
            [DllImport("user32.dll", SetLastError = true)]
            private static extern IntPtr SetWindowsHookEx(HookType hook, IntPtr callback,
                IntPtr hMod, uint dwThreadId);
    
            [DllImport("user32.dll", SetLastError = true)]
            internal static extern bool UnhookWindowsHookEx(IntPtr hhk);
    
            [DllImport("user32.dll")]
            internal static extern int CallNextHookEx(IntPtr hhk, int nCode, IntPtr wParam,
                IntPtr lParam);
    
            [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
            private static extern IntPtr GetModuleHandle(string lpModuleName);
    
            private delegate int HookProc(int code, IntPtr wParam, IntPtr lParam);
    		
    		 private const int
             WM_KEYDOWN = 0x100,
             WM_KEYUP = 0x101,
             WM_SYSKEYDOWN = 0x104,
             WM_SYSKEYUP = 0x105;
    		
            [StructLayout(LayoutKind.Sequential)]
            private struct KeyboardHookStruct
            {
                /// <summary>
                /// Specifies a virtual-key code. The code must be a value in the range 1 to 254. 
                /// </summary>
                public int VirtualKeyCode;
                /// <summary>
                /// Specifies a hardware scan code for the key. 
                /// </summary>
                public int ScanCode;
                /// <summary>
                /// Specifies the extended-key flag, event-injected flag, context code, and transition-state flag.
                /// </summary>
                public int Flags;
                /// <summary>
                /// Specifies the Time stamp for this message.
                /// </summary>
                public int Time;
                /// <summary>
                /// Specifies extra information associated with the message. 
                /// </summary>
                public int ExtraInfo;
            }
    
    		
    		
    	internal 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
        }
    Ответ написан
    3 комментария

Лучшие вопросы пользователя

Все вопросы (1)