开启辅助访问 切换到宽版

精易论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

用微信号发送消息登录论坛

新人指南 邀请好友注册 - 我关注人的新帖 教你赚取精币 - 每日签到


求职/招聘- 论坛接单- 开发者大厅

论坛版规 总版规 - 建议/投诉 - 应聘版主 - 精华帖总集 积分说明 - 禁言标准 - 有奖举报

查看: 3134|回复: 2
收起左侧

[C#源码] C#键盘钩子源码

[复制链接]
发表于 2024-2-2 17:27:05 | 显示全部楼层 |阅读模式   河北省廊坊市
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using KeyMusic;
using static System.Net.Mime.MediaTypeNames;
namespace KeyMusic
{
    public partial class Form1 : Form
    {
        private const int WH_KEYBOARD_LL = 13; //全局键盘钩子
        private const int WM_KEYDOWN = 0x0100; //键盘按下
        //private const int WM_KEYUP = 0x0101; //键盘抬起
        private static LowLevelKeyboardProc _proc = HookCallback;
        private static IntPtr _hookID = IntPtr.Zero;
        private Form2 form2;
        public Form1()
        {
            InitializeComponent();
            form2 = new Form2(this);
            form2.Show();
            SetHook();

        }
      
      
        public static void SetHook()
        {
            using (Process curProcess = Process.GetCurrentProcess())
            using (ProcessModule curModule = curProcess.MainModule)
            {
                _hookID = SetWindowsHookEx(WH_KEYBOARD_LL, _proc, GetModuleHandle(curModule.ModuleName), 0);
            }
        }
        #region 调用API
        private delegate IntPtr LowLevelKeyboardProc(int nCode, IntPtr wParam, IntPtr lParam);
        /// <summary>
        /// 安装钩子
        /// </summary>
        /// <param name="idHook">钩子类型</param>
        /// <param name="lpfn">函数指针</param>
        /// <param name="hMod">包含钩子函数的模块(EXE、DLL)句柄; 一般是 HInstance; 如果是当前线程这里可以是 0</param>
        /// <param name="dwThreadId">关联的线程; 可用 GetCurrentThreadId 获取当前线程; 0 表示是系统级钩子</param>
        /// <returns>返回钩子的句柄; 0 表示失败</returns>
        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern IntPtr SetWindowsHookEx(int idHook, LowLevelKeyboardProc lpfn, IntPtr hMod, uint dwThreadId);
        //钩子类型 idHook 选项:
        //WH_MSGFILTER       = -1; {线程级; 截获用户与控件交互的消息}
        //WH_JOURNALRECORD   = 0;  {系统级; 记录所有消息队列从消息队列送出的输入消息, 在消息从队列中清除时发生; 可用于宏记录}
        //WH_JOURNALPLAYBACK = 1;  {系统级; 回放由 WH_JOURNALRECORD 记录的消息, 也就是将这些消息重新送入消息队列}
        //WH_KEYBOARD        = 2;  {系统级或线程级; 截获键盘消息}
        //WH_GETMESSAGE      = 3;  {系统级或线程级; 截获从消息队列送出的消息}
        //WH_CALLWNDPROC     = 4;  {系统级或线程级; 截获发送到目标窗口的消息, 在 SendMessage 调用时发生}
        //WH_CBT             = 5;  {系统级或线程级; 截获系统基本消息, 譬如: 窗口的创建、激活、关闭、最大最小化、移动等等}
        //WH_SYSMSGFILTER    = 6;  {系统级; 截获系统范围内用户与控件交互的消息}
        //WH_MOUSE           = 7;  {系统级或线程级; 截获鼠标消息}
        //WH_HARDWARE        = 8;  {系统级或线程级; 截获非标准硬件(非鼠标、键盘)的消息}
        //WH_DEBUG           = 9;  {系统级或线程级; 在其他钩子调用前调用, 用于调试钩子}
        //WH_SHELL           = 10; {系统级或线程级; 截获发向外壳应用程序的消息}
        //WH_FOREGROUNDIDLE  = 11; {系统级或线程级; 在程序前台线程空闲时调用}
        //WH_CALLWNDPROCRET  = 12; {系统级或线程级; 截获目标窗口处理完毕的消息, 在 SendMessage 调用后发生}
        //WH_KEYBOARD_LL     = 13; {系统级; 截获低级键盘消息}
        //WH_MOUSE_LL        = 14; {系统级; 截获低级鼠标消息}
        /// <summary>
        /// 卸载钩子
        /// </summary>
        /// <param name="hhk">钩子的句柄</param>
        /// <returns></returns>
        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        private static extern bool UnhookWindowsHookEx(IntPtr hhk);
        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode, IntPtr wParam, IntPtr lParam);
        [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern IntPtr GetModuleHandle(string lpModuleName);
        #endregion
        /// <summary>
        /// 处理函数
        /// </summary>
        /// <param name="nCode"></param>
        /// <param name="wParam"></param>
        /// <param name="lParam"></param>
        /// <returns>
        /// 如果返回1,则结束消息,这个消息到此为止,不再传递;
        /// 如果返回0或调用CallNextHookEx函数则消息出了这个钩子继续往下传递,也就是传给消息真正的接受者;
        /// </returns>
        private static IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam)
        {
            //键盘按下时
            if (nCode >= 0 && wParam == (IntPtr)WM_KEYDOWN)
            {
                int vkCode = Marshal.ReadInt32(lParam);
                Keys key = (Keys)vkCode;
                MessageBox.Show(key.ToString());
                //记录到日志
                //File.AppendAllText(@"D:\hot.txt", DateTime.Now.ToString("HH:mm:ss") + ": " + key.ToString() + "\r\n");
                Console.WriteLine($"Key Pressed: {key.ToString()}");
            }
            return CallNextHookEx(_hookID, nCode, wParam, lParam);
        }
        /// <summary>
        /// 卸载钩子
        /// </summary>
        public static void UnHook()
        {
            if (_hookID != IntPtr.Zero)
            {
                UnhookWindowsHookEx(_hookID);
            }
        }
        private void Form1_Load(object sender, EventArgs e)
        {
        }
        private void button1_Click(object sender, EventArgs e)
        {
            if (checkBox1.Checked == true)
            {
                MessageBox.Show("123");
            }
        }
    }
}


结帖率:0% (0/1)
发表于 2024-4-18 00:12:13 | 显示全部楼层   重庆市重庆市
可以,还是c++的功劳
回复 支持 反对

使用道具 举报

签到天数: 10 天

发表于 2024-3-26 11:18:01 | 显示全部楼层   广东省广州市
这个不错,学习了!!!!
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则 致发广告者

发布主题 收藏帖子 返回列表

sitemap| 易语言源码| 易语言教程| 易语言论坛| 诚聘英才| 易语言模块| 手机版| 广告投放| 精易论坛
拒绝任何人以任何形式在本论坛发表与中华人民共和国法律相抵触的言论,本站内容均为会员发表,并不代表精易立场!
论坛帖子内容仅用于技术交流学习和研究的目的,严禁用于非法目的,否则造成一切后果自负!如帖子内容侵害到你的权益,请联系我们!
防范网络诈骗,远离网络犯罪 违法和不良信息举报电话0663-3422125,QQ: 800073686,邮箱:800073686@b.qq.com
Powered by Discuz! X3.4 揭阳市揭东区精易科技有限公司 ( 粤ICP备12094385号-1) 粤公网安备 44522102000125 增值电信业务经营许可证 粤B2-20192173

快速回复 返回顶部 返回列表