C#全局键盘监听(Hook)的使用(转载)

转载 https://www.cnblogs.com/zhaoyuncai/p/7684958.html  

稍微有些改动 这里只添加 按键按下

一.为什么需要全局键盘监听?

在某些情况下应用程序需要实现快捷键执行特定功能,例如大家熟知的QQ截图功能Ctrl+Alt+A快捷键,只要QQ程序在运行(无论是拥有焦点还是处于后台运行状态),都可以按下快捷键使用此功能…

这个时候在程序中添加键盘监听肯定不能满足需求了,当用户焦点不在App上时(如最小化,或者用户在处理其它事物等等)键盘监听就失效了

二.怎样才能实现全局键盘监听?

这里需要用到Windows API,源码如下:(可以作为一个工具类[KeyboardHook.cs]收藏起来)

  1 using System;
  2 using System.Text;
  3 using System.Runtime.InteropServices;
  4 using System.Reflection;
  5 using System.Windows.Forms;
  6 
  7 namespace BAMdp.MouseKeyboardLibrary
  8 {
  9     public abstract class GlobalHook
 10     {
 11         #region Windows API Code  
 12 
 13         [StructLayout(LayoutKind.Sequential)]
 14         protected class POINT
 15         {
 16             public int x;
 17             public int y;
 18         }
 19 
 20         [StructLayout(LayoutKind.Sequential)]
 21         protected class MouseHookStruct
 22         {
 23             public POINT pt;
 24             public int hwnd;
 25             public int wHitTestCode;
 26             public int dwExtraInfo;
 27         }
 28 
 29         [StructLayout(LayoutKind.Sequential)]
 30         protected class MouseLLHookStruct
 31         {
 32             public POINT pt;
 33             public int mouseData;
 34             public int flags;
 35             public int time;
 36             public int dwExtraInfo;
 37         }
 38 
 39         [StructLayout(LayoutKind.Sequential)]
 40         protected class KeyboardHookStruct
 41         {
 42             public int vkCode;
 43             public int scanCode;
 44             public int flags;
 45             public int time;
 46             public int dwExtraInfo;
 47         }
 48 
 49         [DllImport("user32.dll", CharSet = CharSet.Auto,
 50            CallingConvention = CallingConvention.StdCall, SetLastError = true)]
 51         protected static extern int SetWindowsHookEx(
 52             int idHook,
 53             HookProc lpfn,
 54             IntPtr hMod,
 55             int dwThreadId);
 56 
 57         [DllImport("user32.dll", CharSet = CharSet.Auto,
 58             CallingConvention = CallingConvention.StdCall, SetLastError = true)]
 59         protected static extern int UnhookWindowsHookEx(int idHook);
 60 
 61 
 62         [DllImport("user32.dll", CharSet = CharSet.Auto,
 63              CallingConvention = CallingConvention.StdCall)]
 64         protected static extern int CallNextHookEx(
 65             int idHook,
 66             int nCode,
 67             int wParam,
 68             IntPtr lParam);
 69 
 70         [DllImport("user32")]
 71         protected static extern int ToAscii(
 72             int uVirtKey,
 73             int uScanCode,
 74             byte[] lpbKeyState,
 75             byte[] lpwTransKey,
 76             int fuState);
 77 
 78         [DllImport("user32")]
 79         protected static extern int GetKeyboardState(byte[] pbKeyState);
 80 
 81         [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
 82         protected static extern short GetKeyState(int vKey);
 83 
 84         [DllImport("kernel32.dll")]
 85         private static extern IntPtr GetModuleHandle(string name);
 86 
 87         protected delegate int HookProc(int nCode, int wParam, IntPtr lParam);
 88 
 89         protected const int WH_MOUSE_LL = 14;
 90         protected const int WH_KEYBOARD_LL = 13;
 91 
 92         protected const int WH_MOUSE = 7;
 93         protected const int WH_KEYBOARD = 2;
 94         protected const int WM_MOUSEMOVE = 0x200;
 95         protected const int WM_LBUTTONDOWN = 0x201;
 96         protected const int WM_RBUTTONDOWN = 0x204;
 97         protected const int WM_MBUTTONDOWN = 0x207;
 98         protected const int WM_LBUTTONUP = 0x202;
 99         protected const int WM_RBUTTONUP = 0x205;
100         protected const int WM_MBUTTONUP = 0x208;
101         protected const int WM_LBUTTONDBLCLK = 0x203;
102         protected const int WM_RBUTTONDBLCLK = 0x206;
103         protected const int WM_MBUTTONDBLCLK = 0x209;
104         protected const int WM_MOUSEWHEEL = 0x020A;
105         protected const int WM_KEYDOWN = 0x100;
106         protected const int WM_KEYUP = 0x101;
107         protected const int WM_SYSKEYDOWN = 0x104;
108         protected const int WM_SYSKEYUP = 0x105;
109 
110         protected const byte VK_SHIFT = 0x10;
111         protected const byte VK_CAPITAL = 0x14;
112         protected const byte VK_NUMLOCK = 0x90;
113 
114         protected const byte VK_LSHIFT = 0xA0;
115         protected const byte VK_RSHIFT = 0xA1;
116         protected const byte VK_LCONTROL = 0xA2;
117         protected const byte VK_RCONTROL = 0x3;
118         protected const byte VK_LALT = 0xA4;
119         protected const byte VK_RALT = 0xA5;
120 
121         protected const byte LLKHF_ALTDOWN = 0x20;
122 
123         #endregion
124 
125         #region Private Variables  
126 
127         protected int _hookType;
128         protected int _handleToHook;
129         protected bool _isStarted;
130         protected HookProc _hookCallback;
131 
132         #endregion
133 
134         #region Properties  
135 
136         public bool IsStarted
137         {
138             get
139             {
140                 return _isStarted;
141             }
142         }
143 
144         #endregion
145 
146         #region Constructor  
147 
148         public GlobalHook()
149         {
150 
151             Application.ApplicationExit += new EventHandler(Application_ApplicationExit);
152 
153         }
154 
155         #endregion
156 
157         #region Methods  
158 
159         public void Start()
160         {
161 
162             if (!_isStarted &&
163                 _hookType != 0)
164             {
165 
166                 // Make sure we keep a reference to this delegate!  
167                 // If not, GC randomly collects it, and a NullReference exception is thrown  
168                 _hookCallback = new HookProc(HookCallbackProcedure);
169 
170                 _handleToHook = SetWindowsHookEx(
171                     _hookType,
172                     _hookCallback,
173                     GetModuleHandle(System.Diagnostics.Process.GetCurrentProcess().MainModule.ModuleName),
174                     0);
175                 //GetModuleHandle(System.Diagnostics.Process.GetCurrentProcess().MainModule.ModuleName
176                 //GetModuleHandle(Process.GetCurrentProcess().MainModule.ModuleName)
177                 // Were we able to sucessfully start hook?  
178                 if (_handleToHook != 0)
179                 {
180                     _isStarted = true;
181                 }
182 
183             }
184 
185         }
186 
187         public void Stop()
188         {
189 
190             if (_isStarted)
191             {
192 
193                 UnhookWindowsHookEx(_handleToHook);
194 
195                 _isStarted = false;
196 
197             }
198 
199         }
200 
201         protected virtual int HookCallbackProcedure(int nCode, Int32 wParam, IntPtr lParam)
202         {
203 
204             // This method must be overriden by each extending hook  
205             return 0;
206 
207         }
208 
209         protected void Application_ApplicationExit(object sender, EventArgs e)
210         {
211 
212             if (_isStarted)
213             {
214                 Stop();
215             }
216 
217         }
218 
219         #endregion
220     }
221 }
View Code
  1 using System;
  2 using System.Text;
  3 using System.Windows.Forms;
  4 using System.Runtime.InteropServices;
  5 
  6 namespace BAMdp.MouseKeyboardLibrary
  7 {
  8     public class KeyboardHook : GlobalHook
  9     {
 10         #region Events  
 11 
 12         public event KeyEventHandler KeyDown;
 13         public event KeyEventHandler KeyUp;
 14         public event KeyPressEventHandler KeyPress;
 15 
 16         #endregion
 17 
 18         #region Constructor  
 19 
 20         public KeyboardHook()
 21         {
 22 
 23             _hookType = WH_KEYBOARD_LL;
 24 
 25         }
 26 
 27         #endregion
 28 
 29         #region Methods  
 30 
 31         protected override int HookCallbackProcedure(int nCode, int wParam, IntPtr lParam)
 32         {
 33 
 34             bool handled = false;
 35 
 36             if (nCode > -1 && (KeyDown != null || KeyUp != null || KeyPress != null))
 37             {
 38 
 39                 KeyboardHookStruct keyboardHookStruct =
 40                     (KeyboardHookStruct)Marshal.PtrToStructure(lParam, typeof(KeyboardHookStruct));
 41 
 42                 // Is Control being held down?  
 43                 bool control = ((GetKeyState(VK_LCONTROL) & 0x80) != 0) ||
 44                                ((GetKeyState(VK_RCONTROL) & 0x80) != 0);
 45 
 46                 // Is Shift being held down?  
 47                 bool shift = ((GetKeyState(VK_LSHIFT) & 0x80) != 0) ||
 48                              ((GetKeyState(VK_RSHIFT) & 0x80) != 0);
 49 
 50                 // Is Alt being held down?  
 51                 bool alt = ((GetKeyState(VK_LALT) & 0x80) != 0) ||
 52                            ((GetKeyState(VK_RALT) & 0x80) != 0);
 53 
 54                 // Is CapsLock on?  
 55                 bool capslock = (GetKeyState(VK_CAPITAL) != 0);
 56 
 57                 // Create event using keycode and control/shift/alt values found above  
 58                 KeyEventArgs e = new KeyEventArgs(
 59                     (Keys)(
 60                         keyboardHookStruct.vkCode |
 61                         (control ? (int)Keys.Control : 0) |
 62                         (shift ? (int)Keys.Shift : 0) |
 63                         (alt ? (int)Keys.Alt : 0)
 64                         ));
 65 
 66                 // Handle KeyDown and KeyUp events  
 67                 switch (wParam)
 68                 {
 69 
 70                     case WM_KEYDOWN:
 71                     case WM_SYSKEYDOWN:
 72                         if (KeyDown != null)
 73                         {
 74                             KeyDown(this, e);
 75                             handled = handled || e.Handled;
 76                         }
 77                         break;
 78                     case WM_KEYUP:
 79                     case WM_SYSKEYUP:
 80                         if (KeyUp != null)
 81                         {
 82                             KeyUp(this, e);
 83                             handled = handled || e.Handled;
 84                         }
 85                         break;
 86 
 87                 }
 88 
 89                 // Handle KeyPress event  
 90                 if (wParam == WM_KEYDOWN &&
 91                    !handled &&
 92                    !e.SuppressKeyPress &&
 93                     KeyPress != null)
 94                 {
 95 
 96                     byte[] keyState = new byte[256];
 97                     byte[] inBuffer = new byte[2];
 98                     GetKeyboardState(keyState);
 99 
100                     if (ToAscii(keyboardHookStruct.vkCode,
101                               keyboardHookStruct.scanCode,
102                               keyState,
103                               inBuffer,
104                               keyboardHookStruct.flags) == 1)
105                     {
106 
107                         char key = (char)inBuffer[0];
108                         if ((capslock ^ shift) && Char.IsLetter(key))
109                             key = Char.ToUpper(key);
110                         KeyPressEventArgs e2 = new KeyPressEventArgs(key);
111                         KeyPress(this, e2);
112                         handled = handled || e.Handled;
113 
114                     }
115 
116                 }
117 
118             }
119 
120             if (handled)
121             {
122                 return 1;
123             }
124             else
125             {
126                 return CallNextHookEx(_handleToHook, nCode, wParam, lParam);
127             }
128 
129         }
130 
131         #endregion
132     }
133 }
View Code
using System;
using System.Text;
using System.Runtime.InteropServices;
using System.Windows.Forms;

namespace BAMdp.MouseKeyboardLibrary
{
    /// <summary>  
    /// Standard Keyboard Shortcuts used by most applications  
    /// </summary>  
    public enum StandardShortcut
    {
        Copy,
        Cut,
        Paste,
        SelectAll,
        Save,
        Open,
        New,
        Close,
        Print
    }

    /// <summary>  
    /// Simulate keyboard key presses  
    /// </summary>  
    public static class KeyboardSimulator
    {
        #region Windows API Code  

        const int KEYEVENTF_EXTENDEDKEY = 0x1;
        const int KEYEVENTF_KEYUP = 0x2;

        [DllImport("user32.dll")]
        static extern void keybd_event(byte key, byte scan, int flags, int extraInfo);

        #endregion

        #region Methods  

        public static void KeyDown(Keys key)
        {
            keybd_event(ParseKey(key), 0, 0, 0);
        }

        public static void KeyUp(Keys key)
        {
            keybd_event(ParseKey(key), 0, KEYEVENTF_KEYUP, 0);
        }

        public static void KeyPress(Keys key)
        {
            KeyDown(key);
            KeyUp(key);
        }

        public static void SimulateStandardShortcut(StandardShortcut shortcut)
        {
            switch (shortcut)
            {
                case StandardShortcut.Copy:
                    KeyDown(Keys.Control);
                    KeyPress(Keys.C);
                    KeyUp(Keys.Control);
                    break;
                case StandardShortcut.Cut:
                    KeyDown(Keys.Control);
                    KeyPress(Keys.X);
                    KeyUp(Keys.Control);
                    break;
                case StandardShortcut.Paste:
                    KeyDown(Keys.Control);
                    KeyPress(Keys.V);
                    KeyUp(Keys.Control);
                    break;
                case StandardShortcut.SelectAll:
                    KeyDown(Keys.Control);
                    KeyPress(Keys.A);
                    KeyUp(Keys.Control);
                    break;
                case StandardShortcut.Save:
                    KeyDown(Keys.Control);
                    KeyPress(Keys.S);
                    KeyUp(Keys.Control);
                    break;
                case StandardShortcut.Open:
                    KeyDown(Keys.Control);
                    KeyPress(Keys.O);
                    KeyUp(Keys.Control);
                    break;
                case StandardShortcut.New:
                    KeyDown(Keys.Control);
                    KeyPress(Keys.N);
                    KeyUp(Keys.Control);
                    break;
                case StandardShortcut.Close:
                    KeyDown(Keys.Alt);
                    KeyPress(Keys.F4);
                    KeyUp(Keys.Alt);
                    break;
                case StandardShortcut.Print:
                    KeyDown(Keys.Control);
                    KeyPress(Keys.P);
                    KeyUp(Keys.Control);
                    break;
            }
        }

        static byte ParseKey(Keys key)
        {

            // Alt, Shift, and Control need to be changed for API function to work with them  
            switch (key)
            {
                case Keys.Alt:
                    return (byte)18;
                case Keys.Control:
                    return (byte)17;
                case Keys.Shift:
                    return (byte)16;
                default:
                    return (byte)key;
            }

        }

        #endregion
    }
}
View Code
1  private void Form_Load(object sender, EventArgs e)
2         {
3             keyboardHook = new KeyboardHook();
4             keyboardHook.KeyDown += new KeyEventHandler(keyboardHook_KeyDown);
5             keyboardHook.KeyUp += new KeyEventHandler(keyboardHook_KeyUp);
6             keyboardHook.Start();
7         }
 1 private void keyboardHook_KeyUp(object sender, KeyEventArgs e)
 2         {
 3             if (e.KeyCode == Keys.Space && SpacePrease)
 4             {
 5                 SpacePrease = false;
 6                 m_emergency.ReleaseSpeaker();
 7             }
 8         }
 9 
10         private void keyboardHook_KeyDown(object sender, KeyEventArgs e)
11         {
12             if (e.KeyCode == Keys.Space && !SpacePrease)
13             {
14                 SpacePrease = true;
15                 m_emergency.ApplySpeaker();
16             }
17         }

 

posted @ 2019-06-03 18:34  出来打酱油  阅读(2228)  评论(0编辑  收藏  举报