全局捕获按键动作

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace MonitorKeys
{
  //主窗体类
public partial class Form1 : Form { UserHook hook = new UserHook(); bool flag_PullDown = false; string front = ""; //组合键的前一个按键 string tem_s = ""; //组合键 public Form1() { InitializeComponent(); } private void Form1_Load(object sender, EventArgs e) { hook.KeyDown += new KeyEventHandler(Hook_KeyDown); hook.KeyUp += new KeyEventHandler(Hook_KeyUp); if(hook.Start() ==true) { MessageBox.Show("检测进程启动成功!"); } else { MessageBox.Show("检测进程启动失败!"); } } void Hook_KeyDown(object send,KeyEventArgs e) { AddKeyboardEvent("KeyDown", e.KeyCode.ToString(), "", e.Shift.ToString(), e.Alt.ToString(), e.Control.ToString()); } void Hook_KeyUp(object send, KeyEventArgs e) { AddKeyboardEvent("KeyUp", e.KeyCode.ToString(), "", e.Shift.ToString(), e.Alt.ToString(), e.Control.ToString()); } /// <summary> /// /// </summary> /// <param name="eventType">按键类型</param> /// <param name="keyCode">键名称</param> /// <param name="keyChar">键值</param> /// <param name="shift">是否为Shift键</param> /// <param name="alt">是否为Alt键</param> /// <param name="control">是否为Ctrl键</param> public void AddKeyboardEvent(string eventType,string keyCode,string keyChar,string shift,string alt,string control) { //tem_s = 0; bool b = false; string keyValue = ""; GetKey(keyCode, out b, out keyValue); if(eventType=="KeyDown") { flag_PullDown = true; } if(eventType=="KeyUp") //完成组合键:1.清除有键按下的状态 2.清除组合键记录(先显示,后清除) 3.清除前键值记录 { if (tem_s != "") { textBox1.Text = tem_s; } //else //{ // textBox1.Text = front; //} flag_PullDown = false; front = ""; tem_s = ""; } if((flag_PullDown==true)&&(eventType=="KeyDown")) { //前一键与当前键是否一致,一致则不进行处理,不一致则进行记录 if(front!=keyValue) //判定是否为组合键:是(true) 否(false) { if (front == "") { tem_s = keyValue; } else { tem_s += "+" + keyValue; } } front = keyValue; } } /// <summary> /// /// </summary> /// <param name="k">键名称</param> /// <param name="b">是否有热键</param> /// <param name="keyValue">当前热键名称</param> public void GetKey(string k,out bool b,out string keyValue) { if(k.Contains("ControlKey")) { b = true; keyValue = "Ctrl"; return; } if (k.Contains("Shift")) { b = true; keyValue = "Shift"; return; } if (k.Contains("Alt")) { b = true; keyValue = "Alt"; return; } if (k.Contains("Win")) { b = true; keyValue = "Win"; return; } b = true; keyValue = k; } private void Form1_FormClosed(object sender, FormClosedEventArgs e) { if(hook!=null) { hook.Stop(); } } private void ShowInfo(string info) { MessageBox.Show(info); } private void btn_Open_Click(object sender, EventArgs e) { if(hook.isInstalled==false) { hook.Start(); } } private void btn_Stop_Click(object sender, EventArgs e) { if (hook != null) { hook.Stop(); } } } }

消息捕获类:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Runtime.InteropServices;
using System.Windows.Forms;

namespace MonitorKeys
{
    class UserHook
    {
        private const int WH_KEYBOARD_LL = 13;
        private const int WM_KEYDOWN = 0X0100;
        private const int WM_KEYSYSKEYDOWN = 0X0104;
        private const int WM_KEYUP = 0X0101;
        private const int WM_KEYSYSKEYUP = 0X0105;

        public delegate int HookProc(int nCode, Int32 wParam, IntPtr Iparam);

        [DllImport("user32.dll")]   //参数列表(钩子类型,钩子函数入口地址,钩子所在的实例句柄,钩子监视的线程号)
        public static extern IntPtr SetWindowsHookEx(int HookType, HookProc methodAddress, IntPtr handler, int dwThreadId);

        [DllImport("user32.dll")]   //参数列表(钩子所在的实例句柄)
        public static extern bool UnhookWindowsHookEx(IntPtr idHook);

        [DllImport("kernel32.dll")]
        public static extern IntPtr GetModuleHandle(string name);

        IntPtr p_Hook = IntPtr.Zero;            //钩子句柄
        IntPtr p_Keyboard = IntPtr.Zero;        //键盘的消息句柄

        HookProc keyboardHookProcedure;     //处理键盘信息的钩子
        [StructLayout(LayoutKind.Sequential)]
        public class KeyMSG
        {
            public int vkCode;      //定义一个虚拟键码(1-254之间)
            public int scanCode;    //指定硬件的扫描码
            public int flags;       //键标识
            public int times;       //信息的时间戳
            public int dwExtrainfo; //额外信息
        }


        public event KeyEventHandler KeyPress;
        public event KeyEventHandler KeyDown;
        public event KeyEventHandler KeyUp;

        public bool isInstalled = false;

        public bool Start()
        {
            //p_Hook = (IntPtr)4194304;       //定义钩子句柄;

            p_Hook = GetModuleHandle(System.Diagnostics.Process.GetCurrentProcess().MainModule.ModuleName);
            if(p_Keyboard==IntPtr.Zero)     //键盘句柄是否为空
            {
                keyboardHookProcedure = new HookProc(KeyboardHookProc);
                p_Keyboard = SetWindowsHookEx(WH_KEYBOARD_LL, keyboardHookProcedure, p_Hook, 0);    //安装钩子(将"钩子的句柄"与"键盘消息句柄"进行绑定)
                if(p_Keyboard==IntPtr.Zero)
                {
                    this.Stop();
                    return false;
                }
            }
            isInstalled = true;
            return true;
        }
        public bool Stop()
        {
            if(isInstalled==false)
            {
                return true;
            }
            bool result = true;
            if(this.p_Keyboard!=IntPtr.Zero)
            {
                result = UnhookWindowsHookEx(this.p_Keyboard);
                this.p_Keyboard = IntPtr.Zero;
            }
            return result;
        }
        

        private int KeyboardHookProc(int nCode, Int32 wParam, IntPtr Iparam)
        {
            if(nCode>-1&&((KeyPress!=null)||(KeyDown!=null)||(KeyUp!=null)))
            {
                KeyMSG keybaoardHookStruct = (KeyMSG)Marshal.PtrToStructure(Iparam, typeof(KeyMSG));
                KeyEventArgs e = new KeyEventArgs((Keys)(keybaoardHookStruct.vkCode));
                switch(wParam)
                {
                    case WM_KEYDOWN:
                    case WM_KEYSYSKEYDOWN:
                        KeyDown.Invoke(this, e);
                        break;

                    case WM_KEYUP:
                    case WM_KEYSYSKEYUP:
                        KeyUp.Invoke(this, e);
                        break;
                }
            }
            return 0;
        }
    }
}

UI视图:

(注意:清空的功能,是V0.2版添加的,需要在主窗体代码中补写)

 

posted @ 2022-09-21 14:37  冲云霄  阅读(1)  评论(0)    收藏  举报