C# winform键盘钩子

C# winform键盘钩子http://blog.163.com/da7_1@126/blog/static/1040726782011112652629750/新建一个工程CSharpKeyboardHook,在WinForm窗体上拉一个Lable(用于显示,按下的是那个键)和两个button(用于开关勾子)下面是C#winform键盘勾子的代码,照搬上去就可以的啦:一、新建一个类文件KeyboardHo

大家好,又见面了,我是你们的朋友全栈君。

http://blog.163.com/da7_1@126/blog/static/1040726782011112652629750/

新建一个工程CSharpKeyboardHook,在WinForm窗体上拉一个Lable(用于显示,按下的是那个键)和两个button(用于开关勾子)

下面是C#winform键盘勾子的代码,照搬上去就可以的啦:

一、新建一个类文件KeyboardHookLib,代码如下所示:

using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using System.Reflection;
using System.Diagnostics;
using Microsoft.Win32;
using System.Windows.Forms;


namespace CSharpKeyboardHook
{

    /// <summary>
    /// 键盘Hook管理类

    /// </summary>
    public class KeyboardHookLib
    {
        private const int WH_KEYBOARD_LL = 13; //键盘

        //键盘处理事件委托.
        private delegate int HookHandle(int nCode, int wParam, IntPtr lParam);

        //客户端键盘处理事件
        public delegate void ProcessKeyHandle(HookStruct param, out bool handle);

        //接收SetWindowsHookEx返回值
        private static int _hHookValue = 0;

        //勾子程序处理事件
        private HookHandle _KeyBoardHookProcedure;

        //Hook结构
        [StructLayout(LayoutKind.Sequential)]
        public class HookStruct
        {
            public int vkCode;
            public int scanCode;
            public int flags;
            public int time;
            public int dwExtraInfo;
        }

        //设置钩子
        [DllImport("user32.dll")]
        private static extern int SetWindowsHookEx(int idHook, HookHandle lpfn, IntPtr hInstance, int threadId);

        //取消钩子
        [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
        private static extern bool UnhookWindowsHookEx(int idHook);

        //调用下一个钩子
        [DllImport("user32.dll")]
        private static extern int CallNextHookEx(int idHook, int nCode, int wParam, IntPtr lParam);

        //获取当前线程ID
        [DllImport("kernel32.dll")]
        private static extern int GetCurrentThreadId();

        //Gets the main module for the associated process.
        [DllImport("kernel32.dll")]
        private static extern IntPtr GetModuleHandle(string name);

        private IntPtr _hookWindowPtr = IntPtr.Zero;

        //构造器
        public KeyboardHookLib() { }

        //外部调用的键盘处理事件
        private static ProcessKeyHandle _clientMethod = null;

        /// <summary>
        /// 安装勾子
        /// </summary>
        /// <param name="hookProcess">外部调用的键盘处理事件</param>
        public void InstallHook(ProcessKeyHandle clientMethod)
        {
            _clientMethod = clientMethod;

            // 安装键盘钩子
            if (_hHookValue == 0)
            {
                _KeyBoardHookProcedure = new HookHandle(GetHookProc);

                _hookWindowPtr = GetModuleHandle(Process.GetCurrentProcess().MainModule.ModuleName);

                _hHookValue = SetWindowsHookEx(
                    WH_KEYBOARD_LL,
                    _KeyBoardHookProcedure,
                    _hookWindowPtr,
                    0);

                //如果设置钩子失败.
                if (_hHookValue == 0)

                       UninstallHook();
            }
        }

        //取消钩子事件
        public void UninstallHook()
        {
            if (_hHookValue != 0)
            {
                bool ret = UnhookWindowsHookEx(_hHookValue);
                if (ret) _hHookValue = 0;
            }
        }

        //钩子事件内部调用,调用_clientMethod方法转发到客户端应用。
        private static int GetHookProc(int nCode, int wParam, IntPtr lParam)
        {
            if (nCode >= 0)
            {
                //转换结构
                HookStruct hookStruct = (HookStruct)Marshal.PtrToStructure(lParam, typeof(HookStruct));

                if (_clientMethod != null)
                {
                    bool handle = false;
                    //调用客户提供的事件处理程序。
                    _clientMethod(hookStruct, out handle);
                    if (handle) return 1; //1:表示拦截键盘,return 退出
                }
            }
            return CallNextHookEx(_hHookValue, nCode, wParam, lParam);
        }

    }
}

///

//界面事件代码

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Reflection;
using System.Diagnostics;
using Microsoft.Win32;

namespace CSharpKeyboardHook
{
public partial class frmKeyboardHook : Form
{
//勾子管理类
private KeyboardHookLib _keyboardHook = null;

public frmKeyboardHook()
{
InitializeComponent();
}

private void button1_Click(object sender, EventArgs e)
{
//安装勾子
_keyboardHook = new KeyboardHookLib();
_keyboardHook.InstallHook(this.KeyPress);
}

private void button2_Click(object sender, EventArgs e)
{
//取消勾子
if (_keyboardHook != null) _keyboardHook.UninstallHook();
}

/// <summary>
/// 客户端键盘捕捉事件.
/// </summary>
/// <param name="hookStruct">由Hook程序发送的按键信息</param>
/// <param name="handle">是否拦截</param>
public void KeyPress(KeyboardHookLib.HookStruct hookStruct, out bool handle)
{
handle = false; //预设不拦截任何键

if (hookStruct.vkCode == 91) // 截获左win(开始菜单键)
{
handle = true;
}

if (hookStruct.vkCode == 92)// 截获右win
{
handle = true;
}

//截获Ctrl+Esc
if (hookStruct.vkCode == (int)Keys.Escape && (int)Control.ModifierKeys == (int)Keys.Control)
{
handle = true;
}

//截获alt+f4
if (hookStruct.vkCode == (int)Keys.F4 && (int)Control.ModifierKeys == (int)Keys.Alt)
{
handle = true;
}

//截获alt+tab
if (hookStruct.vkCode == (int)Keys.Tab && (int)Control.ModifierKeys == (int)Keys.Alt)
{
handle = true;
}

//截获F1
if (hookStruct.vkCode == (int)Keys.F1)
{
handle = true;
}

//截获Ctrl+Alt+Delete
if ((int)Control.ModifierKeys == (int)Keys.Control + (int)Keys.Alt + (int)Keys.Delete)
{
handle = true;
}

//如果键A~Z
if (hookStruct.vkCode >= (int)Keys.A && hookStruct.vkCode <= (int)Keys.Z)
{
//挡掉G键,想要挡掉哪些键就把下面的G换成那个要挡掉的键,同理可以挡多个
if (hookStruct.vkCode == (int)Keys.G)
hookStruct.vkCode = (int)Keys.None; //设键为0

handle = true;
}

Keys key = (Keys)hookStruct.vkCode;
label1.Text = "你按下:" + (key == Keys.None ? "" : key.ToString());

}
}
}


版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/143071.html原文链接:https://javaforall.net

(0)
上一篇 2022年5月22日 下午12:20
下一篇 2022年5月22日 下午12:20


相关推荐

  • 静态库和动态库区别

    静态库和动态库区别转自静态库和动态库区别前言我们在编写代码的时候经常用到已有的接口 他们是以库的形式提供给我们使用的 而常见形式有两种 一种常以 a 为后缀 为静态库 另一种以 so 为后缀 为动态库 那么这两种库有什么区别呢 说明 本文主要说明 Linux 下的情况 windows 不涉及 目标文件在解释静态库和动态库之前 需要简单了解一下什么是目标文件 目标文件常常按照特定格式来组织 在 linux 下 它是 ELF 格式 ExecutableLi 可执行可链接格式 而在 windows 下是 PE P

    2025年7月6日
    9
  • 离散数学常见知识点

    离散数学常见知识点对于离散数学常见知识点的整理

    2026年3月16日
    2
  • hack DOS 基础测试网络命令

    hack DOS 基础测试网络命令

    2021年8月30日
    69
  • 三角剖分算法

    三角剖分算法目录一 引言 1 背景 2 研究意义二 散乱点集剖分算法 1 Lawson 算法 2 Bowyer 算法 3 算法的优化 4 程序实现三 三角形剖分算法 1 实现思想 2 代码实现一 引言 1 背景本算法来源于美术馆问题 美术馆问题如下 假如有一个凹四边形的美术馆 我们需要在美术馆当中安排尽可能少的警卫 使得他们能观察到美术馆的所有角落 对于一个形状复杂的美术馆 如下图示 至少需要安排多少个警卫呢 这就是著名的美术馆问题 ArtGaller

    2026年3月17日
    2
  • Double转BigDecimal小数点位数不一致问题「建议收藏」

    Double转BigDecimal小数点位数不一致问题「建议收藏」Doubledouble=1.23d;BigDecimalbd=newBigDecimal(double)时,出现转化得到的BigDecimaldb的小数点位数边长的问题。解决办法:BigDecimalbd=BigDecimal.valueof(double);

    2022年5月29日
    53
  • 字与字节的关系_一个比特等于多少字节

    字与字节的关系_一个比特等于多少字节之前一直认为1个字等于2个字节,刚在书中发现有个说法说,4个字节作为一个字,与之前记忆的1个字等于2个字节相违背,这才“较真”好好查了下相关的概念。基本概念字:计算机进行数据处理时,一次存取、加工和

    2022年8月2日
    8

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号