zoukankan      html  css  js  c++  java
  • [转][C#] 全局键盘获取组件

    KeysHoot.cs
    
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Diagnostics;
    using System.Linq;
    using System.Text;
    using System.Runtime.InteropServices;
    using System.Windows.Forms;
    
    
    namespace Mouse
    {
        public partial class KeysHoot : Component
        {
            public KeysHoot()
            {
                InitializeComponent();
                this.Start();
            }
    
    
            public KeysHoot(IContainer container)
            {
                container.Add(this);
                this.Start();
                InitializeComponent();
            }
    
    
            ~KeysHoot()
            {
                Stop();
            }
            #region 全局常量声明
            private const int WM_KEYDOWN = 0x100;
            private const int WM_KEYUP = 0x101;
            private const int WM_SYSKEYDOWN = 0x104;
            private const int WM_SYSKEYUP = 0x105;
            #endregion
    
    
            #region 全局的事件
            public event KeyEventHandler OnKeyDownEvent;
            public event KeyEventHandler OnKeyUpEvent;
            public event KeyPressEventHandler OnKeyPressEvent;
            #endregion
    
    
            #region 鼠标常量
            static int hKeyboardHook = 0; //键盘钩子句柄
            public const int WH_KEYBOARD_LL = 13; //类型  定义在winuser.h
            #endregion
    
    
            #region 有关键盘
            HookProc KeyboardHookProcedure; //声明键盘钩子事件类型.
            //声明键盘钩子的封送结构类型
            [StructLayout(LayoutKind.Sequential)]
            public class KeyboardHookStruct
            {
                public int vkCode; //表示一个在1到254间的虚似键盘码
                public int scanCode; //表示硬件扫描码
                public int flags;
                public int time;
                public int dwExtraInfo;
            }
            #endregion
    
    
            #region api
            //装置钩子的函数
            [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
            public static extern int SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr hInstance, int threadId);
            //卸下钩子的函数
            [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
            public static extern bool UnhookWindowsHookEx(int idHook);
            //下一个钩挂的函数
            [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
            public static extern int CallNextHookEx(int idHook, int nCode, Int32 wParam, IntPtr lParam);
            [DllImport("user32")]
            public static extern int ToAscii(int uVirtKey, int uScanCode, byte[] lpbKeyState, byte[] lpwTransKey, int fuState);
            [DllImport("user32")]
            public static extern int GetKeyboardState(byte[] pbKeyState);
            [DllImport("kernel32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
            private static extern IntPtr GetModuleHandle(string lpModuleName);
            public delegate int HookProc(int nCode, Int32 wParam, IntPtr lParam);
            //先前按下的键
            public List<Keys> preKeys = new List<Keys>();
            #endregion
    
    
            #region 键盘钩子安装与卸载处理
            /// <summary>
            /// 安装键盘钩子
            /// </summary>
            public void Start()
            {
                //安装键盘钩子
                if (hKeyboardHook == 0)
                {
                    KeyboardHookProcedure = new HookProc(KeyboardHookProc);
                    //hKeyboardHook = SetWindowsHookEx(WH_KEYBOARD_LL, KeyboardHookProcedure, Marshal.GetHINSTANCE(Assembly.GetExecutingAssembly().GetModules()[0]), 0);
                    Process curProcess = Process.GetCurrentProcess();
                    ProcessModule curModule = curProcess.MainModule;
                    hKeyboardHook = SetWindowsHookEx(WH_KEYBOARD_LL, KeyboardHookProcedure, GetModuleHandle(curModule.ModuleName), 0);
                    if (hKeyboardHook == 0)
                    {
                        Stop();
                        throw new Exception("安装键盘钩子");
                    }
                }
            }
            /// <summary>
            /// 卸载键盘钩子
            /// </summary>
            public void Stop()
            {
                bool retKeyboard = true;
                if (hKeyboardHook != 0)
                {
                    retKeyboard = UnhookWindowsHookEx(hKeyboardHook);
                    hKeyboardHook = 0;
                }
                //如果卸下钩子失败
                if (!(retKeyboard)) throw new Exception("卸下钩子失败");
    
    
            }
            #endregion
    
    
            #region 处理方法
            private int KeyboardHookProc(int nCode, Int32 wParam, IntPtr lParam)
            {
                if ((nCode >= 0) && (OnKeyDownEvent != null || OnKeyUpEvent != null || OnKeyPressEvent != null))
                {
                    KeyboardHookStruct MyKeyboardHookStruct = (KeyboardHookStruct)Marshal.PtrToStructure(lParam, typeof(KeyboardHookStruct));
                    //当有OnKeyDownEvent 或 OnKeyPressEvent不为null时,ctrl alt shift keyup时 preKeys
                    //中的对应的键增加                  
                    if ((OnKeyDownEvent != null || OnKeyPressEvent != null) && (wParam == WM_KEYDOWN || wParam == WM_SYSKEYDOWN))
                    {
                        Keys keyData = (Keys)MyKeyboardHookStruct.vkCode;
                        if (IsCtrlAltShiftKeys(keyData) && preKeys.IndexOf(keyData) == -1)
                        {
                            preKeys.Add(keyData);
                        }
                    }
                    //引发OnKeyDownEvent
                    if (OnKeyDownEvent != null && (wParam == WM_KEYDOWN || wParam == WM_SYSKEYDOWN))
                    {
                        Keys keyData = (Keys)MyKeyboardHookStruct.vkCode;
                        KeyEventArgs e = new KeyEventArgs(GetDownKeys(keyData));
                        OnKeyDownEvent(this, e);
                    }
                    //引发OnKeyPressEvent
                    if (OnKeyPressEvent != null && wParam == WM_KEYDOWN)
                    {
                        byte[] keyState = new byte[256];
                        GetKeyboardState(keyState);
                        byte[] inBuffer = new byte[2];
                        if (ToAscii(MyKeyboardHookStruct.vkCode,
                        MyKeyboardHookStruct.scanCode,
                        keyState,
                        inBuffer,
                        MyKeyboardHookStruct.flags) == 1)
                        {
                            KeyPressEventArgs e = new KeyPressEventArgs((char)inBuffer[0]);
                            OnKeyPressEvent(this, e);
                        }
                    }
                    //当有OnKeyDownEvent 或 OnKeyPressEvent不为null时,ctrl alt shift keyup时 preKeys
                    //中的对应的键删除
                    if ((OnKeyDownEvent != null || OnKeyPressEvent != null) && (wParam == WM_KEYUP || wParam == WM_SYSKEYUP))
                    {
                        Keys keyData = (Keys)MyKeyboardHookStruct.vkCode;
                        if (IsCtrlAltShiftKeys(keyData))
                        {
                            for (int i = preKeys.Count - 1; i >= 0; i--)
                            {
                                if (preKeys[i] == keyData)
                                {
                                    preKeys.RemoveAt(i);
                                }
                            }
                        }
                    }
                    //引发OnKeyUpEvent
                    if (OnKeyUpEvent != null && (wParam == WM_KEYUP || wParam == WM_SYSKEYUP))
                    {
                        Keys keyData = (Keys)MyKeyboardHookStruct.vkCode;
                        KeyEventArgs e = new KeyEventArgs(GetDownKeys(keyData));
                        OnKeyUpEvent(this, e);
                    }
                }
                return CallNextHookEx(hKeyboardHook, nCode, wParam, lParam);
            }
            private Keys GetDownKeys(Keys key)
            {
                Keys rtnKey = Keys.None;
                foreach (Keys keyTemp in preKeys)
                {
                    switch (keyTemp)
                    {
                        case Keys.LControlKey:
                        case Keys.RControlKey:
                            rtnKey = rtnKey | Keys.Control;
                            break;
                        case Keys.LMenu:
                        case Keys.RMenu:
                            rtnKey = rtnKey | Keys.Alt;
                            break;
                        case Keys.LShiftKey:
                        case Keys.RShiftKey:
                            rtnKey = rtnKey | Keys.Shift;
                            break;
                        default:
                            break;
                    }
                }
                rtnKey = rtnKey | key;
                return rtnKey;
            }
            private Boolean IsCtrlAltShiftKeys(Keys key)
            {
                switch (key)
                {
                    case Keys.LControlKey:
                    case Keys.RControlKey:
                    case Keys.LMenu:
                    case Keys.RMenu:
                    case Keys.LShiftKey:
                    case Keys.RShiftKey:
                        return true;
                    default:
                        return false;
                }
            }
            #endregion
        }
    }
    KeysHoot.Designer.cs
    
    namespace Mouse
    {
        partial class KeysHoot
        {
            /// <summary>
            /// 必需的设计器变量。
            /// </summary>
            private System.ComponentModel.IContainer components = null;
    
    
            /// <summary> 
            /// 清理所有正在使用的资源。
            /// </summary>
            /// <param name="disposing">如果应释放托管资源,为 true;否则为 false。</param>
            protected override void Dispose(bool disposing)
            {
                if (disposing && (components != null))
                {
                    components.Dispose();
                }
                base.Dispose(disposing);
            }
    
    
            #region 组件设计器生成的代码
    
    
            /// <summary>
            /// 设计器支持所需的方法 - 不要
            /// 使用代码编辑器修改此方法的内容。
            /// </summary>
            private void InitializeComponent()
            {
                components = new System.ComponentModel.Container();
            }
    
    
            #endregion
        }
    }
    


    源代码来源于网络  然后自己修改为组件  


    组件代码如下  :


    作者:qq283868910 发表于2011-12-7 18:25:30 原文链接
    阅读:78 评论:0 查看评论
  • 相关阅读:
    'Undefined symbols for architecture i386,clang: error: linker command failed with exit code 1
    The codesign tool requires there only be one 解决办法
    XCode iOS project only shows “My Mac 64bit” but not simulator or device
    Provisioning profile XXXX can't be found 的解决办法
    UIView 中的控件事件穿透 Passthrough 的实现
    Xcode4.5出现时的OC新语法
    xcode 快捷键(持续更新)
    打越狱包
    php缓存与加速分析与汇总
    浏览器的判断
  • 原文地址:https://www.cnblogs.com/SpeakHero/p/2431308.html
Copyright © 2011-2022 走看看